From ac8874f96a446a0af9f553ccde289422f35c248b Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Wed, 19 Mar 2014 07:43:05 -0400 Subject: [PATCH] Fixed Crash with ChickenChunks Fixed a nasty crash to desktop. It happens when ChickenChunks is installed and a new world is generated with HardcoreLimboEnabled = true. It appears that ChickenChunks forces a chunk to generate in Limbo if LimboProvider.canRespawnHere() = true, which is the case if hardcore Limbo is enabled. Our Monolith and gateway generation code runs as a tick handler instead of through standard world gen calls. I believe Limbo is unloaded immediately after the chunks are generated because no players are around. That would cause DimensionManager to return null for Limbo because it's not loaded, which would crash our code. We probably dealt with this for Monoliths by adding a check. Now it happened again because we didn't take precautions while calling the gateway generation method. I've added code to forcefully load Limbo if it's not loaded. --- .../ticking/CustomLimboPopulator.java | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java index 465e57b..2f4522a 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java @@ -37,24 +37,36 @@ public class CustomLimboPopulator implements IRegularTickReceiver { @Override public void notifyTick() { - //Check if any new spawning requests have come in + World limboWorld = null; + + // Check if any new spawning requests have come in if (!locations.isEmpty()) { - //Check if mob spawning is allowed + // Check if mob spawning is allowed if (isMobSpawningAllowed()) { - //Loop over the locations and call the appropriate function depending - //on whether the request is for Limbo or for a pocket dimension. + // Loop over the locations and call the appropriate function depending + // on whether the request is for Limbo or for a pocket dimension. for (ChunkLocation location : locations) { if (location.DimensionID == properties.LimboDimensionID) { - //Limbo chunk - placeMonolithsInLimbo(location.DimensionID, location.ChunkX, location.ChunkZ); + // Limbo chunk - World world = DimensionManager.getWorld(location.DimensionID); + // SenseiKiwi: Check if we haven't loaded Limbo for another request in this request + // cycle. If so, try to load Limbo up. This solves a strange issue with ChickenChunks + // where CC somehow forces chunks to generate in Limbo if LimboProvider.canRespawnHere() + // is true, yet when execution reaches this point, Limbo isn't loaded anymore! My theory + // is that CC force-loads a chunk for some reason, but since there are no players around, + // Limbo immediately unloads after standard world gen runs, and before this code can run. - mod_pocketDim.instance.gatewayGenerator.generate(world.rand, location.ChunkX, location.ChunkZ,world, world.getChunkProvider(), world.getChunkProvider()); + if (limboWorld == null) + { + limboWorld = PocketManager.loadDimension(properties.LimboDimensionID); + } + placeMonolithsInLimbo(limboWorld, location.ChunkX, location.ChunkZ); + mod_pocketDim.instance.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ, + limboWorld, limboWorld.getChunkProvider(), limboWorld.getChunkProvider()); } else { @@ -145,15 +157,8 @@ public class CustomLimboPopulator implements IRegularTickReceiver { while (sanity < 5 && !didSpawn); } - private void placeMonolithsInLimbo(int dimensionID, int chunkX, int chunkZ) + private void placeMonolithsInLimbo(World limbo, int chunkX, int chunkZ) { - World limbo = DimensionManager.getWorld(dimensionID); - - if (limbo == null) - { - return; - } - //The following initialization code is based on code from ChunkProviderGenerate. //It makes our generation depend on the world seed. Random random = new Random(limbo.getSeed() ^ 0xB5130C4ACC71A822L);