diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java index 9bbda02..aa80721 100644 --- a/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/CommonSetup.java @@ -4,11 +4,10 @@ import com.cursedcauldron.wildbackport.common.entities.Allay; import com.cursedcauldron.wildbackport.common.entities.Frog; import com.cursedcauldron.wildbackport.common.entities.Tadpole; import com.cursedcauldron.wildbackport.common.entities.Warden; -import com.cursedcauldron.wildbackport.common.events.StructureEvent; import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; import com.cursedcauldron.wildbackport.common.registry.worldgen.WBWorldGeneration; -import com.cursedcauldron.wildbackport.core.api.Environment; import com.cursedcauldron.wildbackport.core.api.MobRegistry; +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeModifier; public class CommonSetup { /** @@ -20,15 +19,13 @@ public class CommonSetup { MobRegistry.registerAttributes(WBEntities.FROG, Frog::createAttributes); MobRegistry.registerAttributes(WBEntities.TADPOLE, Tadpole::createAttributes); MobRegistry.registerAttributes(WBEntities.WARDEN, Warden::createAttributes); -// StructureEvent.bootstrap(); - if (Environment.isFabric()) WBWorldGeneration.bootstrap(); } /** * Runs features post bootstrap */ public static void onPostCommon() { -// StructureEvent.bootstrap(); - if (Environment.isForge()) WBWorldGeneration.bootstrap(); + WBWorldGeneration.bootstrap(); + BiomeModifier.setup(); } } \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java index 45ab6a6..8fc3df9 100644 --- a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/FrogBrain.java @@ -5,7 +5,7 @@ import com.cursedcauldron.wildbackport.common.entities.Frog; import com.cursedcauldron.wildbackport.common.entities.brain.frog.BiasedLongJumpTask; import com.cursedcauldron.wildbackport.common.entities.brain.frog.Croak; import com.cursedcauldron.wildbackport.common.entities.brain.frog.FrogEat; -import com.cursedcauldron.wildbackport.common.entities.brain.frog.LayFrogSpawnTask; +import com.cursedcauldron.wildbackport.common.entities.brain.frog.LayFrogSpawn; import com.cursedcauldron.wildbackport.common.entities.brain.frog.WalkTowardsLand; import com.cursedcauldron.wildbackport.common.entities.brain.frog.WalkTowardsWater; import com.cursedcauldron.wildbackport.common.registry.WBBlocks; @@ -80,7 +80,7 @@ public class FrogBrain { } private static void addLaySpawnActivities(Brain brain) { - brain.addActivityWithConditions(WBActivities.LAY_SPAWN.get(), ImmutableList.of(Pair.of(0, new RunSometimes(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(1, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(2, new WalkTowardsWater(8, 1.0F)), Pair.of(3, new LayFrogSpawnTask(WBBlocks.FROGSPAWN.get(), WBMemoryModules.IS_PREGNANT.get())), Pair.of(4, new RunOne<>(ImmutableList.of(Pair.of(new RandomStroll(1.0F), 2), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new Croak(), 2), Pair.of(new RunIf<>(Entity::isOnGround, new DoNothing(5, 20)), 1))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_PREGNANT.get(), MemoryStatus.VALUE_PRESENT))); + brain.addActivityWithConditions(WBActivities.LAY_SPAWN.get(), ImmutableList.of(Pair.of(0, new RunSometimes(new SetEntityLookTarget(EntityType.PLAYER, 6.0F), UniformInt.of(30, 60))), Pair.of(1, new StartAttacking<>(FrogBrain::isNotBreeding, frog -> frog.getBrain().getMemory(MemoryModuleType.NEAREST_ATTACKABLE))), Pair.of(2, new WalkTowardsWater(8, 1.0F)), Pair.of(3, new LayFrogSpawn(WBBlocks.FROGSPAWN.get(), WBMemoryModules.IS_PREGNANT.get())), Pair.of(4, new RunOne<>(ImmutableList.of(Pair.of(new RandomStroll(1.0F), 2), Pair.of(new SetWalkTargetFromLookTarget(1.0F, 3), 1), Pair.of(new Croak(), 2), Pair.of(new RunIf<>(Entity::isOnGround, new DoNothing(5, 20)), 1))))), ImmutableSet.of(Pair.of(MemoryModuleType.LONG_JUMP_MID_JUMP, MemoryStatus.VALUE_ABSENT), Pair.of(WBMemoryModules.IS_PREGNANT.get(), MemoryStatus.VALUE_PRESENT))); } private static void addLongJumpActivities(Brain brain) { diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawnTask.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawn.java similarity index 55% rename from common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawnTask.java rename to common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawn.java index 47ceed8..09dd371 100644 --- a/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawnTask.java +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/entities/brain/frog/LayFrogSpawn.java @@ -14,32 +14,33 @@ import net.minecraft.world.entity.ai.memory.MemoryStatus; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; -public class LayFrogSpawnTask extends Behavior { +public class LayFrogSpawn extends Behavior { private final Block frogSpawn; private final MemoryModuleType triggerMemory; - public LayFrogSpawnTask(Block block, MemoryModuleType memoryModuleType) { + public LayFrogSpawn(Block block, MemoryModuleType triggerMemory) { super(ImmutableMap.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_PRESENT, WBMemoryModules.IS_PREGNANT.get(), MemoryStatus.VALUE_PRESENT)); this.frogSpawn = block; - this.triggerMemory = memoryModuleType; + this.triggerMemory = triggerMemory; } @Override - protected boolean checkExtraStartConditions(ServerLevel serverWorld, Frog arg) { - return !arg.isInWaterOrBubble() && arg.isOnGround(); + protected boolean checkExtraStartConditions(ServerLevel level, Frog frog) { + return !frog.isInWaterOrBubble() && frog.isOnGround(); } @Override - protected void start(ServerLevel serverWorld, Frog arg, long l) { - BlockPos blockPos = arg.blockPosition().below(); + protected void start(ServerLevel level, Frog frog, long time) { + BlockPos blockPos = frog.blockPosition().below(); for (Direction direction : Direction.Plane.HORIZONTAL) { - BlockPos blockPos3; - BlockPos blockPos2 = blockPos.relative(direction); - if (!serverWorld.getBlockState(blockPos2).is(Blocks.WATER) || !serverWorld.getBlockState(blockPos3 = blockPos2.above()).isAir()) continue; - serverWorld.setBlock(blockPos3, this.frogSpawn.defaultBlockState(), 3); - serverWorld.playSound(null, arg, WBSoundEvents.FROG_LAY_SPAWN, SoundSource.BLOCKS, 1.0f, 1.0f); - arg.getBrain().eraseMemory(this.triggerMemory); - return; + BlockPos offset = blockPos.relative(direction); + BlockPos above = offset.above(); + if (level.getBlockState(offset).is(Blocks.WATER) && level.getBlockState(above).isAir()) { + level.setBlock(above, this.frogSpawn.defaultBlockState(), 3); + level.playSound(null, frog, WBSoundEvents.FROG_LAY_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F); + frog.getBrain().eraseMemory(this.triggerMemory); + return; + } } } } \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java index dc32a7f..44835d4 100644 --- a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/WBBiomes.java @@ -2,23 +2,77 @@ package com.cursedcauldron.wildbackport.common.registry; import com.cursedcauldron.wildbackport.WildBackport; import com.cursedcauldron.wildbackport.core.api.CoreRegistry; +import com.cursedcauldron.wildbackport.core.mixin.access.OverworldBiomesAccessor; import net.minecraft.core.Registry; import net.minecraft.data.BuiltinRegistries; -import net.minecraft.data.worldgen.biome.OverworldBiomes; +import net.minecraft.data.worldgen.BiomeDefaultFeatures; +import net.minecraft.data.worldgen.Carvers; +import net.minecraft.data.worldgen.placement.AquaticPlacements; +import net.minecraft.data.worldgen.placement.VegetationPlacements; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.level.biome.AmbientMoodSettings; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeGenerationSettings; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.GenerationStep; import java.util.function.Supplier; public class WBBiomes { public static final CoreRegistry BIOMES = CoreRegistry.create(BuiltinRegistries.BIOME, WildBackport.MOD_ID); - public static final ResourceKey MANGROVE_SWAMP = create("mangrove_swamp", OverworldBiomes::theVoid); - public static final ResourceKey DEEP_DARK = create("deep_dark", OverworldBiomes::theVoid); + public static final ResourceKey MANGROVE_SWAMP = create("mangrove_swamp", WBBiomes::mangroveSwamp); + public static final ResourceKey DEEP_DARK = create("deep_dark", WBBiomes::deepDark); + + // Mangrove Swamp + public static Biome mangroveSwamp() { + MobSpawnSettings.Builder spawn = new MobSpawnSettings.Builder(); + BiomeDefaultFeatures.commonSpawns(spawn); + BiomeGenerationSettings.Builder generation = new BiomeGenerationSettings.Builder(); + BiomeDefaultFeatures.addFossilDecoration(generation); + OverworldBiomesAccessor.callGlobalOverworldGeneration(generation); + BiomeDefaultFeatures.addDefaultOres(generation); + BiomeDefaultFeatures.addSwampClayDisk(generation); + generation.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_NORMAL); + generation.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH); + generation.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_WATERLILY); + generation.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEAGRASS_SWAMP); + return new Biome.BiomeBuilder().biomeCategory(Biome.BiomeCategory.SWAMP).precipitation(Biome.Precipitation.RAIN).temperature(0.8F).downfall(0.9f).specialEffects(new BiomeSpecialEffects.Builder().waterColor(3832426).waterFogColor(5077600).fogColor(12638463).skyColor(calculateSkyColor(0.8f)).foliageColorOverride(9285927).grassColorModifier(BiomeSpecialEffects.GrassColorModifier.SWAMP).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).build()).mobSpawnSettings(spawn.build()).generationSettings(generation.build()).build(); + } + + // Deep Dark + public static Biome deepDark() { + MobSpawnSettings.Builder spawn = new MobSpawnSettings.Builder(); + BiomeGenerationSettings.Builder generation = new BiomeGenerationSettings.Builder(); + generation.addCarver(GenerationStep.Carving.AIR, Carvers.CAVE); + generation.addCarver(GenerationStep.Carving.AIR, Carvers.CAVE_EXTRA_UNDERGROUND); + generation.addCarver(GenerationStep.Carving.AIR, Carvers.CANYON); + BiomeDefaultFeatures.addDefaultCrystalFormations(generation); + BiomeDefaultFeatures.addDefaultMonsterRoom(generation); + BiomeDefaultFeatures.addDefaultUndergroundVariety(generation); + BiomeDefaultFeatures.addSurfaceFreezing(generation); + BiomeDefaultFeatures.addPlainGrass(generation); + BiomeDefaultFeatures.addDefaultOres(generation, true); + BiomeDefaultFeatures.addDefaultSoftDisks(generation); + BiomeDefaultFeatures.addPlainVegetation(generation); + BiomeDefaultFeatures.addDefaultMushrooms(generation); + BiomeDefaultFeatures.addDefaultExtraVegetation(generation); + return new Biome.BiomeBuilder().biomeCategory(Biome.BiomeCategory.UNDERGROUND).precipitation(Biome.Precipitation.RAIN).temperature(0.8F).downfall(0.4F).specialEffects(new BiomeSpecialEffects.Builder().waterColor(4159204).waterFogColor(329011).fogColor(12638463).skyColor(calculateSkyColor(0.8F)).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).build()).mobSpawnSettings(spawn.build()).generationSettings(generation.build()).build(); + } + + // Registry private static ResourceKey create(String key, Supplier biome) { BIOMES.register(key, biome); return ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation(WildBackport.MOD_ID, key)); } + + protected static int calculateSkyColor(float temperature) { + float modifier = temperature / 3.0F; + modifier = Mth.clamp(modifier, -1.0F, 1.0F); + return Mth.hsvToRgb(0.62222224F - modifier * 0.05F, 0.5F + modifier * 0.1F, 1.0F); + } } \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBFeatures.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBFeatures.java index 7ffde0c..052529e 100644 --- a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBFeatures.java +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBFeatures.java @@ -1,6 +1,8 @@ package com.cursedcauldron.wildbackport.common.registry.worldgen; import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.worldgen.features.GrassDiskConfiguration; +import com.cursedcauldron.wildbackport.common.worldgen.features.GrassDiskFeature; import com.cursedcauldron.wildbackport.common.worldgen.features.RootedTreeConfig; import com.cursedcauldron.wildbackport.common.worldgen.features.RootedTreeFeature; import com.cursedcauldron.wildbackport.core.api.CoreRegistry; @@ -15,4 +17,5 @@ public class WBFeatures { public static final CoreRegistry> FEATURES = CoreRegistry.create(Registry.FEATURE, WildBackport.MOD_ID); public static final Supplier> TREE = FEATURES.register("tree", () -> new RootedTreeFeature(RootedTreeConfig.CODEC)); + public static final Supplier> DISK = FEATURES.register("disk", () -> new GrassDiskFeature(GrassDiskConfiguration.CODEC)); } \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBWorldGeneration.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBWorldGeneration.java index 7cce869..6b812cd 100644 --- a/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBWorldGeneration.java +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/registry/worldgen/WBWorldGeneration.java @@ -4,10 +4,13 @@ import com.cursedcauldron.wildbackport.WildBackport; import com.cursedcauldron.wildbackport.common.blocks.MangrovePropaguleBlock; import com.cursedcauldron.wildbackport.common.registry.WBBlocks; import com.cursedcauldron.wildbackport.common.tag.WBBlockTags; +import com.cursedcauldron.wildbackport.common.worldgen.PredicatedStateProvider; +import com.cursedcauldron.wildbackport.common.worldgen.WorldGenerator; import com.cursedcauldron.wildbackport.common.worldgen.decorator.AttachedToLeavesDecorator; import com.cursedcauldron.wildbackport.common.worldgen.decorator.LayerRootDecorator; import com.cursedcauldron.wildbackport.common.worldgen.decorator.MangroveRootPlacement; import com.cursedcauldron.wildbackport.common.worldgen.decorator.WeightedLeaveVineDecorator; +import com.cursedcauldron.wildbackport.common.worldgen.features.GrassDiskConfiguration; import com.cursedcauldron.wildbackport.common.worldgen.features.RootedTreeConfig; import com.cursedcauldron.wildbackport.common.worldgen.placers.MangroveRootPlacer; import com.cursedcauldron.wildbackport.common.worldgen.placers.UpwardBranchingTrunk; @@ -16,6 +19,7 @@ import net.minecraft.core.Direction; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; +import net.minecraft.core.Vec3i; import net.minecraft.data.BuiltinRegistries; import net.minecraft.data.worldgen.placement.PlacementUtils; import net.minecraft.util.valueproviders.ConstantInt; @@ -39,7 +43,9 @@ import net.minecraft.world.level.levelgen.placement.CountPlacement; import net.minecraft.world.level.levelgen.placement.InSquarePlacement; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import net.minecraft.world.level.levelgen.placement.PlacementModifier; +import net.minecraft.world.level.levelgen.placement.RandomOffsetPlacement; import net.minecraft.world.level.levelgen.placement.SurfaceWaterDepthFilter; +import net.minecraft.world.level.material.Fluids; import java.util.List; import java.util.Optional; @@ -47,9 +53,12 @@ import java.util.Optional; //<> public class WBWorldGeneration { - public static void bootstrap() {} + public static void bootstrap() { + WorldGenerator.setup(); + } // Mangrove Swamp + //TODO: fix mangroves not generating moss public static final Holder> MANGROVE = config("mangrove", WBFeatures.TREE.get(), new RootedTreeConfig.Builder( BlockStateProvider.simple(WBBlocks.MANGROVE_LOG.get()), @@ -83,6 +92,8 @@ public class WBWorldGeneration { public static final Holder> MANGROVE_VEGETATION = config("mangrove_vegetation", Feature.RANDOM_SELECTOR, new RandomFeatureConfiguration(List.of(new WeightedPlacedFeature(TALL_MANGROVE_CHECKED, 0.85F)), MANGROVE_CHECKED)); public static final Holder TREES_MANGROVE = place("trees_mangrove", MANGROVE_VEGETATION, CountPlacement.of(25), InSquarePlacement.spread(), SurfaceWaterDepthFilter.forMaxDepth(5), PlacementUtils.HEIGHTMAP_OCEAN_FLOOR, BiomeFilter.biome(), BlockPredicateFilter.forPredicate(BlockPredicate.wouldSurvive(WBBlocks.MANGROVE_PROPAGULE.get().defaultBlockState(), BlockPos.ZERO))); + public static final Holder> DISK_GRASS_CONFIG = config("disk_grass", WBFeatures.DISK.get(), new GrassDiskConfiguration(new PredicatedStateProvider(BlockStateProvider.simple(Blocks.DIRT), List.of(new PredicatedStateProvider.Rule(BlockPredicate.not(BlockPredicate.allOf(BlockPredicate.solid(Direction.UP.getNormal()), BlockPredicate.matchesFluid(Fluids.WATER, Direction.UP.getNormal()))), BlockStateProvider.simple(Blocks.GRASS_BLOCK)))), BlockPredicate.matchesBlocks(List.of(Blocks.DIRT, WBBlocks.MUD.get())), UniformInt.of(2, 6), 2)); + public static final Holder DISK_GRASS = place("disk_grass", DISK_GRASS_CONFIG, CountPlacement.of(1), InSquarePlacement.spread(), PlacementUtils.HEIGHTMAP_TOP_SOLID, RandomOffsetPlacement.vertical(ConstantInt.of(-1)), BlockPredicateFilter.forPredicate(BlockPredicate.matchesBlock(WBBlocks.MUD.get(), Vec3i.ZERO)), BiomeFilter.biome()); // Deep Dark diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/MangroveSwampSurface.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/MangroveSwampSurface.java new file mode 100644 index 0000000..cc6d68f --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/MangroveSwampSurface.java @@ -0,0 +1,24 @@ +package com.cursedcauldron.wildbackport.common.worldgen; + +import com.cursedcauldron.wildbackport.common.registry.WBBiomes; +import com.cursedcauldron.wildbackport.common.registry.WBBlocks; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.Noises; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.VerticalAnchor; + +public class MangroveSwampSurface { + public static final SurfaceRules.ConditionSource ABOVE_60 = SurfaceRules.yBlockCheck(VerticalAnchor.absolute(60), 0); + public static final SurfaceRules.ConditionSource ABOVE_63 = SurfaceRules.yBlockCheck(VerticalAnchor.absolute(63), 0); + + public static SurfaceRules.RuleSource makeRules() { + SurfaceRules.RuleSource terrain = SurfaceRules.sequence(SurfaceRules.ifTrue(SurfaceRules.isBiome(WBBiomes.MANGROVE_SWAMP), makeStateRule(WBBlocks.MUD.get()))); + SurfaceRules.RuleSource generation = SurfaceRules.sequence(SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, SurfaceRules.sequence(SurfaceRules.ifTrue(SurfaceRules.isBiome(WBBiomes.MANGROVE_SWAMP), SurfaceRules.ifTrue(ABOVE_60, SurfaceRules.ifTrue(SurfaceRules.not(ABOVE_63), SurfaceRules.ifTrue(SurfaceRules.noiseCondition(Noises.SWAMP, 0.0F), makeStateRule(Blocks.WATER))))))), SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, SurfaceRules.ifTrue(SurfaceRules.waterBlockCheck(-1, 0), SurfaceRules.sequence(terrain))), SurfaceRules.ifTrue(SurfaceRules.waterStartCheck(-6, -1), SurfaceRules.sequence(SurfaceRules.ifTrue(SurfaceRules.UNDER_FLOOR, terrain)))); + return SurfaceRules.sequence(SurfaceRules.ifTrue(SurfaceRules.abovePreliminarySurface(), generation)); + } + + private static SurfaceRules.RuleSource makeStateRule(Block block) { + return SurfaceRules.state(block.defaultBlockState()); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/PredicatedStateProvider.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/PredicatedStateProvider.java new file mode 100644 index 0000000..48a90f1 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/PredicatedStateProvider.java @@ -0,0 +1,34 @@ +package com.cursedcauldron.wildbackport.common.worldgen; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; + +import java.util.List; +import java.util.Random; + +public record PredicatedStateProvider(BlockStateProvider fallback, List rules) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group(BlockStateProvider.CODEC.fieldOf("fallback").forGetter(PredicatedStateProvider::fallback), Rule.CODEC.listOf().fieldOf("rules").forGetter(PredicatedStateProvider::rules)).apply(instance, PredicatedStateProvider::new)); + + public static PredicatedStateProvider of(BlockStateProvider provider) { + return new PredicatedStateProvider(provider, List.of()); + } + + public static PredicatedStateProvider of(Block block) { + return of(BlockStateProvider.simple(block)); + } + + public BlockState getBlockState(WorldGenLevel level, Random random, BlockPos pos) { + for (Rule rule : this.rules) if (rule.ifTrue.test(level, pos)) return rule.then.getState(random, pos); + return this.fallback.getState(random, pos); + } + + public record Rule(BlockPredicate ifTrue, BlockStateProvider then) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group(BlockPredicate.CODEC.fieldOf("if_true").forGetter(Rule::ifTrue), BlockStateProvider.CODEC.fieldOf("then").forGetter(Rule::then)).apply(instance, Rule::new)); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/WorldGenerator.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/WorldGenerator.java new file mode 100644 index 0000000..fefe218 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/WorldGenerator.java @@ -0,0 +1,33 @@ +package com.cursedcauldron.wildbackport.common.worldgen; + +import com.cursedcauldron.wildbackport.common.registry.WBBiomes; +import com.cursedcauldron.wildbackport.common.registry.entity.WBEntities; +import com.cursedcauldron.wildbackport.common.registry.worldgen.WBWorldGeneration; +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeModifier; +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeWriter; +import net.minecraft.data.worldgen.placement.MiscOverworldPlacements; +import net.minecraft.data.worldgen.placement.VegetationPlacements; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.levelgen.GenerationStep; + +//<> + +public class WorldGenerator { + public static void setup() { + BiomeModifier.add(WorldGenerator::mangroveSwamp, WBBiomes.MANGROVE_SWAMP); + } + + public static void mangroveSwamp(BiomeWriter writer) { + writer.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, WBWorldGeneration.DISK_GRASS); + + writer.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, WBWorldGeneration.TREES_MANGROVE); +// writer.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_NORMAL); +// writer.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH); +// writer.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_WATERLILY); + + writer.addSpawn(MobCategory.MONSTER, EntityType.SLIME, 1, 1, 1); + writer.addSpawn(MobCategory.CREATURE, WBEntities.FROG.get(), 10, 2, 5); + writer.addSpawn(MobCategory.WATER_AMBIENT, EntityType.TROPICAL_FISH, 25, 8, 8); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/features/GrassDiskConfiguration.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/features/GrassDiskConfiguration.java new file mode 100644 index 0000000..9fd4ceb --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/features/GrassDiskConfiguration.java @@ -0,0 +1,12 @@ +package com.cursedcauldron.wildbackport.common.worldgen.features; + +import com.cursedcauldron.wildbackport.common.worldgen.PredicatedStateProvider; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.valueproviders.IntProvider; +import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public record GrassDiskConfiguration(PredicatedStateProvider stateProvider, BlockPredicate target, IntProvider radius, int halfHeight) implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group(PredicatedStateProvider.CODEC.fieldOf("state_provider").forGetter(GrassDiskConfiguration::stateProvider), BlockPredicate.CODEC.fieldOf("target").forGetter(GrassDiskConfiguration::target), IntProvider.codec(0, 8).fieldOf("radius").forGetter(GrassDiskConfiguration::radius), Codec.intRange(0, 4).fieldOf("half_height").forGetter(GrassDiskConfiguration::halfHeight)).apply(instance, GrassDiskConfiguration::new)); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/features/GrassDiskFeature.java b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/features/GrassDiskFeature.java new file mode 100644 index 0000000..ff769e6 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/common/worldgen/features/GrassDiskFeature.java @@ -0,0 +1,55 @@ +package com.cursedcauldron.wildbackport.common.worldgen.features; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +import java.util.Random; + +public class GrassDiskFeature extends Feature { + public GrassDiskFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + GrassDiskConfiguration config = context.config(); + BlockPos pos = context.origin(); + WorldGenLevel level = context.level(); + Random random = context.random(); + boolean place = false; + int y = pos.getY(); + int topY = y + config.halfHeight(); + int bottomY = y - config.halfHeight() - 1; + int radius = config.radius().sample(random); + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + + for (BlockPos position : BlockPos.betweenClosed(pos.offset(-radius, 0, -radius), pos.offset(radius, 0, radius))) { + int x = position.getX() - position.getX(); + int z = position.getZ() - position.getZ(); + if (x * x + z * z <= radius * radius) { + place |= this.placeBlock(config, level, random, topY, bottomY, mutable.set(position)); + } + } + + return place; + } + + protected boolean placeBlock(GrassDiskConfiguration config, WorldGenLevel level, Random random, int topY, int bottomY, BlockPos.MutableBlockPos pos) { + boolean place = false; + for (int y = topY; y > bottomY; y--) { + pos.setY(y); + if (config.target().test(level, pos)) { + BlockState state = config.stateProvider().getBlockState(level, random, pos); + level.setBlock(pos, state, 2); + this.markAboveForPostProcessing(level, pos); + place = true; + } + } + + return place; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/BiomeModifier.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/BiomeModifier.java new file mode 100644 index 0000000..e5d2f45 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/BiomeModifier.java @@ -0,0 +1,28 @@ +package com.cursedcauldron.wildbackport.core.api.worldgen; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +public class BiomeModifier { + private static final Map, ResourceKey[]> FEATURES = new ConcurrentHashMap<>(); + public static final BiomeModifier INSTANCE = new BiomeModifier(); + + @ExpectPlatform + public static void setup() { + throw new AssertionError(); + } + + public void register(BiomeWriter writer) { + FEATURES.forEach(writer::add); + } + + @SafeVarargs + public static void add(Consumer writer, ResourceKey... biomes) { + FEATURES.put(writer, biomes); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/BiomeWriter.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/BiomeWriter.java new file mode 100644 index 0000000..b367d02 --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/BiomeWriter.java @@ -0,0 +1,32 @@ +package com.cursedcauldron.wildbackport.core.api.worldgen; + +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; + +import java.util.function.Consumer; + +//<> + +public abstract class BiomeWriter { + @SafeVarargs + public final void add(Consumer writer, ResourceKey... biomes) { + for (ResourceKey biome : biomes) if (this.is(biome)) writer.accept(this); + } + + public boolean is(ResourceKey biome) { + return biome == ResourceKey.create(Registry.BIOME_REGISTRY, this.name()); + } + + public abstract ResourceLocation name(); + + public abstract void addFeature(GenerationStep.Decoration step, Holder feature); + + public abstract void addSpawn(MobCategory category, EntityType entityType, int weight, int minGroupSize, int maxGroupSize); +} \ No newline at end of file diff --git a/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/OverworldBiomesAccessor.java b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/OverworldBiomesAccessor.java new file mode 100644 index 0000000..4fcc1bf --- /dev/null +++ b/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/access/OverworldBiomesAccessor.java @@ -0,0 +1,14 @@ +package com.cursedcauldron.wildbackport.core.mixin.access; + +import net.minecraft.data.worldgen.biome.OverworldBiomes; +import net.minecraft.world.level.biome.BiomeGenerationSettings; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(OverworldBiomes.class) +public interface OverworldBiomesAccessor { + @Invoker + static void callGlobalOverworldGeneration(BiomeGenerationSettings.Builder builder) { + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/resources/wildbackport-common.mixins.json b/common/src/main/resources/wildbackport-common.mixins.json index e05c625..500dc3f 100644 --- a/common/src/main/resources/wildbackport-common.mixins.json +++ b/common/src/main/resources/wildbackport-common.mixins.json @@ -10,6 +10,7 @@ "access.DoorBlockAccessor", "access.MemoryModuleTypeAccessor", "access.ModelPartAccessor", + "access.OverworldBiomesAccessor", "access.PressurePlateBlockAccessor", "access.RecordItemAccessor", "access.RegistryAccessor", diff --git a/fabric/build.gradle b/fabric/build.gradle index 208dc4f..2a400c2 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -15,10 +15,18 @@ configurations { developmentFabric.extendsFrom common } +repositories { + maven { + url = 'https://maven.minecraftforge.net/' + } +} + dependencies { modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + modImplementation("com.github.glitchfiend:TerraBlender-fabric:${minecraft_version}-${terrablender_version}") + common(project(path: ":common", configuration: "namedElements")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } } diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/fabric/BiomeModifierImpl.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/fabric/BiomeModifierImpl.java new file mode 100644 index 0000000..8850f50 --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/fabric/BiomeModifierImpl.java @@ -0,0 +1,15 @@ +package com.cursedcauldron.wildbackport.core.api.worldgen.fabric; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeModifier; +import net.fabricmc.fabric.api.biome.v1.BiomeModifications; +import net.fabricmc.fabric.api.biome.v1.ModificationPhase; +import net.minecraft.resources.ResourceLocation; + +public class BiomeModifierImpl { + public static void setup() { + BiomeModifications.create(new ResourceLocation(WildBackport.MOD_ID, "biome_modifier")).add(ModificationPhase.ADDITIONS, ctx -> true, (selector, modifier) -> { + BiomeModifier.INSTANCE.register(new FabricBiomeWriter().build(selector, modifier)); + }); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/fabric/FabricBiomeWriter.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/fabric/FabricBiomeWriter.java new file mode 100644 index 0000000..277b1bd --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/fabric/FabricBiomeWriter.java @@ -0,0 +1,38 @@ +package com.cursedcauldron.wildbackport.core.api.worldgen.fabric; + +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeWriter; +import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; + +public class FabricBiomeWriter extends BiomeWriter { + private BiomeSelectionContext selection; + private BiomeModificationContext modification; + + public BiomeWriter build(BiomeSelectionContext selectionCtx, BiomeModificationContext modificationCtx) { + this.selection = selectionCtx; + this.modification = modificationCtx; + return this; + } + + @Override + public ResourceLocation name() { + return this.selection.getBiomeKey().location(); + } + + @Override + public void addFeature(GenerationStep.Decoration step, Holder feature) { + this.modification.getGenerationSettings().addBuiltInFeature(step, feature.value()); + } + + @Override + public void addSpawn(MobCategory category, EntityType entityType, int weight, int minGroupSize, int maxGroupSize) { + this.modification.getSpawnSettings().addSpawn(category, new MobSpawnSettings.SpawnerData(entityType, weight, minGroupSize, maxGroupSize)); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/TerrablenderSetup.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/TerrablenderSetup.java new file mode 100644 index 0000000..b29a28b --- /dev/null +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/TerrablenderSetup.java @@ -0,0 +1,37 @@ +package com.cursedcauldron.wildbackport.fabric; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.common.registry.WBBiomes; +import com.cursedcauldron.wildbackport.common.worldgen.MangroveSwampSurface; +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.biome.Climate; +import terrablender.api.ParameterUtils; +import terrablender.api.Region; +import terrablender.api.RegionType; +import terrablender.api.Regions; +import terrablender.api.SurfaceRuleManager; +import terrablender.api.TerraBlenderApi; + +import java.util.List; +import java.util.function.Consumer; + +public class TerrablenderSetup implements TerraBlenderApi { + @Override + public void onTerraBlenderInitialized() { + Regions.register(new Region(new ResourceLocation(WildBackport.MOD_ID, "overworld"), RegionType.OVERWORLD, 2) { + @Override public void addBiomes(Registry registry, Consumer>> mapper) { + this.addModifiedVanillaOverworldBiomes(mapper, builder -> { + builder.replaceBiome(Biomes.SWAMP, WBBiomes.MANGROVE_SWAMP); + List points = new ParameterUtils.ParameterPointListBuilder().erosion(ParameterUtils.Erosion.span(ParameterUtils.Erosion.EROSION_0, ParameterUtils.Erosion.EROSION_1)).depth(Climate.Parameter.point(1.1F)).build(); + points.forEach(point -> mapper.accept(Pair.of(point, WBBiomes.DEEP_DARK))); + }); + } + }); + SurfaceRuleManager.addSurfaceRules(SurfaceRuleManager.RuleCategory.OVERWORLD, WildBackport.MOD_ID, MangroveSwampSurface.makeRules()); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java index 5d01b6c..411e071 100644 --- a/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java +++ b/fabric/src/main/java/com/cursedcauldron/wildbackport/fabric/WildBackportFabric.java @@ -9,5 +9,6 @@ public class WildBackportFabric implements ModInitializer { public void onInitialize() { WildBackport.bootstrap(); CommonSetup.onCommon(); + CommonSetup.onPostCommon(); } } \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 5f95c5f..af5e491 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -19,6 +19,9 @@ ], "client": [ "com.cursedcauldron.wildbackport.fabric.WildBackportFabricClient" + ], + "terrablender": [ + "com.cursedcauldron.wildbackport.fabric.TerrablenderSetup" ] }, "mixins": [ diff --git a/forge/build.gradle b/forge/build.gradle index e6a44b3..485fba6 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -1,3 +1,11 @@ +buildscript { + repositories { + maven { + url = 'https://maven.minecraftforge.net/' + } + } +} + plugins { id "com.github.johnrengelman.shadow" version "7.1.2" } @@ -26,6 +34,11 @@ configurations { dependencies { forge "net.minecraftforge:forge:${rootProject.forge_version}" +// forge "net.minecraftforge:forge:${rootProject.forge_version}" + + + modApi ("com.github.glitchfiend:TerraBlender-forge:${minecraft_version}-${terrablender_version}") +// implementation fg.deobf('com.github.glitchfiend:TerraBlender-forge:x.x.x-y.y.y.y') common(project(path: ":common", configuration: "namedElements")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/forge/BiomeModifierImpl.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/forge/BiomeModifierImpl.java new file mode 100644 index 0000000..0c91949 --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/forge/BiomeModifierImpl.java @@ -0,0 +1,17 @@ +package com.cursedcauldron.wildbackport.core.api.worldgen.forge; + +import com.cursedcauldron.wildbackport.WildBackport; +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeModifier; +import net.minecraftforge.event.world.BiomeLoadingEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(modid = WildBackport.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) +public class BiomeModifierImpl { + public static void setup() {} + + @SubscribeEvent + public static void event(BiomeLoadingEvent event) { + BiomeModifier.INSTANCE.register(new ForgeBiomeWriter().build(event)); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/forge/ForgeBiomeWriter.java b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/forge/ForgeBiomeWriter.java new file mode 100644 index 0000000..27b8596 --- /dev/null +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/core/api/worldgen/forge/ForgeBiomeWriter.java @@ -0,0 +1,34 @@ +package com.cursedcauldron.wildbackport.core.api.worldgen.forge; + +import com.cursedcauldron.wildbackport.core.api.worldgen.BiomeWriter; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; +import net.minecraftforge.event.world.BiomeLoadingEvent; + +public class ForgeBiomeWriter extends BiomeWriter { + private BiomeLoadingEvent event; + + public BiomeWriter build(BiomeLoadingEvent event) { + this.event = event; + return this; + } + + @Override + public ResourceLocation name() { + return this.event.getName(); + } + + @Override + public void addFeature(GenerationStep.Decoration step, Holder feature) { + this.event.getGeneration().addFeature(step, feature); + } + + @Override + public void addSpawn(MobCategory category, EntityType entityType, int weight, int minGroupSize, int maxGroupSize) { + + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java b/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java index 37a146d..063985a 100644 --- a/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java +++ b/forge/src/main/java/com/cursedcauldron/wildbackport/forge/WildBackportForge.java @@ -3,7 +3,16 @@ package com.cursedcauldron.wildbackport.forge; import com.cursedcauldron.wildbackport.WildBackport; import com.cursedcauldron.wildbackport.client.ClientSetup; import com.cursedcauldron.wildbackport.common.CommonSetup; +import com.cursedcauldron.wildbackport.common.registry.WBBiomes; +import com.cursedcauldron.wildbackport.common.worldgen.MangroveSwampSurface; import com.cursedcauldron.wildbackport.core.api.forge.EventBuses; +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.biome.Climate; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.DistExecutor; @@ -11,6 +20,14 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import terrablender.api.ParameterUtils; +import terrablender.api.Region; +import terrablender.api.RegionType; +import terrablender.api.Regions; +import terrablender.api.SurfaceRuleManager; + +import java.util.List; +import java.util.function.Consumer; @Mod(WildBackport.MOD_ID) public class WildBackportForge { @@ -20,8 +37,23 @@ public class WildBackportForge { bus.addListener(event -> CommonSetup.onPostCommon()); bus.addListener(event -> ClientSetup.onPostClient()); + bus.addListener(this::terrablenderSetup); + WildBackport.bootstrap(); CommonSetup.onCommon(); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientSetup::onClient); } + + private void terrablenderSetup(final FMLCommonSetupEvent event) { + Regions.register(new Region(new ResourceLocation(WildBackport.MOD_ID, "overworld"), RegionType.OVERWORLD, 2) { + @Override public void addBiomes(Registry registry, Consumer>> mapper) { + this.addModifiedVanillaOverworldBiomes(mapper, builder -> { + builder.replaceBiome(Biomes.SWAMP, WBBiomes.MANGROVE_SWAMP); + List points = new ParameterUtils.ParameterPointListBuilder().erosion(ParameterUtils.Erosion.span(ParameterUtils.Erosion.EROSION_0, ParameterUtils.Erosion.EROSION_1)).depth(Climate.Parameter.point(1.1F)).build(); + points.forEach(point -> mapper.accept(Pair.of(point, WBBiomes.DEEP_DARK))); + }); + } + }); + SurfaceRuleManager.addSurfaceRules(SurfaceRuleManager.RuleCategory.OVERWORLD, WildBackport.MOD_ID, MangroveSwampSurface.makeRules()); + } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 0d00283..ba94875 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,3 +7,5 @@ architectury_version=4.5.74 fabric_loader_version=0.14.8 fabric_api_version=0.56.1+1.18.2 forge_version=1.18.2-40.1.54 + +terrablender_version=1.1.0.95 \ No newline at end of file