Implement flora as a Feature on Fabric

This commit is contained in:
dfsek
2020-12-16 02:38:48 -07:00
parent b955e3d9b9
commit beec1a97d4
5 changed files with 54 additions and 33 deletions

View File

@@ -22,6 +22,7 @@ import com.dfsek.terra.fabric.mixin.GeneratorTypeAccessor;
import com.dfsek.terra.fabric.world.FabricBiome;
import com.dfsek.terra.fabric.world.FabricWorldHandle;
import com.dfsek.terra.fabric.world.TerraBiomeSource;
import com.dfsek.terra.fabric.world.features.FloraFeature;
import com.dfsek.terra.fabric.world.generator.FabricChunkGeneratorWrapper;
import com.dfsek.terra.registry.ConfigRegistry;
import net.fabricmc.api.EnvType;
@@ -32,15 +33,21 @@ import net.minecraft.client.world.GeneratorType;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeEffects;
import net.minecraft.world.biome.GenerationSettings;
import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
import net.minecraft.world.gen.decorator.Decorator;
import net.minecraft.world.gen.decorator.NopeDecoratorConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.HugeMushroomFeature;
import net.minecraft.world.gen.feature.TreeFeature;
import net.minecraft.world.gen.feature.TreeFeatureConfig;
@@ -65,6 +72,9 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
return instance;
}
public static final FloraFeature FLORA = new FloraFeature(DefaultFeatureConfig.CODEC);
public static final ConfiguredFeature<?, ?> FLORA_CONFIGURED = FLORA.configure(FeatureConfig.DEFAULT).decorate(Decorator.NOPE.configure(NopeDecoratorConfig.INSTANCE));
private final GenericLoaders genericLoaders = new GenericLoaders(this);
private final Logger logger = Logger.getLogger("Terra");
private final ItemHandle itemHandle = new FabricItemHandle();
@@ -175,6 +185,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
GenerationSettings.Builder generationSettings = new GenerationSettings.Builder();
generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.withConfig(new TernarySurfaceConfig(Blocks.GRASS_BLOCK.getDefaultState(), Blocks.DIRT.getDefaultState(), Blocks.GRAVEL.getDefaultState()))); // It needs a surfacebuilder, even though we dont use it.
generationSettings.feature(GenerationStep.Feature.VEGETAL_DECORATION, FLORA_CONFIGURED);
BiomeEffects.Builder effects = new BiomeEffects.Builder()
.waterColor(vanilla.getWaterColor())
@@ -196,7 +207,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
.scale(vanilla.getScale())
.temperature(0.8F)
.downfall(0.4F)
.effects(effects.build())
.effects(vanilla.getEffects()) // TODO: configurable
.spawnSettings(spawnSettings.build())
.generationSettings(generationSettings.build())
.build();
@@ -233,29 +244,25 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
LangUtil.load("en_us", this);
logger.info("Initializing Terra...");
registry.loadAll(this);
registry.forEach(pack -> pack.getBiomeRegistry().forEach(biome -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, biome)), createBiome(biome)))); // Register all Terra biomes.
/*
registry.forEach(config -> {
String pack = config.getTemplate().getID().toLowerCase();
config.getBiomeRegistry().forEach(terraBiome -> {
Biome biome = (new Biome.Builder()).build();
Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", pack + "_" + terraBiome.getID().toLowerCase()), biome);
});
});
*/
Registry.register(Registry.FEATURE, new Identifier("terra", "flora_populator"), FLORA);
RegistryKey<ConfiguredFeature<?, ?>> floraKey = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN, new Identifier("terra", "flora_populator"));
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, floraKey.getValue(), FLORA_CONFIGURED);
registry.forEach(pack -> pack.getBiomeRegistry().forEach(biome -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, biome)), createBiome(biome)))); // Register all Terra biomes.
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), TerraBiomeSource.CODEC);
if(FabricLoader.getInstance().getEnvironmentType().equals(EnvType.CLIENT)) {
GeneratorTypeAccessor.getValues().add(new GeneratorType("terra") {
@Override
protected ChunkGenerator getChunkGenerator(Registry<Biome> biomeRegistry, Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry, long seed) {
return new FabricChunkGeneratorWrapper(new TerraBiomeSource(biomeRegistry, seed), seed, registry.get("DEFAULT"));
ConfigPack pack = registry.get("DEFAULT");
return new FabricChunkGeneratorWrapper(new TerraBiomeSource(biomeRegistry, seed, pack), seed, pack);
}
});
}
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), TerraBiomeSource.CODEC);
}
}

View File

