From 792fda70b0a340656fe324c7a3210b6c16385d69 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 22 Feb 2022 22:20:28 +0100 Subject: [PATCH] api for checking existence of any structure at position --- .../java/carpet/mixins/Husk_templesMixin.java | 3 +- .../java/carpet/utils/SpawnOverrides.java | 55 +++++++++++++------ 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/main/java/carpet/mixins/Husk_templesMixin.java b/src/main/java/carpet/mixins/Husk_templesMixin.java index 9cffbd1d..24d0254e 100644 --- a/src/main/java/carpet/mixins/Husk_templesMixin.java +++ b/src/main/java/carpet/mixins/Husk_templesMixin.java @@ -1,6 +1,7 @@ package carpet.mixins; import carpet.CarpetSettings; +import carpet.utils.SpawnOverrides; import net.minecraft.core.BlockPos; import net.minecraft.data.worldgen.StructureFeatures; import net.minecraft.server.level.ServerLevel; @@ -17,6 +18,6 @@ public class Husk_templesMixin private static boolean isSkylightOrTempleVisible(ServerLevelAccessor serverWorldAccess, BlockPos pos) { return serverWorldAccess.canSeeSky(pos) || - (CarpetSettings.huskSpawningInTemples && (((ServerLevel)serverWorldAccess).structureFeatureManager().getStructureAt(pos, StructureFeatures.DESERT_PYRAMID.value()).isValid())); + (CarpetSettings.huskSpawningInTemples && SpawnOverrides.isStructureAtPosition((ServerLevel)serverWorldAccess, StructureFeatures.DESERT_PYRAMID.value().feature, pos)); } } diff --git a/src/main/java/carpet/utils/SpawnOverrides.java b/src/main/java/carpet/utils/SpawnOverrides.java index a428d133..7bf671aa 100644 --- a/src/main/java/carpet/utils/SpawnOverrides.java +++ b/src/main/java/carpet/utils/SpawnOverrides.java @@ -1,32 +1,35 @@ package carpet.utils; import carpet.CarpetSettings; +import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.SectionPos; import net.minecraft.data.worldgen.StructureFeatures; +import net.minecraft.server.level.ServerLevel; 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.chunk.ChunkStatus; 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 net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; 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.*; 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)) + 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)) @@ -41,29 +44,23 @@ public class SpawnOverrides { } - public static void addOverride(BooleanSupplier when, MobCategory cat, Holder> poo, - StructureSpawnOverride.BoundingBoxType type, WeightedRandomList spawns) - { + 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) - { + 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 (override.boundingBox() == StructureSpawnOverride.BoundingBoxType.STRUCTURE) { if (structureFeatureManager.getStructureAt(where, confExisting).isValid()) return override.spawns(); - } - else - { + } else { List starts = new ArrayList<>(1); structureFeatureManager.fillStartsForFeature(confExisting, foo, starts::add); - for (StructureStart start: starts) - { + for (StructureStart start : starts) { if (start != null && start.isValid() && structureFeatureManager.structureHasPieceAt(where, start)) { return override.spawns(); } @@ -71,4 +68,28 @@ public class SpawnOverrides { } return null; } + + public static boolean isStructureAtPosition(ServerLevel level, StructureFeature structure, BlockPos pos) + { + for(StructureStart structureStart : startsForFeature(level, SectionPos.of(pos), structure)) { + if (structureStart.getBoundingBox().isInside(pos) && structureStart.isValid()) { + return true; + } + } + return false; + } + + public static List startsForFeature(ServerLevel level, SectionPos sectionPos, StructureFeature structure) { + Map, LongSet> allrefs = level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); + List result = new ArrayList<>(); + for (var entry: allrefs.entrySet()) + { + ConfiguredStructureFeature existing = entry.getKey(); + if (existing.feature == structure) + { + level.structureFeatureManager().fillStartsForFeature(existing, entry.getValue(), result::add); + } + } + return result; + } }