diff options
author | Maxim <maxim235@gmx.de> | 2022-08-12 12:54:15 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-12 11:54:15 +0100 |
commit | c2e1697d9a7d4697f8a96bf838cd0c038fce2f01 (patch) | |
tree | dcda7df812829d997cde89af31768edc1b28441e /src | |
parent | b47d63d17819f579bf200247e66774c6b977635c (diff) | |
download | GT5-Unofficial-c2e1697d9a7d4697f8a96bf838cd0c038fce2f01.tar.gz GT5-Unofficial-c2e1697d9a7d4697f8a96bf838cd0c038fce2f01.tar.bz2 GT5-Unofficial-c2e1697d9a7d4697f8a96bf838cd0c038fce2f01.zip |
Chunkloader code rework (#274)
* Remodeled chunkloader code after RC chunkloaders to make them actually work
* Added limit to chunk radius
* Some cleanup
Diffstat (limited to 'src')
4 files changed, 220 insertions, 387 deletions
diff --git a/src/main/java/gtPlusPlus/GTplusplus.java b/src/main/java/gtPlusPlus/GTplusplus.java index e824d14f5b..48f8139c12 100644 --- a/src/main/java/gtPlusPlus/GTplusplus.java +++ b/src/main/java/gtPlusPlus/GTplusplus.java @@ -257,9 +257,6 @@ public class GTplusplus implements ActionListener { if (LoadedMods.Thaumcraft) { event.registerServerCommand(new CommandDumpAspects()); } - if (GTPP_ChunkManager.debugChunkloaders) { - event.registerServerCommand(new GTPP_ChunkManager.DebugCommand()); - } Core_Manager.serverStart(); INIT_PHASE.STARTED.setPhaseActive(true); } diff --git a/src/main/java/gtPlusPlus/core/chunkloading/GTPP_ChunkManager.java b/src/main/java/gtPlusPlus/core/chunkloading/GTPP_ChunkManager.java index ddfe9b8227..b403646a2a 100644 --- a/src/main/java/gtPlusPlus/core/chunkloading/GTPP_ChunkManager.java +++ b/src/main/java/gtPlusPlus/core/chunkloading/GTPP_ChunkManager.java @@ -1,34 +1,20 @@ package gtPlusPlus.core.chunkloading; -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 com.google.common.collect.LinkedListMultimap; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_Log; import gtPlusPlus.GTplusplus; -import gtPlusPlus.api.interfaces.IChunkLoader; -import gtPlusPlus.core.lib.CORE; -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 gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; +import net.minecraft.entity.Entity; 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; +import java.util.*; /** * @@ -37,181 +23,82 @@ import java.util.Map; * @author Repo-Alt, Alkalus * */ -public class GTPP_ChunkManager implements ForgeChunkManager.OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { - - - private Map<TileEntity, Ticket> registeredTickets = new HashMap<>(); - - private static GTPP_ChunkManager instance = new GTPP_ChunkManager(); +public class GTPP_ChunkManager implements ForgeChunkManager.LoadingCallback, ForgeChunkManager.OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { + private static GTPP_ChunkManager instance; public static boolean enableChunkloaders = true; public static boolean alwaysReloadChunkloaders = false; public static boolean debugChunkloaders = false; + public static GTPP_ChunkManager getInstance() { + if (instance == null) { + instance = new GTPP_ChunkManager(); + } + return instance; + } + public static void init() { if (enableChunkloaders) { - ForgeChunkManager.setForcedChunkLoadingCallback(GTplusplus.instance, instance); + ForgeChunkManager.setForcedChunkLoadingCallback(GTplusplus.instance, getInstance()); + MinecraftForge.EVENT_BUS.register(getInstance()); } } @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 (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) { + public void ticketsLoaded(List<Ticket> tickets, World world) { + for (Ticket ticket : tickets) { + if (ticket.isPlayerTicket()) + continue; + Entity entity = ticket.getEntity(); + if (entity == null) { + int x = ticket.getModData().getInteger("xCoord"); + int y = ticket.getModData().getInteger("yCoord"); + int z = ticket.getModData().getInteger("zCoord"); + + 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()).getResidingChunk()); - } - validTickets.add(ticket); - } + if (((IGregTechTileEntity)tile).getMetaTileEntity() instanceof GregtechMetaTileEntityChunkLoader) { + ((GregtechMetaTileEntityChunkLoader)((IGregTechTileEntity)tile).getMetaTileEntity()).forceChunkLoading(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 (!enableChunkloaders) { - return false; - } - if (!alwaysReloadChunkloaders && chunkXZ == null) { - return false; - } - if (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 (debugChunkloaders) { - GT_Log.out.println("GT_ChunkManager: ForgeChunkManager.requestTicket failed"); + public List<Ticket> ticketsLoaded(List<Ticket> tickets, World world, int maxTicketCount) { + Set<Ticket> validTickets = new HashSet<>(); + for (Ticket ticket : tickets) { + Entity entity = ticket.getEntity(); + if (entity == null) { + int x = ticket.getModData().getInteger("xCoord"); + int y = ticket.getModData().getInteger("yCoord"); + int z = ticket.getModData().getInteger("zCoord"); + + if (y >= 0) { + TileEntity tile = world.getTileEntity(x, y, z); + if (((IGregTechTileEntity)tile).getMetaTileEntity() instanceof GregtechMetaTileEntityChunkLoader) { + validTickets.add(ticket); + } } - return false; } - if (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 (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 (!enableChunkloaders) { - return; - } - Ticket ticket = instance.registeredTickets.get(owner); - if (ticket != null) { - if (debugChunkloaders) { - GT_Log.out.println("GT_ChunkManager: Chunk release: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); - } - ForgeChunkManager.unforceChunk(ticket, chunkXZ); - } + return new LinkedList<>(validTickets); } - static public void releaseTicket(TileEntity owner) { - if (!enableChunkloaders) { - return; - } - Ticket ticket = instance.registeredTickets.get(owner); - if (ticket != null) { - if (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); - } + @Override + public ListMultimap<String, Ticket> playerTicketsLoaded(ListMultimap<String, Ticket> tickets, World world) { + return LinkedListMultimap.create(); } - public static void printTickets() { - if (!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()); + public static Set<ChunkCoordIntPair> getChunksAround(int xChunk, int zChunk, int radius) { + Set<ChunkCoordIntPair> chunkList = new HashSet<>(); + for (int xx = xChunk - radius; xx <= xChunk + radius; xx++) { + for (int zz = zChunk - radius; zz <= zChunk + radius; zz++) { + chunkList.add(new ChunkCoordIntPair(xx, zz)); } - 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 "gtpp: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(); } + return chunkList; } } diff --git a/src/main/java/gtPlusPlus/core/chunkloading/StaticChunkFunctions.java b/src/main/java/gtPlusPlus/core/chunkloading/StaticChunkFunctions.java deleted file mode 100644 index 36d9fa670c..0000000000 --- a/src/main/java/gtPlusPlus/core/chunkloading/StaticChunkFunctions.java +++ /dev/null @@ -1,63 +0,0 @@ -package gtPlusPlus.core.chunkloading; - -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gtPlusPlus.api.interfaces.IChunkLoader; -import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.ChunkCoordIntPair; - -public class StaticChunkFunctions { - - public static void saveNBTDataForTileEntity(IGregTechTileEntity aBaseMetaTileEntity, NBTTagCompound aNBT) { - IChunkLoader aTileEntity = getChunkLoader(aBaseMetaTileEntity); - aNBT.setBoolean("chunkLoadingEnabled", aTileEntity.getChunkLoadingActive()); - aNBT.setBoolean("isChunkloading", aTileEntity.getResidingChunk() != null); - if (aTileEntity.getResidingChunk() != null) { - aNBT.setInteger("loadedChunkXPos", aTileEntity.getResidingChunk().chunkXPos); - aNBT.setInteger("loadedChunkZPos", aTileEntity.getResidingChunk().chunkZPos); - } - } - - public static void loadNBTDataForTileEntity(IGregTechTileEntity aBaseMetaTileEntity, NBTTagCompound aNBT) { - IChunkLoader aTileEntity = getChunkLoader(aBaseMetaTileEntity); - if (aNBT.hasKey("chunkLoadingEnabled")) { - aTileEntity.setChunkLoadingActive(aNBT.getBoolean("chunkLoadingEnabled")); - } - if (aNBT.getBoolean("isChunkloading")) { - aTileEntity.setResidingChunk(new ChunkCoordIntPair(aNBT.getInteger("loadedChunkXPos"), aNBT.getInteger("loadedChunkZPos"))); - } - } - - public static void onRemoval(IGregTechTileEntity aBaseMetaTileEntity) { - IChunkLoader aTileEntity = getChunkLoader(aBaseMetaTileEntity); - if (aTileEntity.getChunkLoadingActive()) { - GTPP_ChunkManager.releaseTicket((TileEntity)aBaseMetaTileEntity); - } - } - - public static boolean onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - IChunkLoader aTileEntity = getChunkLoader(aBaseMetaTileEntity); - if (aBaseMetaTileEntity.isServerSide() && aTileEntity.getResidingChunk() != null && !aTileEntity.getDoesWorkChunkNeedReload() && !aBaseMetaTileEntity.isAllowedToWork()) { - // if machine has stopped, stop chunkloading - GTPP_ChunkManager.releaseTicket((TileEntity)aBaseMetaTileEntity); - aTileEntity.setDoesWorkChunkNeedReload(true); - return false; - } - return true; - } - - public static void createInitialWorkingChunk(IGregTechTileEntity aBaseMetaTileEntity, int aChunkX, int aDrillZ) { - final int centerX = aChunkX >> 4; - final int centerZ = aDrillZ >> 4; - IChunkLoader aTileEntity = getChunkLoader(aBaseMetaTileEntity); - aTileEntity.addChunkToLoadedList(new ChunkCoordIntPair(centerX, centerZ)); - GTPP_ChunkManager.requestChunkLoad((TileEntity)aBaseMetaTileEntity.getMetaTileEntity(), aTileEntity.getResidingChunk()); - aTileEntity.setDoesWorkChunkNeedReload(false); - } - - private static final IChunkLoader getChunkLoader(IGregTechTileEntity aTile) { - return (IChunkLoader) ((IGregTechTileEntity)aTile).getMetaTileEntity(); - } - -} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/basic/GregtechMetaTileEntityChunkLoader.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/basic/GregtechMetaTileEntityChunkLoader.java index 140f1d9cd5..58bddefc19 100644 --- a/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/basic/GregtechMetaTileEntityChunkLoader.java +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/basic/GregtechMetaTileEntityChunkLoader.java @@ -1,10 +1,14 @@ package gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic; import static gregtech.api.enums.GT_Values.V; +import static net.minecraftforge.common.ForgeChunkManager.getMaxChunkDepthFor; import java.util.HashSet; +import java.util.Map; import java.util.Set; +import java.util.UUID; +import com.google.common.collect.MapMaker; import gregtech.api.enums.Textures; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; @@ -12,38 +16,51 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; import gregtech.api.objects.GT_RenderedTexture; import gregtech.api.util.GT_Utility; -import gtPlusPlus.api.interfaces.IChunkLoader; +import gtPlusPlus.GTplusplus; import gtPlusPlus.core.chunkloading.GTPP_ChunkManager; -import gtPlusPlus.core.chunkloading.StaticChunkFunctions; import gtPlusPlus.core.lib.CORE; import gtPlusPlus.xmod.gregtech.common.blocks.textures.TexturesGtBlock; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.ForgeChunkManager; +import net.minecraftforge.common.ForgeChunkManager.Ticket; -public class GregtechMetaTileEntityChunkLoader extends GT_MetaTileEntity_BasicMachine implements IChunkLoader { +public class GregtechMetaTileEntityChunkLoader extends GT_MetaTileEntity_BasicMachine { public GregtechMetaTileEntityChunkLoader(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, 2, "Loads " + getMaxChunksToLoadForTier(aTier) + " chunks when powered", 0, 0, "Recycler.png", "", new ITexture[]{}); + super(aID, aName, aNameRegional, aTier, 4, "Loads " + getMaxChunksToLoadForTier(aTier) + " chunks when powered", 0, 0, "Recycler.png", "", new ITexture[]{}); } public GregtechMetaTileEntityChunkLoader(String aName, int aTier, String aDescription, ITexture[][][] aTextures, String aGUIName, String aNEIName) { - super(aName, aTier, 2, aDescription, aTextures, 0, 0, aGUIName, aNEIName); + super(aName, aTier, 4, aDescription, aTextures, 0, 0, aGUIName, aNEIName); } public static int getMaxChunksToLoadForTier(int aTier) { if (aTier < 4) { - return 3 * 3; + return Math.min(3 * 3, getMaxChunkDepthFor(CORE.MODID)); } if (aTier < 6) { - return 7 * 7; + return Math.min(7 * 7, getMaxChunkDepthFor(CORE.MODID)); } if (aTier < 8) { - return 15 * 15; + return Math.min(15 * 15, getMaxChunkDepthFor(CORE.MODID)); + } + else { + return 0; + } + } + + public static int getChunkRadiusForTier(int aTier) { + if (aTier < 4) { + return Math.min(1, (int)Math.floor(Math.sqrt(getMaxChunkDepthFor(CORE.MODID)))); + } + if (aTier < 6) { + return Math.min(3, (int)Math.floor(Math.sqrt(getMaxChunkDepthFor(CORE.MODID)))); + } + if (aTier < 8) { + return Math.min(7, (int)Math.floor(Math.sqrt(getMaxChunkDepthFor(CORE.MODID)))); } else { return 0; @@ -144,20 +161,6 @@ public class GregtechMetaTileEntityChunkLoader extends GT_MetaTileEntity_BasicMa } @Override - public boolean onRightclick(final IGregTechTileEntity aBaseMetaTileEntity, final EntityPlayer aPlayer) { - if (aBaseMetaTileEntity.isClientSide()){ - return true; - } - this.showPollution(aPlayer.getEntityWorld(), aPlayer); - return true; - } - - private void showPollution(final World worldIn, final EntityPlayer playerIn){ - //PlayerUtils.messagePlayer(playerIn, "Running every "+mFrequency+" minutes. Owner: "+this.getBaseMetaTileEntity().getOwnerName()); - //PlayerUtils.messagePlayer(playerIn, "Last run: "+Utils.getSecondsFromMillis(aDiff)+" seconds ago."); - } - - @Override public boolean allowPullStack(final IGregTechTileEntity aBaseMetaTileEntity, final int aIndex, final byte aSide, final ItemStack aStack) { return false; } @@ -201,53 +204,35 @@ public class GregtechMetaTileEntityChunkLoader extends GT_MetaTileEntity_BasicMa @Override public void onPostTick(final IGregTechTileEntity aBaseMetaTileEntity, final long aTick) { super.onPostTick(aBaseMetaTileEntity, aTick); - - // Have we set the Chunk this Tile resides in yet? - if (mCurrentChunk == null) { - int xTile = getBaseMetaTileEntity().getXCoord(); - int zTile = getBaseMetaTileEntity().getZCoord(); - createInitialWorkingChunk(aBaseMetaTileEntity, xTile, zTile); - } - - // Try unload all chunks if fail to meet global chunkloading conditions. - if (StaticChunkFunctions.onPostTick(aBaseMetaTileEntity, aTick)) { - // Can this tile actively chunkload? - if (getChunkLoadingActive()) { - // Consume some power - this.setEUVar(this.getEUVar() - (maxEUInput() * maxAmperesIn())); - - // Do we need to re-request tickets? - if (getDoesWorkChunkNeedReload()) { - // Request ticket for current chunk. - GTPP_ChunkManager.requestChunkLoad((TileEntity)getBaseMetaTileEntity(), mCurrentChunk); - // Request a ticket for each chunk we have mapped out in a spiral pattern. - if (!mLoadedChunks.isEmpty()) { - for (ChunkCoordIntPair Y : mLoadedChunks) { - GTPP_ChunkManager.requestChunkLoad((TileEntity)getBaseMetaTileEntity(), Y); - } - } - setDoesWorkChunkNeedReload(false); - } - + + if (aBaseMetaTileEntity.isServerSide()) { + if (aBaseMetaTileEntity.getXCoord() != prevX || aBaseMetaTileEntity.getYCoord() != prevY || aBaseMetaTileEntity.getZCoord() != prevZ) { + releaseTicket(); + prevX = aBaseMetaTileEntity.getXCoord(); + prevY = aBaseMetaTileEntity.getYCoord(); + prevZ = aBaseMetaTileEntity.getZCoord(); } - } - } - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - StaticChunkFunctions.saveNBTDataForTileEntity(this.getBaseMetaTileEntity(), aNBT); - } + if (hasActiveTicket() && (getTicket().world != aBaseMetaTileEntity.getWorld() || refreshTicket || !aBaseMetaTileEntity.isAllowedToWork())) { + releaseTicket(); + } - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - StaticChunkFunctions.loadNBTDataForTileEntity(this.getBaseMetaTileEntity(), aNBT); + if (++updateCycle % updateCycleLength == 0) { + updateCycle = 0; + if (canChunkload()) { + setEUVar(getEUVar() - getEnergyConsumption()); + } + } + + if (!hasActiveTicket()) { + requestTicket(); + } + } } @Override public long maxAmperesIn() { - return 2; + return 4; } @Override @@ -265,130 +250,157 @@ public class GregtechMetaTileEntityChunkLoader extends GT_MetaTileEntity_BasicMa return V[mTier]; } - - /* - * Chunkloading Vars - */ - - private long mTicksRemainingForChunkloading = -1; - private ChunkCoordIntPair mCurrentChunk; - private Set<ChunkCoordIntPair> mLoadedChunks = new HashSet<ChunkCoordIntPair>(); - private boolean mRefreshChunkTickets = false; - @Override - public long getTicksRemaining() { - return -1; + public void onRemoval() { + super.onRemoval(); + releaseTicket(); } - @Override - public void setTicksRemaining(long aTicks) { - mTicksRemainingForChunkloading = aTicks; + public long getEnergyConsumption() { + return V[mTier] * 2 * updateCycleLength; } @Override - public ChunkCoordIntPair getResidingChunk() { - return mCurrentChunk; - } + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); - @Override - public void setResidingChunk(ChunkCoordIntPair aCurrentChunk) { - mCurrentChunk = aCurrentChunk; - } + prevX = aNBT.getInteger("prevX"); + prevY = aNBT.getInteger("prevY"); + prevZ = aNBT.getInteger("prevZ"); - @Override - public boolean getChunkLoadingActive() { - return this.getEUVar() >= maxEUInput() * maxAmperesIn(); + NBTTagCompound uuidNBT = aNBT.getCompoundTag("uuid"); + uuid = new UUID(uuidNBT.getLong("most"), uuidNBT.getLong("least")); } @Override - public void setChunkLoadingActive(boolean aActive) { - - } + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); - @Override - public boolean getDoesWorkChunkNeedReload() { - return mRefreshChunkTickets; + aNBT.setInteger("prevX", prevX); + aNBT.setInteger("prevY", prevY); + aNBT.setInteger("prevZ", prevZ); + + if (uuid != null) { + NBTTagCompound uuidNBT = new NBTTagCompound(); + uuidNBT.setLong("most", uuid.getMostSignificantBits()); + uuidNBT.setLong("least", uuid.getLeastSignificantBits()); + aNBT.setTag("uuid", uuidNBT); + } } - @Override - public void setDoesWorkChunkNeedReload(boolean aActive) { - mRefreshChunkTickets = aActive; + public boolean canChunkload() { + return getBaseMetaTileEntity().isAllowedToWork() && getEUVar() >= getEnergyConsumption(); } + + /* + * Chunkloading Vars + */ + + private Set<ChunkCoordIntPair> mLoadedChunks = new HashSet<>(); + private static final Map<UUID, Ticket> tickets = new MapMaker().makeMap(); + private boolean refreshTicket; + private int updateCycle = 0; + private static final int updateCycleLength = 20; + private UUID uuid; + private int prevX, prevY, prevZ; + private boolean hasTicket; - @Override public boolean addChunkToLoadedList(ChunkCoordIntPair aActiveChunk) { return mLoadedChunks.add(aActiveChunk); } - @Override public boolean removeChunkFromLoadedList(ChunkCoordIntPair aActiveChunk) { return mLoadedChunks.remove(aActiveChunk); } - @Override public Set<ChunkCoordIntPair> getManagedChunks() { return mLoadedChunks; } - @Override - public void onRemoval() { - StaticChunkFunctions.onRemoval(getBaseMetaTileEntity()); - super.onRemoval(); + public int getChunkloaderTier() { + return mTier; } - - public static Set<ChunkCoordIntPair> spiralChunks(final IGregTechTileEntity aBaseMetaTileEntity, int X, int Z) { - World w = aBaseMetaTileEntity.getWorld(); - HashSet<ChunkCoordIntPair> aSet = new HashSet<ChunkCoordIntPair>(); - if (w == null) { - return aSet; + + public void forceChunkLoading(Ticket ticket) { + setTicket(ticket); + setupChunks(); + + if (mLoadedChunks != null) { + for (ChunkCoordIntPair chunk : mLoadedChunks) { + ForgeChunkManager.forceChunk(ticket, chunk); + } } - Chunk thisChunk = w.getChunkFromBlockCoords(aBaseMetaTileEntity.getXCoord(), aBaseMetaTileEntity.getZCoord()); - ChunkCoordIntPair aChunkCo = new ChunkCoordIntPair(thisChunk.xPosition, thisChunk.zPosition); - int x,z,dx,dz; - x = z = dx =0; - dz = -1; - int t = Math.max(X,Z); - int maxI = t*t; - for(int i =0; i < maxI; i++){ - if ((-X/2 <= x) && (x <= X/2) && (-Z/2 <= z) && (z <= Z/2)){ - Chunk C = w.getChunkFromChunkCoords(aChunkCo.chunkXPos + x, aChunkCo.chunkZPos + z); - if (C != null) { - aSet.add(new ChunkCoordIntPair(C.xPosition, C.zPosition)); - } - } - if( (x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1-z))){ - t = dx; - dx = -dz; - dz = t; - } - x += dx; - z += dz; - } - return aSet; } - @Override - public int getChunkloaderTier() { - return mTier; + public void setupChunks() { + if (!hasTicket) { + mLoadedChunks = null; + } else { + mLoadedChunks = GTPP_ChunkManager.getChunksAround(getBaseMetaTileEntity().getXCoord() >> 4, getBaseMetaTileEntity().getZCoord() >> 4, getChunkRadiusForTier(mTier)); + } } - - public void createInitialWorkingChunk(IGregTechTileEntity aBaseMetaTileEntity, int aTileX, int aTileZ) { - final int centerX = aTileX >> 4; - final int centerZ = aTileZ >> 4; - addChunkToLoadedList(new ChunkCoordIntPair(centerX, centerZ)); - GTPP_ChunkManager.requestChunkLoad((TileEntity)aBaseMetaTileEntity.getMetaTileEntity(), getResidingChunk()); - // If this surrounding chunk map for this tile is empty, we spiral out and map chunks to keep loaded. - if (getManagedChunks().isEmpty()) { - int aChunks = GregtechMetaTileEntityChunkLoader.getMaxChunksToLoadForTier(getChunkloaderTier()); - mLoadedChunks.addAll(spiralChunks(aBaseMetaTileEntity, getChunkloaderTier(), getChunkloaderTier())); - } - if (!mLoadedChunks.isEmpty()) { - for (ChunkCoordIntPair Y : mLoadedChunks) { - GTPP_ChunkManager.requestChunkLoad((TileEntity)aBaseMetaTileEntity.getMetaTileEntity(), Y); - } - } - setDoesWorkChunkNeedReload(false); + + protected Ticket getTicketFromForge() { + return ForgeChunkManager.requestTicket(GTplusplus.instance, getBaseMetaTileEntity().getWorld(), ForgeChunkManager.Type.NORMAL); + } + + public boolean hasActiveTicket() { + return getTicket() != null; + } + + protected void releaseTicket() { + refreshTicket = false; + setTicket(null); + } + + protected void requestTicket() { + if (canChunkload()) { + Ticket chunkTicket = getTicketFromForge(); + if (chunkTicket != null) { + setTicketData(chunkTicket); + forceChunkLoading(chunkTicket); + } + } } - + protected void setTicketData(Ticket chunkTicket) { + if (chunkTicket != null) { + chunkTicket.getModData().setInteger("xCoord", getBaseMetaTileEntity().getXCoord()); + chunkTicket.getModData().setInteger("yCoord", getBaseMetaTileEntity().getYCoord()); + chunkTicket.getModData().setInteger("zCoord", getBaseMetaTileEntity().getZCoord()); + chunkTicket.setChunkListDepth(getMaxChunksToLoadForTier(mTier)); + } + } + + public void setTicket(Ticket t) { + Ticket ticket = getTicket(); + if (ticket != t) { + if (ticket != null) { + if (ticket.world == getBaseMetaTileEntity().getWorld()) { + for (ChunkCoordIntPair chunk : ticket.getChunkList()) { + if (ForgeChunkManager.getPersistentChunksFor(getBaseMetaTileEntity().getWorld()).keys().contains(chunk)) { + ForgeChunkManager.unforceChunk(ticket, chunk); + } + } + ForgeChunkManager.releaseTicket(ticket); + } + tickets.remove(getUUID()); + } + } + hasTicket = t != null; + if (hasTicket) { + tickets.put(getUUID(), t); + } + } + + public Ticket getTicket() { + return tickets.get(getUUID()); + } + + public UUID getUUID() { + if (uuid == null) { + uuid = UUID.randomUUID(); + } + return uuid; + } }
\ No newline at end of file |