- better handling of wetland terrain

- fix missing logs from tree
- tweaks to biomemap
This commit is contained in:
dags- 2020-03-06 17:22:23 +00:00
parent 5e43e4fc34
commit d3ce349d61
27 changed files with 377 additions and 188 deletions

View File

@ -28,19 +28,32 @@ TerraForged is an ambitious new terrain generator mod for Minecraft (Java Editio
![TerraForged Gallery](https://terraforged.com/curse/gallery.jpg) ![TerraForged Gallery](https://terraforged.com/curse/gallery.jpg)
#### FAQ: #### FAQ:
1. "Is this compatible with mod xyz?" 1) "Is this compatible with mod xyz?"
_Probably! (to some degree) - TerraForged is designed to work with many of the same world-gen systems _Probably! (to some degree) - TerraForged is designed to work with many of the same world-gen systems
that the majority of block & biome providing mods use. Certain biomes' terrain may not always look that the majority of block & biome providing mods use. Certain biomes' terrain may not always look
exactly as their author designed but should otherwise be compatible. Feel free to report any other exactly as their author designed but should otherwise be compatible. Feel free to report any other
compatibility issues on the issue tracker._ compatibility issues on the issue tracker._
2. "How can I use this on my server?" 2) "How can I use this on my server?"
_When Forge supports it, you can simply set level-type=terraforged in your server.properties file. In _When Forge supports it, you can simply set level-type=terraforged in your server.properties file. In
the meantime, you will need to create the world in single player and then copy that to your server the meantime, you will need to create the world in single player and then copy that to your server
directory. (In both cases, TerraForged must be installed on the client and the server)._ directory. (In both cases, TerraForged must be installed on the client and the server)._
3. "Will I need a super-computer to run this?!" 3) "Will I need a super-computer to run this?!"
_No, not really - while this world generator will be a bit slower than vanilla's (on account of it _No, not really - while this world generator will be a bit slower than vanilla's (on account of it
doing more work to make things look nice), it would only be apparent when first generating a chunk - doing more work to make things look nice), it would only be apparent when first generating a chunk
they might load in slower when moving to new parts of the world, but game performance should - they might load in slower when moving to new parts of the world, but game performance should
otherwise be normal. A 4-core CPU should be able to handle this just fine._ otherwise be normal. A 4-core CPU should be able to handle this just fine._
4) "Can this be ported Fabric/Bukkit/Spigot/Sponge?"
_If someone would like to take this task on, yes - a large part of the TerraForged codebase is already
platform independent. There are certain client-side features in the forge-mod that would not translate
onto server-only APIs, but the core experience could certainly be ported. I don't intend to work on
this directly but others are very welcome._
5) "Will this be back-ported to older Forge versions?"
_Not by myself, no - My aim is to keep current with Forge. I'm simply not prolific enough a modder to
write and maintain for multiple versions (hats off to those who do!). Again though, others are welcome
to back-port it, if inclined to do so._
[View questions on github](https://github.com/TerraForged/TerraForged/issues?q=label:question)

View File

@ -34,52 +34,73 @@ import me.dags.noise.Module;
import me.dags.noise.Source; import me.dags.noise.Source;
import me.dags.noise.util.NoiseUtil; import me.dags.noise.util.NoiseUtil;
public class SwampPools implements Decorator { public class Wetlands implements Decorator {
private final Module module; private final Module module;
private final Levels levels; private final float poolBase;
private final Terrains terrains; private final float bankHeight;
private final float minY;
private final float maxY;
private final float blendY;
private final float blendRange;
public SwampPools(Seed seed, Terrains terrains, Levels levels) { private final Terrain wetlands;
this.levels = levels;
this.terrains = terrains; public Wetlands(Seed seed, Terrains terrain, Levels levels) {
this.minY = levels.water(-3); this.wetlands = terrain.wetlands;
this.maxY = levels.water(1); this.poolBase = levels.water(-3);
this.blendY = levels.water(4); this.bankHeight = levels.water(2);
this.blendRange = blendY - maxY; this.module = Source.perlin(seed.next(), 12, 1).clamp(0.35, 0.65).map(0, 1);
this.module = Source.perlin(seed.next(), 14, 1).clamp(0.45, 0.8).map(0, 1);
} }
@Override @Override
public boolean apply(Cell<Terrain> cell, float x, float y) { public boolean apply(Cell<Terrain> cell, float x, float y) {
if (cell.tag == terrains.ocean) { if (cell.value < poolBase) {
return false; return false;
} }
if (cell.moisture < 0.7 || cell.temperature < 0.3) { float tempAlpha = getAlpha(cell.temperature, 0.3F, 0.7F);
if (tempAlpha == 0) {
return false; return false;
} }
if (cell.value <= minY) { float moistAlpha = getAlpha(cell.moisture, 0.7F, 1F);
if (moistAlpha == 0) {
return false; return false;
} }
if (cell.value > blendY) { float riverAlpha = getAlpha(1 - cell.riverMask, 0.85F, 0.95F);
if (riverAlpha == 0) {
return false; return false;
} }
float alpha = module.getValue(x, y); float alpha = tempAlpha * moistAlpha * riverAlpha;
if (cell.value > maxY) { float value1 = NoiseUtil.lerp(cell.value, bankHeight, alpha);
float delta = blendY - cell.value; cell.value = Math.min(cell.value, value1);
float alpha2 = delta / blendRange;
alpha *= alpha2; float poolAlpha = getAlpha(alpha, 0.35F, 0.55F);
float shape = module.getValue(x, y);
float value2 = NoiseUtil.lerp(cell.value, poolBase, shape * poolAlpha);
cell.value = Math.min(cell.value, value2);
if (poolAlpha > 0.5) {
cell.tag = wetlands;
} }
cell.value = NoiseUtil.lerp(cell.value, minY, alpha);
return true; return true;
} }
private static float getAlpha(float value, float min, float max) {
return getAlpha(value, min, max, false);
}
private static float getAlpha(float value, float min, float max, boolean inverse) {
if (value < min) {
return 0F;
}
if (value >= max) {
return 1F;
}
float alpha = (value - min) / (max - min);
if (inverse) {
return 1F - alpha;
}
return alpha;
}
} }

View File

@ -27,7 +27,7 @@ package com.terraforged.core.world;
import com.terraforged.core.decorator.Decorator; import com.terraforged.core.decorator.Decorator;
import com.terraforged.core.decorator.DesertStacks; import com.terraforged.core.decorator.DesertStacks;
import com.terraforged.core.decorator.SwampPools; import com.terraforged.core.decorator.Wetlands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -41,7 +41,7 @@ public class WorldDecorators {
context = context.copy(); context = context.copy();
List<Decorator> list = new ArrayList<>(); List<Decorator> list = new ArrayList<>();
list.add(new DesertStacks(context.seed, context.levels)); list.add(new DesertStacks(context.seed, context.levels));
list.add(new SwampPools(context.seed, context.terrain, context.levels)); list.add(new Wetlands(context.seed, context.terrain, context.levels));
decorators = Collections.unmodifiableList(list); decorators = Collections.unmodifiableList(list);
} }

