From 54f92ff686d30e1ed1e1ac322a12f51b05a335df Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 23 Jun 2023 08:14:31 +0200 Subject: [PATCH] [Fix] Empty Biomes in world generation and mob spawn could crash the game (quiqueck/BCLib#105) --- .../betterend/entity/CubozoaEntity.java | 5 +++- .../betterend/entity/EndFishEntity.java | 5 +++- .../betterend/entity/EndSlimeEntity.java | 29 +++++++++++-------- .../betterx/betterend/registry/EndBiomes.java | 8 ++--- .../betterend/registry/EndFeatures.java | 13 ++++----- .../betterx/betterend/util/LootTableUtil.java | 22 +++++++------- .../terrain/FloatingSpireFeature.java | 5 +++- .../world/features/terrain/SpireFeature.java | 5 +++- .../caves/CaveChunkPopulatorFeature.java | 4 +++ .../CaveChunkPopulatorFeatureConfig.java | 4 ++- .../terrain/caves/EndCaveFeature.java | 7 +++-- .../world/generator/TerrainGenerator.java | 9 ++++-- 12 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java b/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java index 140f9aa9..caedc8cd 100644 --- a/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java +++ b/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java @@ -1,5 +1,7 @@ package org.betterx.betterend.entity; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.betterend.registry.EndBiomes; import org.betterx.betterend.registry.EndItems; @@ -51,7 +53,8 @@ public class CubozoaEntity extends AbstractSchoolingFish { ) { SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); - if (BiomeAPI.getBiome(world.getBiome(blockPosition())).is(EndBiomes.SULPHUR_SPRINGS)) { + BCLBiome biome = BiomeAPI.getBiome(world.getBiome(blockPosition())); + if (!BCLBiomeRegistry.isEmptyBiome(biome) && biome.is(EndBiomes.SULPHUR_SPRINGS)) { this.entityData.set(VARIANT, (byte) 1); } diff --git a/src/main/java/org/betterx/betterend/entity/EndFishEntity.java b/src/main/java/org/betterx/betterend/entity/EndFishEntity.java index add3c5ee..cd33ee9a 100644 --- a/src/main/java/org/betterx/betterend/entity/EndFishEntity.java +++ b/src/main/java/org/betterx/betterend/entity/EndFishEntity.java @@ -1,5 +1,7 @@ package org.betterx.betterend.entity; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.betterend.registry.EndBiomes; import org.betterx.betterend.registry.EndItems; @@ -59,7 +61,8 @@ public class EndFishEntity extends AbstractSchoolingFish { ) { SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); - if (BiomeAPI.getBiome(world.getBiome(blockPosition())).equals(EndBiomes.SULPHUR_SPRINGS)) { + BCLBiome biome = BiomeAPI.getBiome(world.getBiome(blockPosition())); + if (!BCLBiomeRegistry.isEmptyBiome(biome) && biome.equals(EndBiomes.SULPHUR_SPRINGS)) { this.entityData.set(VARIANT, (byte) (random.nextInt(VARIANTS_SULPHUR) + VARIANTS_NORMAL)); } diff --git a/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java b/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java index 297898ed..bda27bdc 100644 --- a/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java +++ b/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java @@ -1,6 +1,7 @@ package org.betterx.betterend.entity; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.util.BlocksHelper; import org.betterx.bclib.util.MHelper; @@ -95,14 +96,16 @@ public class EndSlimeEntity extends Slime { ) { SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); BCLBiome biome = BiomeAPI.getBiome(world.getBiome(blockPosition())); - if (biome.equals(EndBiomes.FOGGY_MUSHROOMLAND)) { - this.setMossy(); - } else if (biome.equals(EndBiomes.MEGALAKE) || biome.equals(EndBiomes.MEGALAKE_GROVE)) { - this.setLake(); - } else if (biome.equals(EndBiomes.AMBER_LAND)) { - this.setAmber(); + if (!BCLBiomeRegistry.isEmptyBiome(biome)) { + if (biome.equals(EndBiomes.FOGGY_MUSHROOMLAND)) { + this.setMossy(); + } else if (biome.equals(EndBiomes.MEGALAKE) || biome.equals(EndBiomes.MEGALAKE_GROVE)) { + this.setLake(); + } else if (biome.equals(EndBiomes.AMBER_LAND)) { + this.setAmber(); + } + this.refreshDimensions(); } - this.refreshDimensions(); return data; } @@ -233,11 +236,13 @@ public class EndSlimeEntity extends Slime { return false; } BCLBiome biome = BiomeAPI.getBiome(world.getBiome(pos)); - if (biome.equals(EndBiomes.CHORUS_FOREST) || biome.equals(EndBiomes.MEGALAKE)) { - return true; - } - if (biome.equals(EndBiomes.MEGALAKE_GROVE) && random.nextBoolean()) { - return true; + if (!BCLBiomeRegistry.isEmptyBiome(biome)) { + if (biome.equals(EndBiomes.CHORUS_FOREST) || biome.equals(EndBiomes.MEGALAKE)) { + return true; + } + if (biome.equals(EndBiomes.MEGALAKE_GROVE) && random.nextBoolean()) { + return true; + } } return random.nextInt(4) == 0 && isWaterNear(world, pos); } diff --git a/src/main/java/org/betterx/betterend/registry/EndBiomes.java b/src/main/java/org/betterx/betterend/registry/EndBiomes.java index 6cbed569..f1a0d28c 100644 --- a/src/main/java/org/betterx/betterend/registry/EndBiomes.java +++ b/src/main/java/org/betterx/betterend/registry/EndBiomes.java @@ -72,9 +72,9 @@ public class EndBiomes { .map(biome -> registry.getHolderOrThrow(registry.getResourceKey(biome).get())) .map(biome -> biome.unwrapKey().orElseThrow().location()) .filter(id -> BiomeAPI.wasRegisteredAs(id, END_CAVE)) - .map(id -> BiomeAPI.getBiome(id)) - .filter(bcl -> bcl != null) - .forEach(bcl -> CAVE_BIOMES.addBiome(bcl)); + .map(BiomeAPI::getBiome) + .filter(bcl -> !BCLBiomeRegistry.isEmptyBiome(bcl)) + .forEach(CAVE_BIOMES::addBiome); CAVE_BIOMES.rebuild(); caveBiomeMap = null; @@ -106,7 +106,7 @@ public class EndBiomes { public static void addSubBiomeIntegration(EndBiome biome, ResourceLocation parent) { if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { BCLBiome parentBiome = BiomeAPI.getBiome(parent); - if (parentBiome != null && biome.getParentBiome().getID().equals(biome.getID())) { + if (!BCLBiomeRegistry.isEmptyBiome(parentBiome) && biome.getParentBiome().getID().equals(biome.getID())) { parentBiome.addSubBiome(biome); } } diff --git a/src/main/java/org/betterx/betterend/registry/EndFeatures.java b/src/main/java/org/betterx/betterend/registry/EndFeatures.java index be059975..b6678faa 100644 --- a/src/main/java/org/betterx/betterend/registry/EndFeatures.java +++ b/src/main/java/org/betterx/betterend/registry/EndFeatures.java @@ -3,6 +3,7 @@ package org.betterx.betterend.registry; import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature; import org.betterx.bclib.api.v3.levelgen.features.BCLFeature; @@ -1360,9 +1361,11 @@ public class EndFeatures { BiomeAPI.addBiomeFeature(biome, CRASHED_SHIP); BCLBiome bclbiome = BiomeAPI.getBiome(id); - BCLFeature feature = getBiomeStructures(bclbiome); - if (feature != null) { - BiomeAPI.addBiomeFeature(biome, feature); + if (!BCLBiomeRegistry.isEmptyBiome(bclbiome)) { + BCLFeature feature = getBiomeStructures(bclbiome.getID()); + if (feature != null) { + BiomeAPI.addBiomeFeature(biome, feature); + } } @@ -1380,10 +1383,6 @@ public class EndFeatures { } } - private static BCLFeature getBiomeStructures(BCLBiome biome) { - return getBiomeStructures(biome.getID()); - } - private static BCLFeature getBiomeStructures(ResourceLocation loc) { String ns = loc.getNamespace(); String nm = loc.getPath(); diff --git a/src/main/java/org/betterx/betterend/util/LootTableUtil.java b/src/main/java/org/betterx/betterend/util/LootTableUtil.java index ae0aa4d4..920ccd05 100644 --- a/src/main/java/org/betterx/betterend/util/LootTableUtil.java +++ b/src/main/java/org/betterx/betterend/util/LootTableUtil.java @@ -114,16 +114,18 @@ public class LootTableUtil { public static ResourceLocation getTable(Holder biome) { BCLBiome bclBiome = BiomeAPI.getBiome(biome.value()); - if (bclBiome.equals(EndBiomes.FOGGY_MUSHROOMLAND)) { - return FOGGY_MUSHROOMLAND; - } else if (bclBiome.equals(EndBiomes.CHORUS_FOREST)) { - return CHORUS_FOREST; - } else if (bclBiome.equals(EndBiomes.SHADOW_FOREST)) { - return SHADOW_FOREST; - } else if (bclBiome.equals(EndBiomes.LANTERN_WOODS)) { - return LANTERN_WOODS; - } else if (bclBiome.equals(EndBiomes.UMBRELLA_JUNGLE)) { - return UMBRELLA_JUNGLE; + if (bclBiome != null) { + if (bclBiome.equals(EndBiomes.FOGGY_MUSHROOMLAND)) { + return FOGGY_MUSHROOMLAND; + } else if (bclBiome.equals(EndBiomes.CHORUS_FOREST)) { + return CHORUS_FOREST; + } else if (bclBiome.equals(EndBiomes.SHADOW_FOREST)) { + return SHADOW_FOREST; + } else if (bclBiome.equals(EndBiomes.LANTERN_WOODS)) { + return LANTERN_WOODS; + } else if (bclBiome.equals(EndBiomes.UMBRELLA_JUNGLE)) { + return UMBRELLA_JUNGLE; + } } return COMMON; } diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java index 63ed07c2..0e97c709 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java @@ -1,5 +1,7 @@ package org.betterx.betterend.world.features.terrain; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.sdf.SDF; import org.betterx.bclib.sdf.operator.SDFDisplacement; @@ -86,7 +88,8 @@ public class FloatingSpireFeature extends SpireFeature { sdf.fillRecursive(world, center); support.forEach((bpos) -> { - if (BiomeAPI.getBiome(world.getBiome(bpos)).is(EndBiomes.BLOSSOMING_SPIRES)) { + BCLBiome biome = BiomeAPI.getBiome(world.getBiome(bpos)); + if (!BCLBiomeRegistry.isEmptyBiome(biome) && biome.is(EndBiomes.BLOSSOMING_SPIRES)) { EndFeatures.TENANEA_BUSH.getFeature() .place(new FeaturePlaceContext( Optional.empty(), diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java index ae6b69f6..7e5fd827 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java @@ -1,5 +1,7 @@ package org.betterx.betterend.world.features.terrain; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.sdf.SDF; @@ -87,7 +89,8 @@ public class SpireFeature extends DefaultFeature { }).fillRecursive(world, center); support.forEach((bpos) -> { - if (BiomeAPI.getBiome(world.getBiome(bpos)).equals(EndBiomes.BLOSSOMING_SPIRES)) { + BCLBiome biome = BiomeAPI.getBiome(world.getBiome(bpos)); + if (!BCLBiomeRegistry.isEmptyBiome(biome) && biome.equals(EndBiomes.BLOSSOMING_SPIRES)) { EndFeatures.TENANEA_BUSH.getFeature() .place(new FeaturePlaceContext( Optional.empty(), diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java index 0f2a41e4..2a89b667 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java @@ -1,5 +1,6 @@ package org.betterx.betterend.world.features.terrain.caves; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.util.BlocksHelper; import org.betterx.betterend.util.BlockFixer; import org.betterx.betterend.world.biome.cave.EndCaveBiome; @@ -42,6 +43,9 @@ public class CaveChunkPopulatorFeature extends Feature CODEC = RecordCodecBuilder.create(instance -> instance .group(ResourceLocation.CODEC.fieldOf("biome").forGetter(o -> o.biomeID)) .apply(instance, CaveChunkPopulatorFeatureConfig::new)); - public EndCaveBiome getCaveBiome() { + public @Nullable EndCaveBiome getCaveBiome() { return (EndCaveBiome) BiomeAPI.getBiome(biomeID); } } diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java index 5e12fcb9..e3148a75 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java @@ -2,6 +2,7 @@ package org.betterx.betterend.world.features.terrain.caves; import org.betterx.bclib.api.v2.generator.BiomePicker; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.util.BlocksHelper; @@ -69,7 +70,7 @@ public abstract class EndCaveFeature extends DefaultFeature { Set floorPositions = Sets.newConcurrentHashSet(); Set ceilPositions = Sets.newConcurrentHashSet(); caveBlocks.parallelStream().forEach((bpos) -> { - if (world.getBlockState(bpos).canBeReplaced()){ + if (world.getBlockState(bpos).canBeReplaced()) { BlockPos side = bpos.below(); if (world.getBlockState(side).is(CommonBlockTags.GEN_END_STONES)) { floorPositions.add(side); @@ -258,7 +259,9 @@ public abstract class EndCaveFeature extends DefaultFeature { if (bclBiome instanceof EndBiome endBiome) hasCaves = endBiome.hasCaves(); - if (!hasCaves && BiomeAPI.wasRegisteredAsEndLandBiome(bclBiome.getID())) { + if (!hasCaves + && !BCLBiomeRegistry.isEmptyBiome(bclBiome) + && BiomeAPI.wasRegisteredAsEndLandBiome(bclBiome.getID())) { return true; } } diff --git a/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java b/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java index 62b0a5e4..8bbb4e1b 100644 --- a/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java +++ b/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java @@ -32,6 +32,7 @@ import java.awt.*; import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; +import org.jetbrains.annotations.Nullable; public class TerrainGenerator { private static final Map TERRAIN_BOOL_CACHE_MAP = Maps.newHashMap(); @@ -114,19 +115,21 @@ public class TerrainGenerator { if (biomeSource == null) { return 0; } - if (getBiome(biomeSource, x, z).settings.getTerrainHeight() < 0.1F) { + BCLBiome biome = getBiome(biomeSource, x, z); + if (biome != null && biome.settings.getTerrainHeight() < 0.1F) { return 0F; } float depth = 0F; for (int i = 0; i < OFFS.length; i++) { int px = x + OFFS[i].x; int pz = z + OFFS[i].y; - depth += getBiome(biomeSource, px, pz).settings.getTerrainHeight() * COEF[i]; + biome = getBiome(biomeSource, px, pz); + depth += biome == null ? 0 : (biome.settings.getTerrainHeight() * COEF[i]); } return depth; } - private static BCLBiome getBiome(BiomeSource biomeSource, int x, int z) { + private static @Nullable BCLBiome getBiome(BiomeSource biomeSource, int x, int z) { return BiomeAPI.getBiome(biomeSource.getNoiseBiome(x, 0, z, sampler)); }