- better handling of wetland terrain
- fix missing logs from tree - tweaks to biomemap
This commit is contained in:
parent
5e43e4fc34
commit
d3ce349d61
37
README.md
37
README.md
@ -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)
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
if (cell.tag == context.terrain.river || cell.tag == context.terrain.riverBanks) {
|
return biomeMap.getWetland(cell.temperature, cell.moisture, cell.biome);
|
||||||
Biome biome = getBiome(cell);
|
|
||||||
if (biome.getCategory() == Biome.Category.SWAMP) {
|
|
||||||
return biome;
|
|
||||||
}
|
|
||||||
return biomeMap.getRiver(cell.temperature, cell.moisture, cell.biome);
|
|
||||||
} else if (cell.tag == context.terrain.ocean) {
|
|
||||||
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 modifyBiome(getBiome(cell), cell, x, z);
|
|
||||||
|
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) {
|
||||||
|
Biome biome = biomeMap.getBiome(cell);
|
||||||
|
if (overridesRiver(biome)) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
return biomeMap.getRiver(cell.temperature, cell.moisture, cell.biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.tag == context.terrain.ocean) {
|
||||||
|
return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
return biomeMap.getDeepOcean(cell.temperature, cell.moisture, cell.biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Binary file not shown.
@ -2,7 +2,6 @@
|
|||||||
"replaceable": false,
|
"replaceable": false,
|
||||||
"values": [
|
"values": [
|
||||||
"minecraft:plains",
|
"minecraft:plains",
|
||||||
"minecraft:sunflower_plains",
|
"minecraft:sunflower_plains"
|
||||||
"minecraft:swamp"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user