View File

@ -61,7 +61,7 @@ public class ClimateModule {
int warpScale = settings.biome.biomeWarpScale; int warpScale = settings.biome.biomeWarpScale;
this.seed = seed.next(); this.seed = seed.next();
this.edgeClamp = 0.85F; this.edgeClamp = 1F;
this.edgeScale = 1 / edgeClamp; this.edgeScale = 1 / edgeClamp;
this.biomeFreq = 1F / biomeSize; this.biomeFreq = 1F / biomeSize;
this.warpStrength = settings.biome.biomeWarpStrength; this.warpStrength = settings.biome.biomeWarpStrength;

View File

@ -134,43 +134,47 @@ public class Terrain implements Tag {
return new Terrain("river_banks", 4); return new Terrain("river_banks", 4);
} }
public static Terrain wetlands(Settings settings) {
return new Terrain("wetlands", 5);
}
public static Terrain steppe(Settings settings) { public static Terrain steppe(Settings settings) {
return new Terrain("steppe", 5, settings.terrain.steppe.weight); return new Terrain("steppe", 6, settings.terrain.steppe.weight);
} }
public static Terrain plains(Settings settings) { public static Terrain plains(Settings settings) {
return new Terrain("plains", 5, settings.terrain.plains.weight); return new Terrain("plains", 7, settings.terrain.plains.weight);
} }
public static Terrain plateau(Settings settings) { public static Terrain plateau(Settings settings) {
return new Terrain("plateau", 6, settings.terrain.plateau.weight); return new Terrain("plateau", 8, settings.terrain.plateau.weight);
} }
public static Terrain badlands(Settings settings) { public static Terrain badlands(Settings settings) {
return new Terrain("badlands", 7, settings.terrain.badlands.weight); return new Terrain("badlands", 9, settings.terrain.badlands.weight);
} }
public static Terrain hills(Settings settings) { public static Terrain hills(Settings settings) {
return new Terrain("hills", 8, settings.terrain.hills.weight); return new Terrain("hills", 10, settings.terrain.hills.weight);
} }
public static Terrain dales(Settings settings) { public static Terrain dales(Settings settings) {
return new Terrain("dales", 9, settings.terrain.dales.weight); return new Terrain("dales", 11, settings.terrain.dales.weight);
} }
public static Terrain torridonian(Settings settings) { public static Terrain torridonian(Settings settings) {
return new Terrain("torridonian_fells", 10, settings.terrain.torridonian.weight); return new Terrain("torridonian_fells", 12, settings.terrain.torridonian.weight);
} }
public static Terrain mountains(Settings settings) { public static Terrain mountains(Settings settings) {
return new Terrain("mountains", 11, settings.terrain.mountains.weight); return new Terrain("mountains", 13, settings.terrain.mountains.weight);
} }
public static Terrain volcano(Settings settings) { public static Terrain volcano(Settings settings) {
return new Terrain("volcano", 12, settings.terrain.volcano.weight); return new Terrain("volcano", 14, settings.terrain.volcano.weight);
} }
public static Terrain volcanoPipe(Settings settings) { public static Terrain volcanoPipe(Settings settings) {
return new Terrain("volcano_pipe", 13, settings.terrain.volcano.weight); return new Terrain("volcano_pipe", 15, settings.terrain.volcano.weight);
} }
} }

View File

