From bb7a64b6293c037608f548e88f911affb123c977 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 22 Feb 2022 01:03:39 +0100 Subject: [PATCH] fix mobs not spawning in structures --- .../ChunkGenerator_customMobSpawnsMixin.java | 40 ++-------- .../java/carpet/utils/SpawnOverrides.java | 74 +++++++++++++++++++ 2 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 src/main/java/carpet/utils/SpawnOverrides.java diff --git a/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java b/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java index 49b838ba..4773fc6d 100644 --- a/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java +++ b/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java @@ -1,13 +1,10 @@ package carpet.mixins; -import carpet.CarpetSettings; +import carpet.utils.SpawnOverrides; import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.core.Holder; -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -27,47 +24,20 @@ import java.util.Map; @Mixin(ChunkGenerator.class) public abstract class ChunkGenerator_customMobSpawnsMixin { - - @Shadow protected abstract void ensureGenerated(); - - private static final WeightedRandomList PYRAMID_SPAWNS = WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.HUSK, 1, 1, 1)); - private static final WeightedRandomList SHULKER_SPAWNS = WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.SHULKER, 10, 4, 4)); - private static final WeightedRandomList BASTION_SPAWNS = WeightedRandomList.create( - new MobSpawnSettings.SpawnerData(EntityType.PIGLIN_BRUTE, 5, 1, 2), - new MobSpawnSettings.SpawnerData(EntityType.PIGLIN, 10, 2, 4), - new MobSpawnSettings.SpawnerData(EntityType.HOGLIN, 2, 1, 2) - ); - @Inject( method = "getMobsAt", locals = LocalCapture.CAPTURE_FAILHARD, at = @At( value = "INVOKE", target = "Ljava/util/Map$Entry;getKey()Ljava/lang/Object;" ), cancellable = true) - private void isInsidePyramid(Holder holder, StructureFeatureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos, + private void checkCMSpawns(Holder holder, StructureFeatureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos, CallbackInfoReturnable> cir, Map, LongSet> map, Iterator var6, Map.Entry, LongSet> entry) { - if (mobCategory == MobCategory.MONSTER) + WeightedRandomList res = SpawnOverrides.test(structureFeatureManager, entry.getValue(), mobCategory, entry.getKey(), blockPos); + if (res != null) { - ConfiguredStructureFeature str = entry.getKey(); - if (CarpetSettings.huskSpawningInTemples - && str.feature == StructureFeatures.DESERT_PYRAMID.value().feature - && structureFeatureManager.getStructureAt(blockPos, StructureFeatures.DESERT_PYRAMID.value()).isValid()) { - cir.setReturnValue(PYRAMID_SPAWNS); - return; - } - if (CarpetSettings.shulkerSpawningInEndCities - && str.feature == StructureFeatures.END_CITY.value().feature - && structureFeatureManager.getStructureAt(blockPos, StructureFeatures.END_CITY.value()).isValid()) { - cir.setReturnValue(SHULKER_SPAWNS); - return; - } - if (CarpetSettings.piglinsSpawningInBastions - && str.feature == StructureFeatures.BASTION_REMNANT.value().feature - && structureFeatureManager.getStructureAt(blockPos, StructureFeatures.BASTION_REMNANT.value()).isValid()) { - cir.setReturnValue(BASTION_SPAWNS); - } + cir.setReturnValue(res); } } } diff --git a/src/main/java/carpet/utils/SpawnOverrides.java b/src/main/java/carpet/utils/SpawnOverrides.java new file mode 100644 index 00000000..a428d133 --- /dev/null +++ b/src/main/java/carpet/utils/SpawnOverrides.java @@ -0,0 +1,74 @@ +package carpet.utils; + +import carpet.CarpetSettings; +import it.unimi.dsi.fastutil.longs.LongSet; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.data.worldgen.StructureFeatures; +import net.minecraft.util.random.WeightedRandomList; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride; +import net.minecraft.world.level.levelgen.structure.StructureStart; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BooleanSupplier; + +public class SpawnOverrides { + final private static Map>, Pair> carpetOverrides = new HashMap<>(); + static { + addOverride(() -> CarpetSettings.huskSpawningInTemples, MobCategory.MONSTER, StructureFeatures.DESERT_PYRAMID, StructureSpawnOverride.BoundingBoxType.STRUCTURE, + WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.HUSK, 1, 1, 1)) + ); + addOverride(() -> CarpetSettings.shulkerSpawningInEndCities, MobCategory.MONSTER, StructureFeatures.END_CITY, StructureSpawnOverride.BoundingBoxType.PIECE, + WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.SHULKER, 10, 4, 4)) + ); + addOverride(() -> CarpetSettings.piglinsSpawningInBastions, MobCategory.MONSTER, StructureFeatures.BASTION_REMNANT, StructureSpawnOverride.BoundingBoxType.PIECE, + WeightedRandomList.create( + new MobSpawnSettings.SpawnerData(EntityType.PIGLIN_BRUTE, 5, 1, 2), + new MobSpawnSettings.SpawnerData(EntityType.PIGLIN, 10, 2, 4), + new MobSpawnSettings.SpawnerData(EntityType.HOGLIN, 2, 1, 2) + ) + ); + + } + + public static void addOverride(BooleanSupplier when, MobCategory cat, Holder> poo, + StructureSpawnOverride.BoundingBoxType type, WeightedRandomList spawns) + { + carpetOverrides.put(Pair.of(cat, poo.value().feature), Pair.of(when, new StructureSpawnOverride(type, spawns))); + } + + public static WeightedRandomList test(StructureFeatureManager structureFeatureManager, LongSet foo, + MobCategory cat, ConfiguredStructureFeature confExisting, BlockPos where) + { + final Pair spawnData = carpetOverrides.get(Pair.of(cat, confExisting.feature)); + if (spawnData == null || !spawnData.getKey().getAsBoolean()) return null; + StructureSpawnOverride override = spawnData.getRight(); + if (override.boundingBox() == StructureSpawnOverride.BoundingBoxType.STRUCTURE) + { + if (structureFeatureManager.getStructureAt(where, confExisting).isValid()) + return override.spawns(); + } + else + { + List starts = new ArrayList<>(1); + structureFeatureManager.fillStartsForFeature(confExisting, foo, starts::add); + for (StructureStart start: starts) + { + if (start != null && start.isValid() && structureFeatureManager.structureHasPieceAt(where, start)) { + return override.spawns(); + } + } + } + return null; + } +}