package codechicken.lib.world; import net.minecraft.client.Minecraft; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.EmptyChunk; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.ChunkDataEvent; import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.ChunkWatchEvent.UnWatch; import net.minecraftforge.event.world.ChunkWatchEvent.Watch; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.ArrayList; import java.util.HashMap; public class WorldExtensionManager { public static class WorldExtensionEventHandler { @SubscribeEvent public void onChunkDataLoad(ChunkDataEvent.Load event) { if (!worldMap.containsKey(event.world)) { WorldExtensionManager.onWorldLoad(event.world); } createChunkExtension(event.world, event.getChunk()); for (WorldExtension extension : worldMap.get(event.world)) { extension.loadChunkData(event.getChunk(), event.getData()); } } @SubscribeEvent public void onChunkDataSave(ChunkDataEvent.Save event) { for (WorldExtension extension : worldMap.get(event.world)) { extension.saveChunkData(event.getChunk(), event.getData()); } if (!event.getChunk().isChunkLoaded) { removeChunk(event.world, event.getChunk()); } } @SubscribeEvent public void onChunkLoad(ChunkEvent.Load event) { if (!worldMap.containsKey(event.world)) { WorldExtensionManager.onWorldLoad(event.world); } createChunkExtension(event.world, event.getChunk()); for (WorldExtension extension : worldMap.get(event.world)) { extension.loadChunk(event.getChunk()); } } @SubscribeEvent public void onChunkUnLoad(ChunkEvent.Unload event) { if (event.getChunk() instanceof EmptyChunk) { return; } for (WorldExtension extension : worldMap.get(event.world)) { extension.unloadChunk(event.getChunk()); } if (event.world.isRemote) { removeChunk(event.world, event.getChunk()); } } @SubscribeEvent public void onWorldSave(WorldEvent.Save event) { if (worldMap.containsKey(event.world)) { for (WorldExtension extension : worldMap.get(event.world)) { extension.save(); } } } @SubscribeEvent public void onWorldLoad(WorldEvent.Load event) { if (!worldMap.containsKey(event.world)) { WorldExtensionManager.onWorldLoad(event.world); } } @SubscribeEvent public void onWorldUnLoad(WorldEvent.Unload event) { if (worldMap.containsKey(event.world))//because force closing unloads a world twice { for (WorldExtension extension : worldMap.remove(event.world)) { extension.unload(); } } } @SubscribeEvent public void onChunkWatch(Watch event) { Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos); for (WorldExtension extension : worldMap.get(event.player.worldObj)) { extension.watchChunk(chunk, event.player); } } @SubscribeEvent @SideOnly(Side.CLIENT) public void onChunkUnWatch(UnWatch event) { Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos); for (WorldExtension extension : worldMap.get(event.player.worldObj)) { extension.unwatchChunk(chunk, event.player); } } @SubscribeEvent @SideOnly(Side.CLIENT) public void clientTick(TickEvent.ClientTickEvent event) { World world = Minecraft.getMinecraft().theWorld; if (worldMap.containsKey(world)) { if (event.phase == TickEvent.Phase.START) { preTick(world); } else { postTick(world); } } } @SubscribeEvent public void serverTick(TickEvent.WorldTickEvent event) { if (!worldMap.containsKey(event.world)) { WorldExtensionManager.onWorldLoad(event.world); } if (event.phase == TickEvent.Phase.START) { preTick(event.world); } else { postTick(event.world); } } } private static boolean initialised; private static ArrayList<WorldExtensionInstantiator> extensionIntialisers = new ArrayList<WorldExtensionInstantiator>(); public static void registerWorldExtension(WorldExtensionInstantiator init) { if (!initialised) { init(); } init.instantiatorID = extensionIntialisers.size(); extensionIntialisers.add(init); } private static void init() { initialised = true; MinecraftForge.EVENT_BUS.register(new WorldExtensionEventHandler()); //FMLCommonHandler.instance().bus().register(new WorldExtensionEventHandler()); } private static HashMap<World, WorldExtension[]> worldMap = new HashMap<World, WorldExtension[]>(); private static void onWorldLoad(World world) { WorldExtension[] extensions = new WorldExtension[extensionIntialisers.size()]; for (int i = 0; i < extensions.length; i++) { extensions[i] = extensionIntialisers.get(i).createWorldExtension(world); } worldMap.put(world, extensions); for (WorldExtension extension : extensions) { extension.load(); } } private static void createChunkExtension(World world, Chunk chunk) { WorldExtension[] extensions = worldMap.get(world); for (int i = 0; i < extensionIntialisers.size(); i++) { if (!extensions[i].containsChunk(chunk)) { extensions[i].addChunk(extensionIntialisers.get(i).createChunkExtension(chunk, extensions[i])); } } } private static void removeChunk(World world, Chunk chunk) { for (WorldExtension extension : worldMap.get(world)) { extension.remChunk(chunk); } } private static void preTick(World world) { for (WorldExtension extension : worldMap.get(world)) { extension.preTick(); } } private static void postTick(World world) { for (WorldExtension extension : worldMap.get(world)) { extension.postTick(); } } public static WorldExtension getWorldExtension(World world, int instantiatorID) { return worldMap.get(world)[instantiatorID]; } }