aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech
diff options
context:
space:
mode:
authorrepo-alt <wvk17@yandex.ru>2019-12-28 21:38:45 +0300
committerbartimaeusnek <33183715+bartimaeusnek@users.noreply.github.com>2019-12-28 19:38:45 +0100
commit317804772b74bbecffc2f92120768d1c768a9abf (patch)
treeb1f5611f4fc5a387e79ed897cb0c282fa8c056be /src/main/java/gregtech
parente94ffcf40114574062d4d7223c7f6f7933034ec5 (diff)
downloadGT5-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')
-rw-r--r--src/main/java/gregtech/GT_Mod.java6
-rw-r--r--src/main/java/gregtech/api/enums/GT_Values.java11
-rw-r--r--src/main/java/gregtech/api/interfaces/IChunkLoader.java9
-rw-r--r--src/main/java/gregtech/api/objects/GT_ChunkManager.java184
-rw-r--r--src/main/java/gregtech/common/GT_Proxy.java6
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java49
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java3
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OreDrillingPlantBase.java123
8 files changed, 373 insertions, 18 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java
index deaf40027f..d121e75d07 100644
--- a/src/main/java/gregtech/GT_Mod.java
+++ b/src/main/java/gregtech/GT_Mod.java
@@ -10,6 +10,7 @@ import gregtech.api.enchants.Enchantment_EnderDamage;
import gregtech.api.enchants.Enchantment_Radioactivity;
import gregtech.api.enums.*;
import gregtech.api.interfaces.internal.IGT_Mod;
+import gregtech.api.objects.GT_ChunkManager;
import gregtech.api.objects.ItemData;
import gregtech.api.objects.XSTR;
import gregtech.api.util.*;
@@ -269,6 +270,9 @@ public class GT_Mod implements IGT_Mod {
//GT_Values.oreveinMaxSize = tMainConfig.get(aTextGeneral, "oreveinMaxSize_64",64).getInt(64);
GT_Values.ticksBetweenSounds = tMainConfig.get("machines", "TicksBetweenSounds", 30).getInt(30);
GT_Values.cleanroomGlass= (float) tMainConfig.get("machines","ReinforcedGlassPercentageForCleanroom",5D).getDouble(5D);
+ GT_Values.enableChunkloaders = tMainConfig.get("machines", "enableChunkloaders", true).getBoolean(true);
+ GT_Values.alwaysReloadChunkloaders = tMainConfig.get("machines", "alwaysReloadChunkloaders", false).getBoolean(false);
+ GT_Values.debugChunkloaders = tMainConfig.get("machines", "debugChunkloaders", false).getBoolean(false);
GregTech_API.TICKS_FOR_LAG_AVERAGING = tMainConfig.get(aTextGeneral, "TicksForLagAveragingWithScanner", 25).getInt(25);
GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING = tMainConfig.get(aTextGeneral, "MillisecondsPassedInGTTileEntityUntilLagWarning", 100).getInt(100);
@@ -1177,6 +1181,8 @@ public class GT_Mod implements IGT_Mod {
tRunnable.run();
}
} catch (Throwable e) {e.printStackTrace(GT_Log.err);}
+ if (GT_Values.debugChunkloaders)
+ aEvent.registerServerCommand(new GT_ChunkManager.DebugCommand());
}
@Mod.EventHandler
diff --git a/src/main/java/gregtech/api/enums/GT_Values.java b/src/main/java/gregtech/api/enums/GT_Values.java
index c89d447d66..43c93450ab 100644
--- a/src/main/java/gregtech/api/enums/GT_Values.java
+++ b/src/main/java/gregtech/api/enums/GT_Values.java
@@ -183,9 +183,18 @@ public class GT_Values {
* This will prevent NEI from crashing but spams the Log.
*/
public static boolean allow_broken_recipemap = false;
-
/**
* This will set the percentage how much ReinforcedGlass is Allowed in Cleanroom Walls.
*/
public static float cleanroomGlass = 5.0f;
+ /**
+ * This will let machines such as drills and pumps chunkload their work area.
+ */
+ public static boolean enableChunkloaders = true;
+ /**
+ * This will make all chunkloading machines act as World Anchors (true) or Passive Anchors (false)
+ */
+ public static boolean alwaysReloadChunkloaders = false;
+
+ public static boolean debugChunkloaders = false;
}
diff --git a/src/main/java/gregtech/api/interfaces/IChunkLoader.java b/src/main/java/gregtech/api/interfaces/IChunkLoader.java
new file mode 100644
index 0000000000..adba5e721e
--- /dev/null
+++ b/src/main/java/gregtech/api/interfaces/IChunkLoader.java
@@ -0,0 +1,9 @@
+package gregtech.api.interfaces;
+
+import net.minecraft.world.ChunkCoordIntPair;
+
+// This interface is implemented by the machines that actively load a working chunk
+public interface IChunkLoader {
+ // return a working chunk coordinates, may be null
+ ChunkCoordIntPair getActiveChunk();
+}
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();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/GT_Proxy.java b/src/main/java/gregtech/common/GT_Proxy.java
index 20fec0b8c5..6ac8264dee 100644
--- a/src/main/java/gregtech/common/GT_Proxy.java
+++ b/src/main/java/gregtech/common/GT_Proxy.java
@@ -9,6 +9,7 @@ import cpw.mods.fml.common.network.IGuiHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import forestry.api.genetics.AlleleManager;
+import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.enums.*;
import gregtech.api.enums.TC_Aspects.TC_AspectStack;
@@ -25,6 +26,7 @@ import gregtech.api.objects.GT_Fluid;
import gregtech.api.objects.GT_FluidStack;
import gregtech.api.objects.GT_UO_DimensionList;
import gregtech.api.objects.ItemData;
+import gregtech.api.objects.GT_ChunkManager;
import gregtech.api.util.*;
import gregtech.common.entities.GT_Entity_Arrow;
import gregtech.common.gui.GT_ContainerVolumetricFlask;
@@ -60,6 +62,7 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldSettings.GameType;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.EnderTeleportEvent;
@@ -499,6 +502,9 @@ public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler {
RecipeSorter.register("gregtech:shaped", GT_Shaped_Recipe.class, RecipeSorter.Category.SHAPED, "after:minecraft:shaped before:minecraft:shapeless");
RecipeSorter.register("gregtech:shapeless", GT_Shapeless_Recipe.class, RecipeSorter.Category.SHAPELESS, "after:minecraft:shapeless");
+
+ // Register chunk manager with Forge
+ GT_ChunkManager.init();
}
public void onLoad() {
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java
index 52ec86e2cc..4a8bddbd39 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java
@@ -11,13 +11,17 @@ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_DataAccess;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
+import gregtech.api.objects.GT_ChunkManager;
import gregtech.api.objects.GT_RenderedTexture;
import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_Utility;
import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.ChunkCoordIntPair;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.ForgeDirection;
@@ -43,6 +47,10 @@ public abstract class GT_MetaTileEntity_DrillerBase extends GT_MetaTileEntity_Mu
protected int workState;
protected static final int STATE_DOWNWARD = 0, STATE_AT_BOTTOM = 1, STATE_UPWARD = 2;
+ protected boolean mChunkLoadingEnabled = true;
+ protected ChunkCoordIntPair mCurrentChunk = null;
+ protected boolean mWorkChunkNeedsReload = true;
+
public GT_MetaTileEntity_DrillerBase(int aID, String aName, String aNameRegional) {
super(aID, aName, aNameRegional);
initFields();
@@ -72,13 +80,51 @@ public abstract class GT_MetaTileEntity_DrillerBase extends GT_MetaTileEntity_Mu
public void saveNBTData(NBTTagCompound aNBT) {
super.saveNBTData(aNBT);
aNBT.setInteger("workState", workState);
+ aNBT.setBoolean("chunkLoadingEnabled", mChunkLoadingEnabled);
+ aNBT.setBoolean("isChunkloading", mCurrentChunk != null);
+ if (mCurrentChunk != null) {
+ aNBT.setInteger("loadedChunkXPos", mCurrentChunk.chunkXPos);
+ aNBT.setInteger("loadedChunkZPos", mCurrentChunk.chunkZPos);
+ }
}
@Override
public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT);
workState = aNBT.getInteger("workState");
- if (aNBT.hasKey("isPickingPipes")) workState = aNBT.getBoolean("isPickingPipes") ? STATE_UPWARD : STATE_DOWNWARD;
+ if (aNBT.hasKey("isPickingPipes"))
+ workState = aNBT.getBoolean("isPickingPipes") ? STATE_UPWARD : STATE_DOWNWARD;
+ if (aNBT.hasKey("chunkLoadingEnabled"))
+ mChunkLoadingEnabled = aNBT.getBoolean("chunkLoadingEnabled");
+ if (aNBT.getBoolean("isChunkloading")) {
+ mCurrentChunk = new ChunkCoordIntPair(aNBT.getInteger("loadedChunkXPos"), aNBT.getInteger("loadedChunkZPos"));
+ }
+ }
+
+ @Override
+ public boolean onSolderingToolRightClick(byte aSide, byte aWrenchingSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (aSide == getBaseMetaTileEntity().getFrontFacing()) {
+ mChunkLoadingEnabled = !mChunkLoadingEnabled;
+ GT_Utility.sendChatToPlayer(aPlayer, mChunkLoadingEnabled ? trans("502", "Mining chunk loading enabled") : trans("503", "Mining chunk loading disabled"));
+ }
+ return super.onSolderingToolRightClick(aSide, aWrenchingSide, aPlayer, aX, aY, aZ);
+ }
+
+ @Override
+ public void onRemoval() {
+ if (mChunkLoadingEnabled)
+ GT_ChunkManager.releaseTicket((TileEntity)getBaseMetaTileEntity());
+ super.onRemoval();
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
+ super.onPostTick(aBaseMetaTileEntity, aTick);
+ if (aBaseMetaTileEntity.isServerSide() && mCurrentChunk != null && !mWorkChunkNeedsReload && !aBaseMetaTileEntity.isAllowedToWork()) {
+ // if machine has stopped, stop chunkloading
+ GT_ChunkManager.releaseTicket((TileEntity)aBaseMetaTileEntity);
+ mWorkChunkNeedsReload = true;
+ }
}
protected boolean tryPickPipe() {
@@ -413,5 +459,4 @@ public abstract class GT_MetaTileEntity_DrillerBase extends GT_MetaTileEntity_Mu
}
return false;
}
-
}
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java
index 109bcf91c3..9f3e03b99c 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java
@@ -47,7 +47,8 @@ public abstract class GT_MetaTileEntity_OilDrillBase extends GT_MetaTileEntity_D
public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT);
mOilId = aNBT.getInteger("mOilId");
- chunkRangeConfig = aNBT.getInteger("chunkRangeConfig");
+ if (aNBT.hasKey("chunkRangeConfig"))
+ chunkRangeConfig = aNBT.getInteger("chunkRangeConfig");
}
protected String[] getDescriptionInternal(String tierSuffix) {
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OreDrillingPlantBase.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OreDrillingPlantBase.java
index c7255e0e74..5a384f66ed 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OreDrillingPlantBase.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OreDrillingPlantBase.java
@@ -4,7 +4,9 @@ import gregtech.api.enums.ItemList;
import gregtech.api.enums.Materials;
import gregtech.api.enums.OrePrefixes;
import gregtech.api.gui.GT_GUIContainer_MultiMachine;
+import gregtech.api.interfaces.IChunkLoader;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.objects.GT_ChunkManager;
import gregtech.api.objects.ItemData;
import gregtech.api.util.GT_OreDictUnificator;
import gregtech.api.util.GT_Recipe;
@@ -18,6 +20,7 @@ import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.ChunkPosition;
import net.minecraftforge.fluids.FluidStack;
@@ -28,11 +31,9 @@ import java.util.HashSet;
import static gregtech.api.enums.GT_Values.VN;
-public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTileEntity_DrillerBase {
-
+public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTileEntity_DrillerBase implements IChunkLoader {
private final ArrayList<ChunkPosition> oreBlockPositions = new ArrayList<>();
- protected int mTier=1;
-
+ protected int mTier = 1;
private int chunkRadiusConfig = getRadiusInChunks();
GT_MetaTileEntity_OreDrillingPlantBase(int aID, String aName, String aNameRegional) {
@@ -52,10 +53,14 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
@Override
public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT);
- chunkRadiusConfig = aNBT.getInteger("chunkRadiusConfig");
+ if (aNBT.hasKey("chunkRadiusConfig"))
+ chunkRadiusConfig = aNBT.getInteger("chunkRadiusConfig");
}
@Override
+ public ChunkCoordIntPair getActiveChunk(){return mCurrentChunk;}
+
+ @Override
public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) {
return new GT_GUIContainer_MultiMachine(aPlayerInventory, aBaseMetaTileEntity, getLocalName(), "OreDrillingPlant.png");
}
@@ -81,8 +86,14 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
@Override
protected boolean workingDownward(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe, int yHead, int oldYHead) {
+ if (mChunkLoadingEnabled)
+ return super.workingDownward(aStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead);
if (yHead != oldYHead) oreBlockPositions.clear();
+ if (mWorkChunkNeedsReload && mChunkLoadingEnabled) { // ask to load machine itself
+ GT_ChunkManager.requestChunkLoad((TileEntity) getBaseMetaTileEntity(), null);
+ mWorkChunkNeedsReload = false;
+ }
fillMineListIfEmpty(xDrill, yDrill, zDrill, xPipe, zPipe, yHead);
if (oreBlockPositions.isEmpty()) {
switch (tryLowerPipeState()) {
@@ -93,7 +104,9 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
//new layer - fill again
fillMineListIfEmpty(xDrill, yDrill, zDrill, xPipe, zPipe, yHead);
}
-
+ return processOreList();
+ }
+ private boolean processOreList(){
ChunkPosition oreBlockPos = null;
Block oreBlock = null;
@@ -112,10 +125,72 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
getBaseMetaTileEntity().getWorld().setBlockToAir(oreBlockPos.chunkPosX, oreBlockPos.chunkPosY, oreBlockPos.chunkPosZ);
mOutputItems = getOutputByDrops(oreBlockDrops);
}
-
return true;
}
+ @Override
+ protected boolean workingAtBottom(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe, int yHead, int oldYHead) {
+ if (!mChunkLoadingEnabled || chunkRadiusConfig == 1)
+ return super.workingAtBottom(aStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead);
+
+ if (mCurrentChunk == null) {
+ createInitialWorkingChunk(xDrill, zDrill);
+ return true;
+ }
+
+ if (mWorkChunkNeedsReload) {
+ GT_ChunkManager.requestChunkLoad((TileEntity)getBaseMetaTileEntity(), mCurrentChunk);
+ mWorkChunkNeedsReload = false;
+ return true;
+ }
+ if (oreBlockPositions.isEmpty()){
+ fillChunkMineList(yHead, yDrill);
+ if (oreBlockPositions.isEmpty()) {
+ GT_ChunkManager.releaseChunk((TileEntity)getBaseMetaTileEntity(), mCurrentChunk);
+ if (!moveToNextChunk(xDrill >> 4, zDrill >> 4))
+ workState = STATE_UPWARD;
+ return true;
+ }
+ }
+ return processOreList();
+ }
+ private void createInitialWorkingChunk(int xDrill, int zDrill) {
+ final int centerX = xDrill >> 4;
+ final int centerZ = zDrill >> 4;
+ mCurrentChunk = new ChunkCoordIntPair(centerX - chunkRadiusConfig + 1, centerZ - chunkRadiusConfig + 1);
+ GT_ChunkManager.requestChunkLoad((TileEntity)getBaseMetaTileEntity(), mCurrentChunk);
+ mWorkChunkNeedsReload = false;
+ }
+
+ @Override
+ protected boolean workingUpward(ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, int zPipe, int yHead, int oldYHead) {
+ if (!mChunkLoadingEnabled || chunkRadiusConfig == 1 || oreBlockPositions.isEmpty())
+ return super.workingUpward(aStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead);
+ boolean result = processOreList();
+ if (oreBlockPositions.isEmpty())
+ GT_ChunkManager.releaseTicket((TileEntity)getBaseMetaTileEntity());
+ return result;
+ }
+ private boolean moveToNextChunk(int centerX, int centerZ){
+ if (mCurrentChunk == null)
+ return false;
+ int nextChunkX = mCurrentChunk.chunkXPos + 1;
+ int nextChunkZ = mCurrentChunk.chunkZPos;
+ if (nextChunkX >= (centerX + chunkRadiusConfig)){
+ nextChunkX = centerX - chunkRadiusConfig + 1;
+ ++nextChunkZ;
+ }
+ if (nextChunkZ >= (centerZ + chunkRadiusConfig)) {
+ mCurrentChunk = null;
+ return false;
+ }
+ // skip center chunk - dug in workingDownward()
+ if (nextChunkX == centerX && nextChunkZ == centerZ)
+ ++nextChunkX;
+ mCurrentChunk = new ChunkCoordIntPair(nextChunkX, nextChunkZ);
+ GT_ChunkManager.requestChunkLoad((TileEntity)getBaseMetaTileEntity(), new ChunkCoordIntPair(nextChunkX, nextChunkZ));
+ return true;
+ }
@Override
protected boolean checkHatches(){
return !mMaintenanceHatches.isEmpty() && !mInputHatches.isEmpty() && !mOutputBusses.isEmpty() && !mEnergyHatches.isEmpty();
@@ -127,7 +202,7 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
this.mEfficiencyIncrease = 10000;
int tier = Math.max(1, GT_Utility.getTier(getMaxInputVoltage()));
this.mEUt = -3 * (1 << (tier << 1));
- this.mMaxProgresstime = (workState == STATE_DOWNWARD ? getBaseProgressTime() : 80) / (1 <<tier);
+ this.mMaxProgresstime = ((workState == STATE_DOWNWARD || workState == STATE_AT_BOTTOM) ? getBaseProgressTime() : 80) / (1 <<tier);
this.mMaxProgresstime = Math.max(1, this.mMaxProgresstime);
}
@@ -184,6 +259,19 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
return true;
}
+ private void fillChunkMineList(int yHead, int yDrill) {
+ if (mCurrentChunk == null || !oreBlockPositions.isEmpty())
+ return;
+ final int minX = mCurrentChunk.chunkXPos << 4;
+ final int maxX = minX + 16;
+ final int minZ = mCurrentChunk.chunkZPos << 4;
+ final int maxZ = minZ + 16;
+ for (int x = minX; x < maxX; ++x)
+ for (int z = minZ; z < maxZ; ++z)
+ for (int y = yHead; y < yDrill; ++y)
+ tryAddOreBlockToMineList(x, y, z);
+ }
+
private void fillMineListIfEmpty(int xDrill, int yDrill, int zDrill, int xPipe, int zPipe, int yHead) {
if (!oreBlockPositions.isEmpty())
return;
@@ -192,11 +280,18 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
if (yHead == yDrill)
return; //skip controller block layer
- int radius = Math.min(Math.max(chunkRadiusConfig, 1), getRadiusInChunks()) << 4;
-
- for (int xOff = -radius; xOff <= radius; xOff++)
- for (int zOff = -radius; zOff <= radius; zOff++)
- tryAddOreBlockToMineList(xDrill + xOff, yHead, zDrill + zOff);
+ if (mChunkLoadingEnabled) {
+ int startX = (xDrill >> 4) << 4;
+ int startZ = (zDrill >> 4) << 4;
+ for (int x = startX; x < (startX + 16); ++x)
+ for (int z = startZ; z < (startZ + 16); ++z)
+ tryAddOreBlockToMineList(x, yHead, z);
+ } else {
+ int radius = chunkRadiusConfig << 4;
+ for (int xOff = -radius; xOff <= radius; xOff++)
+ for (int zOff = -radius; zOff <= radius; zOff++)
+ tryAddOreBlockToMineList(xDrill + xOff, yHead, zDrill + zOff);
+ }
}
private void tryAddOreBlockToMineList(int x, int y, int z) {
@@ -237,4 +332,4 @@ public abstract class GT_MetaTileEntity_OreDrillingPlantBase extends GT_MetaTile
"Maximum radius is " + (getRadiusInChunks() << 4) + " blocks",
"Fortune bonus of " + (mTier + 3)};
}
-} \ No newline at end of file
+}