diff options
author | repo-alt <wvk17@yandex.ru> | 2019-12-28 21:38:45 +0300 |
---|---|---|
committer | bartimaeusnek <33183715+bartimaeusnek@users.noreply.github.com> | 2019-12-28 19:38:45 +0100 |
commit | 317804772b74bbecffc2f92120768d1c768a9abf (patch) | |
tree | b1f5611f4fc5a387e79ed897cb0c282fa8c056be /src/main/java/gregtech/api/objects | |
parent | e94ffcf40114574062d4d7223c7f6f7933034ec5 (diff) | |
download | GT5-Unofficial-317804772b74bbecffc2f92120768d1c768a9abf.tar.gz GT5-Unofficial-317804772b74bbecffc2f92120768d1c768a9abf.tar.bz2 GT5-Unofficial-317804772b74bbecffc2f92120768d1c768a9abf.zip |
Chunkloading support for multiblock miner (#227)
* WIP, doesn't do anything yet, up to RFC
* Initial attempt at Chunk manager
* Added chunkloading support to multiblock miner.
* moved basic miner-independent chunkloading-related stuff up tier, to be more reusable
Co-authored-by: Richard Hendricks <richardhendricks@pobox.com>
Diffstat (limited to 'src/main/java/gregtech/api/objects')
-rw-r--r-- | src/main/java/gregtech/api/objects/GT_ChunkManager.java | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/objects/GT_ChunkManager.java b/src/main/java/gregtech/api/objects/GT_ChunkManager.java new file mode 100644 index 0000000000..1ec8134777 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GT_ChunkManager.java @@ -0,0 +1,184 @@ +package gregtech.api.objects; + +import com.google.common.collect.HashMultimap; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gregtech.GT_Mod; +import gregtech.api.enums.GT_Values; +import gregtech.api.interfaces.IChunkLoader; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.GT_Log; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeChunkManager; +import net.minecraftforge.common.ForgeChunkManager.Ticket; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.WorldEvent; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +// This class handles re-initializing chunks after a server restart +public class GT_ChunkManager implements ForgeChunkManager.OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { + private Map<TileEntity, Ticket> registeredTickets = new HashMap<>(); + public static GT_ChunkManager instance = new GT_ChunkManager(); + + public static void init() { + ForgeChunkManager.setForcedChunkLoadingCallback(GT_Mod.instance, instance); + //MinecraftForge.EVENT_BUS.register(instance); + } + + @Override + public void ticketsLoaded(List<Ticket> tickets, World world) {} + + // Determine if tickets should be kept. Based on if the ticket is a machine or working chunk ticket. Working chunk tickets are tossed + // and re-created when the machine re-activates. Machine tickets are kept only if the config alwaysReloadChunkloaders is true. Otherwise + // machine chunks are tossed and re-created only when the machine re-activates, similar to a Passive Anchor. + @Override + public List<Ticket> ticketsLoaded(List<Ticket> tickets, World world, int maxTicketCount) { + List<Ticket> validTickets = new ArrayList<>(); + if (GT_Values.alwaysReloadChunkloaders) { + for (Ticket ticket : tickets) { + int x = ticket.getModData().getInteger("OwnerX"); + int y = ticket.getModData().getInteger("OwnerY"); + int z = ticket.getModData().getInteger("OwnerZ"); + if (y > 0) { + TileEntity tile = world.getTileEntity(x, y, z); + if (tile != null && tile instanceof IGregTechTileEntity && ((IGregTechTileEntity)tile).isAllowedToWork()) { + ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(x >> 4, z >> 4)); + if (!registeredTickets.containsKey(tile)) { + registeredTickets.put(tile, ticket); + if (((IGregTechTileEntity)tile).getMetaTileEntity() instanceof IChunkLoader) + ForgeChunkManager.forceChunk(ticket, ((IChunkLoader)((IGregTechTileEntity)tile).getMetaTileEntity()).getActiveChunk()); + validTickets.add(ticket); + } + } + } + } + } + return validTickets ; + } + + // Determine if player tickets should be kept. This is where a ticket list per player would be created and maintained. When + // a player join event occurs, their name/UUID/whatevs is compared against tickets on this list and those tickets reactivated. + // Since that info would be maintained/dealt with on a per-player startup, the list returned back to Forge is empty. + @Override + public ListMultimap<String, Ticket> playerTicketsLoaded(ListMultimap<String, Ticket> tickets, World world) { + // Not currently used, so just return an empty list. + return ArrayListMultimap.create(); + } + + // Request a chunk to be loaded for this machine + // may pass null chunk to load just the machine itself, if "alwaysReloadChunkloaders" is enabled in config + static public boolean requestPlayerChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ, String player) { + if (!GT_Values.enableChunkloaders) + return false; + if (!GT_Values.alwaysReloadChunkloaders && chunkXZ == null) + return false; + if (GT_Values.debugChunkloaders && chunkXZ != null) + GT_Log.out.println("GT_ChunkManager: Chunk request: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); + if (instance.registeredTickets.containsKey(owner)) { + ForgeChunkManager.forceChunk(instance.registeredTickets.get(owner), chunkXZ); + } else { + Ticket ticket = null; + if (player != "") + ticket = ForgeChunkManager.requestPlayerTicket(GT_Mod.instance, player, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL); + else + ticket = ForgeChunkManager.requestTicket(GT_Mod.instance, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL); + if (ticket == null) { + if (GT_Values.debugChunkloaders) + GT_Log.out.println("GT_ChunkManager: ForgeChunkManager.requestTicket failed"); + return false; + } + if (GT_Values.debugChunkloaders) + GT_Log.out.println("GT_ChunkManager: ticket issued for machine at: (" + owner.xCoord + ", " + owner.yCoord + ", " + owner.zCoord + ")" ); + NBTTagCompound tag = ticket.getModData(); + tag.setInteger("OwnerX", owner.xCoord); + tag.setInteger("OwnerY", owner.yCoord); + tag.setInteger("OwnerZ", owner.zCoord); + ForgeChunkManager.forceChunk(ticket, chunkXZ); + if (GT_Values.alwaysReloadChunkloaders) + ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(owner.xCoord << 4, owner.zCoord << 4)); + instance.registeredTickets.put(owner, ticket); + } + return true; + } + + static public boolean requestChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ) { + return requestPlayerChunkLoad(owner, chunkXZ, ""); + } + + static public void releaseChunk(TileEntity owner, ChunkCoordIntPair chunkXZ) { + if (!GT_Values.enableChunkloaders) + return; + Ticket ticket = instance.registeredTickets.get(owner); + if (ticket != null) { + if (GT_Values.debugChunkloaders) + GT_Log.out.println("GT_ChunkManager: Chunk release: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); + ForgeChunkManager.unforceChunk(ticket, chunkXZ); + } + } + + static public void releaseTicket(TileEntity owner) { + if (!GT_Values.enableChunkloaders) + return; + Ticket ticket = instance.registeredTickets.get(owner); + if (ticket != null) { + if (GT_Values.debugChunkloaders) { + GT_Log.out.println("GT_ChunkManager: ticket released by machine at: (" + owner.xCoord + ", " + owner.yCoord + ", " + owner.zCoord + ")" ); + for (ChunkCoordIntPair chunk : ticket.getChunkList()) + GT_Log.out.println("GT_ChunkManager: Chunk release: (" + chunk.chunkXPos + ", " + chunk.chunkZPos + ")"); + } + ForgeChunkManager.releaseTicket(ticket); + instance.registeredTickets.remove(owner); + } + } + + public static void printTickets() { + if (!GT_Values.debugChunkloaders) + return; + GT_Log.out.println("GT_ChunkManager: Start forced chunks dump:"); + instance.registeredTickets.forEach((machine, ticket) -> { + GT_Log.out.print("GT_ChunkManager: Chunks forced by the machine at (" + machine.xCoord + ", " + machine.yCoord + ", " + machine.zCoord + ")"); + if (ticket.isPlayerTicket()) + GT_Log.out.print(" Owner: " + ticket.getPlayerName()); + GT_Log.out.print(" :"); + for (ChunkCoordIntPair c : ticket.getChunkList()) { + GT_Log.out.print("("); + GT_Log.out.print(c.chunkXPos); + GT_Log.out.print(", "); + GT_Log.out.print(c.chunkZPos); + GT_Log.out.print("), "); + } + }); + GT_Log.out.println("GT_ChunkManager: End forced chunks dump:"); + } + public static class DebugCommand extends CommandBase { + @Override + public String getCommandName() { + return "gt5u:dump_chunks"; + } + @Override + public int getRequiredPermissionLevel() { + return 0; + } + @Override + public String getCommandUsage(ICommandSender sender) { + return "/" + getCommandName(); + } + @Override + public void processCommand(ICommandSender sender, String[] args) { + printTickets(); + } + } +} |