@@ -17,9 +17,13 @@ import net.minecraft.world.gen.feature.StructureFeature;
import java.util.stream.Collectors;
public class TerraBiomeSource extends BiomeSource {
public static final Codec<ConfigPack> PACK_CODEC = (RecordCodecBuilder.create(config -> config.group(
Codec.STRING.fieldOf("pack").forGetter(pack -> pack.getTemplate().getID())
).apply(config, config.stable(TerraFabricPlugin.getInstance().getRegistry()::get))));
public static final Codec<TerraBiomeSource> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RegistryLookupCodec.of(Registry.BIOME_KEY).forGetter(source -> source.biomeRegistry),
Codec.LONG.fieldOf("seed").stable().forGetter(source -> source.seed))
Codec.LONG.fieldOf("seed").stable().forGetter(source -> source.seed),
PACK_CODEC.fieldOf("pack").stable().forGetter(source -> source.pack))
.apply(instance, instance.stable(TerraBiomeSource::new)));
private final Registry<Biome> biomeRegistry;
@@ -27,12 +31,12 @@ public class TerraBiomeSource extends BiomeSource {
private final TerraBiomeGrid grid;
private final ConfigPack pack;
public TerraBiomeSource(Registry<Biome> biomes, long seed) {
public TerraBiomeSource(Registry<Biome> biomes, long seed, ConfigPack pack) {
super(biomes.stream().collect(Collectors.toList()));
this.biomeRegistry = biomes;
this.seed = seed;
this.grid = new TerraBiomeGrid.TerraBiomeGridBuilder(seed, TerraFabricPlugin.getInstance().getRegistry().get("DEFAULT"), TerraFabricPlugin.getInstance()).build();
this.pack = TerraFabricPlugin.getInstance().getRegistry().get("DEFAULT");
this.grid = new TerraBiomeGrid.TerraBiomeGridBuilder(seed, pack, TerraFabricPlugin.getInstance()).build();
this.pack = pack;
}
@Override
@@ -42,7 +46,7 @@ public class TerraBiomeSource extends BiomeSource {
@Override
public BiomeSource withSeed(long seed) {
return new TerraBiomeSource(this.biomeRegistry, seed);
return new TerraBiomeSource(this.biomeRegistry, seed, pack);
}
@Override

View File

@@ -1,5 +1,9 @@
package com.dfsek.terra.fabric.world.features;
import com.dfsek.terra.fabric.world.generator.FabricChunkGenerator;
import com.dfsek.terra.fabric.world.generator.FabricChunkGeneratorWrapper;
import com.dfsek.terra.fabric.world.handles.FabricWorld;
import com.dfsek.terra.fabric.world.handles.chunk.FabricChunkWorldAccess;
import com.mojang.serialization.Codec;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.StructureWorldAccess;
@@ -16,6 +20,8 @@ public class FloraFeature extends Feature<DefaultFeatureConfig> {
@Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
return false;
((FabricChunkGeneratorWrapper) chunkGenerator).getFloraPopulator().populate(new FabricWorld(world.toServerWorld(), new FabricChunkGenerator(chunkGenerator)),
random, new FabricChunkWorldAccess(world, pos.getX() >> 4, pos.getZ() >> 4));
return true;
}
}

View File

@@ -6,7 +6,7 @@ import com.dfsek.terra.api.generic.Handle;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.fabric.TerraFabricPlugin;
import com.dfsek.terra.fabric.world.TerraBiomeSource;
import com.dfsek.terra.fabric.world.handles.chunk.FabricChunkRegionChunk;
import com.dfsek.terra.fabric.world.handles.chunk.FabricChunkWorldAccess;
import com.dfsek.terra.fabric.world.handles.world.FabricSeededWorldAccess;
import com.dfsek.terra.fabric.world.handles.world.FabricWorldChunkRegion;
import com.dfsek.terra.generation.TerraChunkGenerator;
@@ -53,6 +53,10 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Handl
private final OrePopulator orePopulator = new OrePopulator(TerraFabricPlugin.getInstance());
private final TreePopulator treePopulator = new TreePopulator(TerraFabricPlugin.getInstance());
public FloraPopulator getFloraPopulator() {
return floraPopulator;
}
public FabricChunkGeneratorWrapper(TerraBiomeSource biomeSource, long seed, ConfigPack configPack) {
super(biomeSource, new StructuresConfig(false));
this.pack = configPack;
@@ -99,10 +103,10 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Handl
public void generateFeatures(ChunkRegion region, StructureAccessor accessor) {
FastRandom pop = new FastRandom(MathUtil.getCarverChunkSeed(region.getCenterChunkX(), region.getCenterChunkZ(), seed));
FabricWorldChunkRegion chunkRegion = new FabricWorldChunkRegion(region, this);
FabricChunkRegionChunk regionChunk = new FabricChunkRegionChunk(region);
FabricChunkWorldAccess regionChunk = new FabricChunkWorldAccess(region, region.getCenterChunkX(), region.getCenterChunkZ());
super.generateFeatures(region, accessor);
cavePopulator.populate(chunkRegion, pop, regionChunk);
orePopulator.populate(chunkRegion, pop, regionChunk);
floraPopulator.populate(chunkRegion, pop, regionChunk);
}
@Override

View File

@@ -6,27 +6,27 @@ import com.dfsek.terra.api.generic.world.block.Block;
import com.dfsek.terra.fabric.world.block.FabricBlock;
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkRegion;
import net.minecraft.world.WorldAccess;
public class FabricChunkRegionChunk implements Chunk {
private final ChunkRegion chunkRegion;
public class FabricChunkWorldAccess implements Chunk {
private final WorldAccess chunkRegion;
private final int x;
private final int z;
public FabricChunkRegionChunk(ChunkRegion chunkRegion) {
public FabricChunkWorldAccess(WorldAccess chunkRegion, int x, int z) {
this.chunkRegion = chunkRegion;
this.x = chunkRegion.getCenterChunkX() << 4;
this.z = chunkRegion.getCenterChunkZ() << 4;
this.x = x << 4;
this.z = z << 4;
}
@Override
public int getX() {
return chunkRegion.getCenterChunkX();
return x >> 4;
}
@Override
public int getZ() {
return chunkRegion.getCenterChunkZ();
return z >> 4;
}
@Override
@@ -41,7 +41,7 @@ public class FabricChunkRegionChunk implements Chunk {
}
@Override
public ChunkRegion getHandle() {
public WorldAccess getHandle() {
return chunkRegion;
}
}