@ -40,6 +40,7 @@ public class Terrains {
public final Terrain lake; public final Terrain lake;
public final Terrain river; public final Terrain river;
public final Terrain riverBanks; public final Terrain riverBanks;
public final Terrain wetlands;
public final Terrain badlands; public final Terrain badlands;
public final Terrain steppe; public final Terrain steppe;
public final Terrain plains; public final Terrain plains;
@ -64,6 +65,7 @@ public class Terrains {
river = mutable.river, river = mutable.river,
torridonian = mutable.torridonian, torridonian = mutable.torridonian,
riverBanks = mutable.riverbanks, riverBanks = mutable.riverbanks,
wetlands = mutable.wetlands,
badlands = mutable.badlands, badlands = mutable.badlands,
plateau = mutable.plateau, plateau = mutable.plateau,
steppe = mutable.steppe, steppe = mutable.steppe,
@ -102,6 +104,7 @@ public class Terrains {
terrain.lake = Terrain.lake(settings); terrain.lake = Terrain.lake(settings);
terrain.river = Terrain.river(settings); terrain.river = Terrain.river(settings);
terrain.riverbanks = Terrain.riverBank(settings); terrain.riverbanks = Terrain.riverBank(settings);
terrain.wetlands = Terrain.wetlands(settings);
terrain.badlands = Terrain.badlands(settings); terrain.badlands = Terrain.badlands(settings);
terrain.plateau = Terrain.plateau(settings); terrain.plateau = Terrain.plateau(settings);
terrain.steppe = Terrain.steppe(settings); terrain.steppe = Terrain.steppe(settings);
@ -123,6 +126,7 @@ public class Terrains {
public Terrain lake = Terrain.NONE; public Terrain lake = Terrain.NONE;
public Terrain river = Terrain.NONE; public Terrain river = Terrain.NONE;
public Terrain riverbanks = Terrain.NONE; public Terrain riverbanks = Terrain.NONE;
public Terrain wetlands = Terrain.NONE;
public Terrain badlands = Terrain.NONE; public Terrain badlands = Terrain.NONE;
public Terrain plateau = Terrain.NONE; public Terrain plateau = Terrain.NONE;
public Terrain steppe = Terrain.NONE; public Terrain steppe = Terrain.NONE;

View File

@ -0,0 +1,89 @@
/*
*
* 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.mod.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.biome.SwampBiome;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class Marshland extends BiomeVariant {
public Marshland() {
super((new Builder()).surfaceBuilder(SurfaceBuilder.SWAMP, SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(RainType.RAIN).category(Category.SWAMP).depth(0.2F).scale(0.2F).temperature(0.8F).downfall(0.4F).waterColor(6388580).waterFogColor(2302743).parent((String) null));
this.setRegistryName("terraforged", "marshland");
DefaultBiomeFeatures.addCarvers(this);
DefaultBiomeFeatures.addStructures(this);
DefaultBiomeFeatures.addMonsterRooms(this);
DefaultBiomeFeatures.addStoneVariants(this);
DefaultBiomeFeatures.addOres(this);
DefaultBiomeFeatures.addSedimentDisks(this);
DefaultBiomeFeatures.addDefaultFlowers(this);
DefaultBiomeFeatures.addTallGrass(this);
DefaultBiomeFeatures.addTallGrass(this);
DefaultBiomeFeatures.addTallGrass(this);
DefaultBiomeFeatures.addTallGrass(this);
DefaultBiomeFeatures.addGrass(this);
DefaultBiomeFeatures.addVeryDenseGrass(this);
DefaultBiomeFeatures.addReedsAndPumpkins(this);
DefaultBiomeFeatures.addFreezeTopLayer(this);
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.SHEEP, 12, 4, 4));
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.PIG, 10, 4, 4));
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.CHICKEN, 10, 4, 4));
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.COW, 8, 4, 4));
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.WOLF, 8, 4, 4));
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.RABBIT, 4, 2, 3));
this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.FOX, 8, 2, 4));
this.addSpawn(EntityClassification.AMBIENT, new SpawnListEntry(EntityType.BAT, 10, 8, 8));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SPIDER, 100, 4, 4));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SKELETON, 100, 4, 4));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.CREEPER, 100, 4, 4));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SLIME, 100, 4, 4));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4));
this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.WITCH, 5, 1, 1));
}
public int getGrassColor(double p_225528_1_, double p_225528_3_) {
double d0 = INFO_NOISE.noiseAt(p_225528_1_ * 0.0225D, p_225528_3_ * 0.0225D, false);
return d0 < -0.1D ? 5011004 : 6975545;
}
public int getFoliageColor() {
return 6975545;
}
@Override
public Biome getBase() {
return Biomes.SWAMP;
}
}

View File

@ -46,6 +46,7 @@ public class ModBiomes {
public static final Biome STEPPE = register(new Steppe()); public static final Biome STEPPE = register(new Steppe());
public static final Biome TAIGA_SCRUB = register(new TaigaScrub()); public static final Biome TAIGA_SCRUB = register(new TaigaScrub());
public static final Biome WARM_BEACH = register(new WarmBeach()); public static final Biome WARM_BEACH = register(new WarmBeach());
public static final Biome MARSHLAND = register(new Marshland());
private static Biome register(BiomeVariant biome) { private static Biome register(BiomeVariant biome) {
biomes.add(biome); biomes.add(biome);

View File

@ -38,39 +38,54 @@ import net.minecraft.world.biome.Biomes;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.function.Function;
public abstract class AbstractBiomeMap implements BiomeMap { public abstract class AbstractBiomeMap implements BiomeMap {
private final Biome[][] beach; private final Biome[][] beach;
private final Biome[][] river; private final Biome[][] river;
private final Biome[][] wetland;
private final Biome[][] ocean; private final Biome[][] ocean;
private final Biome[][] deepOcean; 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 defaultWetland = this::defaultWetland;
protected final DefaultBiome defaultOcean = this::defaultOcean;
protected final DefaultBiome defaultDeepOcean = this::defaultDeepOcean;
protected AbstractBiomeMap(BiomeMapBuilder builder) { protected AbstractBiomeMap(BiomeMapBuilder builder) {
river = builder.rivers(); river = builder.rivers();
beach = builder.beaches(); beach = builder.beaches();
ocean = builder.oceans(); ocean = builder.oceans();
wetland = builder.wetlands();
deepOcean = builder.deepOceans(); deepOcean = builder.deepOceans();
} }
@Override @Override
public Biome getBeach(float temperature, float moisture, float shape) { public Biome getBeach(float temperature, float moisture, float shape) {
return get(beach, getCategory(temperature), shape, defaultBeach(temperature)); return get(beach, getCategory(temperature), shape, temperature, defaultBeach);
} }
@Override @Override
public Biome getRiver(float temperature, float moisture, float shape) { public Biome getRiver(float temperature, float moisture, float shape) {
return get(river, getCategory(temperature), shape, defaultRiver(temperature)); return get(river, getCategory(temperature), shape, temperature, defaultRiver);
}
@Override
public Biome getWetland(float temperature, float moisture, float shape) {
return get(wetland, getCategory(temperature), shape, temperature, defaultWetland);
} }
@Override @Override
public Biome getOcean(float temperature, float moisture, float shape) { public Biome getOcean(float temperature, float moisture, float shape) {
return get(ocean, getCategory(temperature), shape, defaultOcean(temperature)); return get(ocean, getCategory(temperature), shape, temperature, defaultOcean);
} }
@Override @Override
public Biome getDeepOcean(float temperature, float moisture, float shape) { public Biome getDeepOcean(float temperature, float moisture, float shape) {
return get(deepOcean, getCategory(temperature), shape, defaultDeepOcean(temperature)); return get(deepOcean, getCategory(temperature), shape, temperature, defaultDeepOcean);
} }
@Override @Override
@ -92,7 +107,8 @@ public abstract class AbstractBiomeMap implements BiomeMap {
public JsonObject toJson() { public JsonObject toJson() {
JsonObject root = new JsonObject(); JsonObject root = new JsonObject();
root.add("rivers", collect(river)); root.add("rivers", collect(river));
root.add("beaches", collect(river)); root.add("wetland", collect(wetland));
root.add("beaches", collect(beach));
root.add("oceans", collect(ocean)); root.add("oceans", collect(ocean));
root.add("deepOceans", collect(deepOcean)); root.add("deepOceans", collect(deepOcean));
return root; return root;
@ -144,6 +160,13 @@ public abstract class AbstractBiomeMap implements BiomeMap {
return Biomes.RIVER; return Biomes.RIVER;
} }
protected Biome defaultWetland(float temperature) {
if (temperature < 0.15) {
return ModBiomes.TAIGA_SCRUB;
}
return ModBiomes.MARSHLAND;
}
protected Biome defaultOcean(float temperature) { protected Biome defaultOcean(float temperature) {
if (temperature < 0.3) { if (temperature < 0.3) {
return Biomes.FROZEN_OCEAN; return Biomes.FROZEN_OCEAN;
@ -164,7 +187,7 @@ public abstract class AbstractBiomeMap implements BiomeMap {
return Biomes.DEEP_OCEAN; return Biomes.DEEP_OCEAN;
} }
protected Biome defaultBiome(float temperature, float moisture) { protected Biome defaultBiome(float temperature) {
if (temperature < 0.3) { if (temperature < 0.3) {
return ModBiomes.TAIGA_SCRUB; return ModBiomes.TAIGA_SCRUB;
} }
@ -174,22 +197,22 @@ public abstract class AbstractBiomeMap implements BiomeMap {
return Biomes.PLAINS; return Biomes.PLAINS;
} }
protected Biome get(Biome[][] group, Biome.TempCategory category, float shape, Biome def) { protected Biome get(Biome[][] group, Biome.TempCategory category, float shape, float temp, DefaultBiome def) {
return get(group, category.ordinal() - 1, shape, def); return get(group, category.ordinal() - 1, shape, temp, def);
} }
protected Biome get(Biome[][] group, BiomeType type, float shape, Biome def) { protected Biome get(Biome[][] group, BiomeType type, float shape, float temp, DefaultBiome def) {
return get(group, type.ordinal(), shape, def); return get(group, type.ordinal(), shape, temp, def);
} }
protected Biome get(Biome[][] group, int ordinal, float shape, Biome def) { protected Biome get(Biome[][] group, int ordinal, float shape, float temp, DefaultBiome def) {
if (ordinal >= group.length) { if (ordinal >= group.length) {
return def; return def.getDefaultBiome(temp);
} }
Biome[] biomes = group[ordinal]; Biome[] biomes = group[ordinal];
if (biomes == null || biomes.length == 0) { if (biomes == null || biomes.length == 0) {
return def; return def.getDefaultBiome(temp);
} }
int index = NoiseUtil.round((biomes.length - 1) * shape); int index = NoiseUtil.round((biomes.length - 1) * shape);

View File

@ -64,7 +64,7 @@ public class BasicBiomeMap extends AbstractBiomeMap {
@Override @Override
public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) {
return get(biomeTypes, type, shape, defaultBiome(temperature, moisture)); return get(biomeTypes, type, shape, temperature, defaultLand);
} }
@Override @Override

View File

@ -26,7 +26,9 @@
package com.terraforged.mod.biome.map; package com.terraforged.mod.biome.map;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.terraforged.core.cell.Cell;
import com.terraforged.core.world.biome.BiomeType; import com.terraforged.core.world.biome.BiomeType;
import com.terraforged.core.world.terrain.Terrain;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import java.util.List; import java.util.List;
@ -38,12 +40,18 @@ public interface BiomeMap {
Biome getRiver(float temperature, float moisture, float shape); Biome getRiver(float temperature, float moisture, float shape);
Biome getWetland(float temperature, float moisture, float shape);
Biome getOcean(float temperature, float moisture, float shape); Biome getOcean(float temperature, float moisture, float shape);
Biome getDeepOcean(float temperature, float moisture, float shape); Biome getDeepOcean(float temperature, float moisture, float shape);
Biome getBiome(BiomeType type, float temperature, float moisture, float shape); Biome getBiome(BiomeType type, float temperature, float moisture, float shape);
default Biome getBiome(Cell<Terrain> cell) {
return getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome);
}
List<Biome> getAllBiomes(BiomeType type); List<Biome> getAllBiomes(BiomeType type);
Set<Biome> getBiomes(BiomeType type); Set<Biome> getBiomes(BiomeType type);
@ -56,12 +64,18 @@ public interface BiomeMap {
JsonElement toJson(); JsonElement toJson();
static Biome getBiome(Biome biome) {
return biome.delegate.get();
}
interface Builder { interface Builder {
Builder addBeach(Biome biome, int count); Builder addBeach(Biome biome, int count);
Builder addRiver(Biome biome, int count); Builder addRiver(Biome biome, int count);
Builder addWetland(Biome biome, int count);
Builder addOcean(Biome biome, int count); Builder addOcean(Biome biome, int count);
Builder addBiome(BiomeType type, Biome biome, int count); Builder addBiome(BiomeType type, Biome biome, int count);

View File

@ -44,6 +44,7 @@ import java.util.function.Function;
public class BiomeMapBuilder implements BiomeMap.Builder { public class BiomeMapBuilder implements BiomeMap.Builder {
private final Map<Biome.TempCategory, List<Biome>> rivers = new HashMap<>(); private final Map<Biome.TempCategory, List<Biome>> rivers = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> wetlands = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> beaches = new HashMap<>(); private final Map<Biome.TempCategory, List<Biome>> beaches = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> oceans = new HashMap<>(); private final Map<Biome.TempCategory, List<Biome>> oceans = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> deepOceans = new HashMap<>(); private final Map<Biome.TempCategory, List<Biome>> deepOceans = new HashMap<>();
@ -87,6 +88,13 @@ public class BiomeMapBuilder implements BiomeMap.Builder {
return this; return this;
} }
@Override
public BiomeMapBuilder addWetland(Biome biome, int count) {
Biome.TempCategory category = BiomeHelper.getTempCategory(biome);
add(wetlands.computeIfAbsent(category, c -> new ArrayList<>()), biome, count);
return this;
}
@Override @Override
public BiomeMapBuilder addBiome(BiomeType type, Biome biome, int count) { public BiomeMapBuilder addBiome(BiomeType type, Biome biome, int count) {
add(map.computeIfAbsent(type, t -> new ArrayList<>()), biome, count); add(map.computeIfAbsent(type, t -> new ArrayList<>()), biome, count);
@ -102,6 +110,10 @@ public class BiomeMapBuilder implements BiomeMap.Builder {
return collectTemps(rivers); return collectTemps(rivers);
} }
Biome[][] wetlands() {
return collectTemps(wetlands);
}
Biome[][] beaches() { Biome[][] beaches() {
return collectTemps(beaches); return collectTemps(beaches);
} }

View File

@ -0,0 +1,12 @@
package com.terraforged.mod.biome.map;
import net.minecraft.world.biome.Biome;
public interface DefaultBiome {
Biome getBiome(float temperature);
default Biome getDefaultBiome(float temperature) {
return getBiome(temperature).delegate.get();
}
}

View File

@ -54,11 +54,6 @@ public class BiomeModifierManager implements BiomeModifier, ModifierManager {
context.factory.getClimate(), context.factory.getClimate(),
context.levels context.levels
)); ));
modifiers.add(new SwampModifier(
context.seed,
context.factory.getClimate(),
context.levels
));
Collections.sort(modifiers); Collections.sort(modifiers);
this.biomeModifiers = modifiers; this.biomeModifiers = modifiers;
} }

View File

@ -1,57 +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.mod.biome.modifier;
import com.terraforged.core.cell.Cell;
import com.terraforged.core.util.Seed;
import com.terraforged.core.world.climate.Climate;
import com.terraforged.core.world.heightmap.Levels;
import com.terraforged.core.world.terrain.Terrain;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
// prevents swamps forming at high levels
public class SwampModifier extends AbstractMaxHeightModifier {
public SwampModifier(Seed seed, Climate climate, Levels levels) {
super(seed, climate, 60, 1, levels.scale(10), levels.ground(4), levels.ground(12));
}
@Override
protected Biome getModifiedBiome(Biome in, Cell<Terrain> cell, int x, int z, float ox, float oz) {
return Biomes.PLAINS;
}
@Override
public int priority() {
return 0;
}
@Override
public boolean test(Biome biome) {
return biome.getCategory() == Biome.Category.SWAMP;
}
}

View File

@ -60,7 +60,7 @@ public class BiomeHelper {
put(BiomeType.DESERT, BiomePredicate.DESERT.or(BiomePredicate.MESA).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_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.TEMPERATE_FOREST, BiomePredicate.TEMPERATE_FOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND));
put(BiomeType.GRASSLAND, BiomePredicate.GRASSLAND.or(BiomePredicate.WETLAND).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); 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.COLD_STEPPE, BiomePredicate.COLD_STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN));
put(BiomeType.STEPPE, BiomePredicate.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.TAIGA, BiomePredicate.TAIGA.not(BiomePredicate.TUNDRA).not(BiomePredicate.COLD_STEPPE).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN));
@ -104,6 +104,8 @@ public class BiomeHelper {
builder.addRiver(biome, weight); builder.addRiver(biome, weight);
} else if (biome.getCategory() == Biome.Category.BEACH || biome == Biomes.STONE_SHORE) { } else if (biome.getCategory() == Biome.Category.BEACH || biome == Biomes.STONE_SHORE) {
builder.addBeach(biome, weight); builder.addBeach(biome, weight);
} else if (biome.getCategory() == Biome.Category.SWAMP) {
builder.addWetland(biome, weight);
} else { } else {
Collection<BiomeType> types = getTypes(data, biome); Collection<BiomeType> types = getTypes(data, biome);
for (BiomeType type : types) { for (BiomeType type : types) {

View File

@ -27,6 +27,7 @@ package com.terraforged.mod.biome.provider;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.decorator.Decorator;
import com.terraforged.core.region.chunk.ChunkReader; import com.terraforged.core.region.chunk.ChunkReader;
import com.terraforged.core.util.concurrent.ObjectPool; import com.terraforged.core.util.concurrent.ObjectPool;
import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.Terrain;
@ -40,8 +41,11 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.feature.structure.Structure; import net.minecraft.world.gen.feature.structure.Structure;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -50,6 +54,7 @@ public class BiomeProvider extends AbstractBiomeProvider {
private final BiomeMap biomeMap; private final BiomeMap biomeMap;
private final TerraContext context; private final TerraContext context;
private final BiomeModifierManager modifierManager; private final BiomeModifierManager modifierManager;
private final Map<Biome, List<Decorator>> decorators = new HashMap<>();
public BiomeProvider(TerraContext context) { public BiomeProvider(TerraContext context) {
this.context = context; this.context = context;
@ -57,19 +62,6 @@ public class BiomeProvider extends AbstractBiomeProvider {
this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy()); this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy());
} }
public BiomeModifierManager getModifierManager() {
return modifierManager;
}
public TerraContainer createBiomeContainer(ChunkReader chunkReader) {
TerraContainer.Builder builder = TerraContainer.builder();
chunkReader.iterate((cell, dx, dz) -> {
Biome biome = getBiome(cell, chunkReader.getBlockX() + dx, chunkReader.getBlockZ() + dz);
builder.fill(dx, dz, biome);
});
return builder.build(chunkReader);
}
@Override @Override
public Biome getBiome(int x, int y, int z) { public Biome getBiome(int x, int y, int z) {
try (ObjectPool.Item<Cell<Terrain>> item = Cell.pooled()) { try (ObjectPool.Item<Cell<Terrain>> item = Cell.pooled()) {
@ -135,29 +127,51 @@ public class BiomeProvider extends AbstractBiomeProvider {
return this.topBlocksCache; return this.topBlocksCache;
} }
public BiomeModifierManager getModifierManager() {
return modifierManager;
}
public List<Decorator> getDecorators(Biome biome) {
return decorators.getOrDefault(biome, Collections.emptyList());
}
public TerraContainer createBiomeContainer(ChunkReader chunkReader) {
TerraContainer.Builder builder = TerraContainer.builder();
chunkReader.iterate((cell, dx, dz) -> {
Biome biome = getBiome(cell, chunkReader.getBlockX() + dx, chunkReader.getBlockZ() + dz);
builder.fill(dx, dz, biome);
});
return builder.build(chunkReader);
}
public Biome getBiome(Cell<Terrain> cell, int x, int z) { public Biome getBiome(Cell<Terrain> cell, int x, int z) {
if (cell.value <= context.levels.water) { if (cell.tag == context.terrain.wetlands) {
return biomeMap.getWetland(cell.temperature, cell.moisture, cell.biome);
}
if (cell.value > context.levels.water) {
return getModifierManager().modify(biomeMap.getBiome(cell), cell, x, z);
}
if (cell.tag == context.terrain.river || cell.tag == context.terrain.riverBanks) { if (cell.tag == context.terrain.river || cell.tag == context.terrain.riverBanks) {
Biome biome = getBiome(cell); Biome biome = biomeMap.getBiome(cell);
if (biome.getCategory() == Biome.Category.SWAMP) { if (overridesRiver(biome)) {
return biome; return biome;
} }
return biomeMap.getRiver(cell.temperature, cell.moisture, cell.biome); return biomeMap.getRiver(cell.temperature, cell.moisture, cell.biome);
} else if (cell.tag == context.terrain.ocean) { }
if (cell.tag == context.terrain.ocean) {
return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome); return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome);
} else if (cell.tag == context.terrain.deepOcean) { }
return biomeMap.getDeepOcean(cell.temperature, cell.moisture, cell.biome); return biomeMap.getDeepOcean(cell.temperature, cell.moisture, cell.biome);
} }
}
return modifyBiome(getBiome(cell), cell, x, z);
}
public Biome getBiome(Cell<Terrain> cell) { private static boolean overridesRiver(Biome biome) {
return biomeMap.getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome); return biome.getCategory() == Biome.Category.SWAMP
} || biome.getCategory() == Biome.Category.JUNGLE;
public Biome modifyBiome(Biome biome, Cell<Terrain> cell, int x, int z) {
return modifierManager.modify(biome, cell, x, z);
} }
private static class SearchContext { private static class SearchContext {

View File

@ -0,0 +1,12 @@
package com.terraforged.mod.chunk;
import com.terraforged.api.chunk.column.DecoratorContext;
import com.terraforged.core.region.chunk.ChunkReader;
import net.minecraft.util.math.ChunkPos;
public interface ChunkProcessor {
void preProcess(ChunkPos pos, ChunkReader chunk, TerraContainer container);
void postProcess(ChunkReader chunk, TerraContainer container, DecoratorContext context);
}

View File

@ -32,6 +32,7 @@ import com.terraforged.api.chunk.surface.SurfaceContext;
import com.terraforged.api.chunk.surface.SurfaceManager; import com.terraforged.api.chunk.surface.SurfaceManager;
import com.terraforged.api.material.layer.LayerManager; import com.terraforged.api.material.layer.LayerManager;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.decorator.Decorator;
import com.terraforged.core.region.RegionCache; import com.terraforged.core.region.RegionCache;
import com.terraforged.core.region.RegionGenerator; import com.terraforged.core.region.RegionGenerator;
import com.terraforged.core.region.Size; import com.terraforged.core.region.Size;
@ -69,7 +70,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeContainer;
import net.minecraft.world.biome.BiomeManager; import net.minecraft.world.biome.BiomeManager;
import net.minecraft.world.biome.Biomes; import net.minecraft.world.biome.Biomes;
import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.chunk.ChunkPrimer;
@ -86,7 +86,7 @@ import net.minecraft.world.gen.feature.template.TemplateManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSettings> { public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSettings> implements ChunkProcessor {
private final TerraContext context; private final TerraContext context;
private final BiomeProvider biomeProvider; private final BiomeProvider biomeProvider;
@ -125,9 +125,23 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSetti
@Override @Override
public final void generateBiomes(IChunk chunk) { public final void generateBiomes(IChunk chunk) {
ChunkPos pos = chunk.getPos(); ChunkPos pos = chunk.getPos();
ChunkReader view = getChunkReader(pos.x, pos.z); ChunkReader reader = getChunkReader(pos.x, pos.z);
BiomeContainer container = getBiomeProvider().createBiomeContainer(view); TerraContainer container = getBiomeProvider().createBiomeContainer(reader);
((ChunkPrimer) chunk).func_225548_a_(container); ((ChunkPrimer) chunk).func_225548_a_(container);
// apply chunk-local heightmap modifications
preProcess(pos, reader, container);
}
@Override
public final void preProcess(ChunkPos pos, ChunkReader chunk, TerraContainer container) {
chunk.iterate((cell, dx, dz) -> {
Biome biome = container.getBiome(dx, dz);
for (Decorator decorator : getBiomeProvider().getDecorators(biome)) {
if (decorator.apply(cell, pos.getXStart() + dx, pos.getZStart() + dz)) {
return;
}
}
});
} }
@Override @Override
@ -142,7 +156,6 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSetti
context.biome = container.getBiome(dx, dz); context.biome = container.getBiome(dx, dz);
ChunkPopulator.INSTANCE.decorate(chunk, context, px, py, pz); ChunkPopulator.INSTANCE.decorate(chunk, context, px, py, pz);
}); });
terrainHelper.flatten(world, chunk, context.blockX, context.blockZ); terrainHelper.flatten(world, chunk, context.blockX, context.blockZ);
} }
@ -193,19 +206,25 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSetti
// place biome features // place biome features
featureManager.decorate(this, regionFix, chunk, biome, pos); featureManager.decorate(this, regionFix, chunk, biome, pos);
// run post processors // run post processes on chunk
container.getChunkReader().iterate((cell, dx, dz) -> { postProcess(container.getChunkReader(), container, context);
// bake biome array & discard gen data
((ChunkPrimer) chunk).func_225548_a_(container.bakeBiomes());
}
@Override
public final void postProcess(ChunkReader chunk, TerraContainer container, DecoratorContext context) {
chunk.iterate((cell, dx, dz) -> {
int px = context.blockX + dx; int px = context.blockX + dx;
int pz = context.blockZ + dz; int pz = context.blockZ + dz;
int py = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, dx, dz); int py = context.chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, dx, dz);
context.cell = cell; context.cell = cell;
context.biome = container.getBiome(dx, dz); context.biome = container.getBiome(dx, dz);
for (ColumnDecorator decorator : getPostProcessors()) { for (ColumnDecorator decorator : getPostProcessors()) {
decorator.decorate(chunk, context, px, py, pz); decorator.decorate(context.chunk, context, px, py, pz);
} }
}); });
((ChunkPrimer) chunk).func_225548_a_(container.bakeBiomes());
} }
@Override @Override

View File

@ -37,10 +37,10 @@ import net.minecraft.world.biome.BiomeContainer;
public class TerraContainer extends BiomeContainer { public class TerraContainer extends BiomeContainer {
private static final int ZOOM_HORIZ = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2; private static final int BITS_WIDTH = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2;
private static final int ZOOM_VERT = (int) Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2; private static final int ZOOM_VERT = (int) Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2;
public static final int SIZE = 1 << ZOOM_HORIZ + ZOOM_HORIZ + ZOOM_VERT; public static final int SIZE = 1 << BITS_WIDTH + BITS_WIDTH + ZOOM_VERT;
public static final int MASK_HORIZ = (1 << ZOOM_HORIZ) - 1; public static final int MASK_HORIZ = (1 << BITS_WIDTH) - 1;
public static final int MASK_VERT = (1 << ZOOM_VERT) - 1; public static final int MASK_VERT = (1 << ZOOM_VERT) - 1;
private final Biome[] biomes; private final Biome[] biomes;
@ -97,10 +97,10 @@ public class TerraContainer extends BiomeContainer {
} }
private static int indexOf(int x, int y, int z) { private static int indexOf(int x, int y, int z) {
int bx = x & MASK_HORIZ; x &= MASK_HORIZ;
int by = MathHelper.clamp(y, 0, MASK_VERT); y = MathHelper.clamp(y, 0, MASK_VERT);
int bz = z & MASK_HORIZ; z &= MASK_HORIZ;
return by << ZOOM_HORIZ + ZOOM_HORIZ | bz << ZOOM_HORIZ | bx; return y << BITS_WIDTH + BITS_WIDTH | z << BITS_WIDTH | x;
} }
public static Builder builder() { public static Builder builder() {
@ -119,7 +119,7 @@ public class TerraContainer extends BiomeContainer {
} }
public void fill(int x, int z, Biome biome) { public void fill(int x, int z, Biome biome) {
for (int y = 0; y < 64; y++) { for (int y = 0; y < 256; y += 4) {
set(x, y, z, biome); set(x, y, z, biome);
} }
} }

View File

@ -35,10 +35,10 @@ public class Test {
public static boolean fixedBiome = true; public static boolean fixedBiome = true;
public static Terrain getTerrainType(Terrains terrains) { public static Terrain getTerrainType(Terrains terrains) {
return terrains.steppe; return terrains.dales;
} }
public static Biome getBiome() { public static Biome getBiome() {
return Biomes.DESERT; return Biomes.PLAINS;
} }
} }

View File

@ -27,7 +27,6 @@ package com.terraforged.mod.chunk.test;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.Terrain;
import com.terraforged.mod.biome.ModBiomes;
import com.terraforged.mod.biome.provider.BiomeProvider; import com.terraforged.mod.biome.provider.BiomeProvider;
import com.terraforged.mod.chunk.TerraContext; import com.terraforged.mod.chunk.TerraContext;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
@ -40,9 +39,6 @@ public class TestBiomeProvider extends BiomeProvider {
@Override @Override
public Biome getBiome(Cell<Terrain> cell, int x, int z) { public Biome getBiome(Cell<Terrain> cell, int x, int z) {
if (cell.biome < 0.5F) {
return ModBiomes.TAIGA_SCRUB;
}
return Test.getBiome(); return Test.getBiome();
} }
} }

View File

@ -75,7 +75,6 @@ public class TestChunkGenerator extends TerraChunkGenerator {
@Override @Override
public void apply(Cell<Terrain> cell, float x, float y) { public void apply(Cell<Terrain> cell, float x, float y) {
super.apply(cell, x, y); super.apply(cell, x, y);
populator.apply(cell, x, y); populator.apply(cell, x, y);
} }

View File

@ -26,6 +26,7 @@
package com.terraforged.mod.command.task; package com.terraforged.mod.command.task;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.decorator.Decorator;
import com.terraforged.core.world.WorldGenerator; import com.terraforged.core.world.WorldGenerator;
import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.Terrain;
import com.terraforged.mod.biome.provider.BiomeProvider; import com.terraforged.mod.biome.provider.BiomeProvider;
@ -58,9 +59,14 @@ public class FindBiomeTask extends FindTask {
@Override @Override
protected boolean search(int x, int z) { protected boolean search(int x, int z) {
generator.getHeightmap().apply(cell, x, z); generator.getHeightmap().apply(cell, x, z);
for (Decorator decorator : generator.getDecorators().getDecorators()) {
if (decorator.apply(cell, x, z)) {
break;
}
}
if (biome.getCategory() != Biome.Category.BEACH && biome.getCategory() != Biome.Category.OCEAN) { if (biome.getCategory() != Biome.Category.BEACH && biome.getCategory() != Biome.Category.OCEAN) {
if (cell.continentEdge > 0.4 && cell.continentEdge < 0.5) { if (cell.continentEdge > 0.4 && cell.continentEdge < 0.45) {
return false; return false;
} }
} }

View File

@ -25,6 +25,7 @@
package com.terraforged.mod.data; package com.terraforged.mod.data;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.terraforged.core.world.biome.BiomeType; import com.terraforged.core.world.biome.BiomeType;
@ -33,7 +34,11 @@ import com.terraforged.mod.biome.provider.BiomeHelper;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Set; import java.util.Set;
public class WorldGenBiomes extends DataGen { public class WorldGenBiomes extends DataGen {
@ -43,6 +48,12 @@ public class WorldGenBiomes extends DataGen {
for (BiomeType type : BiomeType.values()) { for (BiomeType type : BiomeType.values()) {
genBiomes(dataDir, type, map); genBiomes(dataDir, type, map);
} }
try (Writer writer = new BufferedWriter(new FileWriter(new File("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) { private static void genBiomes(File dir, BiomeType type, BiomeMap map) {

View File

@ -2,7 +2,6 @@
"replaceable": false, "replaceable": false,
"values": [ "values": [
"minecraft:plains", "minecraft:plains",
"minecraft:sunflower_plains", "minecraft:sunflower_plains"
"minecraft:swamp"
] ]
} }