diff options
| author | Maxim <maxim235@gmx.de> | 2023-04-22 17:38:49 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-22 08:38:49 -0700 |
| commit | fdde96ab6fef30064b67e28390008ee4ba455655 (patch) | |
| tree | ee169d0d4a8432433c4ec01eada1e24049a0e47a /src/main/java/gregtech/api/multitileentity/multiblock | |
| parent | de864236f83dc31c53ca77a6939357a0959bca75 (diff) | |
| download | GT5-Unofficial-fdde96ab6fef30064b67e28390008ee4ba455655.tar.gz GT5-Unofficial-fdde96ab6fef30064b67e28390008ee4ba455655.tar.bz2 GT5-Unofficial-fdde96ab6fef30064b67e28390008ee4ba455655.zip | |
MuTE overhaul and ACR (#1883)
* complex controller start
* Added methods to get input fluids and items
* Added logic to complex parallel mute
* Added ACR and fixed many, many, many, many bugs
* Added void protection setting to checkRecipe
* do not init nbt, if mteID and mteRegistry are the same
* Improved GUI design
* Force structure check when pressing power switch
* ACR Textures
* Added T1 structure
* Added perfect OC
* Added WAILA
* fix mutes resetting their nbt
* Fix ACR GUI
* fix npe
* Added void protection for MuTEs
* Fixed ACR starting recipe while another one is ongoing
* nbt saving
* maybe fix structure breaking
* Fix complex machine disabling on startup
* correctly update input tanks
* move casings over
* Changed logic of casings to change mode and facing in one go by sneaking
* Fixed the casing target not resetting
* Added side only annotations
* don't leave it empty
* Added power logic and tiered blocks to ACR
* Change facing to wrench side if casing mode is currently none
* lasers anyone?
* Added ACR item chaining
* Remove unncessary item lists
* Use HashSet for process whitelists
* Optimize list capacities
* Fix potential recipe voiding bug
* Rename methods for consistancy
* Fix NPE
* Duct tape fix structure check
* allow MuTEs to connect to cables
* Added separate tank inventories for input separation (#1887)
* Fixed unregistering tank function
* Fixed input busses not being automatable
* Added fluid chaining
* Fixed saving of input tanks
* Forbid inventory registering with empty name
* Display all input tanks in controller GUI
* Fixed fluid hatch GUI height
* Reset casing lists when checking the structure
* Make inventory GUI size consistant
* Make use of the tooltip cache
* rename thing clean up
* Forgot to put tooltip into map
* Added tooltip to ACR
* Reset whitelists when one whitelist window was opened
* Refined scanner string
* Fixed progress times
* Fixed MuTE not consuming fluids
* Properly register controller inventories
* switch to ForgeDirection
* switch to new Renderer
* Added missing contains check on registerInventory
* Fixed output tanks not registering
* Fixed upgrade tank loading
* fix machines not having active/inactive textures
* fix overlays not loading correctly
* Don't register controller directly
* Remove magic strings all
* fix active not setting to inactive
* allow glow
* item renderer
* fix glow
* MuTE improved hatch GUI and fluid output locking (#1889)
* Allow output hatches to be fluid locked
* Reworked hatch GUI
* Check target before trying to open GUI
* Make ACR GUI easier to look at
* fix covers not rendering on mutes
* fix covers not displaying above the item/fluid in/out
* new folder texture structure
* Reduce network traffic caused by covers
* Fixed WAILA fluid locking display
* Don't save everything to the itemstack NBT
* Added possibility to save NBT of MuTE to its itemstack
* fix textures, but make sacrifices
* mah textures
* Removed the need for all textures to be present
* Added glow texture for active coke oven
* Removed unncesssary upgrade casing textures
* shorten nbt tags
---------
Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com>
Co-authored-by: Martin Robertz <dream-master@gmx.net>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Diffstat (limited to 'src/main/java/gregtech/api/multitileentity/multiblock')
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java | 244 | ||||
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java (renamed from src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java) | 626 | ||||
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java | 301 | ||||
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPowerController.java | 44 | ||||
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java | 89 | ||||
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java (renamed from src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlock_Stackable.java) | 2 | ||||
| -rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java | 2 |
7 files changed, 1106 insertions, 202 deletions
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java new file mode 100644 index 0000000000..ecdeb2294d --- /dev/null +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java @@ -0,0 +1,244 @@ +package gregtech.api.multitileentity.multiblock.base; + +import static mcp.mobius.waila.api.SpecialChars.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.LongStream; + +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.logic.ComplexParallelProcessingLogic; +import gregtech.api.logic.interfaces.PollutionLogicHost; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.GT_Waila; + +public abstract class ComplexParallelController<T extends ComplexParallelController<T>> extends PowerController<T> { + + protected ComplexParallelProcessingLogic processingLogic; + protected int maxComplexParallels = 0; + protected int currentComplexParallels = 0; + protected long[] maxProgressTimes = new long[0]; + protected long[] progressTimes = new long[0]; + + public ComplexParallelController() { + isSimpleMachine = false; + } + + protected void setMaxComplexParallels(int parallel) { + if (parallel != maxComplexParallels) { + if (maxComplexParallels != 0) { + stopMachine(false); + } + maxProgressTimes = new long[parallel]; + progressTimes = new long[parallel]; + } + maxComplexParallels = parallel; + } + + @Override + protected void runMachine(long tick) { + if (acceptsFuel() && isActive()) { + if (!consumeFuel()) { + stopMachine(true); + return; + } + } + + if (hasThingsToDo()) { + markDirty(); + runningTick(tick); + } + if ((tick % TICKS_BETWEEN_RECIPE_CHECKS == 0 || hasWorkJustBeenEnabled() || hasInventoryBeenModified()) + && maxComplexParallels != currentComplexParallels) { + if (isAllowedToWork() && maxComplexParallels > currentComplexParallels) { + wasEnabled = false; + boolean started = false; + for (int i = 0; i < maxComplexParallels; i++) { + if (maxProgressTimes[i] <= 0 && checkRecipe(i)) { + currentComplexParallels++; + started = true; + } + } + if (started) { + setActive(true); + updateSlots(); + markDirty(); + issueClientUpdate(); + } + } + } + } + + @Override + protected void runningTick(long tick) { + consumeEnergy(); + boolean allStopped = true; + for (int i = 0; i < maxComplexParallels; i++) { + if (maxProgressTimes[i] > 0 && ++progressTimes[i] >= maxProgressTimes[i]) { + progressTimes[i] = 0; + maxProgressTimes[i] = 0; + outputItems(i); + outputFluids(i); + if (isAllowedToWork()) { + if (checkRecipe(i)) { + allStopped = false; + } else { + currentComplexParallels--; + } + } + updateSlots(); + } else if (maxProgressTimes[i] > 0) { + allStopped = false; + } + } + if (allStopped) { + setActive(false); + issueClientUpdate(); + } + + if (this instanceof PollutionLogicHost && tick % POLLUTION_TICK == 0) { + doPollution(); + } + emitEnergy(); + } + + protected boolean checkRecipe(int index) { + ComplexParallelProcessingLogic processingLogic = getComplexProcessingLogic(); + if (processingLogic == null || index < 0 || index >= maxComplexParallels) { + return false; + } + processingLogic.clear(index); + boolean result = processingLogic.setInputItems(index, getInputItems(index)) + .setInputFluids(index, getInputFluids(index)) + .setTileEntity(this) + .setVoidProtection(index, isVoidProtectionEnabled(index)) + .setEut(index, getEutForComplexParallel(index)) + .setPerfectOverclock(hasPerfectOverclock()) + .process(index); + setDuration(index, processingLogic.getDuration(index)); + setEut(processingLogic.getTotalEU()); + return result; + } + + protected void outputItems(int index) { + ComplexParallelProcessingLogic processingLogic = getComplexProcessingLogic(); + if (processingLogic != null && index >= 0 && index < maxComplexParallels) { + outputItems(processingLogic.getOutputItems(index)); + } + } + + protected void outputFluids(int index) { + ComplexParallelProcessingLogic processingLogic = getComplexProcessingLogic(); + if (processingLogic != null && index >= 0 && index < maxComplexParallels) { + outputFluids(processingLogic.getOutputFluids(index)); + } + } + + protected ComplexParallelProcessingLogic getComplexProcessingLogic() { + return processingLogic; + } + + @Override + public boolean hasThingsToDo() { + return LongStream.of(maxProgressTimes) + .sum() > 0; + } + + @Override + protected void stopMachine(boolean powerShutDown) { + super.stopMachine(powerShutDown); + for (int i = 0; i < maxComplexParallels; i++) { + maxProgressTimes[i] = 0; + } + } + + protected void setDuration(int index, long duration) { + if (duration < 0) { + duration = -duration; + } + if (index >= 0 && index < maxComplexParallels) { + maxProgressTimes[index] = duration; + } + } + + protected ItemStack[] getInputItems(int index) { + return getInputItems(); + } + + protected FluidStack[] getInputFluids(int index) { + return getInputFluids(); + } + + protected boolean isVoidProtectionEnabled(int index) { + return !voidExcess; + } + + protected boolean hasPerfectOverclock() { + return false; + } + + protected long getEutForComplexParallel(int index) { + // As default behavior we'll give the parallel all remaining EU we have + return GT_Values.V[tier] - eut; + } + + @Override + protected void addProgressStringToScanner(EntityPlayer player, int logLevel, ArrayList<String> list) { + for (int i = 0; i < maxComplexParallels; i++) { + list.add( + StatCollector.translateToLocal("GT5U.multiblock.Progress") + " " + + (i + 1) + + ": " + + EnumChatFormatting.GREEN + + GT_Utility.formatNumbers(progressTimes[i] > 20 ? progressTimes[i] / 20 : progressTimes[i]) + + EnumChatFormatting.RESET + + (progressTimes[i] > 20 ? " s / " : " ticks / ") + + EnumChatFormatting.YELLOW + + GT_Utility + .formatNumbers(maxProgressTimes[i] > 20 ? maxProgressTimes[i] / 20 : maxProgressTimes[i]) + + EnumChatFormatting.RESET + + (maxProgressTimes[i] > 20 ? " s" : " ticks")); + } + } + + @Override + public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, + int z) { + super.getWailaNBTData(player, tile, tag, world, x, y, z); + tag.setInteger("maxComplexParallels", maxComplexParallels); + for (int i = 0; i < maxComplexParallels; i++) { + tag.setLong("maxProgress" + i, maxProgressTimes[i]); + tag.setLong("progress" + i, progressTimes[i]); + } + } + + @Override + public void getWailaBody(ItemStack itemStack, List<String> currentTip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + super.getWailaBody(itemStack, currentTip, accessor, config); + final NBTTagCompound tag = accessor.getNBTData(); + maxComplexParallels = tag.getInteger("maxComplexParallels"); + for (int i = 0; i < maxComplexParallels; i++) { + long maxProgress = tag.getLong("maxProgress" + i); + long progress = tag.getLong("progress" + i); + currentTip.add( + "Process " + (i + 1) + + ": " + + GT_Waila + .getMachineProgressString(maxProgress > 0 && maxProgress >= progress, maxProgress, progress)); + } + } +} diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java index 1355ac13a6..9fdac059da 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java @@ -1,8 +1,11 @@ package gregtech.api.multitileentity.multiblock.base; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; import static gregtech.GT_Mod.GT_FML_LOGGER; import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES; -import static gregtech.api.enums.GT_Values.NBT; +import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.*; +import static gregtech.loaders.preload.GT_Loader_MultiTileEntities.COMPONENT_CASING_REGISTRY; +import static mcp.mobius.waila.api.SpecialChars.*; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -15,8 +18,12 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; @@ -24,6 +31,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.util.StatCollector; import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; @@ -44,6 +52,7 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import com.gtnewhorizon.structurelib.structure.IStructureDefinition; import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.IStructureElementChain; import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import com.gtnewhorizon.structurelib.util.Vec3Impl; import com.gtnewhorizons.modularui.api.ModularUITextures; @@ -92,10 +101,13 @@ import gregtech.api.multitileentity.multiblock.casing.UpgradeCasing; import gregtech.api.objects.GT_ItemStack; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Utility; -import gregtech.common.tileentities.casings.upgrade.InventoryUpgrade; +import gregtech.api.util.GT_Waila; +import gregtech.common.tileentities.casings.upgrade.Inventory; + +public abstract class Controller<T extends Controller<T>> extends MultiTileBasicMachine implements IAlignment, + IConstructable, IMultiBlockController, IDescribable, IMTE_AddToolTips, ISurvivalConstructable { -public abstract class MultiBlockController<T extends MultiBlockController<T>> extends MultiTileBasicMachine implements - IAlignment, IConstructable, IMultiBlockController, IDescribable, IMTE_AddToolTips, ISurvivalConstructable { + public static final String ALL_INVENTORIES_NAME = "all"; private static final Map<Integer, GT_Multiblock_Tooltip_Builder> tooltip = new ConcurrentHashMap<>(); private final List<UpgradeCasing> upgradeCasings = new ArrayList<>(); @@ -110,8 +122,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex protected Map<String, String> multiBlockInputTankNames = new LinkedHashMap<>(); protected Map<String, String> multiBlockOutputTankNames = new LinkedHashMap<>(); - protected Map<String, FluidTankGT> multiBlockInputTank = new LinkedHashMap<>(); - protected Map<String, FluidTankGT> multiBlockOutputTank = new LinkedHashMap<>(); + protected Map<String, FluidTankGT[]> multiBlockInputTank = new LinkedHashMap<>(); + protected Map<String, FluidTankGT[]> multiBlockOutputTank = new LinkedHashMap<>(); private boolean structureOkay = false, structureChanged = false; private ExtendedFacing extendedFacing = ExtendedFacing.DEFAULT; @@ -122,6 +134,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex protected boolean voidExcess = false; protected boolean batchMode = false; protected boolean recipeLock = false; + /** If this is set to true, the machine will get default WAILA behavior */ + protected boolean isSimpleMachine = true; // A list of sides // Each side has a list of parts that have a cover that need to be ticked @@ -137,7 +151,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex public abstract short getCasingRegistryID(); /** Meta ID of the required casing */ - public abstract short getCasingMeta(); + public abstract int getCasingMeta(); /** * Create the tooltip for this multi block controller. @@ -164,8 +178,11 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex */ public boolean checkMachine() { double sum = 0; + if (functionalCasings == null || functionalCasings.size() == 0) { + return false; + } for (FunctionalCasing casing : functionalCasings) { - sum += casing.getPartTier(); + sum += casing.getPartTier() * casing.getPartModifier(); } tier = (int) Math.floor(sum / functionalCasings.size()); // Maximum Energy stores will have a cap of 2 minute work time of current voltage @@ -187,6 +204,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex .getIndex()); saveUpgradeInventoriesToNBT(nbt); + saveUpgradeTanksToNBT(nbt); + + nbt.setBoolean(NBT.VOID_EXCESS, voidExcess); + nbt.setBoolean(NBT.SEPARATE_INPUTS, separateInputs); + nbt.setBoolean(NBT.RECIPE_LOCK, recipeLock); + nbt.setBoolean(NBT.BATCH_MODE, batchMode); } private void saveUpgradeInventoriesToNBT(NBTTagCompound nbt) { @@ -216,14 +239,54 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex nbt.setTag(NBT.UPGRADE_INVENTORIES_OUTPUT, outputInvList); } + private void saveUpgradeTanksToNBT(NBTTagCompound nbt) { + final NBTTagList inputTankList = new NBTTagList(); + multiBlockInputTank.forEach((id, tanks) -> { + if (!id.equals("controller") && tanks != null && tanks.length > 0) { + final NBTTagCompound tTag = new NBTTagCompound(); + tTag.setString(NBT.UPGRADE_TANK_UUID, id); + tTag.setString(NBT.UPGRADE_TANK_NAME, multiBlockInputTankNames.get(id)); + // We assume all tanks in the tank-array are equally sized + tTag.setLong(NBT.UPGRADE_TANK_CAPACITY, tanks[0].capacity()); + tTag.setLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER, tanks[0].getCapacityMultiplier()); + tTag.setInteger(NBT.UPGRADE_TANKS_COUNT, tanks.length); + for (int i = 0; i < tanks.length; i++) { + tanks[i].writeToNBT(tTag, NBT.UPGRADE_TANKS_PREFIX + i); + } + inputTankList.appendTag(tTag); + } + }); + final NBTTagList outputTankList = new NBTTagList(); + multiBlockOutputTank.forEach((id, tanks) -> { + if (!id.equals("controller") && tanks != null && tanks.length > 0) { + final NBTTagCompound tTag = new NBTTagCompound(); + tTag.setString(NBT.UPGRADE_TANK_UUID, id); + tTag.setString(NBT.UPGRADE_TANK_NAME, multiBlockInputTankNames.get(id)); + // We assume all tanks in the tank-array are equally sized + tTag.setLong(NBT.UPGRADE_TANK_CAPACITY, tanks[0].capacity()); + tTag.setLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER, tanks[0].getCapacityMultiplier()); + tTag.setInteger(NBT.UPGRADE_TANKS_COUNT, tanks.length); + for (int i = 0; i < tanks.length; i++) { + tanks[i].writeToNBT(tTag, NBT.UPGRADE_TANKS_PREFIX + i); + } + outputTankList.appendTag(tTag); + } + }); + nbt.setTag(NBT.UPGRADE_TANKS_INPUT, inputTankList); + nbt.setTag(NBT.UPGRADE_TANKS_OUTPUT, outputTankList); + } + @Override public void readMultiTileNBT(NBTTagCompound nbt) { super.readMultiTileNBT(nbt); // Multiblock inventories are a collection of inventories. The first inventory is the default internal // inventory, and the others are added by inventory extending blocks. - if (inputInventory != null) multiBlockInputInventory.put("controller", inputInventory); - if (outputInventory != null) multiBlockOutputInventory.put("controller", outputInventory); + if (inputInventory != null) registerInventory("controller", "controller", inputInventory, Inventory.INPUT); + if (outputInventory != null) registerInventory("controller", "controller", outputInventory, Inventory.OUTPUT); + + if (inputTanks != null) registerFluidInventory("controller", "controller", inputTanks, Inventory.INPUT); + if (outputTanks != null) registerFluidInventory("controller", "controller", outputTanks, Inventory.OUTPUT); structureOkay = nbt.getBoolean(NBT.STRUCTURE_OK); extendedFacing = ExtendedFacing.of( @@ -232,10 +295,17 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex Flip.byIndex(nbt.getByte(NBT.FLIP))); loadUpgradeInventoriesFromNBT(nbt); + loadUpgradeTanksFromNBT(nbt); + + voidExcess = nbt.getBoolean(NBT.VOID_EXCESS); + separateInputs = nbt.getBoolean(NBT.SEPARATE_INPUTS); + recipeLock = nbt.getBoolean(NBT.RECIPE_LOCK); + batchMode = nbt.getBoolean(NBT.BATCH_MODE); } private void loadUpgradeInventoriesFromNBT(NBTTagCompound nbt) { - final NBTTagList listInputInventories = nbt.getTagList(NBT.UPGRADE_INVENTORIES_INPUT, 10); + final NBTTagList listInputInventories = nbt + .getTagList(NBT.UPGRADE_INVENTORIES_INPUT, Constants.NBT.TAG_COMPOUND); for (int i = 0; i < listInputInventories.tagCount(); i++) { final NBTTagCompound nbtInv = listInputInventories.getCompoundTagAt(i); String invUUID = nbtInv.getString(NBT.UPGRADE_INVENTORY_UUID); @@ -243,11 +313,11 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex int invSize = nbtInv.getInteger(NBT.UPGRADE_INVENTORY_SIZE); IItemHandlerModifiable inv = new ItemStackHandler(invSize); loadInventory(nbtInv, inv, NBT.INV_INPUT_LIST); - multiBlockInputInventory.put(invUUID, inv); - multiBlockInputInventoryNames.put(invUUID, invName); + registerInventory(invName, invUUID, invSize, Inventory.INPUT); } - final NBTTagList listOutputInventories = nbt.getTagList(NBT.UPGRADE_INVENTORIES_OUTPUT, 10); + final NBTTagList listOutputInventories = nbt + .getTagList(NBT.UPGRADE_INVENTORIES_OUTPUT, Constants.NBT.TAG_COMPOUND); for (int i = 0; i < listOutputInventories.tagCount(); i++) { final NBTTagCompound nbtInv = listOutputInventories.getCompoundTagAt(i); String invUUID = nbtInv.getString(NBT.UPGRADE_INVENTORY_UUID); @@ -255,8 +325,41 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex int invSize = nbtInv.getInteger(NBT.UPGRADE_INVENTORY_SIZE); IItemHandlerModifiable inv = new ItemStackHandler(invSize); loadInventory(nbtInv, inv, NBT.INV_OUTPUT_LIST); - multiBlockOutputInventory.put(invUUID, inv); - multiBlockOutputInventoryNames.put(invUUID, invName); + registerInventory(invName, invUUID, invSize, Inventory.OUTPUT); + } + } + + private void loadUpgradeTanksFromNBT(NBTTagCompound nbt) { + final NBTTagList listInputTanks = nbt.getTagList(NBT.UPGRADE_TANKS_INPUT, Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < listInputTanks.tagCount(); i++) { + final NBTTagCompound nbtTank = listInputTanks.getCompoundTagAt(i); + String tankUUID = nbtTank.getString(NBT.UPGRADE_TANK_UUID); + String tankName = nbtTank.getString(NBT.UPGRADE_TANK_NAME); + long capacity = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY); + long capacityMultiplier = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER); + int count = nbtTank.getInteger(NBT.UPGRADE_TANKS_COUNT); + FluidTankGT[] tanks = new FluidTankGT[count]; + for (int j = 0; j < count; j++) { + tanks[j] = new FluidTankGT(capacity).setCapacityMultiplier(capacityMultiplier) + .readFromNBT(nbtTank, NBT.UPGRADE_TANKS_PREFIX + j); + } + registerFluidInventory(tankName, tankUUID, count, capacity, capacityMultiplier, Inventory.INPUT); + } + + final NBTTagList listOutputTanks = nbt.getTagList(NBT.UPGRADE_TANKS_OUTPUT, Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < listOutputTanks.tagCount(); i++) { + final NBTTagCompound nbtTank = listOutputTanks.getCompoundTagAt(i); + String tankUUID = nbtTank.getString(NBT.UPGRADE_TANK_UUID); + String tankName = nbtTank.getString(NBT.UPGRADE_TANK_NAME); + long capacity = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY); + long capacityMultiplier = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER); + int count = nbtTank.getInteger(NBT.UPGRADE_TANKS_COUNT); + FluidTankGT[] tanks = new FluidTankGT[count]; + for (int j = 0; j < count; j++) { + tanks[j] = new FluidTankGT(capacity).setCapacityMultiplier(capacityMultiplier) + .readFromNBT(nbtTank, NBT.UPGRADE_TANKS_PREFIX + j); + } + registerFluidInventory(tankName, tankUUID, count, capacity, capacityMultiplier, Inventory.OUTPUT); } } @@ -285,7 +388,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex } protected GT_Multiblock_Tooltip_Builder getTooltip() { - return createTooltip(); + GT_Multiblock_Tooltip_Builder builder = tooltip.get(getToolTipID()); + if (builder == null) { + builder = createTooltip(); + tooltip.put(getToolTipID(), builder); + } + return builder; } @Override @@ -306,6 +414,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex } public final boolean checkPiece(String piece, Vec3Impl offset) { + functionalCasings.clear(); + upgradeCasings.clear(); return checkPiece(piece, offset.get0(), offset.get1(), offset.get2()); } @@ -390,8 +500,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex } @SuppressWarnings("unchecked") - private IStructureDefinition<MultiBlockController<T>> getCastedStructureDefinition() { - return (IStructureDefinition<MultiBlockController<T>>) getStructureDefinition(); + private IStructureDefinition<Controller<T>> getCastedStructureDefinition() { + return (IStructureDefinition<Controller<T>>) getStructureDefinition(); } @Override @@ -501,7 +611,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex // Recheck the structure every 30 seconds or so if (!checkStructure(false)) checkStructure(true); } - if (structureOkay) { + if (checkStructure(false)) { runMachine(tick); } else { stopMachine(false); @@ -528,7 +638,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex @Override public boolean allowCoverOnSide(byte aSide, GT_ItemStack aCoverID) { - return aSide != facing; + return facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0; } @Override @@ -563,7 +673,14 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex @Override public FluidStack getDrainableFluid(byte aSide) { - final IFluidTank tank = getFluidTankDrainable(aSide, null); + return getDrainableFluid(aSide, null); + } + + @Override + public FluidStack getDrainableFluid(byte aSide, Fluid fluidToDrain) { + final IFluidTank tank = getFluidTankDrainable( + aSide, + fluidToDrain == null ? null : new FluidStack(fluidToDrain, 0)); return tank == null ? null : tank.getFluid(); } @@ -663,11 +780,11 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex return false; final IMultiBlockController tTarget = part.getTarget(false); - if (tTarget != null && tTarget != MultiBlockController.this) return false; + if (tTarget != null && tTarget != t) return false; - part.setTarget(MultiBlockController.this, modes); + part.setTarget((IMultiBlockController) t, modes); - registerSpecialCasings(part); + ((Controller<?>) t).registerSpecialCasings(part); return true; } @@ -703,9 +820,9 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex } if (world.setBlock(x, y, z, tContainer.mBlock, 15 - tContainer.mBlockMetaData, 2)) { tContainer.setMultiTile(world, x, y, z); - ((MultiBlockPart) te).setTarget(MultiBlockController.this, modes); + ((MultiBlockPart) te).setTarget(Controller.this, modes); - registerSpecialCasings((MultiBlockPart) te); + ((Controller<?>) t).registerSpecialCasings((MultiBlockPart) te); } return false; @@ -717,6 +834,150 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex }; } + protected <S> IStructureElementChain<S> addMotorCasings(int modes) { + return ofChain( + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Motor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Motor.getId(), modes)); + } + + protected <S> IStructureElementChain<S> addPumpCasings(int modes) { + return ofChain( + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Pump.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Pump.getId(), modes)); + } + + protected <S> IStructureElementChain<S> addPistonCasings(int modes) { + return ofChain( + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Piston.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Piston.getId(), modes)); + } + + protected <S> IStructureElementChain<S> addConveyorCasings(int modes) { + return ofChain( + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Conveyor.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Conveyor.getId(), modes)); + } + + protected <S> IStructureElementChain<S> addRobotArmCasings(int modes) { + return ofChain( + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_RobotArm.getId(), modes), + addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_RobotArm.getId(), modes), + addMultiTi |
