diff --git a/Engine b/Engine index 97f83a2..433db36 160000 --- a/Engine +++ b/Engine @@ -1 +1 @@ -Subproject commit 97f83a296a351af688a5f35494b943c0b2b141ae +Subproject commit 433db368f37a8f0a538d017610ce5cb11487d7fe diff --git a/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java b/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java index 62c3c7e..1798853 100644 --- a/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java +++ b/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java @@ -39,13 +39,6 @@ public class SurfaceManager { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map surfaces = new HashMap<>(); - public SurfaceManager replace(Biome biome, Surface surface) { - lock.writeLock().lock(); - surfaces.put(biome.getRegistryName(), surface); - lock.writeLock().unlock(); - return this; - } - public Surface getSurface(Biome biome) { lock.readLock().lock(); Surface surface = surfaces.get(biome.getRegistryName()); @@ -62,11 +55,44 @@ public class SurfaceManager { return surface; } - public SurfaceManager extend(Biome biome, Surface surface) { + public SurfaceManager replace(Biome biome, Surface surface) { + lock.writeLock().lock(); + surfaces.put(biome.getRegistryName(), surface); + lock.writeLock().unlock(); + return this; + } + + public SurfaceManager replace(Surface surface, Biome... biomes) { + for (Biome biome : biomes) { + replace(biome, surface); + } + return this; + } + + public SurfaceManager prepend(Biome biome, Surface surface) { + Surface result = surface.then(getOrCreateSurface(biome)); + return replace(biome, result); + } + + public SurfaceManager prepend(Surface surface, Biome... biomes) { + for (Biome biome : biomes) { + prepend(biome, surface); + } + return this; + } + + public SurfaceManager append(Biome biome, Surface surface) { Surface result = getOrCreateSurface(biome).then(surface); return replace(biome, result); } + public SurfaceManager append(Surface surface, Biome... biomes) { + for (Biome biome : biomes) { + append(biome, surface); + } + return this; + } + public Surface getSurface(SurfaceContext context) { if (context.biome == context.cached.biome) { return context.cached.surface; diff --git a/src/main/java/com/terraforged/biome/Dunes.java b/src/main/java/com/terraforged/biome/Dunes.java deleted file mode 100644 index 660e728..0000000 --- a/src/main/java/com/terraforged/biome/Dunes.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.terraforged.biome; - -import com.terraforged.api.biome.BiomeVariant; -import net.minecraft.entity.EntityClassification; -import net.minecraft.entity.EntityType; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biomes; -import net.minecraft.world.biome.DefaultBiomeFeatures; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.IFeatureConfig; -import net.minecraft.world.gen.feature.structure.MineshaftConfig; -import net.minecraft.world.gen.feature.structure.MineshaftStructure; -import net.minecraft.world.gen.feature.structure.VillageConfig; -import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; - -public class Dunes extends BiomeVariant { - - protected Dunes() { - super((new Biome.Builder()).surfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.SAND_SAND_GRAVEL_CONFIG).precipitation(Biome.RainType.NONE).category(Biome.Category.DESERT).depth(0.125F).scale(0.05F).temperature(2.0F).downfall(0.0F).waterColor(4159204).waterFogColor(329011).parent((String)null)); - this.addStructure(Feature.VILLAGE.withConfiguration(new VillageConfig("village/desert/town_centers", 6))); - this.addStructure(Feature.PILLAGER_OUTPOST.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG)); - this.addStructure(Feature.DESERT_PYRAMID.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG)); - this.addStructure(Feature.MINESHAFT.withConfiguration(new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL))); - this.addStructure(Feature.STRONGHOLD.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG)); - DefaultBiomeFeatures.addCarvers(this); - DefaultBiomeFeatures.addStructures(this); - DefaultBiomeFeatures.addMonsterRooms(this); - DefaultBiomeFeatures.addStoneVariants(this); - DefaultBiomeFeatures.addOres(this); - DefaultBiomeFeatures.addDefaultFlowers(this); - DefaultBiomeFeatures.addSparseGrass(this); - DefaultBiomeFeatures.addDeadBushes(this); - DefaultBiomeFeatures.addMushrooms(this); - DefaultBiomeFeatures.addFreezeTopLayer(this); - this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.RABBIT, 4, 2, 3)); - this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 19, 4, 4)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 1, 1, 1)); - this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.HUSK, 80, 4, 4)); - setRegistryName("terraforged", "dunes"); - } - - @Override - public Biome getBase() { - return Biomes.DESERT; - } -} diff --git a/src/main/java/com/terraforged/biome/ModBiomes.java b/src/main/java/com/terraforged/biome/ModBiomes.java index fe4c313..2b6aca0 100644 --- a/src/main/java/com/terraforged/biome/ModBiomes.java +++ b/src/main/java/com/terraforged/biome/ModBiomes.java @@ -41,7 +41,6 @@ public class ModBiomes { public static final Biome BRICE = register(new Brice()); public static final Biome COLD_STEPPE = register(new ColdSteppe()); - public static final Biome DUNES = register(new Dunes()); public static final Biome FIR_FOREST = register(new FirForest()); public static final Biome FLOWER_PLAINS = register(new FlowerPlains()); public static final Biome FROZEN_LAKE = register(new FrozenLake()); diff --git a/src/main/java/com/terraforged/biome/map/AbstractBiomeMap.java b/src/main/java/com/terraforged/biome/map/AbstractBiomeMap.java deleted file mode 100644 index 4895204..0000000 --- a/src/main/java/com/terraforged/biome/map/AbstractBiomeMap.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2020 TerraForged - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.terraforged.biome.map; - -import com.google.common.collect.Sets; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.terraforged.biome.ModBiomes; -import com.terraforged.biome.provider.BiomeHelper; -import com.terraforged.world.biome.BiomeType; -import me.dags.noise.util.NoiseUtil; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biomes; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public abstract class AbstractBiomeMap implements BiomeMap { - - private final Biome[][] beach; - private final Biome[][] river; - private final Biome[][] lake; - private final Biome[][] wetland; - private final Biome[][] ocean; - private final Biome[][] deepOcean; - - protected final DefaultBiome defaultLand = this::defaultBiome; - protected final DefaultBiome defaultBeach = this::defaultBeach; - protected final DefaultBiome defaultRiver = this::defaultRiver; - protected final DefaultBiome defaultLake = this::defaultLake; - protected final DefaultBiome defaultWetland = this::defaultWetland; - protected final DefaultBiome defaultOcean = this::defaultOcean; - protected final DefaultBiome defaultDeepOcean = this::defaultDeepOcean; - - protected AbstractBiomeMap(BiomeMapBuilder builder) { - river = builder.rivers(); - lake = builder.lakes(); - beach = builder.beaches(); - ocean = builder.oceans(); - wetland = builder.wetlands(); - deepOcean = builder.deepOceans(); - } - - @Override - public Biome getBeach(float temperature, float moisture, float shape) { - return get(beach, getCategory(temperature), shape, temperature, defaultBeach); - } - - @Override - public Biome getRiver(float temperature, float moisture, float shape) { - return get(river, getCategory(temperature), shape, temperature, defaultRiver); - } - - @Override - public Biome getLake(float temperature, float moisture, float shape) { - return get(lake, getCategory(temperature), shape, temperature, defaultLake); - } - - @Override - public Biome getWetland(float temperature, float moisture, float shape) { - return get(wetland, getCategory(temperature), shape, temperature, defaultWetland); - } - - @Override - public Biome getOcean(float temperature, float moisture, float shape) { - return get(ocean, getCategory(temperature), shape, temperature, defaultOcean); - } - - @Override - public Biome getDeepOcean(float temperature, float moisture, float shape) { - return get(deepOcean, getCategory(temperature), shape, temperature, defaultDeepOcean); - } - - @Override - public Set getOceanBiomes(Biome.TempCategory temp) { - return Sets.newHashSet(ocean[temp.ordinal() - 1]); - } - - @Override - public Set getDeepOceanBiomes(Biome.TempCategory temp) { - return Sets.newHashSet(deepOcean[temp.ordinal() - 1]); - } - - @Override - public Set getRivers(Biome.TempCategory temp) { - return Sets.newHashSet(river[temp.ordinal() - 1]); - } - - @Override - public JsonObject toJson() { - JsonObject root = new JsonObject(); - root.add("rivers", collect(river)); - root.add("wetland", collect(wetland)); - root.add("beaches", collect(beach)); - root.add("oceans", collect(ocean)); - root.add("deepOceans", collect(deepOcean)); - return root; - } - - private JsonObject collect(Biome[][] biomes) { - JsonObject root = new JsonObject(); - for (Biome.TempCategory temp : Biome.TempCategory.values()) { - if (temp == Biome.TempCategory.OCEAN) { - continue; - } - JsonArray array = new JsonArray(); - Biome[] group = biomes[temp.ordinal() - 1]; - if (group != null) { - Set set = new HashSet<>(); - Collections.addAll(set, group); - set.stream().map(BiomeHelper::getId).sorted().forEach(array::add); - } - root.add(temp.name(), array); - } - return root; - } - - - protected Biome.TempCategory getCategory(float value) { - if (value < 0.25) { - return Biome.TempCategory.COLD; - } - if (value > 0.75) { - return Biome.TempCategory.WARM; - } - return Biome.TempCategory.MEDIUM; - } - - protected Biome defaultBeach(float temperature) { - if (temperature < 0.25) { - return Biomes.SNOWY_BEACH; - } - if (temperature > 0.75) { - return ModBiomes.WARM_BEACH; - } - return Biomes.BEACH; - } - - protected Biome defaultRiver(float temperature) { - if (temperature < 0.15) { - return Biomes.FROZEN_RIVER; - } - return Biomes.RIVER; - } - - protected Biome defaultLake(float temperature) { - if (temperature < 0.15) { - return ModBiomes.FROZEN_LAKE; - } - return ModBiomes.LAKE; - } - - protected Biome defaultWetland(float temperature) { - if (temperature < 0.15) { - return ModBiomes.TAIGA_SCRUB; - } - return ModBiomes.MARSHLAND; - } - - protected Biome defaultOcean(float temperature) { - if (temperature < 0.3) { - return Biomes.FROZEN_OCEAN; - } - if (temperature > 0.7) { - return Biomes.WARM_OCEAN; - } - return Biomes.OCEAN; - } - - protected Biome defaultDeepOcean(float temperature) { - if (temperature < 0.3) { - return Biomes.DEEP_FROZEN_OCEAN; - } - if (temperature > 0.7) { - return Biomes.DEEP_WARM_OCEAN; - } - return Biomes.DEEP_OCEAN; - } - - protected Biome defaultBiome(float temperature) { - if (temperature < 0.3) { - return ModBiomes.TAIGA_SCRUB; - } - if (temperature > 0.7) { - return ModBiomes.SAVANNA_SCRUB; - } - return Biomes.PLAINS; - } - - protected Biome get(Biome[][] group, Biome.TempCategory category, float shape, float temp, DefaultBiome def) { - return get(group, category.ordinal() - 1, shape, temp, def); - } - - protected Biome get(Biome[][] group, BiomeType type, float shape, float temp, DefaultBiome def) { - return get(group, type.ordinal(), shape, temp, def); - } - - protected Biome get(Biome[][] group, int ordinal, float shape, float temp, DefaultBiome def) { - if (ordinal >= group.length) { - return def.getDefaultBiome(temp); - } - - Biome[] biomes = group[ordinal]; - if (biomes == null || biomes.length == 0) { - return def.getDefaultBiome(temp); - } - - int index = NoiseUtil.round((biomes.length - 1) * shape); - return biomes[index]; - } -} diff --git a/src/main/java/com/terraforged/biome/map/BasicBiomeMap.java b/src/main/java/com/terraforged/biome/map/BasicBiomeMap.java deleted file mode 100644 index 9401d7f..0000000 --- a/src/main/java/com/terraforged/biome/map/BasicBiomeMap.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2020 TerraForged - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.terraforged.biome.map; - -import com.google.common.collect.Sets; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.terraforged.biome.provider.BiomeHelper; -import com.terraforged.world.biome.BiomeType; -import net.minecraft.world.biome.Biome; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -public class BasicBiomeMap extends AbstractBiomeMap { - - private final Biome[][] biomeTypes; - - public BasicBiomeMap(BiomeMapBuilder builder) { - super(builder); - biomeTypes = builder.biomeList(); - } - - @Override - public List getAllBiomes(BiomeType type) { - if (type.ordinal() >= biomeTypes.length) { - return Collections.emptyList(); - } - return Arrays.asList(biomeTypes[type.ordinal()]); - } - - @Override - public Set getBiomes(BiomeType type) { - if (type.ordinal() >= biomeTypes.length) { - return Collections.emptySet(); - } - return Sets.newHashSet(biomeTypes[type.ordinal()]); - } - - @Override - public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { - return get(biomeTypes, type, shape, temperature, defaultLand); - } - - @Override - public JsonObject toJson() { - JsonObject groups = new JsonObject(); - for (BiomeType type : BiomeType.values()) { - JsonArray group = new JsonArray(); - getBiomes(type).stream().map(BiomeHelper::getId).sorted().forEach(group::add); - groups.add(type.name(), group); - } - JsonObject root = super.toJson(); - root.add("biomes", groups); - return root; - } -} diff --git a/src/main/java/com/terraforged/biome/map/BiomeMap.java b/src/main/java/com/terraforged/biome/map/BiomeMap.java index 50f8983..482fdd9 100644 --- a/src/main/java/com/terraforged/biome/map/BiomeMap.java +++ b/src/main/java/com/terraforged/biome/map/BiomeMap.java @@ -28,60 +28,50 @@ package com.terraforged.biome.map; import com.google.gson.JsonElement; import com.terraforged.core.cell.Cell; import com.terraforged.world.biome.BiomeType; +import com.terraforged.world.heightmap.Levels; import net.minecraft.world.biome.Biome; import java.util.List; -import java.util.Set; public interface BiomeMap { - Biome getBeach(float temperature, float moisture, float shape); + Biome getBeach(Cell cell); - Biome getRiver(float temperature, float moisture, float shape); + Biome getCoast(Cell cell, Biome current); - Biome getLake(float temperature, float moisture, float shape); + Biome getRiver(Cell cell); - Biome getWetland(float temperature, float moisture, float shape); + Biome getLake(Cell cell); - Biome getOcean(float temperature, float moisture, float shape); + Biome getWetland(Cell cell); - Biome getDeepOcean(float temperature, float moisture, float shape); + Biome getShallowOcean(Cell cell); - Biome getBiome(BiomeType type, float temperature, float moisture, float shape); + Biome getDeepOcean(Cell cell); - default Biome getBiome(Cell cell) { - return getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome); - } + Biome getLand(Cell cell); + + Biome provideBiome(Cell cell, Levels levels); List getAllBiomes(BiomeType type); - Set getBiomes(BiomeType type); - - Set getRivers(Biome.TempCategory temp); - - Set getOceanBiomes(Biome.TempCategory temp); - - Set getDeepOceanBiomes(Biome.TempCategory temp); - JsonElement toJson(); - static Biome getBiome(Biome biome) { - return biome.delegate.get(); - } - interface Builder { + Builder addOcean(Biome biome, int count); + Builder addBeach(Biome biome, int count); + Builder addCoast(Biome biome, int count); + Builder addRiver(Biome biome, int count); Builder addLake(Biome biome, int count); Builder addWetland(Biome biome, int count); - Builder addOcean(Biome biome, int count); - - Builder addBiome(BiomeType type, Biome biome, int count); + Builder addLand(BiomeType type, Biome biome, int count); BiomeMap build(); } diff --git a/src/main/java/com/terraforged/biome/map/BiomeMapBuilder.java b/src/main/java/com/terraforged/biome/map/BiomeMapBuilder.java index d60943a..61d6f6f 100644 --- a/src/main/java/com/terraforged/biome/map/BiomeMapBuilder.java +++ b/src/main/java/com/terraforged/biome/map/BiomeMapBuilder.java @@ -26,15 +26,10 @@ package com.terraforged.biome.map; import com.terraforged.biome.provider.BiomeHelper; -import com.terraforged.core.util.grid.FixedGrid; -import com.terraforged.util.ListUtils; -import com.terraforged.world.biome.BiomeData; import com.terraforged.world.biome.BiomeType; import net.minecraft.world.biome.Biome; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.EnumMap; import java.util.HashMap; import java.util.List; @@ -43,25 +38,19 @@ import java.util.function.Function; public class BiomeMapBuilder implements BiomeMap.Builder { - private final Map> rivers = new HashMap<>(); - private final Map> lakes = new HashMap<>(); - private final Map> wetlands = new HashMap<>(); - private final Map> beaches = new HashMap<>(); - private final Map> oceans = new HashMap<>(); - private final Map> deepOceans = new HashMap<>(); - private final Map> map = new EnumMap<>(BiomeType.class); - private final Map dataMap = new HashMap<>(); + protected final Map> rivers = new HashMap<>(); + protected final Map> lakes = new HashMap<>(); + protected final Map> wetlands = new HashMap<>(); + protected final Map> coasts = new HashMap<>(); + protected final Map> beaches = new HashMap<>(); + protected final Map> oceans = new HashMap<>(); + protected final Map> deepOceans = new HashMap<>(); + protected final Map> map = new EnumMap<>(BiomeType.class); - private final int gridSize; private final Function constructor; - BiomeMapBuilder(Function constructor, int gridSize, List biomes) { + BiomeMapBuilder(Function constructor) { this.constructor = constructor; - this.gridSize = gridSize; - - for (BiomeData data : biomes) { - dataMap.put((Biome) data.reference, data); - } } @Override @@ -82,6 +71,13 @@ public class BiomeMapBuilder implements BiomeMap.Builder { return this; } + @Override + public BiomeMap.Builder addCoast(Biome biome, int count) { + Biome.TempCategory category = BiomeHelper.getTempCategory(biome); + add(coasts.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + return this; + } + @Override public BiomeMapBuilder addRiver(Biome biome, int count) { Biome.TempCategory category = BiomeHelper.getTempCategory(biome); @@ -104,7 +100,7 @@ public class BiomeMapBuilder implements BiomeMap.Builder { } @Override - public BiomeMapBuilder addBiome(BiomeType type, Biome biome, int count) { + public BiomeMapBuilder addLand(BiomeType type, Biome biome, int count) { add(map.computeIfAbsent(type, t -> new ArrayList<>()), biome, count); return this; } @@ -114,87 +110,13 @@ public class BiomeMapBuilder implements BiomeMap.Builder { return constructor.apply(this); } - Biome[][] rivers() { - return collectTemps(rivers); - } - - Biome[][] lakes() { - return collectTemps(lakes); - } - - Biome[][] wetlands() { - return collectTemps(wetlands); - } - - Biome[][] beaches() { - return collectTemps(beaches); - } - - Biome[][] oceans() { - return collectTemps(oceans); - } - - Biome[][] deepOceans() { - return collectTemps(deepOceans); - } - - Biome[][] biomeList() { - return collectTypes(map); - } - - BiomeGroup[] biomeGroups() { - BiomeGroup[] biomes = new BiomeGroup[BiomeType.values().length]; - - Function moisture = b -> dataMap.get(b).rainfall; - Function temperature = b -> dataMap.get(b).temperature; - for (BiomeType type : BiomeType.values()) { - List list = map.getOrDefault(type, Collections.emptyList()); - if (list.isEmpty()) { - continue; - } - FixedGrid grid = FixedGrid.generate(gridSize, list, moisture, temperature); - biomes[type.ordinal()] = new BiomeGroup(grid); - } - - return biomes; - } - private void add(List list, Biome biome, int count) { for (int i = 0; i < count; i++) { list.add(biome); } } - private Biome[][] collectTemps(Map> map) { - Biome[][] biomes = new Biome[3][]; - for (Biome.TempCategory category : Biome.TempCategory.values()) { - if (category == Biome.TempCategory.OCEAN) { - continue; - } - List list = map.getOrDefault(category, Collections.emptyList()); - list = ListUtils.minimize(list); - list.sort(Comparator.comparing(BiomeHelper::getId)); - biomes[category.ordinal() - 1] = list.toArray(new Biome[0]); - } - return biomes; - } - - private Biome[][] collectTypes(Map> map) { - Biome[][] biomes = new Biome[BiomeType.values().length][]; - for (BiomeType type : BiomeType.values()) { - List list = map.getOrDefault(type, Collections.emptyList()); - list = ListUtils.minimize(list); - list.sort(Comparator.comparing(BiomeHelper::getId)); - biomes[type.ordinal()] = list.toArray(new Biome[0]); - } - return biomes; - } - - public static BiomeMap.Builder basic(List biomes) { - return new BiomeMapBuilder(BasicBiomeMap::new, 0, biomes); - } - - public static BiomeMap.Builder grid(int size, List biomes) { - return new BiomeMapBuilder(GridBiomeMap::new, size, biomes); + public static BiomeMap.Builder create() { + return new BiomeMapBuilder(SimpleBiomeMap::new); } } diff --git a/src/main/java/com/terraforged/biome/map/BiomePredicate.java b/src/main/java/com/terraforged/biome/map/BiomePredicate.java index 7841bde..e3477ee 100644 --- a/src/main/java/com/terraforged/biome/map/BiomePredicate.java +++ b/src/main/java/com/terraforged/biome/map/BiomePredicate.java @@ -84,7 +84,8 @@ public interface BiomePredicate { return false; } - BiomePredicate COAST = type(Biome.Category.BEACH, Biome.Category.MUSHROOM).or(name("shore")).or(name("beach")); + BiomePredicate BEACH = type(Biome.Category.BEACH).or(name("beach")); + BiomePredicate COAST = type(Biome.Category.MUSHROOM).or(name("coast")); BiomePredicate COLD_STEPPE = name("steppe").and(temp(-1, 0.3)); BiomePredicate DESERT = type(Biome.Category.DESERT).or(temp(0.9, 2).and(rain(-1, 0.2))); BiomePredicate GRASSLAND = type(Biome.Category.PLAINS); diff --git a/src/main/java/com/terraforged/biome/map/GridBiomeMap.java b/src/main/java/com/terraforged/biome/map/GridBiomeMap.java deleted file mode 100644 index 5670741..0000000 --- a/src/main/java/com/terraforged/biome/map/GridBiomeMap.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2020 TerraForged - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.terraforged.biome.map; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.terraforged.core.util.grid.FixedList; -import com.terraforged.core.util.grid.MappedList; -import com.terraforged.world.biome.BiomeType; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biomes; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public class GridBiomeMap extends AbstractBiomeMap { - - private final BiomeGroup[] biomeTypes; - - GridBiomeMap(BiomeMapBuilder builder) { - super(builder); - biomeTypes = builder.biomeGroups(); - } - - @Override - public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { - BiomeGroup group = biomeTypes[type.ordinal()]; - if (group == null) { - return Biomes.NETHER; - } - return group.biomes.get(moisture, temperature, shape); - } - - @Override - public List getAllBiomes(BiomeType type) { - BiomeGroup group = biomeTypes[type.ordinal()]; - if (group == null) { - return Collections.emptyList(); - } - List biomes = new LinkedList<>(); - for (MappedList> row : group.biomes) { - for (FixedList cell : row) { - for (Biome biome : cell) { - biomes.add(biome); - } - } - } - return biomes; - } - - @Override - public Set getBiomes(BiomeType type) { - BiomeGroup group = biomeTypes[type.ordinal()]; - if (group == null) { - return Collections.emptySet(); - } - Set biomes = new HashSet<>(); - for (MappedList> row : group.biomes) { - for (FixedList cell : row) { - for (Biome biome : cell) { - biomes.add(biome); - } - } - } - return biomes; - } - - @Override - public JsonObject toJson() { - JsonObject root = new JsonObject(); - for (BiomeType type : BiomeType.values()) { - BiomeGroup group = biomeTypes[type.ordinal()]; - JsonObject grid = new JsonObject(); - if (group != null) { - int rowCount = 0; - float maxRow = group.biomes.size() - 1; - for (MappedList> row : group.biomes) { - int colCount = 0; - float maxCol = row.size() - 1; - - JsonObject rowJson = new JsonObject(); - for (FixedList cell : row) { - JsonArray colJson = new JsonArray(); - for (Biome biome : cell.uniqueValues()) { - colJson.add(biome.getRegistryName() + ""); - } - float colId = colCount / maxCol; - rowJson.add("" + colId, colJson); - colCount++; - } - - float rowId = rowCount / maxRow; - grid.add("" + rowId, rowJson); - rowCount++; - } - } - root.add(type.name(), grid); - } - return root; - } -} diff --git a/src/main/java/com/terraforged/biome/map/SimpleBiomeMap.java b/src/main/java/com/terraforged/biome/map/SimpleBiomeMap.java new file mode 100644 index 0000000..d2bc26c --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/SimpleBiomeMap.java @@ -0,0 +1,132 @@ +package com.terraforged.biome.map; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.terraforged.biome.map.defaults.DefaultBiomes; +import com.terraforged.biome.map.set.BiomeSet; +import com.terraforged.biome.map.set.BiomeTypeSet; +import com.terraforged.biome.map.set.RiverSet; +import com.terraforged.biome.map.set.TemperatureSet; +import com.terraforged.core.cell.Cell; +import com.terraforged.world.biome.BiomeType; +import com.terraforged.world.heightmap.Levels; +import com.terraforged.world.terrain.TerrainType; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.world.biome.Biome; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SimpleBiomeMap implements BiomeMap { + + private final BiomeSet deepOcean; + private final BiomeSet shallowOcean; + private final BiomeSet beach; + private final BiomeSet coast; + private final BiomeSet river; + private final BiomeSet lake; + private final BiomeSet wetland; + private final BiomeSet land; + private final BiomeSet[] terrainBiomes; + + public SimpleBiomeMap(BiomeMapBuilder builder) { + deepOcean = new TemperatureSet(builder.deepOceans, DefaultBiomes::defaultDeepOcean); + shallowOcean = new TemperatureSet(builder.oceans, DefaultBiomes::defaultOcean); + beach = new TemperatureSet(builder.beaches, DefaultBiomes::defaultBeach); + coast = new TemperatureSet(builder.coasts, DefaultBiomes::defaultBiome); + river = new RiverSet(builder.rivers, DefaultBiomes::defaultRiver, this); + lake = new TemperatureSet(builder.lakes, DefaultBiomes::defaultLake); + wetland = new TemperatureSet(builder.wetlands, DefaultBiomes::defaultWetland); + land = new BiomeTypeSet(builder.map, DefaultBiomes::defaultBiome); + terrainBiomes = new BiomeSet[TerrainType.values().length]; + terrainBiomes[TerrainType.SHALLOW_OCEAN.ordinal()] = shallowOcean; + terrainBiomes[TerrainType.DEEP_OCEAN.ordinal()] = deepOcean; + terrainBiomes[TerrainType.WETLAND.ordinal()] = wetland; + terrainBiomes[TerrainType.RIVER.ordinal()] = river; + terrainBiomes[TerrainType.LAKE.ordinal()] = lake; + for (TerrainType type : TerrainType.values()) { + if (terrainBiomes[type.ordinal()] == null) { + terrainBiomes[type.ordinal()] = land; + } + } + } + + public Biome provideBiome(Cell cell, Levels levels) { + TerrainType type = cell.terrain.getType(); + if (type.isSubmerged() && cell.value > levels.water) { + return land.getBiome(cell); + } + return terrainBiomes[cell.terrain.getType().ordinal()].getBiome(cell); + } + + @Override + public Biome getDeepOcean(Cell cell) { + return deepOcean.getBiome(cell); + } + + @Override + public Biome getShallowOcean(Cell cell) { + return shallowOcean.getBiome(cell); + } + + @Override + public Biome getBeach(Cell cell) { + return beach.getBiome(cell); + } + + @Override + public Biome getCoast(Cell cell, Biome current) { + int inland = land.getSize(cell); + Biome[] coastal = coast.getSet(cell); + int total = inland + coastal.length; + int index = NoiseUtil.round((total - 1) * cell.biome); + if (index >= inland) { + return coastal[index - inland]; + } + return current; + } + + @Override + public Biome getRiver(Cell cell) { + return river.getBiome(cell); + } + + @Override + public Biome getLake(Cell cell) { + return lake.getBiome(cell); + } + + @Override + public Biome getWetland(Cell cell) { + return wetland.getBiome(cell); + } + + @Override + public Biome getLand(Cell cell) { + return land.getBiome(cell); + } + + @Override + public List getAllBiomes(BiomeType type) { + int size = land.getSize(type.ordinal()); + if (size == 0) { + return Collections.emptyList(); + } + return Arrays.asList(land.getSet(type.ordinal())); + } + + @Override + public JsonElement toJson() { + JsonObject root = new JsonObject(); + root.add("DEEP_OCEAN", deepOcean.toJson()); + root.add("SHALLOW_OCEAN", shallowOcean.toJson()); + root.add("BEACH", beach.toJson()); + root.add("COAST", coast.toJson()); + root.add("RIVER", river.toJson()); + root.add("LAKE", lake.toJson()); + root.add("WETLAND", wetland.toJson()); + root.add("LAND", land.toJson()); + return root; + } +} diff --git a/src/main/java/com/terraforged/biome/map/DefaultBiome.java b/src/main/java/com/terraforged/biome/map/defaults/DefaultBiome.java similarity index 84% rename from src/main/java/com/terraforged/biome/map/DefaultBiome.java rename to src/main/java/com/terraforged/biome/map/defaults/DefaultBiome.java index afba805..4472694 100644 --- a/src/main/java/com/terraforged/biome/map/DefaultBiome.java +++ b/src/main/java/com/terraforged/biome/map/defaults/DefaultBiome.java @@ -1,4 +1,4 @@ -package com.terraforged.biome.map; +package com.terraforged.biome.map.defaults; import net.minecraft.world.biome.Biome; diff --git a/src/main/java/com/terraforged/biome/map/defaults/DefaultBiomes.java b/src/main/java/com/terraforged/biome/map/defaults/DefaultBiomes.java new file mode 100644 index 0000000..d73b8df --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/defaults/DefaultBiomes.java @@ -0,0 +1,73 @@ +package com.terraforged.biome.map.defaults; + +import com.terraforged.biome.ModBiomes; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +public class DefaultBiomes { + + public static Biome defaultBeach(float temperature) { + if (temperature < 0.25) { + return Biomes.SNOWY_BEACH; + } + if (temperature > 0.75) { + return ModBiomes.WARM_BEACH; + } + return Biomes.BEACH; + } + + public static Biome defaultRiver(float temperature) { + if (temperature < 0.15) { + return Biomes.FROZEN_RIVER; + } + return Biomes.RIVER; + } + + public static Biome defaultLake(float temperature) { + if (temperature < 0.15) { + return ModBiomes.FROZEN_LAKE; + } + return ModBiomes.LAKE; + } + + public static Biome defaultWetland(float temperature) { + if (temperature < 0.15) { + return ModBiomes.TAIGA_SCRUB; + } + return ModBiomes.MARSHLAND; + } + + public static Biome defaultOcean(float temperature) { + if (temperature < 0.3) { + return Biomes.FROZEN_OCEAN; + } + if (temperature > 0.7) { + return Biomes.WARM_OCEAN; + } + return Biomes.OCEAN; + } + + public static Biome defaultDeepOcean(float temperature) { + if (temperature < 0.3) { + return Biomes.DEEP_FROZEN_OCEAN; + } + if (temperature > 0.7) { + return Biomes.DEEP_WARM_OCEAN; + } + return Biomes.DEEP_OCEAN; + } + + public static Biome defaultBiome(float temperature) { + if (temperature < 0.3) { + return ModBiomes.TAIGA_SCRUB; + } + if (temperature > 0.7) { + return ModBiomes.SAVANNA_SCRUB; + } + return Biomes.PLAINS; + } + + public static boolean overridesRiver(Biome biome) { + return biome.getCategory() == Biome.Category.SWAMP || biome.getCategory() == Biome.Category.JUNGLE; + } +} diff --git a/src/main/java/com/terraforged/biome/map/set/BiomeSet.java b/src/main/java/com/terraforged/biome/map/set/BiomeSet.java new file mode 100644 index 0000000..7c408e9 --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/set/BiomeSet.java @@ -0,0 +1,76 @@ +package com.terraforged.biome.map.set; + +import com.google.gson.JsonElement; +import com.terraforged.biome.map.defaults.DefaultBiome; +import com.terraforged.biome.provider.BiomeHelper; +import com.terraforged.core.cell.Cell; +import com.terraforged.util.ListUtils; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.world.biome.Biome; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public abstract class BiomeSet { + + private static final Biome[] EMPTY = new Biome[0]; + + private final Biome[][] biomes; + private final DefaultBiome defaultBiome; + + public BiomeSet(Biome[][] biomes, DefaultBiome defaultBiome) { + this.biomes = biomes; + this.defaultBiome = defaultBiome; + } + + public int getSize(int index) { + return biomes[index].length; + } + + public int getSize(Cell cell) { + return biomes[getIndex(cell)].length; + } + + public Biome[] getSet(int index) { + return biomes[index]; + } + + public Biome[] getSet(Cell cell) { + return biomes[getIndex(cell)]; + } + + public Biome getBiome(Cell cell) { + Biome[] set = biomes[getIndex(cell)]; + if (set.length == 0) { + return defaultBiome.getDefaultBiome(cell.temperature); + } + return set[NoiseUtil.round((set.length - 1) * cell.biome)]; + } + + public abstract int getIndex(Cell cell); + + public abstract JsonElement toJson(); + + protected static Biome[][] collect(Map, List> map, int size, Function, Integer> indexer) { + Biome[][] biomes = new Biome[size][]; + for (Enum type : map.keySet()) { + int index = indexer.apply(type); + if (index < 0 || index >= size) { + continue; + } + List list = map.getOrDefault(type, Collections.emptyList()); + list = ListUtils.minimize(list); + list.sort(Comparator.comparing(BiomeHelper::getId)); + biomes[index] = list.toArray(new Biome[0]); + } + for (int i = 0; i < size; i++) { + if (biomes[i] == null) { + biomes[i] = EMPTY; + } + } + return biomes; + } +} diff --git a/src/main/java/com/terraforged/biome/map/set/BiomeTypeSet.java b/src/main/java/com/terraforged/biome/map/set/BiomeTypeSet.java new file mode 100644 index 0000000..a9162e7 --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/set/BiomeTypeSet.java @@ -0,0 +1,37 @@ +package com.terraforged.biome.map.set; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.terraforged.biome.map.defaults.DefaultBiome; +import com.terraforged.core.cell.Cell; +import com.terraforged.world.biome.BiomeType; +import net.minecraft.world.biome.Biome; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +public class BiomeTypeSet extends BiomeSet { + + public BiomeTypeSet(Map> map, DefaultBiome defaultBiome) { + super(BiomeSet.collect(map, BiomeType.values().length, Enum::ordinal), defaultBiome); + } + + @Override + public int getIndex(Cell cell) { + return cell.biomeType.ordinal(); + } + + @Override + public JsonElement toJson() { + JsonObject root = new JsonObject(); + for (BiomeType type : BiomeType.values()) { + JsonArray array = new JsonArray(); + root.add(type.name(), array); + Stream.of(getSet(type.ordinal())).distinct().map(Biome::getRegistryName).map(Objects::toString).forEach(array::add); + } + return root; + } +} diff --git a/src/main/java/com/terraforged/biome/map/set/Check.java b/src/main/java/com/terraforged/biome/map/set/Check.java new file mode 100644 index 0000000..1ee9415 --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/set/Check.java @@ -0,0 +1,11 @@ +package com.terraforged.biome.map.set; + +import java.util.stream.Stream; + +public class Check { + + public static void main(String[] args) { + String[] s = {null}; + Stream.of(null).forEach(System.out::println); + } +} diff --git a/src/main/java/com/terraforged/biome/map/set/RiverSet.java b/src/main/java/com/terraforged/biome/map/set/RiverSet.java new file mode 100644 index 0000000..3f4b91d --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/set/RiverSet.java @@ -0,0 +1,29 @@ +package com.terraforged.biome.map.set; + +import com.terraforged.biome.map.BiomeMap; +import com.terraforged.biome.map.defaults.DefaultBiome; +import com.terraforged.biome.map.defaults.DefaultBiomes; +import com.terraforged.core.cell.Cell; +import net.minecraft.world.biome.Biome; + +import java.util.List; +import java.util.Map; + +public class RiverSet extends TemperatureSet { + + private final BiomeMap biomes; + + public RiverSet(Map> map, DefaultBiome defaultBiome, BiomeMap biomes) { + super(map, defaultBiome); + this.biomes = biomes; + } + + @Override + public Biome getBiome(Cell cell) { + Biome biome = biomes.getLand(cell); + if (DefaultBiomes.overridesRiver(biome)) { + return biome; + } + return super.getBiome(cell); + } +} diff --git a/src/main/java/com/terraforged/biome/map/set/TemperatureSet.java b/src/main/java/com/terraforged/biome/map/set/TemperatureSet.java new file mode 100644 index 0000000..be8ff48 --- /dev/null +++ b/src/main/java/com/terraforged/biome/map/set/TemperatureSet.java @@ -0,0 +1,45 @@ +package com.terraforged.biome.map.set; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.terraforged.biome.map.defaults.DefaultBiome; +import com.terraforged.core.cell.Cell; +import net.minecraft.world.biome.Biome; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +public class TemperatureSet extends BiomeSet { + + public TemperatureSet(Map> map, DefaultBiome defaultBiome) { + super(BiomeSet.collect(map, 3, e -> e.ordinal() - 1), defaultBiome); + } + + @Override + public int getIndex(Cell cell) { + if (cell.temperature < 0.25) { + return 0; + } + if (cell.temperature > 0.75) { + return 2; + } + return 1; + } + + @Override + public JsonElement toJson() { + JsonObject root = new JsonObject(); + for (Biome.TempCategory temp : Biome.TempCategory.values()) { + int index = temp.ordinal() - 1; + if (index >= 0 && index < 3) { + JsonArray array = new JsonArray(); + root.add(temp.name(), array); + Stream.of(getSet(index)).distinct().map(Biome::getRegistryName).map(Objects::toString).forEach(array::add); + } + } + return root; + } +} diff --git a/src/main/java/com/terraforged/biome/modifier/BeachModifier.java b/src/main/java/com/terraforged/biome/modifier/BeachModifier.java index b1cd91a..234ae34 100644 --- a/src/main/java/com/terraforged/biome/modifier/BeachModifier.java +++ b/src/main/java/com/terraforged/biome/modifier/BeachModifier.java @@ -1,53 +1,33 @@ -/* - * - * MIT License - * - * Copyright (c) 2020 TerraForged - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - package com.terraforged.biome.modifier; import com.terraforged.api.biome.modifier.BiomeModifier; import com.terraforged.biome.map.BiomeMap; -import com.terraforged.chunk.TerraContext; import com.terraforged.core.cell.Cell; -import com.terraforged.world.heightmap.Levels; +import com.terraforged.world.GeneratorContext; +import com.terraforged.world.biome.BiomeType; import com.terraforged.world.terrain.Terrains; +import me.dags.noise.Module; +import me.dags.noise.Source; import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; public class BeachModifier implements BiomeModifier { - private final Levels levels; - private final Terrains terrain; - private final BiomeMap biomeMap; + private final float height; + private final Module noise; + private final BiomeMap biomes; + private final Terrains terrains; - public BeachModifier(BiomeMap biomeMap, TerraContext context) { - this.levels = context.levels; - this.terrain = context.terrain; - this.biomeMap = biomeMap; + public BeachModifier(BiomeMap biomeMap, GeneratorContext context) { + this.biomes = biomeMap; + this.terrains = context.terrain; + this.height = context.levels.water(6); + this.noise = Source.perlin(context.seed.next(), 10, 1).scale(context.levels.scale(5)); } @Override public int priority() { - return 0; + return 9; } @Override @@ -57,11 +37,13 @@ public class BeachModifier implements BiomeModifier { @Override public Biome modify(Biome in, Cell cell, int x, int z) { - if (cell.terrain == terrain.beach) { - return biomeMap.getBeach(cell.temperature, cell.moisture, cell.biome); - } - if (cell.terrain == terrain.coast && cell.value <= levels.water) { - return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome); + if (cell.terrain == terrains.beach && cell.biomeType != BiomeType.DESERT) { + if (cell.value + noise.getValue(x, z) < height) { + if (in == Biomes.MUSHROOM_FIELDS) { + return Biomes.MUSHROOM_FIELD_SHORE; + } + return biomes.getBeach(cell); + } } return in; } diff --git a/src/main/java/com/terraforged/biome/modifier/BiomeModifierManager.java b/src/main/java/com/terraforged/biome/modifier/BiomeModifierManager.java index 25a8958..a4d4a98 100644 --- a/src/main/java/com/terraforged/biome/modifier/BiomeModifierManager.java +++ b/src/main/java/com/terraforged/biome/modifier/BiomeModifierManager.java @@ -47,10 +47,10 @@ public class BiomeModifierManager implements BiomeModifier, ModifierManager { public BiomeModifierManager(TerraContext context, BiomeMap biomes) { desertBiomes = new DesertBiomes(context.materials, biomes.getAllBiomes(BiomeType.DESERT)); List modifiers = new ArrayList<>(); - modifiers.add(new BeachModifier(biomes, context)); + modifiers.add(new CoastModifier(biomes, context)); modifiers.add(new DesertColorModifier(desertBiomes)); modifiers.add(new SandBiomeModifier(context)); - modifiers.add(new MushroomModifier()); + modifiers.add(new BeachModifier(biomes, context)); Collections.sort(modifiers); this.biomeModifiers = modifiers; } diff --git a/src/main/java/com/terraforged/biome/map/BiomeGroup.java b/src/main/java/com/terraforged/biome/modifier/CoastModifier.java similarity index 55% rename from src/main/java/com/terraforged/biome/map/BiomeGroup.java rename to src/main/java/com/terraforged/biome/modifier/CoastModifier.java index 0496819..ba95d13 100644 --- a/src/main/java/com/terraforged/biome/map/BiomeGroup.java +++ b/src/main/java/com/terraforged/biome/modifier/CoastModifier.java @@ -23,16 +23,42 @@ * SOFTWARE. */ -package com.terraforged.biome.map; +package com.terraforged.biome.modifier; -import com.terraforged.core.util.grid.FixedGrid; +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.biome.map.BiomeMap; +import com.terraforged.chunk.TerraContext; +import com.terraforged.core.cell.Cell; +import com.terraforged.world.terrain.Terrains; import net.minecraft.world.biome.Biome; -public class BiomeGroup { +public class CoastModifier implements BiomeModifier { - public final FixedGrid biomes; + private final float height; + private final Terrains terrain; + private final BiomeMap biomeMap; - public BiomeGroup(FixedGrid biomes) { - this.biomes = biomes; + public CoastModifier(BiomeMap biomeMap, TerraContext context) { + this.terrain = context.terrain; + this.biomeMap = biomeMap; + this.height = context.levels.water(8); + } + + @Override + public int priority() { + return 10; + } + + @Override + public boolean test(Biome biome) { + return true; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + if (cell.terrain.isCoast()) { + return biomeMap.getCoast(cell, in); + } + return in; } } diff --git a/src/main/java/com/terraforged/biome/modifier/DesertColorModifier.java b/src/main/java/com/terraforged/biome/modifier/DesertColorModifier.java index ab17ccd..d5ab84f 100644 --- a/src/main/java/com/terraforged/biome/modifier/DesertColorModifier.java +++ b/src/main/java/com/terraforged/biome/modifier/DesertColorModifier.java @@ -40,7 +40,7 @@ public class DesertColorModifier implements BiomeModifier { @Override public int priority() { - return 0; + return 5; } @Override diff --git a/src/main/java/com/terraforged/biome/modifier/DunesModifier.java b/src/main/java/com/terraforged/biome/modifier/DunesModifier.java deleted file mode 100644 index bb2b934..0000000 --- a/src/main/java/com/terraforged/biome/modifier/DunesModifier.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.terraforged.biome.modifier; - -import com.terraforged.api.biome.modifier.BiomeModifier; -import com.terraforged.core.cell.Cell; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biomes; - -public class DunesModifier implements BiomeModifier { - - @Override - public int priority() { - return 0; - } - - @Override - public boolean test(Biome biome) { - return biome.getCategory() == Biome.Category.DESERT; - } - - @Override - public Biome modify(Biome in, Cell cell, int x, int z) { - return Biomes.DESERT; - } -} diff --git a/src/main/java/com/terraforged/biome/modifier/MushroomModifier.java b/src/main/java/com/terraforged/biome/modifier/MushroomModifier.java deleted file mode 100644 index 97a30c2..0000000 --- a/src/main/java/com/terraforged/biome/modifier/MushroomModifier.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.terraforged.biome.modifier; - -import com.terraforged.api.biome.modifier.BiomeModifier; -import com.terraforged.core.cell.Cell; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biomes; - -public class MushroomModifier implements BiomeModifier { - @Override - public int priority() { - return 0; - } - - @Override - public boolean test(Biome biome) { - return biome == Biomes.MUSHROOM_FIELD_SHORE; - } - - @Override - public Biome modify(Biome in, Cell cell, int x, int z) { - return Biomes.MUSHROOM_FIELDS; - } -} diff --git a/src/main/java/com/terraforged/biome/modifier/SandBiomeModifier.java b/src/main/java/com/terraforged/biome/modifier/SandBiomeModifier.java index 98ace32..e7bda85 100644 --- a/src/main/java/com/terraforged/biome/modifier/SandBiomeModifier.java +++ b/src/main/java/com/terraforged/biome/modifier/SandBiomeModifier.java @@ -48,7 +48,7 @@ public class SandBiomeModifier extends AbstractMaxHeightModifier { @Override public int priority() { - return 1; + return 3; } @Override diff --git a/src/main/java/com/terraforged/biome/provider/BiomeAccess.java b/src/main/java/com/terraforged/biome/provider/BiomeAccess.java deleted file mode 100644 index ab31fb8..0000000 --- a/src/main/java/com/terraforged/biome/provider/BiomeAccess.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.terraforged.biome.provider; - -import com.terraforged.core.cell.Cell; -import com.terraforged.world.heightmap.Levels; -import com.terraforged.world.terrain.TerrainType; -import net.minecraft.world.biome.Biome; - -public class BiomeAccess { - - private static final BiomeAccessor DEEP_OCEAN = (m, c) -> m.getDeepOcean(c.temperature, c.moisture, c.biome); - private static final BiomeAccessor SHALLOW_OCEAN = (m, c) -> m.getOcean(c.temperature, c.moisture, c.biome); - private static final BiomeAccessor LAKE = (m, c) -> m.getLake(c.temperature, c.moisture, c.biome); - private static final BiomeAccessor WETLAND = (m, c) -> m.getWetland(c.temperature, c.moisture, c.biome); - private static final BiomeAccessor NORMAL = (m, c) -> m.getBiome(c.biomeType, c.temperature, c.moisture, c.biome); - private static final BiomeAccessor RIVER = (m, c) -> { - Biome biome = m.getBiome(c.biomeType, c.temperature, c.moisture, c.biome); - if (overridesRiver(biome)) { - return biome; - } - return m.getRiver(c.temperature, c.moisture, c.biome); - }; - - private static final BiomeAccessor[] accessors = createAccessorArray(); - - private final Levels levels; - - public BiomeAccess(Levels levels) { - this.levels = levels; - } - - public BiomeAccessor getAccessor(Cell cell) { - TerrainType type = cell.terrain.getType(); - if (type.isSubmerged() && cell.value > levels.water) { - return NORMAL; - } - return accessors[cell.terrain.getType().ordinal()]; - } - - private static BiomeAccessor[] createAccessorArray() { - BiomeAccessor[] accessors = new BiomeAccessor[TerrainType.values().length]; - accessors[TerrainType.SHALLOW_OCEAN.ordinal()] = SHALLOW_OCEAN; - accessors[TerrainType.DEEP_OCEAN.ordinal()] = DEEP_OCEAN; - accessors[TerrainType.WETLAND.ordinal()] = WETLAND; - accessors[TerrainType.RIVER.ordinal()] = RIVER; - accessors[TerrainType.LAKE.ordinal()] = LAKE; - for (TerrainType type : TerrainType.values()) { - if (accessors[type.ordinal()] == null) { - accessors[type.ordinal()] = NORMAL; - } - } - return accessors; - } - - private static boolean overridesRiver(Biome biome) { - return biome.getCategory() == Biome.Category.SWAMP || biome.getCategory() == Biome.Category.JUNGLE; - } -} diff --git a/src/main/java/com/terraforged/biome/provider/BiomeAccessor.java b/src/main/java/com/terraforged/biome/provider/BiomeAccessor.java deleted file mode 100644 index 1d58350..0000000 --- a/src/main/java/com/terraforged/biome/provider/BiomeAccessor.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.terraforged.biome.provider; - -import com.terraforged.biome.map.BiomeMap; -import com.terraforged.core.cell.Cell; -import net.minecraft.world.biome.Biome; - -public interface BiomeAccessor { - - Biome getBiome(BiomeMap map, Cell cell); -} diff --git a/src/main/java/com/terraforged/biome/provider/BiomeHelper.java b/src/main/java/com/terraforged/biome/provider/BiomeHelper.java index e79a972..e4ea305 100644 --- a/src/main/java/com/terraforged/biome/provider/BiomeHelper.java +++ b/src/main/java/com/terraforged/biome/provider/BiomeHelper.java @@ -54,26 +54,22 @@ public class BiomeHelper { private static final Map PREDICATES = new HashMap() {{ put(BiomeType.TROPICAL_RAINFOREST, BiomePredicate.TROPICAL_RAINFOREST); - put(BiomeType.SAVANNA, BiomePredicate.SAVANNA.or(BiomePredicate.MESA).not(BiomePredicate.DESERT).not(BiomePredicate.STEPPE).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); - put(BiomeType.DESERT, BiomePredicate.DESERT.or(BiomePredicate.MESA).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); - put(BiomeType.TEMPERATE_RAINFOREST, BiomePredicate.TEMPERATE_RAINFOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); - put(BiomeType.TEMPERATE_FOREST, BiomePredicate.TEMPERATE_FOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); - put(BiomeType.GRASSLAND, BiomePredicate.GRASSLAND.not(BiomePredicate.WETLAND).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); - put(BiomeType.COLD_STEPPE, BiomePredicate.COLD_STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); - put(BiomeType.STEPPE, BiomePredicate.STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); - put(BiomeType.TAIGA, BiomePredicate.TAIGA.not(BiomePredicate.TUNDRA).not(BiomePredicate.COLD_STEPPE).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); - put(BiomeType.TUNDRA, BiomePredicate.TUNDRA.not(BiomePredicate.TAIGA).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.SAVANNA, BiomePredicate.SAVANNA.or(BiomePredicate.MESA).not(BiomePredicate.DESERT).not(BiomePredicate.STEPPE).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.DESERT, BiomePredicate.DESERT.or(BiomePredicate.MESA).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.TEMPERATE_RAINFOREST, BiomePredicate.TEMPERATE_RAINFOREST.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TEMPERATE_FOREST, BiomePredicate.TEMPERATE_FOREST.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.GRASSLAND, BiomePredicate.GRASSLAND.not(BiomePredicate.WETLAND).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.COLD_STEPPE, BiomePredicate.COLD_STEPPE.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.STEPPE, BiomePredicate.STEPPE.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TAIGA, BiomePredicate.TAIGA.not(BiomePredicate.TUNDRA).not(BiomePredicate.COLD_STEPPE).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TUNDRA, BiomePredicate.TUNDRA.not(BiomePredicate.TAIGA).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN)); put(BiomeType.ALPINE, BiomePredicate.MOUNTAIN); }}; - public static BiomeMap.Builder getBuilder(List biomes) { - return BiomeMapBuilder.basic(biomes); - } - - public static BiomeMap getDefaultBiomeMap() { + public static BiomeMap createBiomeMap() { List biomes = getAllBiomeData(); BiomeWeights weights = new BiomeWeights(); - BiomeMap.Builder builder = getBuilder(biomes); + BiomeMap.Builder builder = BiomeMapBuilder.create(); for (BiomeData data : biomes) { Biome biome = (Biome) data.reference; if (biome.isMutation() && getId(biome).contains("hills")) { @@ -81,8 +77,10 @@ public class BiomeHelper { } int weight = weights.getWeight(biome); - if (BiomePredicate.COAST.test(data)) { + if (BiomePredicate.BEACH.test(data)) { builder.addBeach(biome, weight); + } else if (BiomePredicate.COAST.test(data)) { + builder.addCoast(biome, weight); } else if (biome.getCategory() == Biome.Category.OCEAN) { builder.addOcean(biome, weight); } else if (BiomePredicate.RIVER.test(data)) { @@ -94,16 +92,16 @@ public class BiomeHelper { } else { Collection types = getTypes(data, biome); for (BiomeType type : types) { - builder.addBiome(type, biome, weight); + builder.addLand(type, biome, weight); } } } - builder.addBiome(BiomeType.TEMPERATE_RAINFOREST, Biomes.PLAINS, 10); - builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.FLOWER_FOREST, 2); - builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.PLAINS, 10); - builder.addBiome(BiomeType.TUNDRA, ModBiomes.SNOWY_TAIGA_SCRUB, 5); - builder.addBiome(BiomeType.TAIGA, ModBiomes.TAIGA_SCRUB, 5); + builder.addLand(BiomeType.TEMPERATE_RAINFOREST, Biomes.PLAINS, 5); + builder.addLand(BiomeType.TEMPERATE_FOREST, Biomes.FLOWER_FOREST, 2); + builder.addLand(BiomeType.TEMPERATE_FOREST, Biomes.PLAINS, 5); + builder.addLand(BiomeType.TUNDRA, ModBiomes.SNOWY_TAIGA_SCRUB, 2); + builder.addLand(BiomeType.TAIGA, ModBiomes.TAIGA_SCRUB, 2); return builder.build(); } @@ -185,6 +183,9 @@ public class BiomeHelper { if (biome.getCategory() == Biome.Category.NETHER) { return true; } + if (biome == Biomes.MUSHROOM_FIELD_SHORE) { + return true; + } return !BiomeDictionary.getTypes(biome).contains(BiomeDictionary.Type.OVERWORLD); } diff --git a/src/main/java/com/terraforged/biome/provider/BiomeProvider.java b/src/main/java/com/terraforged/biome/provider/BiomeProvider.java index f5726d3..51c2864 100644 --- a/src/main/java/com/terraforged/biome/provider/BiomeProvider.java +++ b/src/main/java/com/terraforged/biome/provider/BiomeProvider.java @@ -47,7 +47,6 @@ import java.util.Set; public class BiomeProvider extends AbstractBiomeProvider { private final BiomeMap biomeMap; - private final BiomeAccess biomeAccess; private final TerraContext context; private final WorldLookup worldLookup; private final BiomeModifierManager modifierManager; @@ -55,8 +54,7 @@ public class BiomeProvider extends AbstractBiomeProvider { public BiomeProvider(TerraContext context) { this.context = context; - this.biomeMap = BiomeHelper.getDefaultBiomeMap(); - this.biomeAccess = new BiomeAccess(context.levels); + this.biomeMap = BiomeHelper.createBiomeMap(); this.worldLookup = new WorldLookup(context.factory, context); this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy()); } @@ -143,8 +141,7 @@ public class BiomeProvider extends AbstractBiomeProvider { } public Biome getBiome(Cell cell, int x, int z) { - BiomeAccessor accessor = biomeAccess.getAccessor(cell); - Biome biome = accessor.getBiome(biomeMap, cell); + Biome biome = biomeMap.provideBiome(cell, context.levels); if (modifierManager.hasModifiers(cell.terrain)) { return modifierManager.modify(biome, cell, x, z); } diff --git a/src/main/java/com/terraforged/biome/surface/ForestSurface.java b/src/main/java/com/terraforged/biome/surface/ForestSurface.java new file mode 100644 index 0000000..f3faa5c --- /dev/null +++ b/src/main/java/com/terraforged/biome/surface/ForestSurface.java @@ -0,0 +1,36 @@ +package com.terraforged.biome.surface; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.material.state.States; +import com.terraforged.world.GeneratorContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; + +public class ForestSurface implements Surface { + + private final Module noise; + + public ForestSurface(GeneratorContext context) { + noise = Source.simplex(context.seed.next(), 40, 2).warp(Source.RAND, context.seed.next(), 2, 1, 4); + } + + @Override + public void buildSurface(int x, int z, int height, SurfaceContext ctx) { + BlockState state = getMaterial(x, z); + ctx.buffer.setBlockState(ctx.pos.setPos(x, height, z), state, false); + } + + private BlockState getMaterial(int x, int z) { + float value = noise.getValue(x, z); + if (value > 0.6) { + if (value < 0.75) { + return Blocks.PODZOL.getDefaultState(); + } + return States.DIRT.get(); + } + return States.GRASS_BLOCK.get(); + } +} diff --git a/src/main/java/com/terraforged/chunk/TerraSetupFactory.java b/src/main/java/com/terraforged/chunk/TerraSetupFactory.java index 0165c25..931b28c 100644 --- a/src/main/java/com/terraforged/chunk/TerraSetupFactory.java +++ b/src/main/java/com/terraforged/chunk/TerraSetupFactory.java @@ -5,10 +5,10 @@ import com.terraforged.api.chunk.column.ColumnDecorator; import com.terraforged.api.chunk.surface.SurfaceManager; import com.terraforged.biome.ModBiomes; import com.terraforged.biome.surface.BriceSurface; +import com.terraforged.biome.surface.ForestSurface; import com.terraforged.biome.surface.IcebergsSurface; import com.terraforged.biome.surface.SwampSurface; import com.terraforged.chunk.column.BedrockDecorator; -import com.terraforged.chunk.column.CoastDecorator; import com.terraforged.chunk.column.ErosionDecorator; import com.terraforged.chunk.column.GeologyDecorator; import com.terraforged.chunk.column.post.LayerDecorator; @@ -53,7 +53,6 @@ public class TerraSetupFactory { Log.info(" - Erosion decorator enabled"); processors.add(new ErosionDecorator(context)); } - processors.add(new CoastDecorator(context)); processors.add(new BedrockDecorator(context)); return processors; } @@ -112,9 +111,21 @@ public class TerraSetupFactory { SurfaceManager manager = new SurfaceManager(); manager.replace(Biomes.DEEP_FROZEN_OCEAN.delegate.get(), new IcebergsSurface(context, 30, 30)); manager.replace(Biomes.FROZEN_OCEAN.delegate.get(), new IcebergsSurface(context, 20, 15)); - manager.replace(Biomes.SWAMP.delegate.get(), new SwampSurface()); - manager.replace(ModBiomes.MARSHLAND, new SwampSurface()); - manager.extend(ModBiomes.BRICE, new BriceSurface(context.seed)); + manager.append(ModBiomes.BRICE, new BriceSurface(context.seed)); + manager.replace( + new SwampSurface(), + Biomes.SWAMP.delegate.get(), + ModBiomes.MARSHLAND + ); + manager.append( + new ForestSurface(context), + Biomes.FOREST, + Biomes.BIRCH_FOREST, + Biomes.BIRCH_FOREST_HILLS, + Biomes.TALL_BIRCH_FOREST, + Biomes.DARK_FOREST, + Biomes.DARK_FOREST_HILLS + ); return SetupHooks.setup(manager, context); } diff --git a/src/main/java/com/terraforged/data/WorldGenBiomes.java b/src/main/java/com/terraforged/data/WorldGenBiomes.java index c97e777..057685b 100644 --- a/src/main/java/com/terraforged/data/WorldGenBiomes.java +++ b/src/main/java/com/terraforged/data/WorldGenBiomes.java @@ -26,56 +26,28 @@ package com.terraforged.data; import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; import com.terraforged.biome.map.BiomeMap; import com.terraforged.biome.provider.BiomeHelper; import com.terraforged.world.biome.BiomeType; import net.minecraft.util.ResourceLocation; -import net.minecraft.world.biome.Biome; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; -import java.util.Set; public class WorldGenBiomes extends DataGen { public static void genBiomeMap(File dataDir) { - BiomeMap map = BiomeHelper.getDefaultBiomeMap(); - for (BiomeType type : BiomeType.values()) { - genBiomes(dataDir, type, map); - } - - try (Writer writer = new BufferedWriter(new FileWriter(new File("biome_map.json")))) { + BiomeMap map = BiomeHelper.createBiomeMap(); + try (Writer writer = new BufferedWriter(new FileWriter(new File(dataDir, "biome_map.json")))) { new GsonBuilder().setPrettyPrinting().create().toJson(map.toJson(), writer); } catch (IOException e) { e.printStackTrace(); } } - private static void genBiomes(File dir, BiomeType type, BiomeMap map) { - String path = getJsonPath("tags/biomes", getName(type)); - - write(new File(dir, path), writer -> { - Set biomes = map.getBiomes(type); - JsonObject root = new JsonObject(); - JsonArray values = new JsonArray(); - - root.addProperty("replaceable", false); - root.add("values", values); - - biomes.stream() - .map(b -> b.getRegistryName() + "") - .sorted() - .forEach(values::add); - - write(root, writer); - }); - } - private static ResourceLocation getName(BiomeType type) { return new ResourceLocation("terraforged", type.name().toLowerCase()); } diff --git a/src/main/java/com/terraforged/material/Materials.java b/src/main/java/com/terraforged/material/Materials.java index 35f60c5..4ec046d 100644 --- a/src/main/java/com/terraforged/material/Materials.java +++ b/src/main/java/com/terraforged/material/Materials.java @@ -41,7 +41,12 @@ import net.minecraft.block.MyceliumBlock; import net.minecraft.tags.BlockTags; import net.minecraft.tags.Tag; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.registries.IForgeRegistryEntry; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Set; public class Materials { @@ -103,4 +108,16 @@ public class Materials { return state.getBlockHardness(reader.get(), BlockPos.ZERO); } } + + public static > List toList(Collection collection) { + List list = new ArrayList<>(collection); + list.sort(Materials::compare); + return Collections.unmodifiableList(list); + } + + public static int compare(IForgeRegistryEntry a, IForgeRegistryEntry b) { + String as = a.getRegistryName() + ""; + String bs = b.getRegistryName() + ""; + return as.compareTo(bs); + } } diff --git a/src/main/java/com/terraforged/material/geology/GeoGenerator.java b/src/main/java/com/terraforged/material/geology/GeoGenerator.java index 3ae90eb..57a0299 100644 --- a/src/main/java/com/terraforged/material/geology/GeoGenerator.java +++ b/src/main/java/com/terraforged/material/geology/GeoGenerator.java @@ -48,10 +48,10 @@ public class GeoGenerator implements StrataGenerator { public GeoGenerator(Materials materials) { types.add(Source.PERLIN); - rock = new ArrayList<>(materials.stone); - soil = new ArrayList<>(materials.dirt); - clay = new ArrayList<>(materials.clay); - sediment = new ArrayList<>(materials.sediment); + rock = Materials.toList(materials.stone); + soil = Materials.toList(materials.dirt); + clay = Materials.toList(materials.clay); + sediment = Materials.toList(materials.sediment); } @Override diff --git a/src/main/resources/data/terraforged/features/shrubs/birch_forest_bush.json b/src/main/resources/data/terraforged/features/shrubs/birch_forest_bush.json new file mode 100644 index 0000000..d3ab905 --- /dev/null +++ b/src/main/resources/data/terraforged/features/shrubs/birch_forest_bush.json @@ -0,0 +1,115 @@ +{ + "biomes": [ + "minecraft:birch*", + "minecraft:tall_birch*" + ], + "match": [ + [ + "minecraft:birch_log", + "minecraft:birch_leaves" + ], + [ + "terraforged:poisson_surface" + ] + ], + "after": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:birch_leaves", + "Properties": { + "distance": "3", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 3 + }, + "chance": 0.15 + }, + { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_leaves", + "Properties": { + "distance": "3", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 4 + }, + "chance": 0.25 + } + ], + "default": { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_leaves", + "Properties": { + "distance": "3", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 3 + } + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 0, + "extra_chance": 0.05, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/terraforged/features/shrubs/forest_bush.json b/src/main/resources/data/terraforged/features/shrubs/forest_bush.json new file mode 100644 index 0000000..9537464 --- /dev/null +++ b/src/main/resources/data/terraforged/features/shrubs/forest_bush.json @@ -0,0 +1,117 @@ +{ + "biomes": [ + "minecraft:forest", + "minecraft:forest_hills", + "minecraft:dark_forest", + "minecraft:dark_forest_hills" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ], + [ + "terraforged:poisson_surface" + ] + ], + "after": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:birch_leaves", + "Properties": { + "distance": "3", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 3 + }, + "chance": 0.15 + }, + { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_leaves", + "Properties": { + "distance": "3", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 4 + }, + "chance": 0.25 + } + ], + "default": { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_leaves", + "Properties": { + "distance": "3", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 3 + } + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 1, + "extra_chance": 0.05, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/terraforged/features/shrubs/forest_fern.json b/src/main/resources/data/terraforged/features/shrubs/forest_fern.json new file mode 100644 index 0000000..8783843 --- /dev/null +++ b/src/main/resources/data/terraforged/features/shrubs/forest_fern.json @@ -0,0 +1,110 @@ +{ + "biomes": [ + "minecraft:birch*", + "minecraft:tall_birch*", + "minecraft:forest", + "minecraft:forest_hills", + "minecraft:dark_forest", + "minecraft:dark_forest_hills" + ], + "match": [ + [ + "minecraft:decorated", + "minecraft:grass" + ] + ], + "after": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:fern" + } + }, + "block_placer": { + "type": "minecraft:simple_block_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 20, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": true, + "need_water": false + }, + "chance": 0.3 + }, + { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:large_fern", + "Properties": { + "half": "lower" + } + } + }, + "block_placer": { + "type": "minecraft:double_plant_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 20, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": false, + "need_water": false + }, + "chance": 0.2 + } + ], + "default": { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:fern" + } + }, + "block_placer": { + "type": "minecraft:simple_block_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 10, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": true, + "need_water": false + } + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 1, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/terraforged/features/shrubs/forest_grass.json b/src/main/resources/data/terraforged/features/shrubs/forest_grass.json index e6a19e9..4959c94 100644 --- a/src/main/resources/data/terraforged/features/shrubs/forest_grass.json +++ b/src/main/resources/data/terraforged/features/shrubs/forest_grass.json @@ -1,7 +1,7 @@ { "biomes": [ - "minecraft:birch_forest", - "minecraft:birch_forest_hills", + "minecraft:birch*", + "minecraft:tall_birch*", "minecraft:forest", "minecraft:forest_hills", "minecraft:dark_forest", diff --git a/src/main/resources/data/terraforged/features/trees/acacia_bush.json b/src/main/resources/data/terraforged/features/trees/acacia_bush.json new file mode 100644 index 0000000..b2d7dbf --- /dev/null +++ b/src/main/resources/data/terraforged/features/trees/acacia_bush.json @@ -0,0 +1,44 @@ +{ + "biomes": [ + "terraforged:savanna_scrub", + "terraforged:shattered_savanna_scrub" + ], + "match": [ + [ + "minecraft:dead_bush" + ] + ], + "before": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:template", + "config": { + "template": "terraforged:acacia_bush" + }, + "chance": 0.1 + } + ], + "default": { + "name": "terraforged:template", + "config": { + "template": "terraforged:acacia_bush" + } + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 0, + "extra_chance": 0.025, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/terraforged/features/trees/birch.json b/src/main/resources/data/terraforged/features/trees/birch.json index c73c3ea..8cca74a 100644 --- a/src/main/resources/data/terraforged/features/trees/birch.json +++ b/src/main/resources/data/terraforged/features/trees/birch.json @@ -42,11 +42,11 @@ "decorator": { "name": "terraforged:poisson_surface", "config": { - "radius": 9, - "biome_fade": 0.25, + "radius": 8, + "biome_fade": 0.12, "density_noise_scale": 300, - "density_noise_min": 0, - "density_noise_max": 2 + "density_noise_min": 0.5, + "density_noise_max": 1.5 } } } diff --git a/src/main/resources/data/terraforged/features/trees/oak_forest.json b/src/main/resources/data/terraforged/features/trees/oak_forest.json index a165f30..bda0b2e 100644 --- a/src/main/resources/data/terraforged/features/trees/oak_forest.json +++ b/src/main/resources/data/terraforged/features/trees/oak_forest.json @@ -41,10 +41,10 @@ "decorator": { "name": "terraforged:poisson_surface", "config": { - "radius": 9, - "biome_fade": 0.2, + "radius": 8, + "biome_fade": 0.12, "density_noise_scale": 150, - "density_noise_min": 0.15, + "density_noise_min": 0.5, "density_noise_max": 1.75 } } diff --git a/src/main/resources/data/terraforged/templates/trees/acacia_bush.json b/src/main/resources/data/terraforged/templates/trees/acacia_bush.json new file mode 100644 index 0000000..df55399 --- /dev/null +++ b/src/main/resources/data/terraforged/templates/trees/acacia_bush.json @@ -0,0 +1,11 @@ +{ + "type": "tree", + "name": "terraforged:acacia_bush", + "paths": [ + "terraforged:trees/acacia/bush" + ], + "config": { + "extend_base": 2, + "check_bounds": false + } +} \ No newline at end of file