- tweak scrub trees

- allow both colour deserts on a single continent
- fix a possible performance related bug
This commit is contained in:
dags- 2020-06-19 20:28:28 +01:00
parent 3adbbc0c0e
commit 30faf7febf
21 changed files with 175 additions and 56 deletions

2
Engine

@ -1 +1 @@
Subproject commit fd12dc3d3913ca610da26c2d8898897647877aa2
Subproject commit 4a9677caf9d6805893747ce91ffb116ec9db64e6

View File

@ -25,7 +25,7 @@
package com.terraforged;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.chunk.ChunkGeneratorFactory;
import com.terraforged.chunk.TerraChunkGenerator;
import com.terraforged.chunk.TerraContext;
@ -84,7 +84,7 @@ public class TerraWorld extends WorldType {
world.getWorldInfo().setGeneratorOptions(NBTHelper.serializeCompact(settings));
TerraContext context = new TerraContext(world, terrains, settings);
BiomeProvider biomeProvider = new BiomeProvider(context);
TerraBiomeProvider biomeProvider = new TerraBiomeProvider(context);
Log.debug("Creating Terra {} generator", world.getDimension().getType().getRegistryName());
return factory.create(context, biomeProvider, genSettings);

View File

@ -48,7 +48,7 @@ public class BiomeModifierManager implements BiomeModifier, ModifierManager {
desertBiomes = new DesertBiomes(context.materials, biomes.getAllBiomes(BiomeType.DESERT));
List<BiomeModifier> modifiers = new ArrayList<>();
modifiers.add(new CoastModifier(biomes, context));
modifiers.add(new DesertColorModifier(desertBiomes));
modifiers.add(new DesertColorModifier(context, desertBiomes));
modifiers.add(new SandBiomeModifier(context));
modifiers.add(new BeachModifier(biomes, context));
Collections.sort(modifiers);

View File

@ -28,14 +28,23 @@ package com.terraforged.biome.modifier;
import com.terraforged.api.biome.modifier.BiomeModifier;
import com.terraforged.biome.provider.DesertBiomes;
import com.terraforged.core.cell.Cell;
import com.terraforged.n2d.Module;
import com.terraforged.n2d.Source;
import com.terraforged.world.GeneratorContext;
import com.terraforged.world.climate.Climate;
import net.minecraft.world.biome.Biome;
public class DesertColorModifier implements BiomeModifier {
private final Module noise;
private final Climate climate;
private final DesertBiomes biomes;
public DesertColorModifier(DesertBiomes biomes) {
public DesertColorModifier(GeneratorContext context, DesertBiomes biomes) {
int scale = context.settings.terrain.general.terrainRegionSize;
this.biomes = biomes;
this.climate = context.factory.getClimate();
this.noise = Source.cell(context.seed.next(), scale * 3).warp(context.seed.next(), scale / 2, 1, scale / 4F);
}
@Override
@ -50,12 +59,17 @@ public class DesertColorModifier implements BiomeModifier {
@Override
public Biome modify(Biome in, Cell cell, int x, int z) {
float px = x + climate.getOffsetX(x, z, 12);
float pz = z + climate.getOffsetZ(x, z, 12);
float type = noise.getValue(px, pz);
if (biomes.isRedDesert(in)) {
if (cell.continent <= 0.5F) {
if (type <= 0.5F) {
return biomes.getWhiteDesert(cell.biome);
}
} else if (cell.continent > 0.5F) {
return biomes.getRedDesert(cell.biome);
} else {
if (type > 0.5F) {
return biomes.getRedDesert(cell.biome);
}
}
return in;
}

View File

@ -53,7 +53,7 @@ public class SandBiomeModifier extends AbstractMaxHeightModifier {
@Override
public boolean test(Biome biome) {
return biome.getCategory() == Biome.Category.DESERT && biomes.contains(biome);
return false; // biome.getCategory() == Biome.Category.DESERT && biomes.contains(biome);
}
@Override

View File

@ -36,6 +36,8 @@ import com.terraforged.world.heightmap.WorldLookup;
import com.terraforged.world.terrain.decorator.Decorator;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeManager;
import net.minecraft.world.biome.ColumnFuzzedBiomeMagnifier;
import java.util.Collections;
import java.util.HashMap;
@ -44,16 +46,18 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
public class BiomeProvider extends AbstractBiomeProvider {
public class TerraBiomeProvider extends AbstractBiomeProvider {
private final long seed;
private final BiomeMap biomeMap;
private final TerraContext context;
private final WorldLookup worldLookup;
private final BiomeModifierManager modifierManager;
private final Map<Biome, List<Decorator>> decorators = new HashMap<>();
public BiomeProvider(TerraContext context) {
public TerraBiomeProvider(TerraContext context) {
this.context = context;
this.seed = context.terraSettings.world.seed;
this.biomeMap = BiomeHelper.createBiomeMap();
this.worldLookup = new WorldLookup(context.factory, context);
this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy());
@ -124,6 +128,10 @@ public class BiomeProvider extends AbstractBiomeProvider {
return blockpos;
}
public Biome getSurfaceBiome(int x, int z, BiomeManager.IBiomeReader reader) {
return ColumnFuzzedBiomeMagnifier.INSTANCE.getBiome(seed, x, 0, z, reader);
}
public WorldLookup getWorldLookup() {
return worldLookup;
}

View File

@ -1,7 +1,7 @@
package com.terraforged.biome.spawn;
import com.terraforged.Log;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.world.continent.MutableVeci;
import com.terraforged.world.continent.SpawnType;
import net.minecraft.util.math.BlockPos;
@ -23,9 +23,9 @@ public class SpawnHandler {
if (event.getWorld() instanceof ServerWorld) {
ServerWorld world =(ServerWorld) event.getWorld();
ChunkGenerator<?> generator = world.getChunkProvider().getChunkGenerator();
if (generator.getBiomeProvider() instanceof BiomeProvider) {
if (generator.getBiomeProvider() instanceof TerraBiomeProvider) {
Log.info("Searching for world spawn position");
BiomeProvider provider = (BiomeProvider) generator.getBiomeProvider();
TerraBiomeProvider provider = (TerraBiomeProvider) generator.getBiomeProvider();
BlockPos center = getSearchCenter(provider);
SpawnSearch search = new SpawnSearch(center, provider);
@ -46,7 +46,7 @@ public class SpawnHandler {
}
}
private static BlockPos getSearchCenter(BiomeProvider provider) {
private static BlockPos getSearchCenter(TerraBiomeProvider provider) {
SpawnType spawnType = provider.getContext().terraSettings.world.properties.spawnType;
if (spawnType == SpawnType.WORLD_ORIGIN) {
return BlockPos.ZERO;

View File

@ -1,17 +1,17 @@
package com.terraforged.biome.spawn;
import com.terraforged.Log;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.command.search.Search;
import com.terraforged.core.cell.Cell;
import net.minecraft.util.math.BlockPos;
public class SpawnSearch extends Search {
private final BiomeProvider biomeProvider;
private final TerraBiomeProvider biomeProvider;
private final Cell cell = new Cell();
public SpawnSearch(BlockPos center, BiomeProvider biomeProvider) {
public SpawnSearch(BlockPos center, TerraBiomeProvider biomeProvider) {
super(center, 0, 2048);
this.biomeProvider = biomeProvider;
}

View File

@ -0,0 +1,51 @@
package com.terraforged.biome.surface;
import com.terraforged.api.chunk.surface.Surface;
import com.terraforged.api.chunk.surface.SurfaceContext;
import com.terraforged.api.material.state.States;
import com.terraforged.n2d.Module;
import com.terraforged.n2d.Source;
import com.terraforged.world.GeneratorContext;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
public class DesertSurface implements Surface {
private final float level;
private final Module noise;
private final BlockState low = Blocks.TERRACOTTA.delegate.get().getDefaultState();
private final BlockState mid = Blocks.ORANGE_TERRACOTTA.delegate.get().getDefaultState();
private final BlockState high = Blocks.BROWN_TERRACOTTA.delegate.get().getDefaultState();
public DesertSurface(GeneratorContext context) {
level = context.levels.ground(40);
noise = Source.perlin(context.seed.next(), 10, 1)
.scale(context.levels.scale(10));
}
@Override
public void buildSurface(int x, int z, int height, SurfaceContext ctx) {
if (ctx.cell.steepness < 0.15) {
return;
}
if (ctx.cell.steepness > 0.3 || ctx.cell.value + noise.getValue(x, z) > level) {
BlockState state = States.SANDSTONE.get();
if (ctx.cell.value > level) {
if (ctx.cell.steepness > 0.85) {
state = high;
} else if (ctx.cell.steepness > 0.75) {
state = mid;
} else if (ctx.cell.steepness > 0.625) {
state = low;
}
}
for (int dy = 0; dy < 4; dy++) {
ctx.buffer.setBlockState(ctx.pos.setPos(x, height - dy, z), state, false);
}
}
}
}

View File

@ -28,7 +28,7 @@ package com.terraforged.biome.surface;
import com.terraforged.api.chunk.surface.Surface;
import com.terraforged.api.chunk.surface.SurfaceContext;
import com.terraforged.api.material.layer.LayerMaterial;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.biome.provider.DesertBiomes;
import com.terraforged.chunk.TerraContext;
import com.terraforged.core.cell.Cell;
@ -87,7 +87,7 @@ public class DunesSurface implements Surface {
ctx.chunk.setBlockState(pos.setPos(x, duneTop, z), top, false);
}
public static Surface create(TerraContext context, BiomeProvider provider) {
public static Surface create(TerraContext context, TerraBiomeProvider provider) {
return create(context, provider.getModifierManager().getDesertBiomes());
}

View File

@ -25,11 +25,11 @@
package com.terraforged.chunk;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.OverworldGenSettings;
public interface ChunkGeneratorFactory<T extends ChunkGenerator<?>> {
T create(TerraContext context, BiomeProvider biomeProvider, OverworldGenSettings settings);
T create(TerraContext context, TerraBiomeProvider biomeProvider, OverworldGenSettings settings);
}

View File

@ -28,7 +28,7 @@ package com.terraforged.chunk;
import com.terraforged.api.chunk.column.ColumnDecorator;
import com.terraforged.api.chunk.surface.SurfaceManager;
import com.terraforged.api.material.layer.LayerManager;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.chunk.generator.BiomeGenerator;
import com.terraforged.chunk.generator.FeatureGenerator;
import com.terraforged.chunk.generator.Generator;
@ -68,7 +68,7 @@ import java.util.List;
public class TerraChunkGenerator extends ChunkGenerator<GenerationSettings> {
private final TerraContext context;
private final BiomeProvider biomeProvider;
private final TerraBiomeProvider biomeProvider;
private final Generator.Mobs mobGenerator;
private final Generator.Biomes biomeGenerator;
@ -88,7 +88,7 @@ public class TerraChunkGenerator extends ChunkGenerator<GenerationSettings> {
private final RegionCache regionCache;
public TerraChunkGenerator(TerraContext context, BiomeProvider biomeProvider, GenerationSettings settings) {
public TerraChunkGenerator(TerraContext context, TerraBiomeProvider biomeProvider, GenerationSettings settings) {
super(context.world, biomeProvider, settings);
this.context = context;
this.biomeProvider = biomeProvider;
@ -188,7 +188,7 @@ public class TerraChunkGenerator extends ChunkGenerator<GenerationSettings> {
}
@Override
public BiomeProvider getBiomeProvider() {
public TerraBiomeProvider getBiomeProvider() {
return biomeProvider;
}

View File

@ -5,6 +5,7 @@ import com.terraforged.api.chunk.column.ColumnDecorator;
import com.terraforged.api.chunk.surface.SurfaceManager;
import com.terraforged.biome.ModBiomes;
import com.terraforged.biome.surface.BriceSurface;
import com.terraforged.biome.surface.DesertSurface;
import com.terraforged.biome.surface.ForestSurface;
import com.terraforged.biome.surface.IcebergsSurface;
import com.terraforged.biome.surface.SwampSurface;
@ -109,9 +110,15 @@ public class TerraSetupFactory {
public static SurfaceManager createSurfaceManager(TerraContext context) {
SurfaceManager manager = new SurfaceManager();
manager.replace(Biomes.DEEP_FROZEN_OCEAN.delegate.get(), new IcebergsSurface(context, 30, 30));
manager.replace(Biomes.FROZEN_OCEAN.delegate.get(), new IcebergsSurface(context, 20, 15));
manager.replace(Biomes.DEEP_FROZEN_OCEAN, new IcebergsSurface(context, 30, 30));
manager.replace(Biomes.FROZEN_OCEAN, new IcebergsSurface(context, 20, 15));
manager.append(ModBiomes.BRYCE, new BriceSurface(context.seed));
manager.append(
new DesertSurface(context),
Biomes.DESERT,
Biomes.DESERT_HILLS,
Biomes.DESERT_LAKES
);
manager.replace(
new SwampSurface(),
Biomes.SWAMP.delegate.get(),
@ -120,6 +127,7 @@ public class TerraSetupFactory {
manager.append(
new ForestSurface(context),
Biomes.FOREST,
Biomes.BIRCH_FOREST_HILLS,
Biomes.TALL_BIRCH_FOREST,
Biomes.DARK_FOREST,
Biomes.DARK_FOREST_HILLS

View File

@ -1,6 +1,6 @@
package com.terraforged.chunk.generator;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.chunk.TerraChunkGenerator;
import com.terraforged.chunk.util.TerraContainer;
import com.terraforged.core.region.chunk.ChunkReader;
@ -12,7 +12,7 @@ import net.minecraft.world.chunk.IChunk;
public class BiomeGenerator implements Generator.Biomes {
private final TerraChunkGenerator generator;
private final BiomeProvider biomeProvider;
private final TerraBiomeProvider biomeProvider;
public BiomeGenerator(TerraChunkGenerator generator) {
this.generator = generator;

View File

@ -25,12 +25,12 @@
package com.terraforged.chunk.test;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.chunk.TerraContext;
import com.terraforged.core.cell.Cell;
import net.minecraft.world.biome.Biome;
public class TestBiomeProvider extends BiomeProvider {
public class TestBiomeProvider extends TerraBiomeProvider {
public TestBiomeProvider(TerraContext chunkContext) {
super(chunkContext);

View File

@ -25,7 +25,7 @@
package com.terraforged.chunk.test;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.chunk.TerraChunkGenerator;
import com.terraforged.chunk.TerraContext;
import com.terraforged.core.cell.Cell;
@ -36,15 +36,15 @@ import net.minecraft.world.gen.GenerationSettings;
public class TestChunkGenerator extends TerraChunkGenerator {
private final BiomeProvider biomeProvider;
private final TerraBiomeProvider biomeProvider;
public TestChunkGenerator(TerraContext context, BiomeProvider biomeProvider, GenerationSettings settings) {
public TestChunkGenerator(TerraContext context, TerraBiomeProvider biomeProvider, GenerationSettings settings) {
super(new TestTerraContext(context), biomeProvider, settings);
this.biomeProvider = new TestBiomeProvider(context);
}
@Override
public BiomeProvider getBiomeProvider() {
public TerraBiomeProvider getBiomeProvider() {
return biomeProvider;
}

View File

@ -1,10 +1,11 @@
package com.terraforged.chunk.util;
import com.terraforged.api.biome.BiomeVariant;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.core.cell.Cell;
import com.terraforged.core.region.chunk.ChunkReader;
import com.terraforged.core.util.PosIterator;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeContainer;
@ -61,17 +62,28 @@ public class TerraContainer extends BiomeContainer {
return new BiomeContainer(biomes);
}
public static TerraContainer getOrCreate(IChunk chunk, ChunkReader reader, BiomeProvider biomeProvider) {
if (chunk.getBiomes() instanceof TerraContainer) {
return (TerraContainer) chunk.getBiomes();
} else {
TerraContainer container = TerraContainer.create(reader, biomeProvider);
((ChunkPrimer) chunk).func_225548_a_(container);
return container;
public static TerraContainer getOrCreate(IChunk chunk, ChunkReader reader, TerraBiomeProvider biomeProvider) {
BiomeContainer biomes = chunk.getBiomes();
if (biomes instanceof TerraContainer) {
return (TerraContainer) biomes;
}
TerraContainer container;
if (biomes == null) {
// create new container based on the provided ChunkReader
container = TerraContainer.create(reader, biomeProvider);
} else {
// converts an existing non-tf biome container into one that TerraForged can use
container = TerraContainer.convert(chunk.getPos(), biomes, biomeProvider);
}
// replace/set the primer's biomes
((ChunkPrimer) chunk).func_225548_a_(container);
return container;
}
public static TerraContainer create(ChunkReader chunkReader, BiomeProvider biomeProvider) {
public static TerraContainer create(ChunkReader chunkReader, TerraBiomeProvider biomeProvider) {
Biome[] biomes2D = new Biome[BIOMES_2D_SIZE];
Biome[] biomes3D = new Biome[BIOMES_3D_SIZE];
PosIterator iterator = PosIterator.area(0, 0, 16, 16);
@ -91,6 +103,24 @@ public class TerraContainer extends BiomeContainer {
return new TerraContainer(biomes3D, biomes2D);
}
private static TerraContainer convert(ChunkPos pos, BiomeContainer biomes, TerraBiomeProvider biomeProvider) {
Biome[] biomes2D = new Biome[BIOMES_2D_SIZE];
Biome[] biomes3D = new Biome[BIOMES_3D_SIZE];
PosIterator iterator = PosIterator.area(0, 0, 16, 16);
while (iterator.next()) {
int dx = iterator.x();
int dz = iterator.z();
Biome biome = biomeProvider.getSurfaceBiome(pos.getXStart() + dx, pos.getZStart() + dz, biomes);
biomes2D[indexOf(dx, dz)] = biome;
if ((dx & 3) == 0 && (dz & 3) == 0) {
for (int dy = 0; dy < 64; dy++) {
biomes3D[indexOf(dx >> 2, dy, dz >> 2)] = biome;
}
}
}
return new TerraContainer(biomes3D, biomes2D);
}
private static int indexOf(int x, int z) {
return (z << 4) + x;
}

View File

@ -32,7 +32,7 @@ import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.terraforged.Log;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.chunk.TerraChunkGenerator;
import com.terraforged.chunk.TerraContext;
import com.terraforged.command.arg.BiomeArgType;
@ -128,7 +128,7 @@ public class TerraCommand {
));
BlockPos pos = context.getSource().asPlayer().getPosition();
BiomeProvider biomeProvider = getBiomeProvider(context);
TerraBiomeProvider biomeProvider = getBiomeProvider(context);
try (Resource<Cell> cell = biomeProvider.lookupPos(pos.getX(), pos.getZ())) {
Biome biome = biomeProvider.getBiome(cell.get(), pos.getX(), pos.getZ());
context.getSource().sendFeedback(
@ -292,8 +292,8 @@ public class TerraCommand {
return context.getSource().getWorld().getChunkProvider().getChunkGenerator();
}
private static BiomeProvider getBiomeProvider(CommandContext<CommandSource> context) {
return (BiomeProvider) context.getSource().getWorld().getChunkProvider().getChunkGenerator().getBiomeProvider();
private static TerraBiomeProvider getBiomeProvider(CommandContext<CommandSource> context) {
return (TerraBiomeProvider) context.getSource().getWorld().getChunkProvider().getChunkGenerator().getBiomeProvider();
}
private static CommandSyntaxException createException(String type, String message, Object... args) {

View File

@ -1,6 +1,6 @@
package com.terraforged.command.search;
import com.terraforged.biome.provider.BiomeProvider;
import com.terraforged.biome.provider.TerraBiomeProvider;
import com.terraforged.core.cell.Cell;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
@ -9,11 +9,11 @@ import net.minecraft.world.gen.ChunkGenerator;
public class BiomeSearchTask extends ChunkGeneratorSearch {
private final Biome biome;
private final BiomeProvider biomeProvider;
private final TerraBiomeProvider biomeProvider;
private final Cell cell = new Cell();
public BiomeSearchTask(BlockPos center, Biome biome, ChunkGenerator<?> generator, BiomeProvider biomeProvider) {
public BiomeSearchTask(BlockPos center, Biome biome, ChunkGenerator<?> generator, TerraBiomeProvider biomeProvider) {
super(center, generator);
this.biomeProvider = biomeProvider;
this.biome = biome;

View File

@ -20,7 +20,7 @@ public class ConfigRef implements Supplier<CommentedFileConfig> {
public CommentedFileConfig get() {
synchronized (lock) {
if (ref != null) {
Log.info("Loading config: %s", ref.getFile().getName());
Log.info("Loading config: {}", ref.getFile().getName());
ref.load();
return ref;
}

View File

@ -1,5 +1,6 @@
{
"biomes": [
"terraforged:steppe",
"terraforged:savanna_scrub",
"terraforged:shattered_savanna_scrub"
],
@ -15,6 +16,13 @@
"name": "minecraft:random_selector",
"config": {
"features": [
{
"name": "terraforged:template",
"config": {
"template": "terraforged:oak_small"
},
"chance": 0.2
},
{
"name": "terraforged:template",
"config": {
@ -26,7 +34,7 @@
"default": {
"name": "terraforged:template",
"config": {
"template": "terraforged:acacia_bush"
"template": "terraforged:oak_small"
}
}
}
@ -35,8 +43,8 @@
"name": "minecraft:count_extra_heightmap",
"config": {
"count": 0,
"extra_chance": 0.025,
"extra_count": 1
"extra_chance": 0.02,
"extra_count": 3
}
}
}