From c22479c0e885dd1d02d3304289b1d0eb6b449f44 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 10 Jul 2014 08:28:42 -0400 Subject: [PATCH 01/12] Tick Handler Changes 1. Renamed CommonTickHandler to ServerTickHandler. Given that it only handles server ticks, this seems like a reasonable name. Also changed its profiler label to the new name. 2. Deleted ClientTickHandler and removed any references to it in mod_pocketDim. It was never used for anything. --- .../mod_pocketDim/mod_pocketDim.java | 6 +- ...ickHandler.java => ServerTickHandler.java} | 6 +- .../ClientTickHandler.java | 65 ------------------- 3 files changed, 5 insertions(+), 72 deletions(-) rename src/main/java/StevenDimDoors/mod_pocketDim/ticking/{CommonTickHandler.java => ServerTickHandler.java} (94%) delete mode 100644 src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java index a044a06..9468678 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java @@ -52,12 +52,12 @@ import StevenDimDoors.mod_pocketDim.items.ItemUnstableDoor; import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor; import StevenDimDoors.mod_pocketDim.items.ItemWorldThread; import StevenDimDoors.mod_pocketDim.items.itemRiftRemover; -import StevenDimDoors.mod_pocketDim.ticking.CommonTickHandler; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator; import StevenDimDoors.mod_pocketDim.ticking.LimboDecay; import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; +import StevenDimDoors.mod_pocketDim.ticking.ServerTickHandler; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold; import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift; @@ -69,7 +69,6 @@ import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider; import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator; import StevenDimDoors.mod_pocketDimClient.ClientPacketHandler; -import StevenDimDoors.mod_pocketDimClient.ClientTickHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; @@ -183,8 +182,7 @@ public class mod_pocketDim @EventHandler public void onInitialization(FMLInitializationEvent event) { - CommonTickHandler commonTickHandler = new CommonTickHandler(); - TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT); + ServerTickHandler commonTickHandler = new ServerTickHandler(); TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER); //MonolithSpawner should be initialized before any provider instances are created diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CommonTickHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java similarity index 94% rename from src/main/java/StevenDimDoors/mod_pocketDim/ticking/CommonTickHandler.java rename to src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java index 26057b4..2e2ccb1 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CommonTickHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java @@ -7,15 +7,15 @@ import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; -public class CommonTickHandler implements ITickHandler, IRegularTickSender +public class ServerTickHandler implements ITickHandler, IRegularTickSender { - private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick"; + private static final String PROFILING_LABEL = "Dimensional Doors: Server Tick"; private int tickCount = 0; private ArrayList receivers; - public CommonTickHandler() + public ServerTickHandler() { this.receivers = new ArrayList(); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java deleted file mode 100644 index cece273..0000000 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/ClientTickHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -package StevenDimDoors.mod_pocketDimClient; -import java.util.EnumSet; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import cpw.mods.fml.common.ITickHandler; -import cpw.mods.fml.common.TickType; - -public class ClientTickHandler implements ITickHandler -{ - - @Override - public void tickStart(EnumSet type, Object... tickData) {} - - @Override - public void tickEnd(EnumSet type, Object... tickData) - { - if (type.equals(EnumSet.of(TickType.RENDER))) - { - onRenderTick(); - } - else if (type.equals(EnumSet.of(TickType.CLIENT))) - { - GuiScreen guiscreen = Minecraft.getMinecraft().currentScreen; - if (guiscreen != null) - { - onTickInGUI(guiscreen); - } else { - onTickInGame(); - } - } - } - - @Override - public EnumSet ticks() - { - return EnumSet.of(TickType.RENDER, TickType.CLIENT); - // In my testing only RENDER, CLIENT, & PLAYER did anything on the client side. - // Read 'cpw.mods.fml.common.TickType.java' for a full list and description of available types - } - - @Override - public String getLabel() { return null; } - - - public void onRenderTick() - { - //System.out.println("onRenderTick"); - //TODO: Your Code Here - } - - public void onTickInGUI(GuiScreen guiscreen) - { - //System.out.println("onTickInGUI"); - //TODO: Your Code Here - } - - public void onTickInGame() - { - - - //System.out.println("onTickInGame"); - //TODO: Your Code Here - } -} \ No newline at end of file -- 2.39.5 From c00c65eeee2493c1fe47bd8cdedbddb7a042526e Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 10 Jul 2014 15:11:44 -0400 Subject: [PATCH 02/12] Reorganized Tick Receivers 1. Reorganized our code to initialize tick receivers each time the server starts rather than once when the mod is initialized. This is needed because reusing a single instance of each class across different single-player sessions could cause scheduled events for one world to leak into another world. This approach ensures that we discard all pending events. 2. Separated the implementation of Limbo decay from a tick receiver that periodically triggers fast decay. All of the decay code has been kept in LimboDecay, while the ticking is handled by LimboDecayScheduler. This change separates some functionality that should be independent, but also, it's needed so that BlockLimbo can have access to LimboDecay's methods without holding on to a tick receiver instance. 3. Minor change: renamed ChunkLoaderHelper.loadChunkForcedWorlds() to loadForcedChunkWorlds(). --- .../mod_pocketDim/blocks/BlockLimbo.java | 2 +- .../helpers/ChunkLoaderHelper.java | 2 +- .../mod_pocketDim/mod_pocketDim.java | 42 ++++++++++++------- .../ticking/CustomLimboPopulator.java | 2 +- .../ticking/FastRiftRegenerator.java | 3 +- .../ticking/IRegularTickSender.java | 3 +- .../ticking/LimboDecayScheduler.java | 28 +++++++++++++ .../ticking/RiftRegenerator.java | 2 +- .../ticking/ServerTickHandler.java | 9 +++- .../{ticking => world}/LimboDecay.java | 19 ++------- 10 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java rename src/main/java/StevenDimDoors/mod_pocketDim/{ticking => world}/LimboDecay.java (91%) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java index 8da0dfe..07f1247 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockLimbo.java @@ -9,7 +9,7 @@ import net.minecraft.util.Icon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.ticking.LimboDecay; +import StevenDimDoors.mod_pocketDim.world.LimboDecay; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java index e866ec4..6483afd 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/ChunkLoaderHelper.java @@ -83,7 +83,7 @@ public class ChunkLoaderHelper implements LoadingCallback } } - public static void loadChunkForcedWorlds(FMLServerStartingEvent event) + public static void loadForcedChunkWorlds(FMLServerStartingEvent event) { for (NewDimData data : PocketManager.getDimensions()) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java index 9468678..8329d25 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java @@ -54,7 +54,7 @@ import StevenDimDoors.mod_pocketDim.items.ItemWorldThread; import StevenDimDoors.mod_pocketDim.items.itemRiftRemover; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator; -import StevenDimDoors.mod_pocketDim.ticking.LimboDecay; +import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler; import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; import StevenDimDoors.mod_pocketDim.ticking.ServerTickHandler; @@ -65,6 +65,7 @@ import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor; import StevenDimDoors.mod_pocketDim.world.BiomeGenLimbo; import StevenDimDoors.mod_pocketDim.world.BiomeGenPocket; import StevenDimDoors.mod_pocketDim.world.DDBiomeGenBase; +import StevenDimDoors.mod_pocketDim.world.LimboDecay; import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider; import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator; @@ -142,9 +143,13 @@ public class mod_pocketDim public static DDProperties properties; public static DDWorldProperties worldProperties; public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later. + private static RiftRegenerator riftRegenerator; public static FastRiftRegenerator fastRiftRegenerator; public static GatewayGenerator gatewayGenerator; public static DeathTracker deathTracker; + private static ServerTickHandler serverTickHandler; + private static LimboDecayScheduler limboDecayScheduler; + private static LimboDecay limboDecay; private static EventHookContainer hooks; //TODO this is a temporary workaround for saving data @@ -182,16 +187,14 @@ public class mod_pocketDim @EventHandler public void onInitialization(FMLInitializationEvent event) { - ServerTickHandler commonTickHandler = new ServerTickHandler(); - TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER); - - //MonolithSpawner should be initialized before any provider instances are created - //Register the other regular tick receivers as well - spawner = new CustomLimboPopulator(commonTickHandler, properties); - new RiftRegenerator(commonTickHandler); //No need to store the reference - LimboDecay decay = new LimboDecay(commonTickHandler, properties); - fastRiftRegenerator = new FastRiftRegenerator(commonTickHandler); + // Initialize ServerTickHandler instance + serverTickHandler = new ServerTickHandler(); + TickRegistry.registerTickHandler(serverTickHandler, Side.SERVER); + + // Initialize LimboDecay instance: required for BlockLimbo + limboDecay = new LimboDecay(properties); + // Initialize blocks and items transientDoor = new TransientDoor(properties.TransientDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("transientDoor"); goldenDimensionalDoor = new BlockGoldDimDoor(properties.GoldenDimensionalDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorGold"); @@ -200,7 +203,7 @@ public class mod_pocketDim blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm"); warpDoor = new WarpDoor(properties.WarpDoorID, Material.wood, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp"); blockRift = (BlockRift) (new BlockRift(properties.RiftBlockID, 0, Material.air, properties).setHardness(1.0F) .setUnlocalizedName("rift")); - blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, decay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F); + blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, limboDecay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F); unstableDoor = (new UnstableDoor(properties.UnstableDoorID, Material.iron, properties).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) ); dimensionalDoor = (DimensionalDoor) (new DimensionalDoor(properties.DimensionalDoorID, Material.iron, properties).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor")); transTrapdoor = (TransTrapdoor) (new TransTrapdoor(properties.TransTrapdoorID, Material.wood).setHardness(1.0F) .setUnlocalizedName("dimHatch")); @@ -317,7 +320,11 @@ public class mod_pocketDim deathTracker.writeToFile(); deathTracker = null; worldProperties = null; - this.currrentSaveRootDirectory=null; + currrentSaveRootDirectory = null; + + // Unregister all tick receivers from serverTickHandler to avoid leaking + // scheduled tasks between single-player game sessions + serverTickHandler.unregisterReceivers(); } catch (Exception e) { @@ -333,9 +340,16 @@ public class mod_pocketDim // Load the config file that's specific to this world worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg")); hooks.setWorldProperties(worldProperties); - + // Initialize a new DeathTracker deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt"); + + // Register regular tick receivers + // CustomLimboPopulator should be initialized before any provider instances are created + spawner = new CustomLimboPopulator(serverTickHandler, properties); + riftRegenerator = new RiftRegenerator(serverTickHandler); + limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay); + fastRiftRegenerator = new FastRiftRegenerator(serverTickHandler); } @EventHandler @@ -353,7 +367,7 @@ public class mod_pocketDim try { - ChunkLoaderHelper.loadChunkForcedWorlds(event); + ChunkLoaderHelper.loadForcedChunkWorlds(event); } catch (Exception e) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java index ddc018c..231eec2 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/CustomLimboPopulator.java @@ -30,7 +30,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver { { this.properties = properties; this.locations = new ConcurrentLinkedQueue(); - sender.registerForTicking(this, MONOLITH_SPAWNING_INTERVAL, false); + sender.registerReceiver(this, MONOLITH_SPAWNING_INTERVAL, false); } @Override diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java index b0f203f..e680b2a 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java @@ -20,7 +20,7 @@ public class FastRiftRegenerator implements IRegularTickReceiver { public FastRiftRegenerator(IRegularTickSender sender) { - sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false); + sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false); } @Override @@ -33,6 +33,7 @@ public class FastRiftRegenerator implements IRegularTickReceiver { { if (!locationsToRegen.isEmpty()) { + @SuppressWarnings("cast") List loadedWorlds = (List) Arrays.asList(DimensionManager.getIDs()); for (Point4D point: locationsToRegen) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java index 6ed2dca..7b5502c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/IRegularTickSender.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.ticking; public interface IRegularTickSender { - public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart); + public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart); + public void unregisterReceivers(); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java new file mode 100644 index 0000000..73f275c --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecayScheduler.java @@ -0,0 +1,28 @@ +package StevenDimDoors.mod_pocketDim.ticking; + +import StevenDimDoors.mod_pocketDim.world.LimboDecay; + +/** + * Handles scheduling of periodic fast Limbo decay operations. + */ +public class LimboDecayScheduler implements IRegularTickReceiver { + + private static final int LIMBO_DECAY_INTERVAL = 10; //Apply fast decay every 10 ticks + + private LimboDecay decay; + + public LimboDecayScheduler(IRegularTickSender tickSender, LimboDecay decay) + { + this.decay = decay; + tickSender.registerReceiver(this, LIMBO_DECAY_INTERVAL, false); + } + + /** + * Applies fast Limbo decay periodically. + */ + @Override + public void notifyTick() + { + decay.applyRandomFastDecay(); + } +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java index 192669c..23b0f9b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java @@ -20,7 +20,7 @@ public class RiftRegenerator implements IRegularTickReceiver { public RiftRegenerator(IRegularTickSender sender) { - sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false); + sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false); } @Override diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java index 2e2ccb1..58da365 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/ServerTickHandler.java @@ -14,18 +14,23 @@ public class ServerTickHandler implements ITickHandler, IRegularTickSender private int tickCount = 0; private ArrayList receivers; - public ServerTickHandler() { this.receivers = new ArrayList(); } @Override - public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart) + public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart) { RegularTickReceiverInfo info = new RegularTickReceiverInfo(receiver, interval, onTickStart); receivers.add(info); } + + @Override + public void unregisterReceivers() + { + receivers.clear(); + } @Override public void tickStart(EnumSet type, Object... tickData) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/LimboDecay.java similarity index 91% rename from src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java rename to src/main/java/StevenDimDoors/mod_pocketDim/world/LimboDecay.java index e5c9420..13edb19 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/LimboDecay.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/LimboDecay.java @@ -1,4 +1,4 @@ -package StevenDimDoors.mod_pocketDim.ticking; +package StevenDimDoors.mod_pocketDim.world; import java.util.Random; @@ -13,13 +13,12 @@ import StevenDimDoors.mod_pocketDim.config.DDProperties; * Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo * naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes. */ -public class LimboDecay implements IRegularTickReceiver { +public class LimboDecay { private static final int MAX_DECAY_SPREAD_CHANCE = 100; private static final int DECAY_SPREAD_CHANCE = 50; private static final int CHUNK_SIZE = 16; private static final int SECTION_HEIGHT = 16; - private static final int LIMBO_DECAY_INTERVAL = 10; //Apply spread decay every 10 ticks //Provides a reversed list of the block IDs that blocks cycle through during decay. private final int[] decaySequence; @@ -28,7 +27,7 @@ public class LimboDecay implements IRegularTickReceiver { private final DDProperties properties; private final int[] blocksImmuneToDecay; - public LimboDecay(IRegularTickSender tickSender, DDProperties properties) + public LimboDecay(DDProperties properties) { decaySequence = new int[] { properties.LimboBlockID, @@ -51,16 +50,6 @@ public class LimboDecay implements IRegularTickReceiver { this.properties = properties; this.random = new Random(); - tickSender.registerForTicking(this, LIMBO_DECAY_INTERVAL, false); - } - - /** - * Applies fast Limbo decay periodically. - */ - @Override - public void notifyTick() - { - applyRandomFastDecay(); } /** @@ -88,7 +77,7 @@ public class LimboDecay implements IRegularTickReceiver { * Picks random blocks from each active chunk in Limbo and, if decay is applicable, converts them directly to Unraveled Fabric. * This decay method is designed to stop players from avoiding Limbo decay by building floating structures. */ - private void applyRandomFastDecay() + public void applyRandomFastDecay() { int x, y, z; int sectionY; -- 2.39.5 From 782c6d5e50f18b07abaeb2ae1b8547c923bf5b7c Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 10 Jul 2014 17:13:10 -0400 Subject: [PATCH 03/12] Minor Changes to NewDimData Made some minor changes to NewDimData. Fixed some comments for the rift search functions that incorrectly indicated the search would not detect rifts adjacent to the center of the search range. That behavior changed some time ago. Also added an unused field called "chunkMapping" for associating chunks with lists of links. It'll be used for implementing queuing of rift regeneration when chunks load. --- .../mod_pocketDim/core/NewDimData.java | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 326b7d4..5d7e50a 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -7,13 +7,14 @@ import java.util.Random; import java.util.Stack; import java.util.TreeMap; -import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; +import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.dungeon.DungeonData; import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack; import StevenDimDoors.mod_pocketDim.util.Point4D; +import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher; public abstract class NewDimData @@ -134,6 +135,9 @@ public abstract class NewDimData protected boolean modified; public IUpdateWatcher linkWatcher; + // Don't write this field to a file - it should be recreated on startup + private Map> chunkMapping; + protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon, IUpdateWatcher linkWatcher) { @@ -204,23 +208,20 @@ public abstract class NewDimData public DimLink findNearestRift(World world, int range, int x, int y, int z) { - //TODO: Rewrite this later to use an octtree - - //Sanity check... + // Sanity check... if (world.provider.dimensionId != id) { throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!"); } - //Note: Only detect rifts at a distance > 1, so we ignore the rift - //that called this function and any adjacent rifts. - - DimLink nearest = null; + // Note: Only detect rifts at a distance > 0, so we ignore the rift + // at the center of the search space. DimLink link; - + DimLink nearest = null; + + int i, j, k; int distance; int minDistance = Integer.MAX_VALUE; - int i, j, k; DDProperties properties = DDProperties.instance(); for (i = -range; i <= range; i++) @@ -232,7 +233,7 @@ public abstract class NewDimData distance = getAbsoluteSum(i, j, k); if (distance > 0 && distance < minDistance && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID) { - link = getLink(x+i, y+j, z+k); + link = getLink(x + i, y + j, z + k); if (link != null) { nearest = link; @@ -248,24 +249,20 @@ public abstract class NewDimData public ArrayList findRiftsInRange(World world, int range, int x, int y, int z) { - ArrayList links = new ArrayList(); - //TODO: Rewrite this later to use an octtree - - //Sanity check... + // Sanity check... if (world.provider.dimensionId != id) { throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!"); } - - //Note: Only detect rifts at a distance > 1, so we ignore the rift - //that called this function and any adjacent rifts. - - DimLink link; - - int distance; - int i, j, k; - DDProperties properties = DDProperties.instance(); + // Note: Only detect rifts at a distance > 0, so we ignore the rift + // at the center of the search space. + int i, j, k; + int distance; + DimLink link; + DDProperties properties = DDProperties.instance(); + ArrayList links = new ArrayList(); + for (i = -range; i <= range; i++) { for (j = -range; j <= range; j++) @@ -275,7 +272,7 @@ public abstract class NewDimData distance = getAbsoluteSum(i, j, k); if (distance > 0 && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID) { - link = getLink(x+i, y+j, z+k); + link = getLink(x + i, y + j, z + k); if (link != null) { links.add(link); -- 2.39.5 From 85ff28298ebddd8a9e2bc003ba3838f788d0cc40 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 10 Jul 2014 18:21:10 -0400 Subject: [PATCH 04/12] Implemented Chunk-Links Mapping Implemented support for tracking the list of links in each chunk in a dimension. This will be used for scheduling rift regeneration when chunks load. --- .../mod_pocketDim/core/DimLink.java | 7 +- .../mod_pocketDim/core/NewDimData.java | 70 ++++++++++++++++--- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java index 8b0e3d8..409b815 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.core; import java.util.LinkedList; import java.util.List; +import net.minecraft.world.ChunkCoordIntPair; import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; @@ -15,7 +16,6 @@ public abstract class DimLink protected DimLink(ClientLinkData link, DimLink parent) { - if (parent.link.point.getDimension() != link.point.getDimension()) { // Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails @@ -95,6 +95,11 @@ public abstract class DimLink { return tail.getLinkType(); } + + public ChunkCoordIntPair getChunkCoordinates() + { + return new ChunkCoordIntPair(link.point.getX() >> 4, link.point.getZ() >> 4); + } @Override public String toString() diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 5d7e50a..5045b9d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -1,6 +1,7 @@ package StevenDimDoors.mod_pocketDim.core; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; @@ -117,6 +118,8 @@ public abstract class NewDimData } } + private static int EXPECTED_LINKS_PER_CHUNK = 2; + protected static Random random = new Random(); protected int id; @@ -163,6 +166,7 @@ public abstract class NewDimData this.origin = null; this.dungeon = null; this.linkWatcher = linkWatcher; + this.chunkMapping = new HashMap>(); this.modified = true; //Register with parent @@ -203,6 +207,7 @@ public abstract class NewDimData this.linkWatcher = null; this.depth = 0; this.root = root; + this.chunkMapping = null; } @@ -297,13 +302,26 @@ public abstract class NewDimData public DimLink createLink(Point4D source, int linkType, int orientation) { - //Return an existing link if there is one to avoid creating multiple links starting at the same point. + // Return an existing link if there is one to avoid creating multiple links starting at the same point. InnerDimLink link = linkMapping.get(source); if (link == null) { link = new InnerDimLink(source, linkType, orientation); linkMapping.put(source, link); linkList.add(link); + + // If this code is running on the server side, add this link to chunkMapping. + if (linkType != LinkTypes.CLIENT_SIDE) + { + ChunkCoordIntPair chunk = link.getChunkCoordinates(); + List chunkLinks = chunkMapping.get(chunk); + if (chunkLinks == null) + { + chunkLinks = new ArrayList(EXPECTED_LINKS_PER_CHUNK); + chunkMapping.put(chunk, chunkLinks); + } + chunkLinks.add(link); + } } else { @@ -311,7 +329,7 @@ public abstract class NewDimData } modified = true; - //Link created! + // Link created! if (linkType != LinkTypes.CLIENT_SIDE) { linkWatcher.onCreated(link.link); @@ -331,8 +349,8 @@ public abstract class NewDimData private DimLink createChildLink(Point4D source, InnerDimLink parent) { - //To avoid having multiple links at a single point, if we find an existing link then we overwrite - //its destination data instead of creating a new instance. + // To avoid having multiple links at a single point, if we find an existing link then we overwrite + // its destination data instead of creating a new instance. InnerDimLink link = linkMapping.get(source); if (link == null) @@ -341,14 +359,28 @@ public abstract class NewDimData linkMapping.put(source, link); linkList.add(link); - //Link created! + // If this code is running on the server side, add this link to chunkMapping. + // Granted, the client side code should never create child links anyway... + if (link.linkType() != LinkTypes.CLIENT_SIDE) + { + ChunkCoordIntPair chunk = link.getChunkCoordinates(); + List chunkLinks = chunkMapping.get(chunk); + if (chunkLinks == null) + { + chunkLinks = new ArrayList(EXPECTED_LINKS_PER_CHUNK); + chunkMapping.put(chunk, chunkLinks); + } + chunkLinks.add(link); + } + + // Link created! linkWatcher.onCreated(link.link); } else { if (link.overwrite(parent, parent.link.orientation)) { - //Link created! + // Link created! linkWatcher.onCreated(link.link); } } @@ -366,7 +398,19 @@ public abstract class NewDimData if (target != null) { linkList.remove(target); - //Raise deletion event + + // If this code is running on the server side, remove this link to chunkMapping. + if (link.linkType() != LinkTypes.CLIENT_SIDE) + { + ChunkCoordIntPair chunk = target.getChunkCoordinates(); + List chunkLinks = chunkMapping.get(chunk); + if (chunkLinks != null) + { + chunkLinks.remove(target); + } + } + + // Raise deletion event linkWatcher.onDeleted(target.link); target.clear(); modified = true; @@ -388,7 +432,7 @@ public abstract class NewDimData public DimLink getLink(Point3D location) { - return linkMapping.get(new Point4D(location.getX(),location.getY(),location.getZ(),this.id)); + return linkMapping.get(new Point4D(location.getX(), location.getY(), location.getZ(), this.id)); } public DimLink getLink(Point4D location) @@ -618,6 +662,16 @@ public abstract class NewDimData return linkList.get(0); } + public Iterable getChunkLinks(int chunkX, int chunkZ) + { + List chunkLinks = chunkMapping.get(new ChunkCoordIntPair(chunkX, chunkZ)); + if (chunkLinks != null) + { + return chunkLinks; + } + return new ArrayList(0); + } + public boolean isModified() { return modified; -- 2.39.5 From b197237dfd3fb82a2c57bdbe3b27e3cc7511ee60 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 10 Jul 2014 18:25:41 -0400 Subject: [PATCH 05/12] Minor Change Rewrote the NewDimData.deleteLink() version that would accept x, y, and z as parameters. There was some redundant code for getting the parameters from a Point4D instance just to create another one to find the target link. Now we pass the source point in directly. --- .../java/StevenDimDoors/mod_pocketDim/core/NewDimData.java | 3 +-- .../StevenDimDoors/mod_pocketDim/core/PocketManager.java | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 5045b9d..9a8a0b5 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -418,9 +418,8 @@ public abstract class NewDimData return (target != null); } - public boolean deleteLink(int x, int y, int z) + public boolean deleteLink(Point4D location) { - Point4D location = new Point4D(x, y, z, id); return this.deleteLink(this.getLink(location)); } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java index 5a1f1d6..1939e1d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/PocketManager.java @@ -171,9 +171,8 @@ public class PocketManager public void onDeleted(ClientLinkData link) { Point4D source = link.point; - NewDimData dimension = getDimensionData(source.getDimension()); - dimension.deleteLink(source.getX(), source.getY(), source.getZ()); - } + getDimensionData(source.getDimension()).deleteLink(source); + } } private static class ClientDimWatcher implements IUpdateWatcher -- 2.39.5 From 79bd5102bad6ea88a5b92f5d166b8f4f3a4748a0 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Thu, 10 Jul 2014 18:29:48 -0400 Subject: [PATCH 06/12] Minor Changes Minor changes to DimLink to simplify DimLink.getDestinationOrientation() and to clarify the output of DimLink.toString() when no destination is available. --- .../StevenDimDoors/mod_pocketDim/core/DimLink.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java index 409b815..abfed4d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java @@ -63,12 +63,12 @@ public abstract class DimLink public int getDestinationOrientation() { - DimLink link = PocketManager.getLink(this.destination().getX(), this.destination().getY(), this.destination().getZ(), this.destination().getDimension()); - if(link !=null) + DimLink destinationLink = PocketManager.getLink(tail.getDestination()); + if (destinationLink != null) { - return link.orientation(); + return destinationLink.orientation(); } - return (this.orientation()+2)%4; + return (link.orientation + 2) % 4; } public boolean hasDestination() @@ -104,6 +104,6 @@ public abstract class DimLink @Override public String toString() { - return link.point + " -> " + (hasDestination() ? destination() : ""); + return link.point + " -> " + (hasDestination() ? destination() : "()"); } } -- 2.39.5 From 1f59dc17d9b8e3f383f006c4a4493c1af0041b1d Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Fri, 11 Jul 2014 01:21:43 -0400 Subject: [PATCH 07/12] Implemented Scheduled Rift Regeneration 1. Implemented scheduled rift regeneration in RiftRegenerator. The previous randomized selection algorithm has been removed completely. All regeneration is scheduled now. We perform numerous checks to make sure that regenerating a rift is safe. 2. Removed FastRiftRegenerator as RiftRegenerator performs roughly the same task but with more flexibility. Updated TileEntityDimDoor to use RiftRegenerator instead for creating rifts when doors are broken. 3. Modified EventHookContainer to receive the chunk loaded event. We iterate over the list of links in a loaded chunk and schedule them for regeneration. 4. Reorganized the code in BlockRift. Divided the list of immune blocks into two lists - one for DD blocks and one for regular MC blocks. RiftRegenerator has to be able to distinguish between the two types. 5. Factored out some duplicate code from ItemRiftSignature and ItemStabilizedRiftSignature. Most of the block immunity checks were used to check if it would be safe to spawn a rift when using one of those items. BlockRift.tryPlacingRift() covers all that logic in a single function and makes the item code a little simpler. --- .../mod_pocketDim/EventHookContainer.java | 27 +++- .../mod_pocketDim/blocks/BlockRift.java | 64 ++++++---- .../items/ItemRiftSignature.java | 23 ++-- .../items/ItemStabilizedRiftSignature.java | 31 ++--- .../mod_pocketDim/mod_pocketDim.java | 13 +- .../ticking/FastRiftRegenerator.java | 54 -------- .../ticking/RiftRegenerator.java | 117 +++++++++++++----- .../mod_pocketDim/ticking/RiftTicket.java | 40 ++++++ .../tileentities/TileEntityDimDoor.java | 43 +++---- 9 files changed, 239 insertions(+), 173 deletions(-) delete mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java create mode 100644 src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java b/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java index 1855963..9fd2d41 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java @@ -8,6 +8,7 @@ import net.minecraft.item.ItemDoor; import net.minecraft.item.ItemStack; import net.minecraft.world.World; import net.minecraft.world.WorldProvider; +import net.minecraft.world.chunk.Chunk; import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent; import net.minecraftforge.client.event.sound.SoundLoadEvent; import net.minecraftforge.event.EventPriority; @@ -17,12 +18,16 @@ import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; import net.minecraftforge.event.terraingen.InitMapGenEvent; +import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.WorldEvent; import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.config.DDWorldProperties; import StevenDimDoors.mod_pocketDim.core.DDTeleporter; +import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.items.BaseItemDoor; +import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider; @@ -36,18 +41,20 @@ public class EventHookContainer private final DDProperties properties; private DDWorldProperties worldProperties; + private RiftRegenerator regenerator; public EventHookContainer(DDProperties properties) { this.properties = properties; } - public void setWorldProperties(DDWorldProperties worldProperties) + public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator) { // SenseiKiwi: - // Why have a setter rather than accessing mod_pocketDim.worldProperties? + // Why have a setter rather than accessing mod_pocketDim directly? // I want to make this dependency explicit in our code. this.worldProperties = worldProperties; + this.regenerator = regenerator; } @ForgeSubscribe(priority = EventPriority.LOW) @@ -217,6 +224,22 @@ public class EventHookContainer } } } + + @ForgeSubscribe + public void onChunkLoad(ChunkEvent.Load event) + { + // Schedule rift regeneration for any links located in this chunk. + // This event runs on both the client and server. Allow server only. + Chunk chunk = event.getChunk(); + if (!chunk.worldObj.isRemote) + { + NewDimData dimension = PocketManager.getDimensionData(chunk.worldObj); + for (DimLink link : dimension.getChunkLinks(chunk.xPosition, chunk.zPosition)) + { + regenerator.scheduleSlowRegeneration(link); + } + } + } public void playMusicForDim(World world) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java index ada00b6..78f666a 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java @@ -7,6 +7,7 @@ import java.util.Queue; import java.util.Random; import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockFlowing; import net.minecraft.block.BlockFluid; import net.minecraft.block.ITileEntityProvider; @@ -47,25 +48,27 @@ public class BlockRift extends Block implements ITileEntityProvider public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000; private final DDProperties properties; - private final ArrayList blocksImmuneToRift; + private final ArrayList blocksImmuneToRift; // List of Vanilla blocks immune to rifts + private final ArrayList modBlocksImmuneToRift; // List of DD blocks immune to rifts public BlockRift(int i, int j, Material par2Material, DDProperties properties) { super(i, par2Material); this.setTickRandomly(true); this.properties = properties; + this.modBlocksImmuneToRift = new ArrayList(); + this.modBlocksImmuneToRift.add(properties.FabricBlockID); + this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID); + this.modBlocksImmuneToRift.add(properties.DimensionalDoorID); + this.modBlocksImmuneToRift.add(properties.WarpDoorID); + this.modBlocksImmuneToRift.add(properties.TransTrapdoorID); + this.modBlocksImmuneToRift.add(properties.UnstableDoorID); + this.modBlocksImmuneToRift.add(properties.RiftBlockID); + this.modBlocksImmuneToRift.add(properties.TransientDoorID); + this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID); + this.modBlocksImmuneToRift.add(properties.GoldenDoorID); + this.blocksImmuneToRift = new ArrayList(); - this.blocksImmuneToRift.add(properties.FabricBlockID); - this.blocksImmuneToRift.add(properties.PermaFabricBlockID); - this.blocksImmuneToRift.add(properties.DimensionalDoorID); - this.blocksImmuneToRift.add(properties.WarpDoorID); - this.blocksImmuneToRift.add(properties.TransTrapdoorID); - this.blocksImmuneToRift.add(properties.UnstableDoorID); - this.blocksImmuneToRift.add(properties.RiftBlockID); - this.blocksImmuneToRift.add(properties.TransientDoorID); - this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID); - this.blocksImmuneToRift.add(properties.GoldenDoorID); - this.blocksImmuneToRift.add(Block.blockLapis.blockID); this.blocksImmuneToRift.add(Block.blockIron.blockID); this.blocksImmuneToRift.add(Block.blockGold.blockID); @@ -220,7 +223,7 @@ public class BlockRift extends Block implements ITileEntityProvider return targets; } - private void dropWorldThread(int blockID, World world, int x, int y, int z, Random random) + public void dropWorldThread(int blockID, World world, int x, int y, int z, Random random) { if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance) && !(Block.blocksList[blockID] instanceof BlockFlowing || @@ -251,16 +254,6 @@ public class BlockRift extends Block implements ITileEntityProvider } } } - - public void regenerateRift(World world, int x, int y, int z, Random random) - { - if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4)) - { - int blockID = world.getBlockId(x, y, z); - if (world.setBlock(x, y, z, properties.RiftBlockID)) - dropWorldThread(blockID, world, x, y, z, random); - } - } public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random) { @@ -412,6 +405,15 @@ public class BlockRift extends Block implements ITileEntityProvider } } } + + public boolean tryPlacingRift(World world, int x, int y, int z) + { + if (world != null && !isBlockImmune(world, x, y, z)) + { + return world.setBlock(x, y, z, mod_pocketDim.blockRift.blockID); + } + return false; + } public boolean isBlockImmune(World world, int x, int y, int z) { @@ -424,7 +426,21 @@ public class BlockRift extends Block implements ITileEntityProvider // is designed to receive an entity, the source of the blast. We have no entity so // I've set this to access blockResistance directly. Might need changing later. - return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || blocksImmuneToRift.contains(block.blockID)); + return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || + modBlocksImmuneToRift.contains(block.blockID) || + blocksImmuneToRift.contains(block.blockID)); + } + return false; + } + + public boolean isModBlockImmune(World world, int x, int y, int z) + { + // Check whether the block at the specified location is one of the + // rift-resistant blocks from DD. + Block block = Block.blocksList[world.getBlockId(x, y, z)]; + if (block != null) + { + return modBlocksImmuneToRift.contains(block.blockID); } return false; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java index 9cc5053..84dbde6 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java @@ -71,7 +71,8 @@ public class ItemRiftSignature extends Item int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; if (source != null) { - //The link was used before and already has an endpoint stored. Create links connecting the two endpoints. + // The link was used before and already has an endpoint stored. + // Create links connecting the two endpoints. NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); NewDimData destinationDimension = PocketManager.getDimensionData(world); DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation()); @@ -79,27 +80,21 @@ public class ItemRiftSignature extends Item destinationDimension.setLinkDestination(link, x, adjustedY, z); sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); - //Try placing a rift at the destination point - if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) - { - world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID); - } + // Try placing a rift at the destination point + mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z); - //Try placing a rift at the source point, but check if its world is loaded first + // Try placing a rift at the source point + // We don't need to check if sourceWorld is null - that's already handled. World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); - if (sourceWorld != null && - !mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ())) - { - sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ()); if (!player.capabilities.isCreativeMode) { stack.stackSize--; } clearSource(stack); - mod_pocketDim.sendChat(player,("Rift Created")); - world.playSoundAtEntity(player,mod_pocketDim.modid+":riftEnd", 0.6f, 1); + mod_pocketDim.sendChat(player, "Rift Created"); + world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1); } else { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java index b47bff6..c06d598 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java @@ -90,19 +90,13 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); // Try placing a rift at the destination point - if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) - { - world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z); } - - // Try placing a rift at the source point, but check if its world is loaded first + + // Try placing a rift at the source point + // We don't need to check if sourceWorld is null - that's already handled. World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); - if (sourceWorld != null && - !mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ())) - { - sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ()); mod_pocketDim.sendChat(player, "Rift Created"); world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); @@ -111,8 +105,8 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature { // The link signature has not been used. Store its current target as the first location. setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world)); - mod_pocketDim.sendChat(player,"Location Stored in Stabilized Rift Signature"); - world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftStart", 0.6f, 1); + mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature"); + world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1); } return true; } @@ -148,14 +142,11 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature // Only the source-to-destination link is needed. link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL, source.getOrientation()); destinationDimension.setLinkDestination(link, x, adjustedY, z); - - // Try placing a rift at the source point, but check if its world is loaded first + + // Try placing a rift at the source point + // We don't need to check if sourceWorld is null - that's already handled. World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); - if (sourceWorld != null && - !mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ())) - { - sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID); - } + mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ()); // This call doesn't seem to be working... world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java index 8329d25..a8633d9 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java @@ -53,7 +53,6 @@ import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor; import StevenDimDoors.mod_pocketDim.items.ItemWorldThread; import StevenDimDoors.mod_pocketDim.items.itemRiftRemover; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; -import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator; import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler; import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; @@ -143,8 +142,7 @@ public class mod_pocketDim public static DDProperties properties; public static DDWorldProperties worldProperties; public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later. - private static RiftRegenerator riftRegenerator; - public static FastRiftRegenerator fastRiftRegenerator; + public static RiftRegenerator riftRegenerator; public static GatewayGenerator gatewayGenerator; public static DeathTracker deathTracker; private static ServerTickHandler serverTickHandler; @@ -325,6 +323,9 @@ public class mod_pocketDim // Unregister all tick receivers from serverTickHandler to avoid leaking // scheduled tasks between single-player game sessions serverTickHandler.unregisterReceivers(); + spawner = null; + riftRegenerator = null; + limboDecayScheduler = null; } catch (Exception e) { @@ -339,7 +340,6 @@ public class mod_pocketDim // Load the config file that's specific to this world worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg")); - hooks.setWorldProperties(worldProperties); // Initialize a new DeathTracker deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt"); @@ -347,9 +347,10 @@ public class mod_pocketDim // Register regular tick receivers // CustomLimboPopulator should be initialized before any provider instances are created spawner = new CustomLimboPopulator(serverTickHandler, properties); - riftRegenerator = new RiftRegenerator(serverTickHandler); + riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift); limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay); - fastRiftRegenerator = new FastRiftRegenerator(serverTickHandler); + + hooks.setSessionFields(worldProperties, riftRegenerator); } @EventHandler diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java deleted file mode 100644 index e680b2a..0000000 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/FastRiftRegenerator.java +++ /dev/null @@ -1,54 +0,0 @@ -package StevenDimDoors.mod_pocketDim.ticking; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; - -import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.core.PocketManager; -import StevenDimDoors.mod_pocketDim.util.Point4D; - -public class FastRiftRegenerator implements IRegularTickReceiver { - - private static final int RIFT_REGENERATION_INTERVAL = 10; //Regenerate scheduled rifts every 10 ticks - private static Random random = new Random(); - - private ArrayList locationsToRegen = new ArrayList(); - - public FastRiftRegenerator(IRegularTickSender sender) - { - sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false); - } - - @Override - public void notifyTick() - { - regenerateScheduledRifts(); - } - - public void regenerateScheduledRifts() - { - if (!locationsToRegen.isEmpty()) - { - @SuppressWarnings("cast") - List loadedWorlds = (List) Arrays.asList(DimensionManager.getIDs()); - for (Point4D point: locationsToRegen) - { - if (loadedWorlds.contains(point.getDimension()) && PocketManager.getLink(point) != null) - { - World world = DimensionManager.getWorld(point.getDimension()); - mod_pocketDim.blockRift.regenerateRift(world, point.getX(), point.getY(), point.getZ(), random); - } - } - locationsToRegen.clear(); - } - } - - public void registerRiftForRegen(int x, int y, int z, int dimID) - { - this.locationsToRegen.add(new Point4D(x, y, z, dimID)); - } -} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java index 23b0f9b..0b957da 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java @@ -1,56 +1,113 @@ package StevenDimDoors.mod_pocketDim.ticking; -import java.util.Arrays; -import java.util.List; +import java.util.PriorityQueue; import java.util.Random; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import StevenDimDoors.mod_pocketDim.blocks.BlockRift; import StevenDimDoors.mod_pocketDim.core.DimLink; -import StevenDimDoors.mod_pocketDim.core.NewDimData; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.util.Point4D; public class RiftRegenerator implements IRegularTickReceiver { - private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks - private static final int RIFTS_REGENERATED_PER_DIMENSION = 5; + // Ranges of regeneration delays, in seconds + private static final int MIN_FAST_DELAY = 1; + private static final int MAX_FAST_DELAY = 3; + private static final int MIN_SLOW_DELAY = 5; + private static final int MAX_SLOW_DELAY = 15; + private static final int MIN_RESCHEDULE_DELAY = 4 * 60; + private static final int MAX_RESCHEDULE_DELAY = 6 * 60; + + private static final int TICKS_PER_SECOND = 20; + private static final int RIFT_REGENERATION_INTERVAL = 1; // Check the regeneration queue every tick private static Random random = new Random(); - public RiftRegenerator(IRegularTickSender sender) + private long tickCount = 0; + private PriorityQueue ticketQueue; + private BlockRift blockRift; + + public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift) { + this.ticketQueue = new PriorityQueue(); + this.blockRift = blockRift; sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false); } @Override public void notifyTick() { - regenerateRiftsInLoadedWorlds(); + processTicketQueue(); + tickCount++; } - private static void regenerateRiftsInLoadedWorlds() + public void scheduleSlowRegeneration(DimLink link) { - // Regenerate rifts that have been replaced (not permanently removed) by players - // Only do this in dimensions that are currently loaded - List loadedWorlds = Arrays.asList(DimensionManager.getIDs()); - for (Integer dimensionID : loadedWorlds) - { - NewDimData dimension = PocketManager.getDimensionData(dimensionID); - if (dimension.linkCount() > 0) - { - World world = DimensionManager.getWorld(dimension.id()); - - if (world != null) - { - for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++) - { - DimLink link = dimension.getRandomLink(); - Point4D source = link.source(); - mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random); - } - } - } - } + scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY); } + + public void scheduleFastRegeneration(DimLink link) + { + scheduleRegeneration(link, MIN_FAST_DELAY, MAX_FAST_DELAY); + } + + private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay) + { + int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND); + ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay)); + } + + private void processTicketQueue() + { + RiftTicket ticket; + while (!ticketQueue.isEmpty() && ticketQueue.peek().timestamp() <= tickCount) + { + ticket = ticketQueue.remove(); + regenerateRift(ticket.location()); + } + } + + private void regenerateRift(Point4D location) + { + int x = location.getX(); + int y = location.getY(); + int z = location.getZ(); + + // Try to regenerate a rift, or possibly reschedule its regeneration. + // The world for the given location must be loaded. + World world = DimensionManager.getWorld(location.getDimension()); + if (world == null) + return; + + // There must be a link at the given location. + DimLink link = PocketManager.getLink(location); + if (link == null) + return; + + // The chunk at the given location must be loaded. + // FIXME: I can't figure out how to check if a chunk is loaded. + // Will only check if the chunk exists for now. This isn't a big deal. --SenseiKiwi + if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4)) + return; + + // If the location is occupied by an immune DD block, then don't regenerate. + if (blockRift.isModBlockImmune(world, x, y, z)) + return; + + // If the location is occupied by an immune block, then reschedule. + if (blockRift.isBlockImmune(world, x, y, z)) + { + scheduleRegeneration(link, MIN_RESCHEDULE_DELAY, MAX_RESCHEDULE_DELAY); + } + else + { + // All of the necessary conditions have been met. Restore the rift! + int blockID = world.getBlockId(x, y, z); + if (world.setBlock(x, y, z, blockRift.blockID)) + blockRift.dropWorldThread(blockID, world, x, y, z, random); + } + } + } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java new file mode 100644 index 0000000..d618a51 --- /dev/null +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftTicket.java @@ -0,0 +1,40 @@ +package StevenDimDoors.mod_pocketDim.ticking; + +import StevenDimDoors.mod_pocketDim.util.Point4D; + +public class RiftTicket implements Comparable { + + private long timestamp; + private Point4D location; + + public RiftTicket(Point4D location, long timestamp) + { + this.timestamp = timestamp; + this.location = location; + } + + @Override + public int compareTo(RiftTicket other) + { + if (this.timestamp < other.timestamp) + { + return -1; + } + else if (this.timestamp > other.timestamp) + { + return 1; + } + return 0; + } + + public long timestamp() + { + return timestamp; + } + + public Point4D location() + { + return location; + } + +} diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java index fe478b6..9703ae1 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java @@ -1,17 +1,13 @@ package StevenDimDoors.mod_pocketDim.tileentities; import java.util.Random; -import StevenDimDoors.mod_pocketDim.ServerPacketHandler; -import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import StevenDimDoors.mod_pocketDim.blocks.IDimDoor; -import StevenDimDoors.mod_pocketDim.core.NewDimData; -import StevenDimDoors.mod_pocketDim.core.PocketManager; -import net.minecraft.block.Block; + import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.Packet130UpdateSign; -import net.minecraft.network.packet.Packet250CustomPayload; -import net.minecraft.tileentity.TileEntity; +import StevenDimDoors.mod_pocketDim.ServerPacketHandler; +import StevenDimDoors.mod_pocketDim.mod_pocketDim; +import StevenDimDoors.mod_pocketDim.core.DimLink; +import StevenDimDoors.mod_pocketDim.core.PocketManager; public class TileEntityDimDoor extends DDTileEntityBase { @@ -28,25 +24,26 @@ public class TileEntityDimDoor extends DDTileEntityBase } @Override - public Packet getDescriptionPacket() - { - if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) - { - return ServerPacketHandler.createLinkPacket(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj).link()); - } - return null; - } + public Packet getDescriptionPacket() + { + DimLink link = PocketManager.getLink(xCoord, yCoord, zCoord, worldObj); + if (link != null) + { + return ServerPacketHandler.createLinkPacket(link.link()); + } + return null; + } @Override public void invalidate() { - this.tileEntityInvalid = true; - - if(this.worldObj.getBlockId(xCoord, yCoord, zCoord)==0&&!this.worldObj.isRemote) + super.invalidate(); + if (!worldObj.isRemote && worldObj.getBlockId(xCoord, yCoord, zCoord) == 0) { - if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) + DimLink link = PocketManager.getLink(xCoord, yCoord, zCoord, worldObj); + if (link != null) { - mod_pocketDim.fastRiftRegenerator.registerRiftForRegen(xCoord, yCoord, zCoord, this.worldObj.provider.dimensionId); + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(link); } } } @@ -74,7 +71,7 @@ public class TileEntityDimDoor extends DDTileEntityBase public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); - + nbt.setBoolean("openOrClosed", this.openOrClosed); nbt.setBoolean("hasExit", this.hasExit); nbt.setInteger("orientation", this.orientation); -- 2.39.5 From 71e7fdaafce55ba5ff4ac9932d4bd644dc8b95a2 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Fri, 11 Jul 2014 03:26:40 -0400 Subject: [PATCH 08/12] Implemented Regeneration for BlockRift 1. Made it so that rifts regenerate when rift blocks are replaced by other blocks. 2. Changed the rift regeneration scheduling functions to streamline their use in other classes. Common code that was needed to validate links before calling those functions has been moved into them so that the checks are always performed internally. --- .../mod_pocketDim/blocks/BlockRift.java | 19 +++++++++++++------ .../ticking/RiftRegenerator.java | 16 ++++++++++++---- .../tileentities/TileEntityDimDoor.java | 6 +----- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java index 78f666a..c7f8508 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java @@ -7,7 +7,6 @@ import java.util.Queue; import java.util.Random; import net.minecraft.block.Block; -import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockFlowing; import net.minecraft.block.BlockFluid; import net.minecraft.block.ITileEntityProvider; @@ -87,9 +86,6 @@ public class BlockRift extends Block implements ITileEntityProvider { return false; } - - @Override - public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {} @Override public boolean isOpaqueCube() @@ -116,10 +112,10 @@ public class BlockRift extends Block implements ITileEntityProvider return true; } - //this doesnt do anything yet. @Override public int getRenderType() { + // This doesn't do anything yet if (mod_pocketDim.isPlayerWearingGoogles) { return 0; @@ -235,7 +231,7 @@ public class BlockRift extends Block implements ITileEntityProvider } } - private void addAdjacentBlocks(int x, int y, int z, int distance, HashMap pointDistances, Queue points) + private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap pointDistances, Queue points) { Point3D[] neighbors = new Point3D[] { new Point3D(x - 1, y, z), @@ -462,4 +458,15 @@ public class BlockRift extends Block implements ITileEntityProvider { return new TileEntityRift(); } + + @Override + public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta) + { + // This function runs on the server side after a block is replaced + // We MUST call super.breakBlock() since it involves removing tile entities + super.breakBlock(world, x, y, z, oldBlockID, oldMeta); + + // Schedule rift regeneration for this block + mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world); + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java index 0b957da..66bdd1d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java @@ -48,15 +48,23 @@ public class RiftRegenerator implements IRegularTickReceiver { scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY); } - public void scheduleFastRegeneration(DimLink link) + public void scheduleSlowRegeneration(int x, int y, int z, World world) { - scheduleRegeneration(link, MIN_FAST_DELAY, MAX_FAST_DELAY); + scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_SLOW_DELAY, MAX_SLOW_DELAY); + } + + public void scheduleFastRegeneration(int x, int y, int z, World world) + { + scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_FAST_DELAY, MAX_FAST_DELAY); } private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay) { - int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND); - ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay)); + if (link != null) + { + int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND); + ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay)); + } } private void processTicketQueue() diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java index 9703ae1..781427b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java @@ -40,11 +40,7 @@ public class TileEntityDimDoor extends DDTileEntityBase super.invalidate(); if (!worldObj.isRemote && worldObj.getBlockId(xCoord, yCoord, zCoord) == 0) { - DimLink link = PocketManager.getLink(xCoord, yCoord, zCoord, worldObj); - if (link != null) - { - mod_pocketDim.riftRegenerator.scheduleFastRegeneration(link); - } + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(xCoord, yCoord, zCoord, worldObj); } } -- 2.39.5 From 29c8a09218cdb4281ca29d1342cb928417a118b0 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Fri, 11 Jul 2014 03:44:26 -0400 Subject: [PATCH 09/12] Improved Door Code 1. Removed code from BaseDimDoor that was already implemented almost identically in BlockDoor. Clarified some uses of setBlock() by changing them to setBlockToAir() instead. 2. Removed TileEntityDimDoor.invalidate() and moved the regeneration scheduling code to BaseDimDoor.breakBlock(). I would prefer to move away from overriding the invalidate() method. This also simplifies the code since we don't need to perform some of the checks we had in breakBlock(). --- .../mod_pocketDim/blocks/BaseDimDoor.java | 27 +++++++++---------- .../tileentities/TileEntityDimDoor.java | 10 ------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java index d26a0e3..782acfa 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java @@ -306,7 +306,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn { if (world.getBlockId(x, y - 1, z) != this.blockID) { - world.setBlock(x, y, z, 0); + world.setBlockToAir(x, y, z); } if (neighborID > 0 && neighborID != this.blockID) @@ -318,7 +318,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn { if (world.getBlockId(x, y + 1, z) != this.blockID) { - world.setBlock(x, y, z, 0); + world.setBlockToAir(x, y, z); if (!world.isRemote) { this.dropBlockAsItem(world, x, y, z, metadata, 0); @@ -354,18 +354,6 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn return isUpperDoorBlock(metadata) ? 0 : this.getDrops(); } - /** - * Called when the block is attempted to be harvested - */ - @Override - public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) - { - if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID) - { - par1World.setBlock(par2, par3 - 1, par4, 0); - } - } - @Override public TileEntity createNewTileEntity(World world) { @@ -445,4 +433,15 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn world.setBlockTileEntity(x, y, z, te); return te; } + + @Override + public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta) + { + // This function runs on the server side after a block is replaced + // We MUST call super.breakBlock() since it involves removing tile entities + super.breakBlock(world, x, y, z, oldBlockID, oldMeta); + + // Schedule rift regeneration for this block + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world); + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java index 781427b..881577c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java @@ -34,16 +34,6 @@ public class TileEntityDimDoor extends DDTileEntityBase return null; } - @Override - public void invalidate() - { - super.invalidate(); - if (!worldObj.isRemote && worldObj.getBlockId(xCoord, yCoord, zCoord) == 0) - { - mod_pocketDim.riftRegenerator.scheduleFastRegeneration(xCoord, yCoord, zCoord, worldObj); - } - } - @Override public void readFromNBT(NBTTagCompound nbt) { -- 2.39.5 From 1bf1f4f78c7db0e410dec147bedb0b50780af138 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Fri, 11 Jul 2014 04:10:12 -0400 Subject: [PATCH 10/12] Improved Regeneration Code 1. Added code so that Transdimensional Trapdoors detect that they have been broken and schedule rift regeneration at their location. This had previously been neglected. Trapdoors deserve a little more attention. 2. Tweaked the breakBlock() code for BlockRift and BaseDimDoor so that rift regeneration is only scheduled if the underlying block was removed. We don't want that to happen if the only change was for metadata. --- .../mod_pocketDim/blocks/BaseDimDoor.java | 7 +++++-- .../mod_pocketDim/blocks/BlockRift.java | 7 +++++-- .../mod_pocketDim/blocks/TransTrapdoor.java | 14 ++++++++++++++ .../tileentities/TileEntityTransTrapdoor.java | 3 +-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java index 782acfa..de8db5b 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BaseDimDoor.java @@ -441,7 +441,10 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn // We MUST call super.breakBlock() since it involves removing tile entities super.breakBlock(world, x, y, z, oldBlockID, oldMeta); - // Schedule rift regeneration for this block - mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world); + // Schedule rift regeneration for this block if it was replaced + if (world.getBlockId(x, y, z) != oldBlockID) + { + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world); + } } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java index c7f8508..6400978 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/BlockRift.java @@ -466,7 +466,10 @@ public class BlockRift extends Block implements ITileEntityProvider // We MUST call super.breakBlock() since it involves removing tile entities super.breakBlock(world, x, y, z, oldBlockID, oldMeta); - // Schedule rift regeneration for this block - mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world); + // Schedule rift regeneration for this block if it was changed + if (world.getBlockId(x, y, z) != oldBlockID) + { + mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world); + } } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java index 4a1df0d..aefb277 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java @@ -140,4 +140,18 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit world.setBlockTileEntity(x, y, z, te); return te; } + + @Override + public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta) + { + // This function runs on the server side after a block is replaced + // We MUST call super.breakBlock() since it involves removing tile entities + super.breakBlock(world, x, y, z, oldBlockID, oldMeta); + + // Schedule rift regeneration for this block if it was replaced + if (world.getBlockId(x, y, z) != oldBlockID) + { + mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world); + } + } } \ No newline at end of file diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java index d26b46f..25cc3b4 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java @@ -1,9 +1,8 @@ package StevenDimDoors.mod_pocketDim.tileentities; import java.util.Random; + import StevenDimDoors.mod_pocketDim.mod_pocketDim; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; public class TileEntityTransTrapdoor extends DDTileEntityBase { -- 2.39.5 From 107aa4b7f24c90b24ffca64a93b3f118b2253543 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Fri, 11 Jul 2014 04:33:19 -0400 Subject: [PATCH 11/12] Cleaned up Transdimensional Trapdoor Code Removed unnecessary code for the Transdimensional Trapdoor. Most of it was code dedicated to updating TileEntityTransTrapdoor.hasRift. That flag was never used for anything. --- .../mod_pocketDim/blocks/TransTrapdoor.java | 20 +--------------- .../tileentities/TileEntityTransTrapdoor.java | 2 -- .../RenderTransTrapdoor.java | 24 ++++--------------- 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java index aefb277..d2eda14 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/blocks/TransTrapdoor.java @@ -63,14 +63,6 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit { this.placeLink(world, x, y, z); world.setBlockTileEntity(x, y, z, this.createNewTileEntity(world)); - updateAttachedTile(world, x, y, z); - } - - @Override - public void updateTick(World world, int x, int y, int z, Random random) - { - TileEntityTransTrapdoor tile = (TileEntityTransTrapdoor) world.getBlockTileEntity(x, y, z); - tile.hasRift = PocketManager.getLink(x, y, z, world) != null; } @Override @@ -79,16 +71,6 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit return new TileEntityTransTrapdoor(); } - public static void updateAttachedTile(World world, int x, int y, int z) - { - TileEntity tile = world.getBlockTileEntity(x, y, z); - if (tile instanceof TileEntityTransTrapdoor) - { - TileEntityTransTrapdoor trapdoorTile = (TileEntityTransTrapdoor) tile; - trapdoorTile.hasRift = (PocketManager.getLink(x, y, z, world) != null); - } - } - @Override public void placeLink(World world, int x, int y, int z) { @@ -98,7 +80,7 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit DimLink link = dimension.getLink(x, y, z); if (link == null && dimension.isPocketDimension()) { - dimension.createLink(x, y, z, LinkTypes.UNSAFE_EXIT,0); + dimension.createLink(x, y, z, LinkTypes.UNSAFE_EXIT, 0); } } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java index 25cc3b4..3df7f6c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityTransTrapdoor.java @@ -6,8 +6,6 @@ import StevenDimDoors.mod_pocketDim.mod_pocketDim; public class TileEntityTransTrapdoor extends DDTileEntityBase { - public boolean hasRift; - @Override public boolean canUpdate() { diff --git a/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java b/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java index 0f3ea97..98f8e88 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDimClient/RenderTransTrapdoor.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDimClient; import java.nio.FloatBuffer; import java.util.Random; +import net.minecraft.block.BlockTrapDoor; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; @@ -38,21 +39,6 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer */ public void renderTransTrapdoorTileEntity(TileEntityTransTrapdoor tile, double x, double y, double z, float par8) { - try - { - mod_pocketDim.transTrapdoor.updateAttachedTile(tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord); - } - catch(Exception e) - { - e.printStackTrace(); - } - - - // float playerX = (float)this.tileEntityRenderer.playerX; - // float playerY = (float)this.tileEntityRenderer.playerY; - // float playerZ = (float)this.tileEntityRenderer.playerZ; - - //float distance = (float) tile.getDistanceFrom(playerX, playerY, playerZ); GL11.glDisable(GL11.GL_LIGHTING); Random random = new Random(31100L); int metadata = tile.worldObj.getBlockMetadata(tile.xCoord, tile.yCoord, tile.zCoord); @@ -77,7 +63,6 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer if (count == 1) { this.bindTexture(warpPath); - // move files into assets/modid and change to new ResourceLocation(modid:/WARP.png) GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); var16 = .5F; @@ -127,7 +112,7 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer GL11.glColor4d(var21 * var17, var22 * var17, var23 * var17, 1.0F); if (TransTrapdoor.isTrapdoorSetLow(metadata)) { - if (TransTrapdoor.isTrapdoorOpen(metadata)) + if (BlockTrapDoor.isTrapdoorOpen(metadata)) { GL11.glVertex3d(x, y+0.2, z); GL11.glVertex3d(x, y+0.2, z+1); @@ -144,7 +129,7 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer } else { - if (TransTrapdoor.isTrapdoorOpen(metadata)) + if (BlockTrapDoor.isTrapdoorOpen(metadata)) { GL11.glVertex3d(x, y+0.95, z); GL11.glVertex3d(x, y+0.95, z+1); @@ -180,7 +165,8 @@ public class RenderTransTrapdoor extends TileEntitySpecialRenderer return this.field_76908_a; } - public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) + @Override + public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) { if (properties.DoorRenderingEnabled) { -- 2.39.5 From 2c7435585d08147a806ca5c3307eaf8b0e775c17 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Fri, 11 Jul 2014 15:44:01 -0400 Subject: [PATCH 12/12] Minor Changes Removed a pointless check in yCoordHelper and corrected some comments in RiftRegenerator. It turns out that ChunkProviderServer.chunkExists() returns whether a chunk is loaded, not whether it has already been created. --- .../StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java | 5 +---- .../mod_pocketDim/ticking/RiftRegenerator.java | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java index 3810c8b..26aa178 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/yCoordHelper.java @@ -215,10 +215,7 @@ public class yCoordHelper { for (int dz = -1; dz <= 1; dz++) { - if (!provider.chunkExists(chunkX + dx, chunkZ + dz)) - { - provider.loadChunk(chunkX, chunkZ); - } + provider.loadChunk(chunkX, chunkZ); } } return target; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java index 66bdd1d..f23c38c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ticking/RiftRegenerator.java @@ -95,8 +95,8 @@ public class RiftRegenerator implements IRegularTickReceiver { return; // The chunk at the given location must be loaded. - // FIXME: I can't figure out how to check if a chunk is loaded. - // Will only check if the chunk exists for now. This isn't a big deal. --SenseiKiwi + // Note: ChunkProviderServer.chunkExists() returns whether a chunk is + // loaded, not whether it has already been created. if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4)) return; -- 2.39.5