aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
diff options
context:
space:
mode:
authorBlueWeabo <ilia.iliev2005@gmail.com>2024-01-06 00:41:00 +0200
committerGitHub <noreply@github.com>2024-01-05 23:41:00 +0100
commit02bedd5c0a96a654c6692edd1b7f2765fd9c46b4 (patch)
tree57dd675f658dda3caba629f15d4708247e702f88 /src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
parentfc63cee4c0284635c601889ce49a892cf73082ff (diff)
downloadGT5-Unofficial-02bedd5c0a96a654c6692edd1b7f2765fd9c46b4.tar.gz
GT5-Unofficial-02bedd5c0a96a654c6692edd1b7f2765fd9c46b4.tar.bz2
GT5-Unofficial-02bedd5c0a96a654c6692edd1b7f2765fd9c46b4.zip
Merge MuTEMaster into Master (#2431)
* Fix MuTE structure check and power intake (#1975) * Fixed casing lists being cleared for every checked structure piece * Fixed power being taken from any side BUT the right one * ACP Structure - Rebased (#1978) * Added 2nd structure tier to ACR and make complex parallels depend on it * Added tier 3 to 8 structure pieces to ACR * Added disclaimer * Renamed ACR to ACP because MV CR already is named ACR * Add autopush functionality to MuTE (#1976) - fix conflict * Working auto push * Revert wildcard import * Addresssed reviews * Fix reference issue * Minor MuTE fixes - Rebased (#1983) * Fixed ACP recipe map * Fixed controller side being used instead of part side when accessing tanks * Fix Structure not forming (#1984) * fix cables not connecting * fix structure and don't store controller * Add missing tooltips (#1981) * Add missing tooltips * Address blue's change * Distillation MuTE (#1989) * Started work on DT MuTE * Renamed methods so they also make sense when used horizontally * MuTE Upgrade Casings - Rebased (#1988) - fix conflict * Added cleanroom upgrade casing * Added inventory and tank upgrades * Added tooltips to mute casings * Added power upgrades * Set player UUID when placing MuTE * MuTE fixes (#1991) * Fixed pipes not connectable to MuTE casings * Fixed not all things being renamed to ACP * Fix running in obf * fix for real yo * Add a Generic Processing Logic and extract methods - Rebased (#1992) * add a generic processing logic * calculate tier in another method * calculate power logic in another method * Add Layered Coke Foundry (#1995) * Add the Foundry class and call it * Foundry name correction * Buildable stackable structure * Fixed min stacks and added motor casings * checkMachine override for custom checking * Working checkMachine for all stacks, and recipes * Fix getOutputFluids * Change recipe processing to GenericProcessingLogic * Change inventoryName to protected for override * Override checkRecipe for multis that consume EU * Rename class and add inner walls to multi * Structure update and other fixes * Fix processing logic being static * MuTE inventory upgrade logic (#2082) * Catch potential NPE * Don't load name when it doesn't exist * Potentially cause weird non-replicatable issue where registry ends up with different key * Use proper block removal method * Validate index before using it * Don't open controller GUI from inventory upgrade * semi-working concept * sync the ID of the inventory upgrade to correctly remove it later * remove unneeded boolean --------- Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * fixed layeredCokeBattery checkMachine to prevent 'already in building state' (#2099) * MuTE casing structure element (#2105) - fix conflict * Added class containing MuTE relevant structure elements * Migrate MuTE to new structure element * Formatting fix * Use int array instead of int hashmap, since its expected these arrays will never get long enough to be faster as hashmap * Delete old code * Cache MuTEs for non-instance specific actions (#2109) * Introduce map of cached TEs, which are used to perform actions that don't require a specific instance of the TE. This prevents constant creation of new TEs * Remove static modifier from map of cached TEs * First Modular Upgrade Casings Implementation (#2142) * Base support for Heater MUCs - Define Heater upgrade casings; - Create the 5 tiers of Heaters; - Add method to increase and decrease count. * Refactor the cache of MUCs in structure - Change the way that each MUC is counted: since there will be several types, the integer that counted heaters is now a hashmap that divides all MUCs based on their type and tier, to be counted separately from each other. * Add Insulator MUC - Add second MUC type (insulator) to test alongside heaters on the Layered Coke Battery. * Fix MUC count reset * Refactor MUC implementation into subclass - Move the new methods and hashmap away from the base classes, and onto a s specific one that won't be used by unrelated multiblocks. * Remove empty lines * Refactor MUC implementations into subclasses * Requested fixes in StackableModularController * Change hashmap keys to an enum * Hashmap getter for load order purposes - Added a getter that generates the default value for the hashmap if it is null, due to problems with load order; * Apply spotless * NotNull annotations * More Additions to MUCs and the LCB (#2215) * Fix old LCB multi name in some locations * Refactor mucMap and override checkRecipe - Refactor mucMap to an array of primitive integers instead of the wrapper type, for ease of use with other methods such as stream; - Override checkRecipe for custom recipe behavior on MUC multis, to be implemented in a future commit; * First implementation of bonuses and MUC requirements - Change EU/t and recipe duration of this multi based on the count of different MUCs in the multi; - Fail the structure check based on the count of each of the allowed MUCs. * Parallel count implementation - Calculate parallels based on the count of base MUCs, the cheapest option amongst the possibilities, in this case heaters; - Added more abstract methods to require specific values from the multi classes. * Fix parallel count and processing - Fixed the handling of parallels by pointing to the corrent maxParallel variable in ProcessingLogic. * Test of parallels with additional amp input * Structure fix for the intended LCB - Changed MUC placements to match what I intended at the beginning, to better test the multi. * One more comment * Remove checkRecipe override * Refactor Item and Fluid to be in separate logic classes (#2178) - fix conflict * basics of inventory logic * mostly working item logic * working nbt saving/loading * fluid handler * FluidSlotHandler WIP * fluid handler mostly working * remove fluid handler from gt5u * prepare for conversion * use correct imports * spotless * more controller logic * spotless * final refactor. migration next * spotless * add more methods to logic classes * convert almost everything to use new Logic * spotless * make mute casing mode an int * allow pump cover to work with FluidInventoryLogic * pumps work * spotless * make item inventory logic work with every item input thing * rework Fluid Inventory Logic to work with all fluid inputs * spotless * address annotation reviews * finish off todos * missed to dos * cleanup Coke oven will get a new GUI when i get to it * address review * prevent npes from ControllerXXXLogic * null checks * remove accidentally added methods * fix missed return * fixes after rebase - fix conflict * Laser Engraver Multi. (#2223) - fix conflict * saving............. * clean up * savin * Small fixes + Adding back stuff, Crashes you and spams logs. * fix stack overflow * Fixes * Fixes --------- Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * Add TickableTask (#2216) * Add autopush functionality to MuTE (#1976) * Working auto push * Revert wildcard import * Addresssed reviews * Fix reference issue * MuTE Upgrade Casings (#1988) * Added cleanroom upgrade casing * Added inventory and tank upgrades * Added tooltips to mute casings * Added power upgrades * Set player UUID when placing MuTE * Add a Generic Processing Logic and extract methods (#1992) * add a generic processing logic * calculate tier in another method * calculate power logic in another method * MuTE inventory upgrade logic (#2082) * Catch potential NPE * Don't load name when it doesn't exist * Potentially cause weird non-replicatable issue where registry ends up with different key * Use proper block removal method * Validate index before using it * Don't open controller GUI from inventory upgrade * semi-working concept * sync the ID of the inventory upgrade to correctly remove it later * remove unneeded boolean --------- Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * MuTE casing structure element (#2105) * Added class containing MuTE relevant structure elements * Migrate MuTE to new structure element * Formatting fix * Use int array instead of int hashmap, since its expected these arrays will never get long enough to be faster as hashmap * Delete old code * Refactor Item and Fluid to be in separate logic classes (#2178) * basics of inventory logic * mostly working item logic * working nbt saving/loading * fluid handler * FluidSlotHandler WIP * fluid handler mostly working * remove fluid handler from gt5u * prepare for conversion * use correct imports * spotless * more controller logic * spotless * final refactor. migration next * spotless * add more methods to logic classes * convert almost everything to use new Logic * spotless * make mute casing mode an int * allow pump cover to work with FluidInventoryLogic * pumps work * spotless * make item inventory logic work with every item input thing * rework Fluid Inventory Logic to work with all fluid inputs * spotless * address annotation reviews * finish off todos * missed to dos * cleanup Coke oven will get a new GUI when i get to it * address review * prevent npes from ControllerXXXLogic * null checks * Base work * PollutionTask * move package * Fix generics * Internal -> OverrideOnly * rebase fix * Ducttape addPollution --------- Co-authored-by: Maxim <maxim235@gmx.de> Co-authored-by: BlueWeabo <ilia.iliev2005@gmail.com> Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * Rework a bit of ProcessingLogic to fit MuTEs (#2283) - fix conflicts * Add a way to enable or disable the crafting buffer on GPL multiblocks (#2218) * add a way to enable or disable the crafting buffer on GPL multiblocks * don't register the hatch either * fix Refractory Capsule (#2219) * Fix PAs overclocking ulv recipes too much (#2220) * fix PAs overclocking ulv recipes too much * make sure we save the returned value * Fix Digital Tank capacity for Fluid Storage Monitor (#2217) * Fix Digital Tank capacity for Fluid Storage Monitor * Annotations * Blacklist AE2FC drop and packet, and Chisel stones from Recycler (#2222) * Fix recycler blacklist being sensitive to NBT * Blacklist AE2FC drop and packet, and Chisel stones * fix class loader issue * Add detailed logging for ME hatches (#2224) * Fix overclock calculator calculating eu/t use for ulv recipe wrong on certain parallel (#2225) * fix overclock calculator calculating eu/t use for ulv recipe wrong on certain parallel * make formula into its own method * Fix drilling rigs, plants and concrete backfiller to fail with multiple energy hatches (#2227) * max-1-energy-hatch-in-drilling-rigs.-plants-and-concrete-backfiller * spotlessApply (#2228) Co-authored-by: GitHub GTNH Actions <> * revert --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * clear stale crafting input bus list (#2233) * add ability to remove item data and use it for clay (#2229) * Update buildscript (#2232) * Fix server crash with RecipeFilter (#2231) * Fix server crash with RecipeFilter * Make client send filtered machines to server * Use mUniqueIdentifier * Fix a NPE w/ injecting into super/quantum chests (#2234) When simulating an injection, if the stackSize > chest's capacity, it causes a NPE when the internal chest is empty. Also fixes a potential bug when void overflow is set; the chest should return null in such a scenario regardless of simulation/modulation. * Fix lag caused by getRecipeMap for PA (#2236) * Experimental fix to prevent infinite loop in Grid destruction (#2235) Co-authored-by: Firenoo <49818773+firenoo@users.noreply.github.com> * Fix ME Output Bus and Crafting Input Bus overflow when save/load (#2238) * Remove fire display from singleblock generator (#2240) * Fix some output slots allowing insertion (#2230) * fix overlay zfighting by disable depth test (#2226) * Crafting input - Optimize isEmpty check to reduce lag (#2239) * Optimize isEmpty check * rearrage * remove broken hsla recipe (#2241) * Correct PCB Factory Energy Hatch description (#2237) * Correct PCB Factory Energy Hatch description Changes the PCB factory description (the one seen when holding shift) which currently says "Energy Hatches: 1+" I believe this is incorrect and that the correct description is 1-2 energy hatches or 1 TT energy hatch. I believe the PCB factory uses this, which checks for 1-2 or 1 TT: public boolean checkExoticAndNormalEnergyHatches() { if (mExoticEnergyHatches.isEmpty() && mEnergyHatches.isEmpty()) { return false; } if (!mExoticEnergyHatches.isEmpty()) { if (!mEnergyHatches.isEmpty()) { return false; } if (mExoticEnergyHatches.size() != 1) { return false; } } return mEnergyHatches.size() <= 2; } * gradlew spotlessApply * Correct file name on resource pack guide (#2242) * Fix GT_RecipeConstants.Fuel (#2243) * Update text (#2246) * Fix startup tier for fusion NEI (#2249) * Update the conditionals buttons and tooltips on covers to reflect their actual effects (#2244) * Update redstone buttons and tooltips to better reflect actual use * Spotless Apply * Update GT_Cover_FluidRegulator.java * Update GT_Cover_FluidRegulator.java * Typo fix, Icon Improved and interactive blocking ui - Fixed a typo in the world machine - Fixed double button situation for conveyor belts. - There was never any issue, the testing methodology gave me invalid results. - Conveyor behaviour is in line with all the other covers affected by this PR/Branch. - Updated icon for the machine state to be a miniature machine controller cover. - Made the block/allow input section more interactive in order to better reflect the actual effect of these buttons. - In import mode, it actually blocks the machine from outputting from that side. * typos I can't write to save myself sometimes * Better text alignment - Better text alignment * fix typos I swear I can't write to save myself. --------- Co-authored-by: Martin Robertz <dream-master@gmx.net> * Fix Orichalcum and Shadowiron smelting (#2251) * fix orichalcum and shadowiron smelting * add Alduorite and Chrysotile * Fix tier display for Fusion NEI header (#2250) * fix ulv recipes being broken again when under 1 tick calculation is taken (#2254) * change way to fix zfighting (#2253) * Crafting input hatches QoLs (#2200) * Fixes + Detect Inventory Slot Changes * support rename + check for updates * add back onChangeListener + fix npe * ICustomNameObject TileEntity * Fix NPEs * Use IInterfaceTerminalSupport * fix * register * dep * spotless * General Crafting Input Hatch QoL fixes (#2212) * feat: refactor naming && include circuit and catalyst in default name * feat: add 4 more slot to solve my ocd * fix: formatting * feat: migrate from 4x8 to 4x9 * spotlessApply (#2213) Co-authored-by: GitHub GTNH Actions <> * QoLs * 9 manual items * spotless * feat: open master GUI when used, without holding a data-stick (#2221) * fix destpos * optimize empty check * Fix error when fluidInventory.size() == 0 If the fluidInventory size is 0, there is no element to get. Add a check for it. * name in waila + fix int overflow * unnecssary super * update deps --------- Co-authored-by: Fox_white <39846845+foxwhite25@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Firenoo <49818773+firenoo@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> * Use real stack limit (#2256) * Fix incorrect data stick behaviors for hatches (#2257) * Fix pcb factory not applying its roughness multiplier when it doesn't OC (#2258) * fix PCB Factory not applying its roughness multiplier when it doesn't do any overclocks * spotless * Remove duplicate obsidian long rod (#2259) * disable gt obsidian long rod * cleaner code * Add hazmat to ThaumicBoots (#2260) * Add hazmat to ThaumicBoots does what it says * fixed * fix item names (#2263) * Fix renaming recipe check might ignore NBT equality (#2261) * Fix GPL ignoring if the recipe is allowed to be cached (#2262) * Added bricked blast furnace recipe progress to waila. (#2265) * Added bricked blast furnace recipe progress to waila. * fixed formatting issues. * Fix cutter recipes not being added (#2271) * add processing task * clean up item logic host * temporary fix for GT_StructrureMuTE * use j9+ feature on pollution task * prepare complex parallel logic for transition * feature to ProcessingLogicHost * fix up multiblock bases * add processing logic for each multi to prepare for transition * spotless * removed debug text from wailaBody of GT_MetaTileEntity_Hatch_CraftingInput_ME (#2272) * Proper recipe selection for output overflow in LCR and other multiblocks (#2247) * Implement Stream<FindRecipeResult> findRecipesWithResult for GT_RecipeMap * Change ProcessingLogic.process to actually use new findRecipesWithResult * Change ProcessingLogic.process to start finding something only for OUTPUT_FULL result * Refactor ProcessingLogic.process to make logic more readable * Replace while with for loop, remove NOT_FOUND return in end of findRecipesWithResult * Apply spotless * Make findRecipe use findRecipes, add annotation to GT_Recipe and FindRecipeResult for processRecipe and make method protected, replace wildcard imports * Remake isRecipeWithOutputFullFound * Add @Nonnull to methods * Apply spotless * Remove Stream version of findRecipeWithResult, replace with predicate one. Add GT_Predicated_Recipe_Map class for utilizing this method. Changes some existent recipe maps to inherit from base class. * Remove GT_Predicated_Recipe_Map, add Predicate directly to GT_Recipe_Map#findRecipeWithResult. Add AdvancedRecipeValidatorPredicate and FindRecipeWithAdvancedValidatorResult to allow store validation calculations for further use and proper errors displaying. * Fix InsufficientVoltage errors * Changes according to review comments. Integrate FindRecipeWithAdvancedValidatorResult to FindRecipeResult, rename AdvancedRecipeValidatorPredicate, encapsulate AdvancedRecipeValidatorPredicate fields, fixes some typos, etc * Moves InsufficientVoltage check to GT_ParallelHelper. Removes FindRecipeResult#State#INSUFFICIENT_VOLTAGE * Return an old findRecipeWithResult * Renames things, call old methods for singleblocks * Renames things, makes FindRecipeResult ctor private * Apply spotless * Move RecipeValidator, fix comments typos * update deps * fix up complex processing logic * add a getter for voiding mode * fix getAccessibleSlotsFromSide being wrong sometimes * allow for subtraction of a specific item * use long for amount * add a setter for machine host * initial work on finding recipes and input consumption * Deprecate PA by removing its controller recipe (#2273) * Restore PA controller recipe (#2276) * Restore PA controller recipe * Remove duplicated recipe * Add optional description to input hatch constructors (#2278) * mini fix (#2204) * [chore] Bump fallback version to 44 (#2274) * find recipe in theory working * add some helper methods to inventory logics * update deps * use collect not toList * fix loading crash * fix complex processing logic using wrong find recipe * fix up everything and get recipe finding working * annotate and clean up methods * spotless * save things to nbt * input separation for mutes and fully working processing * apply mute mode on processing logic * clean up overrides --------- Co-authored-by: chochem <40274384+chochem@users.noreply.github.com> Co-authored-by: miozune <miozune@gmail.com> Co-authored-by: Pxx500 <81298696+Pxx500@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Glease <4586901+Glease@users.noreply.github.com> Co-authored-by: firenoo <49818773+firenoo@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> Co-authored-by: Harry <harryyunull@gmail.com> Co-authored-by: Eraldoe <Eraldoe@users.noreply.github.com> Co-authored-by: Jakub <53441451+kuba6000@users.noreply.github.com> Co-authored-by: Connor-Colenso <52056774+Connor-Colenso@users.noreply.github.com> Co-authored-by: Guillaume Mercier <C0bra5@users.noreply.github.com> Co-authored-by: Fox_white <39846845+foxwhite25@users.noreply.github.com> Co-authored-by: Alastors <78517796+Alastors@users.noreply.github.com> Co-authored-by: Kyium <43573052+Kyium@users.noreply.github.com> Co-authored-by: SKProCH <29896317+SKProCH@users.noreply.github.com> Co-authored-by: Sampsa <69092953+S4mpsa@users.noreply.github.com> Co-authored-by: Jaiden Baker <jaidencolebaker@gmail.com> * address minecraft's reviews from #2283 * Refactor MuTE processing logic (#2301) -fix conflicts * Fix void protection for mutes (#2298) - fix conflicts * initial variables * implement working void protection on items and fluids * Adds a Simple PowerOutput task and cleans up some of the code. (#2303) * create a power output task which can be used for dynamos * refactor the controllers and clean up * add some documentation to power logic * make a wireless network manager class instead of using an interface * clean up and add documentation. * setAmperage to setMaxAmperage * fix comment * remove IGlobalWirelessEnergy usage * getAmperage -> getMaxAmperage * add todo for future * Cleanup MuTEMaster code (#2282) * exit early * spotless * better side checking * make if blocks mutually exclusive * more exit early * convert nested ternary operators into if blocks * remove dead code * collapse nested if blocks * add todo to break verylong condition into much smaller ones * spotless apply * collapsing nested if blocks and more exit early * spotless apply * extract try/catch block to its own utility method * break down this unreadable condition * boolean magic (1/5) * boolean magic (2/5) Also corrected some logic on the player null check, we want it to be non null * boolean magic (3/5) * boolean magic (4/5) * boolean magic (5/5) * remove todo * Fix logic --------- Co-authored-by: Jason Mitchell <jason@puzzle.io> Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * Clean up a lil bit and fix some issues with MuTEs (#2316) * clean up fixes * actual fix and remove useless if * Rework MuTEGUI structure (#2429) - fix conflicts` Merged to rebase MuTEMaster and fix any non-compile errors and game not launching in there * some docs on a few methods * innitial GUI class * try to implement guis * almost working - fix comflict * add UIBuildContext to getGUI method * make it compile * sketch gui - fix conflict * compile and spotless * add config option to enabling MuTEs * Spotless apply for branch feature/MuTEMaster for #2431 (#2432) spotlessApply Co-authored-by: GitHub GTNH Actions <> * address reviews on broken processing logic * spotless * fix doc and review --------- Co-authored-by: Maxim <maxim235@gmx.de> Co-authored-by: RIONDY 'POPlol333' Adam <76914762+POPlol333@users.noreply.github.com> Co-authored-by: Jason Mitchell <mitchej@gmail.com> Co-authored-by: Daniel Mendes <70096037+Steelux8@users.noreply.github.com> Co-authored-by: kstvr32 <109012629+kstvr32@users.noreply.github.com> Co-authored-by: TheEpicGamer274 <102255081+TheEpicGamer274@users.noreply.github.com> Co-authored-by: miozune <miozune@gmail.com> Co-authored-by: chochem <40274384+chochem@users.noreply.github.com> Co-authored-by: Pxx500 <81298696+Pxx500@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Glease <4586901+Glease@users.noreply.github.com> Co-authored-by: firenoo <49818773+firenoo@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> Co-authored-by: Harry <harryyunull@gmail.com> Co-authored-by: Eraldoe <Eraldoe@users.noreply.github.com> Co-authored-by: Jakub <53441451+kuba6000@users.noreply.github.com> Co-authored-by: Connor-Colenso <52056774+Connor-Colenso@users.noreply.github.com> Co-authored-by: Guillaume Mercier <C0bra5@users.noreply.github.com> Co-authored-by: Fox_white <39846845+foxwhite25@users.noreply.github.com> Co-authored-by: Alastors <78517796+Alastors@users.noreply.github.com> Co-authored-by: Kyium <43573052+Kyium@users.noreply.github.com> Co-authored-by: SKProCH <29896317+SKProCH@users.noreply.github.com> Co-authored-by: Sampsa <69092953+S4mpsa@users.noreply.github.com> Co-authored-by: Jaiden Baker <jaidencolebaker@gmail.com> Co-authored-by: boubou19 <miisterunknown@gmail.com> Co-authored-by: Jason Mitchell <jason@puzzle.io>
Diffstat (limited to 'src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java')
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java688
1 files changed, 259 insertions, 429 deletions
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
index db9053b0d7..223edc0761 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
@@ -2,7 +2,6 @@ package gregtech.api.multitileentity.multiblock.base;
import static com.google.common.math.LongMath.log2;
import static gregtech.api.enums.GT_Values.B;
-import static gregtech.api.enums.GT_Values.NBT;
import static gregtech.api.enums.Textures.BlockIcons.FLUID_IN_SIGN;
import static gregtech.api.enums.Textures.BlockIcons.FLUID_OUT_SIGN;
import static gregtech.api.enums.Textures.BlockIcons.ITEM_IN_SIGN;
@@ -11,13 +10,17 @@ import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ENERGY_IN_MULTI;
import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ENERGY_OUT_MULTI;
import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_IN;
import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT;
-import static org.apache.commons.lang3.ObjectUtils.firstNonNull;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -25,44 +28,42 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChunkCoordinates;
+import net.minecraft.util.StatCollector;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
-import net.minecraftforge.fluids.FluidStack;
-import net.minecraftforge.fluids.FluidTankInfo;
-import net.minecraftforge.fluids.IFluidTank;
-import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable;
-import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
-import com.gtnewhorizons.modularui.common.widget.DropDownWidget;
-import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget;
-import com.gtnewhorizons.modularui.common.widget.Scrollable;
-import com.gtnewhorizons.modularui.common.widget.SlotGroup;
-import com.gtnewhorizons.modularui.common.widget.SlotWidget;
-import com.gtnewhorizons.modularui.common.widget.TextWidget;
-
-import gregtech.api.enums.GT_Values;
+
+import gregtech.api.enums.GT_Values.NBT;
+import gregtech.api.enums.InventoryType;
import gregtech.api.fluid.FluidTankGT;
-import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.api.gui.GUIHost;
+import gregtech.api.gui.GUIProvider;
import gregtech.api.interfaces.ITexture;
+import gregtech.api.logic.FluidInventoryLogic;
+import gregtech.api.logic.ItemInventoryLogic;
+import gregtech.api.logic.NullPowerLogic;
import gregtech.api.logic.PowerLogic;
import gregtech.api.logic.interfaces.PowerLogicHost;
+import gregtech.api.multitileentity.MultiTileEntityRegistry;
import gregtech.api.multitileentity.base.NonTickableMultiTileEntity;
+import gregtech.api.multitileentity.enums.MultiTileCasingPurpose;
import gregtech.api.multitileentity.interfaces.IMultiBlockController;
import gregtech.api.multitileentity.interfaces.IMultiBlockPart;
-import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_BreakBlock;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_HasModes;
import gregtech.api.net.GT_Packet_MultiTileEntity;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_Utility;
import gregtech.common.covers.CoverInfo;
+import gregtech.common.gui.PartGUIProvider;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
public abstract class MultiBlockPart extends NonTickableMultiTileEntity
- implements IMultiBlockPart, IMTE_BreakBlock, IMTE_HasModes, PowerLogicHost {
+ implements IMultiBlockPart, IMTE_HasModes, PowerLogicHost, IMultiTileEntity.IMTE_AddToolTips, GUIHost {
public static final int NOTHING = 0, ENERGY_IN = B[0], ENERGY_OUT = B[1], FLUID_IN = B[2], FLUID_OUT = B[3],
ITEM_IN = B[4], ITEM_OUT = B[5];
@@ -70,16 +71,20 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
protected final List<Integer> BASIC_MODES = new ArrayList<>(
Arrays.asList(NOTHING, ENERGY_IN, ENERGY_OUT, FLUID_IN, FLUID_OUT, ITEM_IN, ITEM_OUT));
- protected ChunkCoordinates mTargetPos = null;
- protected IMultiBlockController target = null;
+ protected Set<MultiTileCasingPurpose> registeredPurposes = new HashSet<>();
- protected int mAllowedModes = NOTHING; // BITMASK - Modes allowed for this part
- protected byte mMode = 0; // Mode selected for this part
+ protected ChunkCoordinates targetPosition = null;
- protected String mLockedInventory = GT_Values.E;
+ protected int allowedModes = NOTHING; // BITMASK - Modes allowed for this part
+ protected int mode = 0; // Mode selected for this part
+
+ protected UUID lockedInventory;
protected int mLockedInventoryIndex = 0;
protected FluidTankGT configurationTank = new FluidTankGT();
+ @Nonnull
+ protected final GUIProvider<?> guiProvider = createGUIProvider();
+
/**
* What Part Tier is this part? All Basic Casings are Tier 1, and will allow: Energy, Item, Fluid input/output. Some
* of the more advanced modes can be set to require a higher tier part.
@@ -88,33 +93,40 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return 1;
}
- public String getLockedInventory() {
- // TODO: Can this cause side-effects? Removed for now because it causes huge network traffic when using covers
- // issueClientUpdate();
- IMultiBlockController controller = getTarget(false);
- if (modeSelected(ITEM_IN) || modeSelected(ITEM_OUT)) {
- if (!getNameOfInventoryFromIndex(controller, mLockedInventoryIndex).equals(mLockedInventory)) {
- mLockedInventory = getNameOfInventoryFromIndex(controller, mLockedInventoryIndex);
- if (mLockedInventory.equals(Controller.ALL_INVENTORIES_NAME)) {
- mLockedInventory = "";
- }
- }
- } else {
- if (!getNameOfTankArrayFromIndex(controller, mLockedInventoryIndex).equals(mLockedInventory)) {
- mLockedInventory = getNameOfTankArrayFromIndex(controller, mLockedInventoryIndex);
- if (mLockedInventory.equals(Controller.ALL_INVENTORIES_NAME)) {
- mLockedInventory = "";
- }
+ @Override
+ public UUID getLockedInventory() {
+ return lockedInventory;
+ }
+
+ public void setTarget(IMultiBlockController newTarget, int aAllowedModes) {
+ IMultiBlockController currentTarget = getTarget(false);
+ if (currentTarget != null && currentTarget != newTarget) {
+ for (MultiTileCasingPurpose purpose : registeredPurposes) {
+ unregisterPurpose(purpose);
}
}
- return mLockedInventory.equals("") ? null : mLockedInventory;
+ targetPosition = (newTarget == null ? null : newTarget.getCoords());
+ allowedModes = aAllowedModes;
+ if (newTarget != null) {
+ registerCovers(newTarget);
+ registerPurposes();
+ }
}
- public void setTarget(IMultiBlockController aTarget, int aAllowedModes) {
- target = aTarget;
- mTargetPos = (target == null ? null : target.getCoords());
- mAllowedModes = aAllowedModes;
- if (target != null) registerCovers(target);
+ protected void registerPurpose(MultiTileCasingPurpose purpose) {
+ IMultiBlockController target = getTarget(false);
+ if (target != null) {
+ target.registerCaseWithPurpose(purpose, this);
+ registeredPurposes.add(purpose);
+ }
+ }
+
+ protected void unregisterPurpose(MultiTileCasingPurpose purpose) {
+ IMultiBlockController target = getTarget(false);
+ if (target != null) {
+ target.unregisterCaseWithPurpose(purpose, this);
+ }
+ registeredPurposes.remove(purpose);
}
@Override
@@ -125,14 +137,14 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
} else {
tList.add("No Controller");
}
- tList.add("Casing Mode: " + getModeName(mMode));
+ tList.add("Casing Mode: " + getModeName(mode));
}
@Override
public void getWailaBody(ItemStack itemStack, List<String> currentTip, IWailaDataAccessor accessor,
IWailaConfigHandler config) {
super.getWailaBody(itemStack, currentTip, accessor, config);
- currentTip.add(String.format("Mode: %s", getModeName(mMode)));
+ currentTip.add(String.format("Mode: %s", getModeName(mode)));
if (modeSelected(FLUID_OUT)) {
if (configurationTank != null && configurationTank.get() != null) {
currentTip.add(
@@ -147,19 +159,22 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
}
public IMultiBlockController getTarget(boolean aCheckValidity) {
- if (mTargetPos == null) return null;
- if (target == null || target.isDead()) {
- if (worldObj.blockExists(mTargetPos.posX, mTargetPos.posY, mTargetPos.posZ)) {
- final TileEntity te = worldObj.getTileEntity(mTargetPos.posX, mTargetPos.posY, mTargetPos.posZ);
- if (te instanceof IMultiBlockController) {
- target = (IMultiBlockController) te;
- // Register our covers with the controller
- registerCovers(target);
- } else {
- mTargetPos = null;
- }
- }
+ if (targetPosition == null) {
+ return null;
+ }
+
+ if (!worldObj.blockExists(targetPosition.posX, targetPosition.posY, targetPosition.posZ)) {
+ return null;
+ }
+ final TileEntity te = worldObj.getTileEntity(targetPosition.posX, targetPosition.posY, targetPosition.posZ);
+ IMultiBlockController target = null;
+ if (te instanceof IMultiBlockController targetFound) {
+ target = targetFound;
+ } else {
+ targetPosition = null;
+ return null;
}
+
if (aCheckValidity) {
return target != null && target.checkStructure(false) ? target : null;
}
@@ -175,17 +190,26 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
}
}
+ protected void registerPurposes() {
+ for (MultiTileCasingPurpose purpose : registeredPurposes) {
+ registerPurpose(purpose);
+ }
+ }
+
@Override
public void setCoverItemAtSide(ForgeDirection side, ItemStack aCover) {
super.setCoverItemAtSide(side, aCover);
// TODO: Filter on tickable covers
final IMultiBlockController tTarget = getTarget(true);
- if (tTarget != null) {
- final CoverInfo coverInfo = getCoverInfoAtSide(side);
- if (coverInfo.isValid() && coverInfo.getTickRate() > 0) {
- tTarget.registerCoveredPartOnSide(side, this);
- }
+ if (tTarget == null) {
+ return;
}
+
+ final CoverInfo coverInfo = getCoverInfoAtSide(side);
+ if (coverInfo.isValid() && coverInfo.getTickRate() > 0) {
+ tTarget.registerCoveredPartOnSide(side, this);
+ }
+
}
public void unregisterCovers(IMultiBlockController controller) {
@@ -208,16 +232,16 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public void readMultiTileNBT(NBTTagCompound aNBT) {
- if (aNBT.hasKey(NBT.ALLOWED_MODES)) mAllowedModes = aNBT.getInteger(NBT.ALLOWED_MODES);
- if (aNBT.hasKey(NBT.MODE)) mMode = aNBT.getByte(NBT.MODE);
+ if (aNBT.hasKey(NBT.ALLOWED_MODES)) allowedModes = aNBT.getInteger(NBT.ALLOWED_MODES);
+ if (aNBT.hasKey(NBT.MODE)) setMode(aNBT.getByte(NBT.MODE));
if (aNBT.hasKey(NBT.TARGET)) {
- mTargetPos = new ChunkCoordinates(
+ targetPosition = new ChunkCoordinates(
aNBT.getInteger(NBT.TARGET_X),
aNBT.getShort(NBT.TARGET_Y),
aNBT.getInteger(NBT.TARGET_Z));
}
if (aNBT.hasKey(NBT.LOCKED_INVENTORY)) {
- mLockedInventory = aNBT.getString(NBT.LOCKED_INVENTORY);
+ lockedInventory = UUID.fromString(aNBT.getString(NBT.LOCKED_INVENTORY));
}
if (aNBT.hasKey(NBT.LOCKED_INVENTORY_INDEX)) {
mLockedInventoryIndex = aNBT.getInteger(NBT.LOCKED_INVENTORY_INDEX);
@@ -225,20 +249,26 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
if (aNBT.hasKey(NBT.LOCKED_FLUID)) {
configurationTank.readFromNBT(aNBT, NBT.LOCKED_FLUID);
}
+ if (modeSelected(ITEM_OUT)) {
+ registeredPurposes.add(MultiTileCasingPurpose.ItemOutput);
+ }
+ if (modeSelected(FLUID_OUT)) {
+ registeredPurposes.add(MultiTileCasingPurpose.FluidOutput);
+ }
}
@Override
public void writeMultiTileNBT(NBTTagCompound aNBT) {
- if (mAllowedModes != NOTHING) aNBT.setInteger(NBT.ALLOWED_MODES, mAllowedModes);
- if (mMode != 0) aNBT.setInteger(NBT.MODE, mMode);
- if (mTargetPos != null) {
+ if (allowedModes != NOTHING) aNBT.setInteger(NBT.ALLOWED_MODES, allowedModes);
+ if (mode != 0) aNBT.setInteger(NBT.MODE, mode);
+ if (targetPosition != null) {
aNBT.setBoolean(NBT.TARGET, true);
- aNBT.setInteger(NBT.TARGET_X, mTargetPos.posX);
- aNBT.setShort(NBT.TARGET_Y, (short) mTargetPos.posY);
- aNBT.setInteger(NBT.TARGET_Z, mTargetPos.posZ);
+ aNBT.setInteger(NBT.TARGET_X, targetPosition.posX);
+ aNBT.setShort(NBT.TARGET_Y, (short) targetPosition.posY);
+ aNBT.setInteger(NBT.TARGET_Z, targetPosition.posZ);
}
- if (mLockedInventory != null) {
- aNBT.setString(NBT.LOCKED_INVENTORY, mLockedInventory);
+ if (lockedInventory != null) {
+ aNBT.setString(NBT.LOCKED_INVENTORY, lockedInventory.toString());
}
if (mLockedInventoryIndex != 0) {
aNBT.setInteger(NBT.LOCKED_INVENTORY_INDEX, mLockedInventoryIndex);
@@ -270,34 +300,47 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public void setTargetPos(ChunkCoordinates aTargetPos) {
- mTargetPos = aTargetPos;
- IMultiBlockController mTarget = getTarget(false);
- setTarget(mTarget, mAllowedModes);
+ targetPosition = aTargetPos;
+ IMultiBlockController target = getTarget(false);
+ setTarget(target, allowedModes);
}
@Override
public ChunkCoordinates getTargetPos() {
- return mTargetPos;
+ return targetPosition;
}
@Override
- public void setMode(byte aMode) {
- mMode = aMode;
+ public void setMode(int mode) {
+ if (this.mode == mode) return;
+ if (modeSelected(FLUID_OUT)) {
+ unregisterPurpose(MultiTileCasingPurpose.FluidOutput);
+ }
+ if (modeSelected(ITEM_OUT)) {
+ unregisterPurpose(MultiTileCasingPurpose.ItemOutput);
+ }
+ this.mode = mode;
+ if (modeSelected(FLUID_OUT)) {
+ registerPurpose(MultiTileCasingPurpose.FluidOutput);
+ }
+ if (modeSelected(ITEM_OUT)) {
+ registerPurpose(MultiTileCasingPurpose.ItemOutput);
+ }
}
@Override
- public byte getMode() {
- return mMode;
+ public int getMode() {
+ return mode;
}
@Override
public int getAllowedModes() {
- return mAllowedModes;
+ return allowedModes;
}
@Override
public void setAllowedModes(int aAllowedModes) {
- mAllowedModes = aAllowedModes;
+ allowedModes = aAllowedModes;
}
/**
@@ -305,7 +348,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
*/
public boolean hasMode(int aMode) {
// This is not sent to the client
- return (mAllowedModes & aMode) != 0;
+ return (allowedModes & aMode) != 0;
}
/**
@@ -313,7 +356,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
*/
public boolean modeSelected(int... aModes) {
for (int aMode : aModes) {
- if (hasMode(aMode) && mMode == getModeOrdinal(aMode)) return true;
+ if (hasMode(aMode) && mode == getModeOrdinal(aMode)) return true;
}
return false;
}
@@ -344,39 +387,39 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public ITexture getTexture(ForgeDirection side) {
ITexture texture = super.getTexture(side);
- if (mMode != 0 && side == facing) {
- if (mMode == getModeOrdinal(ITEM_IN)) {
+ if (mode != 0 && side == facing) {
+ if (mode == getModeOrdinal(ITEM_IN)) {
return TextureFactory.of(
texture,
TextureFactory.of(OVERLAY_PIPE_IN),
TextureFactory.of(ITEM_IN_SIGN),
getCoverTexture(side));
}
- if (mMode == getModeOrdinal(ITEM_OUT)) {
+ if (mode == getModeOrdinal(ITEM_OUT)) {
return TextureFactory.of(
texture,
TextureFactory.of(OVERLAY_PIPE_OUT),
TextureFactory.of(ITEM_OUT_SIGN),
getCoverTexture(side));
}
- if (mMode == getModeOrdinal(FLUID_IN)) {
+ if (mode == getModeOrdinal(FLUID_IN)) {
return TextureFactory.of(
texture,
TextureFactory.of(OVERLAY_PIPE_IN),
TextureFactory.of(FLUID_IN_SIGN),
getCoverTexture(side));
}
- if (mMode == getModeOrdinal(FLUID_OUT)) {
+ if (mode == getModeOrdinal(FLUID_OUT)) {
return TextureFactory.of(
texture,
TextureFactory.of(OVERLAY_PIPE_OUT),
TextureFactory.of(FLUID_OUT_SIGN),
getCoverTexture(side));
}
- if (mMode == getModeOrdinal(ENERGY_IN)) {
+ if (mode == getModeOrdinal(ENERGY_IN)) {
return TextureFactory.of(texture, TextureFactory.of(OVERLAY_ENERGY_IN_MULTI), getCoverTexture(side));
}
- if (mMode == getModeOrdinal(ENERGY_OUT)) {
+ if (mode == getModeOrdinal(ENERGY_OUT)) {
return TextureFactory.of(texture, TextureFactory.of(OVERLAY_ENERGY_OUT_MULTI), getCoverTexture(side));
}
}
@@ -384,11 +427,6 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return TextureFactory.of(texture, getCoverTexture(side));
}
- @Override
- public boolean isUseableByPlayer(EntityPlayer entityPlayer) {
- return false;
- }
-
protected String getModeName(int aMode) {
if (aMode == NOTHING) return "Nothing";
if (aMode == getModeOrdinal(ITEM_IN)) return "Item Input";
@@ -407,11 +445,11 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
}
protected byte getNextAllowedMode(List<Integer> allowedModes) {
- if (mAllowedModes == NOTHING) return NOTHING;
+ if (this.allowedModes == NOTHING) return NOTHING;
final int numModes = allowedModes.size();
for (byte i = 1; i <= numModes; i++) {
- final byte curMode = (byte) ((mMode + i) % numModes);
+ final byte curMode = (byte) ((mode + i) % numModes);
if (curMode == NOTHING || hasMode(1 << (curMode - 1))) return curMode;
}
// Nothing valid found
@@ -420,16 +458,16 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public boolean onMalletRightClick(EntityPlayer aPlayer, ItemStack tCurrentItem, ForgeDirection wrenchSide, float aX,
- float aY, float aZ, ItemStack aTool) {
- if (mAllowedModes == NOTHING) return true;
- if (mMode == NOTHING) {
+ float aY, float aZ) {
+ if (allowedModes == NOTHING) return true;
+ if (mode == NOTHING) {
facing = wrenchSide;
}
- mMode = getNextAllowedMode(BASIC_MODES);
+ setMode(getNextAllowedMode(BASIC_MODES));
if (aPlayer.isSneaking()) {
facing = wrenchSide;
}
- GT_Utility.sendChatToPlayer(aPlayer, "Mode set to `" + getModeName(mMode) + "' (" + mMode + ")");
+ GT_Utility.sendChatToPlayer(aPlayer, "Mode set to `" + getModeName(mode) + "' (" + mode + ")");
sendClientData((EntityPlayerMP) aPlayer);
return true;
}
@@ -447,109 +485,50 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return "gt.multitileentity.multiblock.part";
}
+ @Override
+ public boolean shouldTick(long tickTimer) {
+ return modeSelected(ITEM_OUT, FLUID_OUT);
+ }
+
/**
* TODO: Make sure the energy/item/fluid hatch is facing that way! or has that mode enabled on that side Check
* SIDE_UNKNOWN for or coverbehavior
*/
- /**
- * Fluid - Depending on the part type - proxy it to the multiblock controller, if we have one
- */
+ // #region Fluid - Depending on the part type - proxy it to the multiblock controller, if we have one
@Override
- public int fill(ForgeDirection aDirection, FluidStack aFluidStack, boolean aDoFill) {
- if (!modeSelected(FLUID_IN)) return 0;
+ @Nullable
+ public FluidInventoryLogic getFluidLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type) {
+ if (side != facing && side != ForgeDirection.UNKNOWN) return null;
- if (aFluidStack == null || isWrongFluid(aFluidStack.getFluid())) return 0;
- if (aDirection != ForgeDirection.UNKNOWN
- && (facing.compareTo(aDirection) != 0 || !coverLetsFluidIn(aDirection, aFluidStack.getFluid()))) return 0;
- final IMultiBlockController controller = getTarget(true);
- return controller == null ? 0 : controller.fill(this, aDirection, aFluidStack, aDoFill);
- }
+ if (!modeSelected(FLUID_IN, FLUID_OUT)) return null;
- @Override
- public FluidStack drain(ForgeDirection aDirection, FluidStack aFluidStack, boolean aDoDrain) {
- if (!modeSelected(FLUID_OUT)) return null;
- if (aFluidStack == null || isWrongFluid(aFluidStack.getFluid())) return null;
- if (aDirection != ForgeDirection.UNKNOWN
- && (facing.compareTo(aDirection) != 0 || !coverLetsFluidOut(aDirection, aFluidStack.getFluid())))
- return null;
- final IMultiBlockController controller = getTarget(true);
- return controller == null ? null : controller.drain(this, aDirection, aFluidStack, aDoDrain);
- }
-
- @Override
- public FluidStack drain(ForgeDirection aDirection, int aAmountToDrain, boolean aDoDrain) {
- if (!modeSelected(FLUID_OUT)) return null;
- final IMultiBlockController controller = getTarget(true);
+ IMultiBlockController controller = getTarget(false);
if (controller == null) return null;
- FluidStack aFluidStack = null;
- if (getLockedFluid() != null) {
- aFluidStack = controller.getDrainableFluid(aDirection, getLockedFluid());
- } else {
- aFluidStack = controller.getDrainableFluid(aDirection);
- }
- if (aFluidStack == null || isWrongFluid(aFluidStack.getFluid())) return null;
- if (aDirection != ForgeDirection.UNKNOWN
- && (facing.compareTo(aDirection) != 0 || !coverLetsFluidOut(aDirection, aFluidStack.getFluid())))
- return null;
- return controller.drain(this, aDirection, aFluidStack, aDoDrain);
- }
-
- @Override
- public boolean canFill(ForgeDirection aDirection, Fluid aFluid) {
- if (!modeSelected(FLUID_IN)) return false;
-
- if (aDirection != ForgeDirection.UNKNOWN
- && (facing.compareTo(aDirection) != 0 || !coverLetsFluidIn(aDirection, aFluid))) return false;
- if (isWrongFluid(aFluid)) return false;
- final IMultiBlockController controller = getTarget(true);
- return controller != null && controller.canFill(this, aDirection, aFluid);
+ return controller
+ .getFluidLogic(modeSelected(FLUID_IN) ? InventoryType.Input : InventoryType.Output, lockedInventory);
}
- @Override
- public boolean canDrain(ForgeDirection aDirection, Fluid aFluid) {
- if (!modeSelected(FLUID_OUT)) return false;
- if (aDirection != ForgeDirection.UNKNOWN
- && (facing.compareTo(aDirection) != 0 || !coverLetsFluidOut(aDirection, aFluid))) return false;
- if (isWrongFluid(aFluid)) return false;
- final IMultiBlockController controller = getTarget(true);
- return controller != null && controller.canDrain(this, aDirection, aFluid);
- }
-
- @Override
- public FluidTankInfo[] getTankInfo(ForgeDirection aDirection) {
- if (!modeSelected(FLUID_IN, FLUID_OUT)
- || (aDirection != ForgeDirection.UNKNOWN && facing.compareTo(aDirection) != 0))
- return GT_Values.emptyFluidTankInfo;
- final IMultiBlockController controller = getTarget(true);
- if (controller == null) return GT_Values.emptyFluidTankInfo;
-
- final CoverInfo coverInfo = getCoverInfoAtSide(aDirection);
-
- if ((controller.isLiquidInput(aDirection) && coverInfo.letsFluidIn(null, controller))
- || (controller.isLiquidOutput(aDirection) && coverInfo.letsFluidOut(null, controller)))
- return controller.getTankInfo(this, aDirection);
-
- return GT_Values.emptyFluidTankInfo;
- }
+ // #endregion Fluid
// #region Energy - Depending on the part type - proxy to the multiblock controller, if we have one
@Override
- public PowerLogic getPowerLogic(ForgeDirection side) {
- if (facing == side) {
- return null;
+ @Nonnull
+ public PowerLogic getPowerLogic(@Nonnull ForgeDirection side) {
+ if (side != facing && side != ForgeDirection.UNKNOWN) {
+ return new NullPowerLogic();
}
if (!modeSelected(ENERGY_IN, ENERGY_OUT)) {
- return null;
+ return new NullPowerLogic();
}
final IMultiBlockController controller = getTarget(true);
if (controller == null) {
- return null;
+ return new NullPowerLogic();
}
- return controller.getPowerLogic(this, side);
+ return controller.getPowerLogic();
}
@Override
@@ -562,119 +541,32 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return modeSelected(ENERGY_OUT);
}
- // #endregion
-
- /**
- * Inventory - Depending on the part type - proxy to the multiblock controller, if we have one
- */
- @Override
- public boolean hasInventoryBeenModified() {
- final IMultiBlockController controller = getTarget(true);
- return (controller != null && controller.hasInventoryBeenModified(this));
- }
-
- @Override
- public boolean isValidSlot(int aIndex) {
- final IMultiBlockController controller = getTarget(true);
- return (controller != null && controller.isValidSlot(this, aIndex));
- }
-
- @Override
- public boolean addStackToSlot(int aIndex, ItemStack aStack) {
- if (!modeSelected(ITEM_IN, ITEM_OUT)) return false;
- final IMultiBlockController controller = getTarget(true);
- return (controller != null && controller.addStackToSlot(this, aIndex, aStack));
- }
-
- @Override
- public boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount) {
- if (!modeSelected(ITEM_IN, ITEM_OUT)) return false;
- final IMultiBlockController controller = getTarget(true);
- return (controller != null && controller.addStackToSlot(this, aIndex, aStack, aAmount));
- }
+ // #endregion Energy
- @Override
- public int[] getAccessibleSlotsFromSide(int ordinalSide) {
- final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide);
- if (!modeSelected(ITEM_IN, ITEM_OUT) || (facing != ForgeDirection.UNKNOWN && facing.compareTo(side) != 0))
- return GT_Values.emptyIntArray;
- final IMultiBlockController controller = getTarget(true);
- return controller != null ? controller.getAccessibleSlotsFromSide(this, side) : GT_Values.emptyIntArray;
- }
+ // #region Item - Depending on the part type - proxy to the multiblock controller, if we have one
@Override
- public boolean canInsertItem(int aSlot, ItemStack aStack, int ordinalSide) {
- final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide);
- if (!modeSelected(ITEM_IN, ITEM_OUT)
- || (facing != ForgeDirection.UNKNOWN && (facing.compareTo(side) != 0 || !coverLetsItemsIn(side, aSlot))))
- return false;
- final IMultiBlockController controller = getTarget(true);
- return (controller != null && controller.canInsertItem(this, aSlot, aStack, side));
- }
+ @Nullable
+ public ItemInventoryLogic getItemLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType unused) {
+ if (side != facing && side != ForgeDirection.UNKNOWN) return null;
- @Override
- public boolean canExtractItem(int aSlot, ItemStack aStack, int ordinalSide) {
- final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide);
- if (!modeSelected(ITEM_IN, ITEM_OUT)
- || (facing != ForgeDirection.UNKNOWN && (facing.compareTo(side) != 0 || !coverLetsItemsOut(side, aSlot))))
- return false;
- final IMultiBlockController controller = getTarget(true);
- return (controller != null && controller.canExtractItem(this, aSlot, aStack, side));
- }
-
- @Override
- public int getSizeInventory() {
- if (!modeSelected(ITEM_IN, ITEM_OUT)) return 0;
- final IMultiBlockController controller = getTarget(true);
- return controller != null ? controller.getSizeInventory(this) : 0;
- }
-
- @Override
- public ItemStack getStackInSlot(int aSlot) {
if (!modeSelected(ITEM_IN, ITEM_OUT)) return null;
- final IMultiBlockController controller = getTarget(true);
- return controller != null ? controller.getStackInSlot(this, aSlot) : null;
- }
-
- @Override
- public ItemStack decrStackSize(int aSlot, int aDecrement) {
- if (!modeSelected(ITEM_IN, ITEM_OUT)) return null;
- final IMultiBlockController controller = getTarget(true);
- return controller != null ? controller.decrStackSize(this, aSlot, aDecrement) : null;
- }
- @Override
- public ItemStack getStackInSlotOnClosing(int aSlot) {
- final IMultiBlockController controller = getTarget(true);
- return controller != null ? controller.getStackInSlotOnClosing(this, aSlot) : null;
- }
-
- @Override
- public void setInventorySlotContents(int aSlot, ItemStack aStack) {
- final IMultiBlockController controller = getTarget(true);
- if (controller != null) controller.setInventorySlotContents(this, aSlot, aStack);
- }
-
- @Override
- public String getInventoryName() {
- final IMultiBlockController controller = getTarget(true);
- if (controller != null) return controller.getInventoryName(this);
- return firstNonNull(getCustomName(), getTileEntityName());
- }
+ final IMultiBlockController controller = getTarget(false);
+ if (controller == null) return null;
- @Override
- public int getInventoryStackLimit() {
- final IMultiBlockController controller = getTarget(true);
- return controller != null ? controller.getInventoryStackLimit(this) : 0;
+ return controller
+ .getItemLogic(modeSelected(ITEM_IN) ? InventoryType.Input : InventoryType.Output, lockedInventory);
}
@Override
- public boolean isItemValidForSlot(int aSlot, ItemStack aStack) {
- final IMultiBlockController controller = getTarget(true);
- return controller != null && controller.isItemValidForSlot(this, aSlot, aStack);
+ @Nullable
+ public InventoryType getItemInventoryType() {
+ if (!modeSelected(ITEM_IN, ITEM_OUT)) return InventoryType.Both;
+ return modeSelected(ITEM_IN) ? InventoryType.Input : InventoryType.Output;
}
- // End Inventory
+ // #endregion Item
// === Modular UI ===
@Override
@@ -700,62 +592,6 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return getTarget(true) != null;
}
- protected void addItemInventory(Builder builder, UIBuildContext buildContext) {
- final IMultiBlockController controller = getTarget(false);
- if (controller == null) {
- return;
- }
- final IItemHandlerModifiable inv = controller.getInventoryForGUI(this);
- final Scrollable scrollable = new Scrollable().setVerticalScroll();
- for (int rows = 0; rows * 4 < Math.min(inv.getSlots(), 128); rows++) {
- int columnsToMake = Math.min(Math.min(inv.getSlots(), 128) - rows * 4, 4);
- for (int column = 0; column < columnsToMake; column++) {
- scrollable.widget(
- new SlotWidget(inv, rows * 4 + column).setPos(column * 18, rows * 18)
- .setSize(18, 18));
- }
- }
- builder.widget(
- scrollable.setSize(18 * 4 + 4, 18 * 4)
- .setPos(52, 18));
- DropDownWidget dropDown = new DropDownWidget();
- dropDown.addDropDownItemsSimple(
- controller.getInventoryNames(this),
- (buttonWidget, index, label, setSelected) -> buttonWidget.setOnClick((clickData, widget) -> {
- if (getNameOfInventoryFromIndex(controller, index).equals(Controller.ALL_INVENTORIES_NAME)) {
- mLockedInventory = GT_Values.E;
- mLockedInventoryIndex = 0;
- } else {
- mLockedInventory = getNameOfInventoryFromIndex(controller, index);
- mLockedInventoryIndex = index;
- }
- setSelected.run();
- }),
- true);
- builder.widget(
- dropDown.setSelected(mLockedInventoryIndex)
- .setExpandedMaxHeight(60)
- .setDirection(DropDownWidget.Direction.DOWN)
- .setPos(53, 5)
- .setSize(70, 11));
- }
-
- protected String getNameOfInventoryFromIndex(final IMultiBlockController controller, int index) {
- final List<String> invNames = controller.getInventoryIDs(this);
- if (index > invNames.size()) {
- return invNames.get(0);
- }
- return invNames.get(index);
- }
-
- protected String getNameOfTankArrayFromIndex(final IMultiBlockController controller, int index) {
- final List<String> tankNames = controller.getTankArrayIDs(this);
- if (index > tankNames.size()) {
- return tankNames.get(0);
- }
- return tankNames.get(index);
- }
-
protected boolean isWrongFluid(Fluid fluid) {
if (fluid == null) {
return true;
@@ -776,98 +612,34 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return null;
}
- protected void addFluidInventory(Builder builder, UIBuildContext buildContext) {
- final IMultiBlockController controller = getTarget(false);
+ @Override
+ public void addUIWidgets(Builder builder, UIBuildContext buildContext) {
+ super.addUIWidgets(builder, buildContext);
+ IMultiBlockController controller = getTarget(false);
if (controller == null) {
return;
}
- builder.widget(
- new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK)
- .setPos(7, 4)
- .setSize(85, 95));
- if (modeSelected(FLUID_OUT)) {
+ if ((modeSelected(ITEM_IN, ITEM_OUT))) {
builder.widget(
- new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK)
- .setPos(getGUIWidth() - 77, 4)
- .setSize(70, 40))
- .widget(
- new TextWidget("Locked Fluid").setDefaultColor(COLOR_TEXT_WHITE.get())
- .setPos(getGUIWidth() - 72, 8));
- }
- final IFluidTank[] tanks = controller.getFluidTanksForGUI(this);
- final Scrollable scrollable = new Scrollable().setVerticalScroll();
- for (int rows = 0; rows * 4 < tanks.length; rows++) {
- int columnsToMake = Math.min(tanks.length - rows * 4, 4);
- for (int column = 0; column < columnsToMake; column++) {
- FluidSlotWidget fluidSlot = new FluidSlotWidget(tanks[rows * 4 + column]);
- if (modeSelected(FLUID_OUT)) {
- fluidSlot.setInteraction(true, false);
- }
- scrollable.widget(
- fluidSlot.setPos(column * 18, rows * 18)
- .setSize(18, 18));
- }
+ controller
+ .getItemLogic(modeSelected(ITEM_IN) ? InventoryType.Input : InventoryType.Output, lockedInventory)
+ .getGuiPart()
+ .setSize(18 * 4 + 4, 18 * 5)
+ .setPos(52, 7));
}
- builder.widget(
- scrollable.setSize(18 * 4 + 4, 18 * 4)
- .setPos(12, 21));
- DropDownWidget dropDown = new DropDownWidget();
- dropDown.addDropDownItemsSimple(
- controller.getTankArrayNames(this),
- (buttonWidget, index, label, setSelected) -> buttonWidget.setOnClick((clickData, widget) -> {
- if (getNameOfTankArrayFromIndex(controller, index).equals(Controller.ALL_INVENTORIES_NAME)) {
- mLockedInventory = GT_Values.E;
- mLockedInventoryIndex = 0;
- } else {
- mLockedInventory = getNameOfTankArrayFromIndex(controller, index);
- mLockedInventoryIndex = index;
- }
- setSelected.run();
- }),
- true);
- builder.widget(
- dropDown.setSelected(mLockedInventoryIndex)
- .setExpandedMaxHeight(60)
- .setDirection(DropDownWidget.Direction.DOWN)
- .setPos(13, 8)
- .setSize(70, 11));
- }
- @Override
- public void addUIWidgets(Builder builder, UIBuildContext buildContext) {
- if (modeSelected(ITEM_IN, ITEM_OUT)) {
- addItemInventory(builder, buildContext);
- return;
- }
- if (modeSelected(FLUID_IN, FLUID_OUT)) {
- addFluidInventory(builder, buildContext);
- if (modeSelected(FLUID_OUT)) {
- builder.widget(
- SlotGroup.ofFluidTanks(Collections.singletonList(configurationTank), 1)
- .startFromSlot(0)
- .endAtSlot(0)
- .phantom(true)
- .build()
- .setPos(getGUIWidth() - 72, 20));
- }
- return;
+ if ((modeSelected(FLUID_IN, FLUID_OUT))) {
+ builder.widget(
+ controller
+ .getFluidLogic(modeSelected(FLUID_IN) ? InventoryType.Input : InventoryType.Output, lockedInventory)
+ .getGuiPart()
+ .setSize(18 * 4 + 4, 18 * 5)
+ .setPos(52, 7));
}
}
- @Override
- public ModularWindow createWindow(UIBuildContext buildContext) {
- if (isServerSide()) {
- issueClientUpdate();
- }
- System.out.println("MultiBlockPart::createWindow");
- if (modeSelected(NOTHING, ENERGY_IN, ENERGY_OUT) || mMode == NOTHING) {
- IMultiBlockController controller = getTarget(false);
- if (controller == null) {
- return super.createWindow(buildContext);
- }
- return controller.createWindowGUI(buildContext);
- }
- return super.createWindow(buildContext);
+ protected boolean canOpenControllerGui() {
+ return true;
}
@Override
@@ -891,4 +663,62 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
super.addGregTechLogo(builder);
}
}
+
+ @Override
+ public void addToolTips(List<String> list, ItemStack stack, boolean f3_h) {
+ list.add("A MultiTileEntity Casing");
+ }
+
+ public String getInventoryName() {
+ IMultiBlockController controller = getTarget(false);
+ if (controller == null) return "";
+ if (modeSelected(ITEM_IN, ITEM_OUT)) {
+ InventoryType type = modeSelected(ITEM_IN) ? InventoryType.Input : InventoryType.Output;
+ ItemInventoryLogic itemLogic = controller.getItemLogic(type, lockedInventory);
+ return itemLogic.getDisplayName();
+ }
+ if (modeSelected(FLUID_IN, FLUID_OUT)) {
+ InventoryType type = modeSelected(FLUID_IN) ? InventoryType.Input : InventoryType.Output;
+ FluidInventoryLogic fluidLogic = controller.getFluidLogic(type, lockedInventory);
+ return fluidLogic.getDisplayName();
+ }
+ return "";
+ }
+
+ @Override
+ @Nonnull
+ public ForgeDirection getPowerOutputSide() {
+ if (!modeSelected(ENERGY_OUT)) return ForgeDirection.UNKNOWN;
+ return facing;
+ }
+
+ @Nonnull
+ protected GUIProvider<?> createGUIProvider() {
+ return new PartGUIProvider<>(this);
+ }
+
+ @Override
+ @Nonnull
+ public GUIProvider<?> getGUI(@Nonnull UIBuildContext uiContext) {
+ IMultiBlockController controller = getTarget(false);
+ if (controller == null) return guiProvider;
+ if (!modeSelected(NOTHING, ENERGY_IN, ENERGY_OUT)) return guiProvider;
+ if (!canOpenControllerGui()) return guiProvider;
+ if (uiContext.getPlayer()
+ .isSneaking()) return guiProvider;
+ GUIProvider<?> controllerGUI = controller.getGUI(uiContext);
+ return controllerGUI;
+ }
+
+ @Override
+ public ItemStack getAsItem() {
+ return MultiTileEntityRegistry.getRegistry(getMultiTileEntityRegistryID())
+ .getItem(getMultiTileEntityID());
+ }
+
+ @Override
+ public String getMachineName() {
+ return StatCollector.translateToLocal(getAsItem().getUnlocalizedName());
+ }
+
}