diff options
author | BlueWeabo <ilia.iliev2005@gmail.com> | 2024-01-06 00:41:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-05 23:41:00 +0100 |
commit | 02bedd5c0a96a654c6692edd1b7f2765fd9c46b4 (patch) | |
tree | 57dd675f658dda3caba629f15d4708247e702f88 /src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java | |
parent | fc63cee4c0284635c601889ce49a892cf73082ff (diff) | |
download | GT5-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/Controller.java')
-rw-r--r-- | src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java | 2013 |
1 files changed, 435 insertions, 1578 deletions
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java index 606d957fd6..8ac908be12 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java @@ -1,261 +1,109 @@ 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.multitileentity.enums.GT_MultiTileComponentCasing.EV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.EV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.HV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.IV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.LuV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MAX_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.MV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UEV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UHV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UIV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UMV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.UXV_Sensor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_Conveyor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_Emitter; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_FieldGenerator; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_Motor; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_Piston; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_Pump; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_RobotArm; -import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.ZPM_Sensor; -import static gregtech.loaders.preload.GT_Loader_MultiTileEntities.COMPONENT_CASING_REGISTRY_NAME; -import static mcp.mobius.waila.api.SpecialChars.GREEN; -import static mcp.mobius.waila.api.SpecialChars.RED; -import static mcp.mobius.waila.api.SpecialChars.RESET; +import static gregtech.api.util.GT_Utility.moveMultipleItemStacks; +import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; +import static mcp.mobius.waila.api.SpecialChars.*; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import net.minecraft.block.Block; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; 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; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidTank; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.input.Keyboard; import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.alignment.IAlignment; import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; -import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable; import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; 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; -import com.gtnewhorizons.modularui.api.drawable.ItemDrawable; -import com.gtnewhorizons.modularui.api.forge.IItemHandler; -import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; -import com.gtnewhorizons.modularui.api.forge.ItemStackHandler; -import com.gtnewhorizons.modularui.api.forge.ListItemHandler; -import com.gtnewhorizons.modularui.api.math.Pos2d; import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; -import com.gtnewhorizons.modularui.common.widget.MultiChildWidget; -import com.gtnewhorizons.modularui.common.widget.Scrollable; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; -import com.gtnewhorizons.modularui.common.widget.TabButton; -import com.gtnewhorizons.modularui.common.widget.TabContainer; import cpw.mods.fml.common.network.NetworkRegistry; -import gnu.trove.list.TIntList; -import gnu.trove.list.array.TIntArrayList; -import gregtech.api.enums.GT_Values; import gregtech.api.enums.GT_Values.NBT; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.TextureSet; +import gregtech.api.enums.InventoryType; import gregtech.api.enums.VoidingMode; -import gregtech.api.fluid.FluidTankGT; -import gregtech.api.gui.modularui.GT_UITextures; import gregtech.api.interfaces.IDescribable; import gregtech.api.interfaces.fluid.IFluidStore; -import gregtech.api.interfaces.modularui.ControllerWithOptionalFeatures; +import gregtech.api.logic.ControllerFluidLogic; +import gregtech.api.logic.ControllerItemLogic; +import gregtech.api.logic.FluidInventoryLogic; +import gregtech.api.logic.ItemInventoryLogic; +import gregtech.api.logic.MuTEProcessingLogic; import gregtech.api.logic.PowerLogic; -import gregtech.api.logic.ProcessingLogic; -import gregtech.api.logic.interfaces.PowerLogicHost; -import gregtech.api.logic.interfaces.ProcessingLogicHost; -import gregtech.api.multitileentity.MultiTileEntityContainer; -import gregtech.api.multitileentity.MultiTileEntityRegistry; +import gregtech.api.multitileentity.enums.MultiTileCasingPurpose; import gregtech.api.multitileentity.interfaces.IMultiBlockController; import gregtech.api.multitileentity.interfaces.IMultiBlockPart; -import gregtech.api.multitileentity.interfaces.IMultiTileEntity; import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_AddToolTips; import gregtech.api.multitileentity.machine.MultiTileBasicMachine; import gregtech.api.multitileentity.multiblock.casing.FunctionalCasing; import gregtech.api.multitileentity.multiblock.casing.UpgradeCasing; +import gregtech.api.net.GT_Packet_MultiTileEntity; import gregtech.api.objects.GT_ItemStack; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.recipe.check.CheckRecipeResult; -import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Utility; import gregtech.api.util.GT_Waila; -import gregtech.common.tileentities.casings.upgrade.Inventory; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; /** * Multi Tile Entities - or MuTEs - don't have dedicated hatches, but their casings can become hatches. */ -public abstract class Controller<T extends Controller<T>> extends MultiTileBasicMachine - implements IAlignment, IConstructable, IMultiBlockController, IDescribable, IMTE_AddToolTips, - ISurvivalConstructable, ControllerWithOptionalFeatures { +public abstract class Controller<C extends Controller<C, P>, P extends MuTEProcessingLogic<P>> + extends MultiTileBasicMachine<P> + implements IAlignment, IMultiBlockController, IDescribable, IMTE_AddToolTips, ISurvivalConstructable { public static final String ALL_INVENTORIES_NAME = "all"; + protected static final int AUTO_OUTPUT_FREQUENCY_TICK = 20; private static final Map<Integer, GT_Multiblock_Tooltip_Builder> tooltip = new ConcurrentHashMap<>(); private final List<UpgradeCasing> upgradeCasings = new ArrayList<>(); private final List<FunctionalCasing> functionalCasings = new ArrayList<>(); protected BuildState buildState = new BuildState(); - protected Map<String, String> multiBlockInputInventoryNames = new LinkedHashMap<>(); - protected Map<String, String> multiBlockOutputInventoryNames = new LinkedHashMap<>(); - protected Map<String, String> multiBlockInputInventoryToTankLink = new LinkedHashMap<>(); - protected Map<String, IItemHandlerModifiable> multiBlockInputInventory = new LinkedHashMap<>(); - protected Map<String, IItemHandlerModifiable> multiBlockOutputInventory = new LinkedHashMap<>(); - - 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<>(); - private boolean structureOkay = false, structureChanged = false; private ExtendedFacing extendedFacing = ExtendedFacing.DEFAULT; private IAlignmentLimits limits = getInitialAlignmentLimits(); - private String inventoryName; - private String tankName; protected boolean separateInputs = getDefaultInputSeparationMode(); protected VoidingMode voidingMode = getDefaultVoidingMode(); protected boolean batchMode = getDefaultBatchMode(); protected boolean recipeLock = getDefaultRecipeLockingMode(); + protected boolean shouldSort = false; /** If this is set to true, the machine will get default WAILA behavior */ protected boolean isSimpleMachine = true; + protected boolean isCleanroom = false; + protected ControllerItemLogic controllerItemInput = new ControllerItemLogic(); + protected ControllerItemLogic controllerItemOutput = new ControllerItemLogic(); + protected ControllerFluidLogic controllerFluidInput = new ControllerFluidLogic(); + protected ControllerFluidLogic controllerFluidOutput = new ControllerFluidLogic(); + // A list of sides // Each side has a list of parts that have a cover that need to be ticked protected List<LinkedList<WeakReference<IMultiBlockPart>>> registeredCoveredParts = Arrays.asList( @@ -266,6 +114,15 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic new LinkedList<>(), new LinkedList<>()); + // A list for each purpose that a casing can register to, to be ticked + protected List<LinkedList<WeakReference<IMultiBlockPart>>> registeredTickableParts = new ArrayList<>(); + + public Controller() { + for (int i = 0; i < MultiTileCasingPurpose.values().length; i++) { + registeredTickableParts.add(new LinkedList<>()); + } + } + /** Registry ID of the required casing */ public abstract short getCasingRegistryID(); @@ -288,7 +145,7 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic * other instances, even for those of the same class. */ @Override - public abstract IStructureDefinition<T> getStructureDefinition(); + public abstract IStructureDefinition<C> getStructureDefinition(); /** * Checks the Machine. @@ -296,16 +153,20 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic * NOTE: If using `buildState` be sure to `startBuilding()` and either `endBuilding()` or `failBuilding()` */ public boolean checkMachine() { + calculateTier(); + updatePowerLogic(); + return tier > 0; + } + + protected void calculateTier() { double sum = 0; if (functionalCasings == null || functionalCasings.size() == 0) { - return false; + return; } for (FunctionalCasing casing : functionalCasings) { 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 - return tier > 0; + tier = (int) Math.min(Math.floor(sum / functionalCasings.size()), 14); } @Override @@ -322,77 +183,26 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic (byte) extendedFacing.getFlip() .getIndex()); - saveUpgradeInventoriesToNBT(nbt); - saveUpgradeTanksToNBT(nbt); - nbt.setString(NBT.VOIDING_MODE, voidingMode.name); nbt.setBoolean(NBT.SEPARATE_INPUTS, separateInputs); nbt.setBoolean(NBT.RECIPE_LOCK, recipeLock); nbt.setBoolean(NBT.BATCH_MODE, batchMode); } - private void saveUpgradeInventoriesToNBT(NBTTagCompound nbt) { - final NBTTagList inputInvList = new NBTTagList(); - multiBlockInputInventory.forEach((id, inv) -> { - if (!id.equals("controller")) { - final NBTTagCompound tTag = new NBTTagCompound(); - tTag.setString(NBT.UPGRADE_INVENTORY_UUID, id); - tTag.setString(NBT.UPGRADE_INVENTORY_NAME, multiBlockInputInventoryNames.get(id)); - tTag.setInteger(NBT.UPGRADE_INVENTORY_SIZE, inv.getSlots()); - writeInventory(tTag, inv, NBT.INV_INPUT_LIST); - inputInvList.appendTag(tTag); - } - }); - final NBTTagList outputInvList = new NBTTagList(); - multiBlockOutputInventory.forEach((id, inv) -> { - if (!id.equals("controller")) { - final NBTTagCompound tTag = new NBTTagCompound(); - tTag.setString(NBT.UPGRADE_INVENTORY_UUID, id); - tTag.setString(NBT.UPGRADE_INVENTORY_NAME, multiBlockOutputInventoryNames.get(id)); - tTag.setInteger(NBT.UPGRADE_INVENTORY_SIZE, inv.getSlots()); - writeInventory(tTag, inv, NBT.INV_OUTPUT_LIST); - outputInvList.appendTag(tTag); - } - }); - nbt.setTag(NBT.UPGRADE_INVENTORIES_INPUT, inputInvList); - 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 + protected void saveItemLogic(NBTTagCompound nbt) { + NBTTagCompound itemInputNBT = controllerItemInput.saveToNBT(); + nbt.setTag(NBT.INV_INPUT_LIST, itemInputNBT); + NBTTagCompound itemOutputNBT = controllerItemOutput.saveToNBT(); + nbt.setTag(NBT.INV_OUTPUT_LIST, itemOutputNBT); + } + + @Override + protected void saveFluidLogic(NBTTagCompound nbt) { + NBTTagCompound fluidInputNBT = controllerFluidInput.saveToNBT(); + nbt.setTag(NBT.TANK_IN, fluidInputNBT); + NBTTagCompound fluidOutputNBT = controllerFluidOutput.saveToNBT(); + nbt.setTag(NBT.TANK_OUT, fluidOutputNBT); } @Override @@ -401,83 +211,37 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic // 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) 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(getFrontFacing(), Rotation.byIndex(nbt.getByte(NBT.ROTATION)), Flip.byIndex(nbt.getByte(NBT.FLIP))); - loadUpgradeInventoriesFromNBT(nbt); - loadUpgradeTanksFromNBT(nbt); - voidingMode = VoidingMode.fromName(nbt.getString(NBT.VOIDING_MODE)); 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, Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < listInputInventories.tagCount(); i++) { - final NBTTagCompound nbtInv = listInputInventories.getCompoundTagAt(i); - final String invUUID = nbtInv.getString(NBT.UPGRADE_INVENTORY_UUID); - final String invName = nbtInv.getString(NBT.UPGRADE_INVENTORY_NAME); - final int invSize = nbtInv.getInteger(NBT.UPGRADE_INVENTORY_SIZE); - final IItemHandlerModifiable inv = new ItemStackHandler(invSize); - loadInventory(nbtInv, inv, NBT.INV_INPUT_LIST); - registerInventory(invName, invUUID, invSize, Inventory.INPUT); - } - - 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); - final String invUUID = nbtInv.getString(NBT.UPGRADE_INVENTORY_UUID); - final String invName = nbtInv.getString(NBT.UPGRADE_INVENTORY_NAME); - final int invSize = nbtInv.getInteger(NBT.UPGRADE_INVENTORY_SIZE); - IItemHandlerModifiable inv = new ItemStackHandler(invSize); - loadInventory(nbtInv, inv, NBT.INV_OUTPUT_LIST); - registerInventory(invName, invUUID, invSize, Inventory.OUTPUT); + @Override + protected void loadItemLogic(NBTTagCompound nbt) { + if (!nbt.hasKey(NBT.INV_INPUT_LIST) && !nbt.hasKey(NBT.INV_OUTPUT_LIST)) { + controllerItemInput.addInventory(new ItemInventoryLogic(16)); + controllerItemOutput.addInventory(new ItemInventoryLogic(16)); + return; } + controllerItemInput.loadFromNBT(nbt.getCompoundTag(NBT.INV_INPUT_LIST)); + controllerItemOutput.loadFromNBT(nbt.getCompoundTag(NBT.INV_OUTPUT_LIST)); } - 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); + @Override + protected void loadFluidLogic(NBTTagCompound nbt) { + if (!nbt.hasKey(NBT.TANK_IN) && !nbt.hasKey(NBT.TANK_OUT)) { + controllerFluidInput.addInventory(new FluidInventoryLogic(16, 32000)); + controllerFluidOutput.addInventory(new FluidInventoryLogic(16, 32000)); + return; } + controllerFluidInput.loadFromNBT(nbt.getCompoundTag(NBT.TANK_IN)); + controllerFluidOutput.loadFromNBT(nbt.getCompoundTag(NBT.TANK_OUT)); } @Override @@ -489,9 +253,9 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic public String[] getDescription() { if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { return getTooltip().getStructureInformation(); - } else { - return getTooltip().getInformation(); } + + return getTooltip().getInformation(); } @Override @@ -519,6 +283,7 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic // Only trigger an update if forced (from onPostTick, generally), or if the structure has changed if ((structureChanged || aForceReset)) { + clearSpecialLists(); structureOkay = checkMachine(); } structureChanged = false; @@ -531,8 +296,6 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } public final boolean checkPiece(String piece, Vec3Impl offset) { - functionalCasings.clear(); - upgradeCasings.clear(); return checkPiece(piece, offset.get0(), offset.get1(), offset.get2()); } @@ -617,8 +380,8 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @SuppressWarnings("unchecked") - private IStructureDefinition<Controller<T>> getCastedStructureDefinition() { - return (IStructureDefinition<Controller<T>>) getStructureDefinition(); + private IStructureDefinition<Controller<C, P>> getCastedStructureDefinition() { + return (IStructureDefinition<Controller<C, P>>) getStructureDefinition(); } @Override @@ -628,24 +391,27 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic @Override public void setExtendedFacing(ExtendedFacing newExtendedFacing) { - if (extendedFacing != newExtendedFacing) { - onStructureChange(); - if (structureOkay) stopMachine(false); - extendedFacing = newExtendedFacing; - structureOkay = false; - if (isServerSide()) { - StructureLibAPI.sendAlignment( - this, - new NetworkRegistry.TargetPoint( - getWorld().provider.dimensionId, - getXCoord(), - getYCoord(), - getZCoord(), - 512)); - } else { - issueTextureUpdate(); - } + if (extendedFacing == newExtendedFacing) { + return; + } + + onStructureChange(); + if (structureOkay) stopMachine(false); + extendedFacing = newExtendedFacing; + structureOkay = false; + if (isServerSide()) { + StructureLibAPI.sendAlignment( + this, + new NetworkRegistry.TargetPoint( + getWorld().provider.dimensionId, + getXCoord(), + getYCoord(), + getZCoord(), + 512)); + } else { + issueTextureUpdate(); } + } @Override @@ -686,6 +452,31 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override + public void registerCaseWithPurpose(MultiTileCasingPurpose purpose, IMultiBlockPart part) { + final LinkedList<WeakReference<IMultiBlockPart>> tickableParts = registeredTickableParts.get(purpose.ordinal()); + final Iterator<WeakReference<IMultiBlockPart>> it = tickableParts.iterator(); + while (it.hasNext()) { + final IMultiBlockPart next = (it.next()).get(); + if (next == null) { + it.remove(); + } else if (next == part) { + return; + } + } + tickableParts.add(new WeakReference<>(part)); + } + + @Override + public void unregisterCaseWithPurpose(MultiTileCasingPurpose purpose, IMultiBlockPart part) { + final LinkedList<WeakReference<IMultiBlockPart>> tickableParts = registeredTickableParts.get(purpose.ordinal()); + final Iterator<WeakReference<IMultiBlockPart>> it = tickableParts.iterator(); + while (it.hasNext()) { + final IMultiBlockPart next = (it.next()).get(); + if (next == null || next == part) it.remove(); + } + } + + @Override public void onFirstTick(boolean isServerSide) { super.onFirstTick(isServerSide); if (isServerSide) { @@ -715,7 +506,7 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public void onTick(long timer, boolean isServerSide) { + public void onTick(long tick, boolean isServerSide) { if (!tickCovers()) { return; } @@ -723,24 +514,94 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic @Override public void onPostTick(long tick, boolean isServerSide) { - if (isServerSide) { - if (tick % 600 == 5) { - clearSpecialLists(); - // Recheck the structure every 30 seconds or so - if (!checkStructure(false)) checkStructure(true); + if (!isServerSide) { // client side + doActivitySound(getActivitySoundLoop()); + return; + } + + // server side + if (tick % 600 == 5) { + // Recheck the structure every 30 seconds or so + if (!checkStructure(false)) checkStructure(true); + } + if (checkStructure(false)) { + runMachine(tick); + pushItemOutputs(tick); + pushFluidOutputs(tick); + + } else { + stopMachine(false); + } + + } + + protected void pushItemOutputs(long tick) { + if (tick % AUTO_OUTPUT_FREQUENCY_TICK != 0) return; + final LinkedList<WeakReference<IMultiBlockPart>> registeredItemOutputs = registeredTickableParts + .get(MultiTileCasingPurpose.ItemOutput.ordinal()); + final Iterator<WeakReference<IMultiBlockPart>> itemOutputIterator = registeredItemOutputs.iterator(); + while (itemOutputIterator.hasNext()) { + final IMultiBlockPart part = (itemOutputIterator.next()).get(); + if (part == null) { + itemOutputIterator.remove(); + continue; } - if (checkStructure(false)) { - runMachine(tick); - } else { - stopMachine(false); + if (!part.shouldTick(mTickTimer)) { + itemOutputIterator.remove(); + continue; + } + + final IInventory facingInventory = part.getIInventoryAtSide(part.getFrontFacing()); + if (facingInventory == null) { + continue; + } + + moveMultipleItemStacks( + part, + facingInventory, + part.getFrontFacing(), + part.getBackFacing(), + null, + false, + (byte) 64, + (byte) 1, + (byte) 64, + (byte) 1, + part.getSizeInventory()); + for (int i = 0; i < part.getSizeInventory(); i++) { + if (part.getStackInSlot(i) != null && part.getStackInSlot(i).stackSize <= 0) { + part.setInventorySlotContents(i, null); + } + } + + } + } + + protected void pushFluidOutputs(long tick) { + if (tick % AUTO_OUTPUT_FREQUENCY_TICK != 0) return; + final LinkedList<WeakReference<IMultiBlockPart>> registeredFluidOutputs = registeredTickableParts + .get(MultiTileCasingPurpose.FluidOutput.ordinal()); + final Iterator<WeakReference<IMultiBlockPart>> fluidOutputIterator = registeredFluidOutputs.iterator(); + while (fluidOutputIterator.hasNext()) { + final IMultiBlockPart part = (fluidOutputIterator.next()).get(); + if (part == null) { + fluidOutputIterator.remove(); + continue; + } + if (!part.shouldTick(mTickTimer)) { + fluidOutputIterator.remove(); } - } else { - doActivitySound(getActivitySoundLoop()); } } + @Override + public void setCleanroom(boolean cleanroom) { + isCleanroom = cleanroom; + } + protected void clearSpecialLists() { upgradeCasings.clear(); + functionalCasings.clear(); } @Override @@ -773,47 +634,6 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic this.limits = mLimits; } - // IMachineProgress - @Override - public long getProgress() { - return progressTime; - } - - @Override - public long getMaxProgress() { - return maxProgressTime; - } - - @Override - public boolean increaseProgress(int aProgressAmountInTicks) { - return increaseProgressGetOverflow(aProgressAmountInTicks) != aProgressAmountInTicks; - } - - @Override - public FluidStack getDrainableFluid(ForgeDirection side) { - return getDrainableFluid(side, null); - } - - @Override - public FluidStack getDrainableFluid(ForgeDirection side, Fluid fluidToDrain) { - final IFluidTank tank = getFluidTankDrainable( - side, - fluidToDrain == null ? null : new FluidStack(fluidToDrain, 0)); - return tank == null ? null : tank.getFluid(); - } - - /** - * Increases the Progress, returns the overflown Progress. - */ - public int increaseProgressGetOverflow(int aProgress) { - return 0; - } - - @Override - public boolean hasThingsToDo() { - return getMaxProgress() > 0; - } - public boolean isSeparateInputs() { return separateInputs; } @@ -822,8 +642,6 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic separateInputs = aSeparateInputs; } - // End IMachineProgress - protected IAlignmentLimits getInitialAlignmentLimits() { return (d, r, f) -> !f.isVerticallyFliped(); } @@ -877,226 +695,7 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } } - public <S> IStructureElement<S> addMultiTileCasing(String registryName, int meta, int modes) { - MultiTileEntityRegistry registry = MultiTileEntityRegistry.getRegistry(registryName); - int registryID = Block.getIdFromBlock(registry.mBlock); - return addMultiTileCasing(registryID, meta, modes); - } - - public <S> IStructureElement<S> addMultiTileCasing(int registryID, int meta, int modes) { - return new IStructureElement<S>() { - - private final short[] DEFAULT = new short[] { 255, 255, 255, 0 }; - private IIcon[] mIcons = null; - - @Override - public boolean check(S t, World world, int x, int y, int z) { - final TileEntity tileEntity = world.getTileEntity(x, y, z); - if (!(tileEntity instanceof MultiBlockPart part)) return false; - - if (registryID != part.getMultiTileEntityRegistryID() || meta != part.getMultiTileEntityID()) - return false; - - final IMultiBlockController tTarget = part.getTarget(false); - if (tTarget != null && tTarget != t) return false; - - part.setTarget((IMultiBlockController) t, modes); - - ((Controller<?>) t).registerSpecialCasings(part); - return true; - } - - @Override - public boolean spawnHint(S t, World world, int x, int y, int z, ItemStack trigger) { - if (mIcons == null) { - mIcons = new IIcon[6]; - Arrays.fill(mIcons, TextureSet.SET_NONE.mTextures[OrePrefixes.block.mTextureIndex].getIcon()); - // Arrays.fill(mIcons, getTexture(aCasing); - // for (byte i : ALL_VALID_SIDES) { - // mIcons[i] = aCasing.getIcon(i, aMeta); - // } - } - final short[] RGBA = DEFAULT; - StructureLibAPI.hintParticleTinted(world, x, y, z, mIcons, RGBA); - // StructureLibAPI.hintParticle(world, x, y, z, aCasing, aMeta); - return true; - } - - @Override - public boolean placeBlock(S t, World world, int x, int y, int z, ItemStack trigger) { - final MultiTileEntityRegistry tRegistry = MultiTileEntityRegistry.getRegistry(registryID); - final MultiTileEntityContainer tContainer = tRegistry - .getNewTileEntityContainer(world, x, y, z, meta, null); - if (tContainer == null) { - GT_FML_LOGGER.error("NULL CONTAINER"); - return false; - } - final IMultiTileEntity te = ((IMultiTileEntity) tContainer.mTileEntity); - if (!(te instanceof MultiBlockPart)) { - GT_FML_LOGGER.error("Not a multiblock part"); - return false; - } - if (world.setBlock(x, y, z, tContainer.mBlock, 15 - tContainer.mBlockMetaData, 2)) { - tContainer.setMultiTile(world, x, y, z); - ((MultiBlockPart) te).setTarget(Controller.this, modes); - - ((Controller<?>) t).registerSpecialCasings((MultiBlockPart) te); - } - - return false; - } - - public IIcon getTexture(OrePrefixes aBlock) { - return TextureSet.SET_NONE.mTextures[OrePrefixes.block.mTextureIndex].getIcon(); - } - }; - } - - protected <S> IStructureElementChain<S> addMotorCasings(int modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_Motor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_Motor.getId(), modes)); - } - - protected <S> IStructureElementChain<S> addPumpCasings(int modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_Pump.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_Pump.getId(), modes)); - } - - protected <S> IStructureElementChain<S> addPistonCasings(int modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_Piston.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_Piston.getId(), modes)); - } - - protected <S> IStructureElementChain<S> addConveyorCasings(int modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_Conveyor.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_Conveyor.getId(), modes)); - } - - protected <S> IStructureElementChain<S> addRobotArmCasings(int modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_RobotArm.getId(), modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_RobotArm.getId(), modes)); - } - - protected <S> IStructureElementChain<S> addSensorCasings(int Modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_Sensor.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_Sensor.getId(), Modes)); - } - - protected <S> IStructureElementChain<S> addEmitterCasings(int Modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_Emitter.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_Emitter.getId(), Modes)); - } - - protected <S> IStructureElementChain<S> addFieldGeneratorCasings(int Modes) { - return ofChain( - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, HV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, EV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, IV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, LuV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, ZPM_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UHV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UEV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UIV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UMV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, UXV_FieldGenerator.getId(), Modes), - addMultiTileCasing(COMPONENT_CASING_REGISTRY_NAME, MAX_FieldGenerator.getId(), Modes)); - } - - protected void registerSpecialCasings(MultiBlockPart part) { + public void registerSpecialCasings(MultiBlockPart part) { if (part instanceof UpgradeCasing) { upgradeCasings.add((UpgradeCasing) part); } @@ -1105,728 +704,177 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } } - /** - * Fluid - MultiBlock related Fluid Tank behaviour. - */ - public void registerFluidInventory(String name, String id, int numberOfSlots, long capacity, - long capacityMultiplier, int type) { - if (name == null || name.equals("") - || id == null - || id.equals("") - || numberOfSlots < 0 - || capacity < 0 - || capacityMultiplier < 0) { - return; - } - FluidTankGT[] tanks = new FluidTankGT[numberOfSlots]; - for (int i = 0; i < numberOfSlots; i++) { - tanks[i] = new FluidTankGT(capacity).setCapacityMultiplier(capacityMultiplier); - } - registerFluidInventory(name, id, tanks, type); - } - - public void registerFluidInventory(String name, String id, FluidTankGT[] fluidInventory, int type) { - if (name == null || name.equals("") - || id == null - || id.equals("") - || fluidInventory == null - || fluidInventory.length == 0) { - return; - } - if (type == Inventory.INPUT || type == Inventory.BOTH) { - if (multiBlockInputTank.containsKey(id)) return; - multiBlockInputTank.put(id, fluidInventory); - multiBlockInputTankNames.put(id, name); - } - if (type == Inventory.OUTPUT || type == Inventory.BOTH) { - if (multiBlockOutputTank.containsKey(id)) return; - multiBlockOutputTank.put(id, fluidInventory); - multiBlockOutputTankNames.put(id, name); - } - } - - public void unregisterFluidInventory(String aName, String aID, int aType) { - if ((aType == Inventory.INPUT || aType == Inventory.BOTH) && multiBlockInputTank.containsKey(aID)) { - multiBlockInputTank.remove(aID, multiBlockInputTank.get(aID)); - multiBlockInputTankNames.remove(aID, aName); - } - if ((aType == Inventory.OUTPUT || aType == Inventory.BOTH) && multiBlockOutputTank.containsKey(aID)) { - multiBlockOutputTank.remove(aID, multiBlockOutputTank.get(aID)); - multiBlockOutputTankNames.remove(aID, aName); - } - } - - protected FluidTankGT[] getTanksForInput() { - List<FluidTankGT> tanks = new ArrayList<>(); - for (FluidTankGT[] inputTanks : multiBlockInputTank.values()) { - tanks.addAll(Arrays.asList(inputTanks)); - } - return tanks.toArray(new FluidTankGT[0]); - } - - protected FluidTankGT[] getTanksForOutput() { - List<FluidTankGT> tanks = new ArrayList<>(); - for (FluidTankGT[] outputTanks : multiBlockOutputTank.values()) { - tanks.addAll(Arrays.asList(outputTanks)); - } - return tanks.toArray(new FluidTankGT[0]); - } - - protected IFluidTank getFluidTankFillable(MultiBlockPart aPart, ForgeDirection side, FluidStack aFluidToFill) { - return getFluidTankFillable(side, aFluidToFill); - } - - protected IFluidTank getFluidTankDrainable(MultiBlockPart aPart, ForgeDirection side, FluidStack aFluidToDrain) { - return getFluidTankDrainable(side, aFluidToDrain); - } - - protected IFluidTank[] getFluidTanks(MultiBlockPart aPart, ForgeDirection side) { - return getFluidTanks(side); - } - - @Override - public int fill(MultiBlockPart aPart, ForgeDirection aDirection, FluidStack aFluid, boolean aDoFill) { - if (aFluid == null || aFluid.amount <= 0) return 0; - final IFluidTank tTank = getFluidTankFillable(aPart, aDirection, aFluid); - if (tTank == null) return 0; - final int rFilledAmount = tTank.fill(aFluid, aDoFill); - if (rFilledAmount > 0 && aDoFill) hasInventoryChanged = true; - return rFilledAmount; - } - - @Override - public FluidStack drain(MultiBlockPart aPart, ForgeDirection aDirection, FluidStack aFluid, boolean aDoDrain) { - if (aFluid == null || aFluid.amount <= 0) return null; - final IFluidTank tTank = getFluidTankDrainable(aPart, aDirection, aFluid); - if (tTank == null || tTank.getFluid() == null - || tTank.getFluidAmount() == 0 - || !tTank.getFluid() - .isFluidEqual(aFluid)) - return null; - final FluidStack rDrained = tTank.drain(aFluid.amount, aDoDrain); - if (rDrained != null && aDoDrain) markInventoryBeenModified(); - return rDrained; - } - - @Override - public FluidStack drain(MultiBlockPart aPart, ForgeDirection aDirection, int aAmountToDrain, boolean aDoDrain) { - if (aAmountToDrain <= 0) return null; - final IFluidTank tTank = getFluidTankDrainable(aPart, aDirection, null); - if (tTank == null || tTank.getFluid() == null || tTank.getFluidAmount() == 0) return null; - final FluidStack rDrained = tTank.drain(aAmountToDrain, aDoDrain); - if (rDrained != null && aDoDrain) markInventoryBeenModified(); - return rDrained; - } - - @Override - public boolean canFill(MultiBlockPart aPart, ForgeDirection aDirection, Fluid aFluid) { - if (aFluid == null) return false; - final IFluidTank tTank = getFluidTankFillable(aPart, aDirection, new FluidStack(aFluid, 0)); - return tTank != null && (tTank.getFluid() == null || tTank.getFluid() - .getFluid() == aFluid); - } - - @Override - public boolean canDrain(MultiBlockPart aPart, ForgeDirection aDirection, Fluid aFluid) { - if (aFluid == null) return false; - final IFluidTank tTank = getFluidTankDrainable(aPart, aDirection, new FluidStack(aFluid, 0)); - return tTank != null && (tTank.getFluid() != null && tTank.getFluid() - .getFluid() == aFluid); - } - - @Override - public FluidTankInfo[] getTankInfo(MultiBlockPart aPart, ForgeDirection aDirection) { - final IFluidTank[] tTanks = getFluidTanks(aPart, aDirection); - if (tTanks == null || tTanks.length <= 0) return GT_Values.emptyFluidTankInfo; - final FluidTankInfo[] rInfo = new FluidTankInfo[tTanks.length]; - for (int i = 0; i < tTanks.length; i++) rInfo[i] = new FluidTankInfo(tTanks[i]); - return rInfo; - } - - @Override - public IFluidTank[] getFluidTanksForGUI(MultiBlockPart aPart) { - final String lockedInventory = aPart.getLockedInventory(); - if (lockedInventory == null) { - if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return getTanksForInput(); - else if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return getTanksForOutput(); - } else { - final Map<String, FluidTankGT[]> tankMap = getMultiBlockTankArray(aPart); - if (tankMap == null) return GT_Values.emptyFluidTank; - final FluidTankGT[] tanks = tankMap.get(lockedInventory); - return tanks != null ? tanks : GT_Values.emptyFluidTank; - } - return GT_Values.emptyFluidTank; - } - - // #region Energy - @Override - public PowerLogic getPowerLogic(IMultiBlockPart part, ForgeDirection side) { - if (!(this instanceof PowerLogicHost powerLogicHost)) { - return null; - } - - if (part.getFrontFacing() != side) { - return null; - } - - return powerLogicHost.getPowerLogic(side); - } - // #endregion Energy - - /** - * Item - MultiBlock related Item behaviour. - */ - @Override - public void registerInventory(String aName, String aID, int aInventorySize, int aType) { - registerInventory(aName, aID, new ItemStackHandler(aInventorySize), aType); - } - - public void registerInventory(String name, String id, IItemHandlerModifiable inventory, int type) { - if (name == null || name.equals("") || id == null || id.equals("") || inventory == null) { - return; - } - if (type == Inventory.INPUT || type == Inventory.BOTH) { - if (multiBlockInputInventory.containsKey(id)) return; - multiBlockInputInventory.put(id, inventory); - multiBlockInputInventoryNames.put(id, name); - } - if (type == Inventory.OUTPUT || type == Inventory.BOTH) { - if (multiBlockOutputInventory.containsKey(id)) return; - multiBlockOutputInventory.put(id, inventory); - multiBlockOutputInventoryNames.put(id, name); - } - } - - @Override - public void unregisterInventory(String aName, String aID, int aType) { - if ((aType == Inventory.INPUT || aType == Inventory.BOTH) && multiBlockInputInventory.containsKey(aID)) { - multiBlockInputInventory.remove(aID, multiBlockInputInventory.get(aID)); - multiBlockInputInventoryNames.remove(aID, aName); - } - if ((aType == Inventory.OUTPUT || aType == Inventory.BOTH) && multiBlockOutputInventory.containsKey(aID)) { - multiBlockOutputInventory.remove(aID, multiBlockOutputInventory.get(aID)); - multiBlockOutputInventoryNames.remove(aID, aName); - } - } - - @Override - public void changeInventoryName(String aName, String aID, int aType) { - if ((aType == Inventory.INPUT || aType == Inventory.BOTH) && multiBlockInputInventoryNames.containsKey(aID)) { - multiBlockInputInventoryNames.put(aID, aName); - } - if ((aType == Inventory.OUTPUT || aType == Inventory.BOTH) && multiBlockOutputInventoryNames.containsKey(aID)) { - multiBlockOutputInventoryNames.put(aID, aName); - } - } - - @Override - public boolean hasInventoryBeenModified(MultiBlockPart aPart) { - if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) return hasInventoryBeenModified(); - else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) return hasOutputInventoryBeenModified(); - - return false; - } + // #region Fluid - MultiBlock related Fluid Tank behaviour. @Override - public boolean isValidSlot(MultiBlockPart aPart, int aIndex) { - return false; + @Nullable + public FluidInventoryLogic getFluidLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type) { + if (side == facing) return null; + return switch (type) { + case Input -> controllerFluidInput.getAllInventoryLogics(); + case Output -> controllerFluidOutput.getAllInventoryLogics(); + default -> null; + }; } - @Override - public void enableWorking() { - super.enableWorking(); - if (!structureOkay) { - checkStructure(true); - } + @Nullable + public FluidInventoryLogic getFluidLogic(@Nonnull InventoryType type, @Nullable UUID id) { + return switch (type) { + case Input -> controllerFluidInput.getInventoryLogic(id); + case Output -> controllerFluidOutput.getInventoryLogic(id); + default -> null; + }; } @Override - public IItemHandlerModifiable getInventoryForGUI(MultiBlockPart aPart) { - if (isServerSide()) { - for (UpgradeCasing tPart : upgradeCasings) { - if (!(tPart instanceof Inventory)) continue; - tPart.issueClientUpdate(); + @Nonnull + public UUID registerFluidInventory(int tanks, long capacity, int tier, @Nonnull InventoryType type, + boolean isUpgradeInventory) { + return switch (type) { + case Input -> controllerFluidInput + .addInventory(new FluidInventoryLogic(tanks, capacity, tier, isUpgradeInventory)); + case Output -> controllerFluidOutput + .addInventory(new FluidInventoryLogic(tanks, capacity, tier, isUpgradeInventory)); + case Both -> { + UUID id = controllerFluidInput + .addInventory(new FluidInventoryLogic(tanks, capacity, tier, isUpgradeInventory)); + controllerFluidOutput + .addInventory(id, new FluidInventoryLogic(tanks, capacity, tier, isUpgradeInventory)); + yield id; } - } - final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart); - if (multiBlockInventory == null) return null; - - final String lockedInventory = aPart.getLockedInventory(); - if (lockedInventory == null) { - return new ListItemHandler(multiBlockInventory.values()); - } else { - final IItemHandlerModifiable inv = multiBlockInventory.get(lockedInventory); - return inv; - } - } - - @Override - public boolean addStackToSlot(MultiBlockPart aPart, int aIndex, ItemStack aStack) { - return false; + }; } @Override - public boolean addStackToSlot(MultiBlockPart aPart, int aIndex, ItemStack aStack, int aAmount) { - return false; - } - - protected Map<String, FluidTankGT[]> getMultiBlockTankArray(MultiBlockPart aPart) { - if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return multiBlockInputTank; - else if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return multiBlockOutputTank; - return null; - } - - protected Map<String, String> getMultiBlockTankArrayNames(MultiBlockPart aPart) { - if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return multiBlockInputTankNames; - else if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return multiBlockOutputTankNames; - return null; - } - - protected Map<String, IItemHandlerModifiable> getMultiBlockInventory(MultiBlockPart aPart) { - if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) return multiBlockInputInventory; - else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) return multiBlockOutputInventory; - return null; - } - - protected Map<String, String> getMultiBlockInventoryNames(MultiBlockPart aPart) { - if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) return multiBlockInputInventoryNames; - else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) return multiBlockOutputInventoryNames; - return null; - } - - protected Pair<IItemHandlerModifiable, Integer> getInventory(MultiBlockPart aPart, int aSlot) { - final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart); - if (multiBlockInventory == null) return null; - - final String invName = aPart.getLockedInventory(); - if (invName != null && !invName.isEmpty()) return new ImmutablePair<>(multiBlockInventory.get(invName), aSlot); - - int start = 0; - for (IItemHandlerModifiable inv : multiBlockInventory.values()) { - if (aSlot >= start && aSlot < start + inv.getSlots()) { - return new ImmutablePair<>(inv, aSlot - start); + @Nonnull + public FluidInventoryLogic unregisterFluidInventory(@Nonnull UUID id, @Nonnull InventoryType type) { + return switch (type) { + case Input -> controllerFluidInput.removeInventory(id); + case Output -> controllerFluidOutput.removeInventory(id); + case Both -> { + FluidInventoryLogic input = controllerFluidInput.removeInventory(id); + FluidInventoryLogic output = controllerFluidOutput.removeInventory(id); + yield new FluidInventoryLogic( + Arrays.asList(input, output) + .stream() + .map(inv -> inv.getInventory()) + .collect(Collectors.toList())); } - start += inv.getSlots(); - } - return null; + }; } @Override - public int[] getAccessibleSlotsFromSide(MultiBlockPart aPart, ForgeDirection side) { - final TIntList tList = new TIntArrayList(); - final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart); - if (multiBlockInventory == null) return tList.toArray(); - - final String lockedInventory = aPart.getLockedInventory(); - // Item in --> input inv - // Item out --> output inv - - int start = 0; - if (lockedInventory == null) { - for (IItemHandlerModifiable inv : multiBlockInventory.values()) { - for (int i = start; i < inv.getSlots() + start; i++) tList.add(i); - start += inv.getSlots(); - } - } else { - final IItemHandlerModifiable inv = multiBlockInventory.get(lockedInventory); - final int len = inv != null ? inv.getSlots() : 0; - for (int i = 0; i < len; i++) tList.add(i); + public void changeFluidInventoryDisplayName(@Nullable UUID id, @Nullable String displayName, + @Nonnull InventoryType type) { + switch (type) { + case Input: + controllerFluidInput.setInventoryDisplayName(id, displayName); + break; + case Output: + controllerFluidOutput.setInventoryDisplayName(id, displayName); + break; + case Both: + controllerFluidInput.setInventoryDisplayName(id, displayName); + controllerFluidOutput.setInventoryDisplayName(id, displayName); + break; } - return tList.toArray(); } - @Override - public boolean canInsertItem(MultiBlockPart aPart, int aSlot, ItemStack aStack, ForgeDirection side) { - final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot); - if (tInv == null) return false; - - final int tSlot = tInv.getRight(); - final IItemHandlerModifiable inv = tInv.getLeft(); - - return inv.getStackInSlot(tSlot) == null || GT_Utility.areStacksEqual(aStack, inv.getStackInSlot(tSlot)); // && - // allowPutStack(getBaseMetaTileEntity(), - // aIndex, - // (byte) - // aSide, - // aStack) - } + // #endregion Fluid - @Override - public boolean canExtractItem(MultiBlockPart aPart, int aSlot, ItemStack aStack, ForgeDirection side) { - final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot); - if (tInv == null) return false; - - final int tSlot = tInv.getRight(); - final IItemHandlerModifiable inv = tInv.getLeft(); - - return inv.getStackInSlot(tSlot) != null; // && allowPullStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, - // aStack); - } + // #region Item - MultiBlock related Item behaviour. @Override - public int getSizeInventory(MultiBlockPart aPart) { - final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart); - if (multiBlockInventory == null) return 0; - - final String lockedInventory = aPart.getLockedInventory(); - if (lockedInventory == null) { - int len = 0; - for (IItemHandlerModifiable inv : multiBlockInventory.values()) len += inv.getSlots(); - return len; - } else { - final IItemHandlerModifiable inv = multiBlockInventory.get(lockedInventory); - return inv != null ? inv.getSlots() : 0; - } + @Nullable + public ItemInventoryLogic getItemLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type) { + if (side == facing) return null; + return switch (type) { + case Input -> controllerItemInput.getAllInventoryLogics(); + case Output -> controllerItemOutput.getAllInventoryLogics(); + default -> null; + }; } @Override - public ItemStack getStackInSlot(MultiBlockPart aPart, int aSlot) { - final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot); - if (tInv == null) return null; - - final int tSlot = tInv.getRight(); - final IItemHandlerModifiable inv = tInv.getLeft(); - if (inv == null) return null; - - return inv.getStackInSlot(tSlot); + @Nullable + public ItemInventoryLogic getItemLogic(@Nonnull InventoryType type, @Nullable UUID id) { + return switch (type) { + case Input -> controllerItemInput.getInventoryLogic(id); + case Output -> controllerItemOutput.getInventoryLogic(id); + default -> null; + }; } @Override - public ItemStack decrStackSize(MultiBlockPart aPart, int aSlot, int aDecrement) { - final ItemStack tStack = getStackInSlot(aPart, aSlot); - ItemStack rStack = GT_Utility.copyOrNull(tStack); - if (tStack != null) { - if (tStack.stackSize <= aDecrement) { - setInventorySlotContents(aPart, aSlot, null); - } else { - rStack = tStack.splitStack(aDecrement); - if (tStack.stackSize == 0) setInventorySlotContents(aPart, aSlot, null); + @Nonnull + public UUID registerItemInventory(int slots, int tier, @Nonnull InventoryType type, boolean isUpgradeInventory) { + return switch (type) { + case Input -> controllerItemInput.addInventory(new ItemInventoryLogic(slots, tier, isUpgradeInventory)); + case Output -> controllerItemOutput.addInventory(new ItemInventoryLogic(slots, tier, isUpgradeInventory)); + case Both -> { + UUID id = controllerItemInput.addInventory(new ItemInventoryLogic(slots, tier, isUpgradeInventory)); + controllerItemOutput.addInventory(id, new ItemInventoryLogic(slots, tier, isUpgradeInventory)); + yield id; } - } - return rStack; - } - - @Override - public ItemStack getStackInSlotOnClosing(MultiBlockPart aPart, int aSlot) { - final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot); - if (tInv == null) return null; - - final IItemHandlerModifiable inv = tInv.getLeft(); - final int tSlot = tInv.getRight(); - - final ItemStack rStack = inv.getStackInSlot(tSlot); - inv.setStackInSlot(tSlot, null); - return rStack; - } - - @Override - public void setInventorySlotContents(MultiBlockPart aPart, int aSlot, ItemStack aStack) { - final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot); - if (tInv == null) return; - - final IItemHandlerModifiable inv = tInv.getLeft(); - final int tSlot = tInv.getRight(); - inv.setStackInSlot(tSlot, aStack); - } - - @Override - public List<String> getInventoryNames(MultiBlockPart aPart) { - final List<String> inventoryNames = new ArrayList<>(); - inventoryNames.add(ALL_INVENTORIES_NAME); - inventoryNames.addAll(getMultiBlockInventoryNames(aPart).values()); - return inventoryNames; - } - - @Override - public List<String> getInventoryIDs(MultiBlockPart aPart) { - final List<String> tInventoryIDs = new ArrayList<>(); - tInventoryIDs.add(ALL_INVENTORIES_NAME); - tInventoryIDs.addAll(getMultiBlockInventory(aPart).keySet()); - return tInventoryIDs; - } - - @Override - public String getInventoryName(MultiBlockPart aPart) { - final StringBuilder str = new StringBuilder(); - str.append(getInventoryName()); - if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) { - str.append(" Input"); - } else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) { - str.append(" Output"); - String a; - } else { - str.append(" Unknown"); - } - final String lockedInventory = aPart.getLockedInventory(); - if (lockedInventory != null && !lockedInventory.equals("")) { - str.append(" [Locked: ") - .append(lockedInventory) - .append("]"); - } - - return str.toString(); - } - - @Override - public List<String> getTankArrayNames(MultiBlockPart aPart) { - final List<String> inventoryNames = new ArrayList<>(); - inventoryNames.add(ALL_INVENTORIES_NAME); - inventoryNames.addAll(getMultiBlockTankArrayNames(aPart).values()); - return inventoryNames; - } - - @Override - public List<String> getTankArrayIDs(MultiBlockPart aPart) { - final List<String> inventoryIDs = new ArrayList<>(); - inventoryIDs.add(ALL_INVENTORIES_NAME); - inventoryIDs.addAll(getMultiBlockTankArray(aPart).keySet()); - return inventoryIDs; - } - - @Override - public boolean hasCustomInventoryName(MultiBlockPart aPart) { - return hasCustomInventoryName(); - } - - @Override - public int getInventoryStackLimit(MultiBlockPart aPart) { - return getInventoryStackLimit(); - } - - @Override - public void markDirty(MultiBlockPart aPart) { - markDirty(); - if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) markOutputInventoryBeenModified(); - else markInventoryBeenModified(); - } - - @Override - public boolean isUseableByPlayer(MultiBlockPart aPart, EntityPlayer aPlayer) { - return isUseableByPlayer(aPlayer); - } - - @Override - public void openInventory(MultiBlockPart aPart) { - // TODO: MultiInventory - consider the part's inventory - openInventory(); - } - - @Override - public void closeInventory(MultiBlockPart aPart) { - // TODO: MultiInventory - consider the part's inventory - closeInventory(); - } - - @Override - public boolean isItemValidForSlot(MultiBlockPart aPart, int aSlot, ItemStack aStack) { - return isItemValidForSlot(aSlot, aStack); - } - - /* - * Helper Methods For Recipe checking - */ - - @Override - protected ItemStack[] getInputItems() { - return getInventoriesForInput().getStacks() - .toArray(new ItemStack[0]); - } - - protected ItemStack[] getOutputItems() { - return getInventoriesForOutput().getStacks() - .toArray(new ItemStack[0]); - } - - protected Iterable<Pair<ItemStack[], String>> getItemInputsForEachInventory() { - return multiBlockInputInventory.entrySet() - .stream() - .map( - (entry) -> Pair.of( - entry.getValue() - .getStacks() - .toArray(new ItemStack[0]), - entry.getKey())) - .collect(Collectors.toList()); - } - - protected ItemStack[] getItemInputsForInventory(String id) { - IItemHandlerModifiable inventory = multiBlockInputInventory.get(id); - if (inventory != null) { - return inventory.getStacks() - .toArray(new ItemStack[0]); - } - return null; + }; } @Override - protected FluidStack[] getInputFluids() { - List<FluidStack> fluidStacks = new ArrayList<>(); - for (FluidTankGT[] inputTanks : multiBlockInputTank.values()) { - for (FluidTankGT inputTank : inputTanks) { - FluidStack fluidStack = inputTank.get(); - if (fluidStack != null) { - fluidStacks.add(fluidStack); - } + public ItemInventoryLogic unregisterItemInventory(@Nonnull UUID id, @Nonnull InventoryType type) { + return switch (type) { + case Input -> controllerItemInput.removeInventory(id); + case Output -> controllerItemOutput.removeInventory(id); + case Both -> { + ItemInventoryLogic input = controllerItemInput.removeInventory(id); + ItemInventoryLogic output = controllerItemOutput.removeInventory(id); + yield new ItemInventoryLogic( + Arrays.asList(input, output) + .stream() + .map(inv -> inv.getInventory()) + .collect(Collectors.toList())); } - } - return fluidStacks.toArray(new FluidStack[0]); - } - - protected FluidStack[] getOutputFluids() { - List<FluidStack> fluidStacks = new ArrayList<>(); - for (FluidTankGT[] inputTanks : multiBlockInputTank.values()) { - for (FluidTankGT inputTank : inputTanks) { - FluidStack fluidStack = inputTank.getFluid(); - if (fluidStack != null) { - fluidStacks.add(fluidStack); - } - } - } - return fluidStacks.toArray(new FluidStack[0]); - } - - protected Iterable<Pair<FluidStack[], String>> getFluidInputsForEachTankArray() { - return multiBlockInputTank.entrySet() - .stream() - .map((entry) -> Pair.of(FluidTankGT.getFluidsFromTanks(entry.getValue()), entry.getKey())) - .collect(Collectors.toList()); - } - - protected FluidStack[] getFluidInputsForTankArray(String id) { - return FluidTankGT.getFluidsFromTanks(multiBlockInputTank.get(id)); - } - - protected void setItemOutputs(String inventory, ItemStack... itemOutputs) { - itemsToOutput = itemOutputs; - inventoryName = inventory; - } - - @Override - protected void setItemOutputs(ItemStack... outputs) { - super.setItemOutputs(outputs); - inventoryName = null; + }; } @Override - protected void outputItems() { - if (itemsToOutput == null) { - return; - } - - IItemHandlerModifiable inv; - if (inventoryName != null) { - inv = multiBlockOutputInventory.getOrDefault(inventoryName, getInventoriesForOutput()); - } else { - inv = getInventoriesForOutput(); + public void changeItemInventoryDisplayName(@Nullable UUID id, @Nullable String displayName, + @Nonnull InventoryType type) { + switch (type) { + case Input: + controllerItemInput.setInventoryDisplayName(id, displayName); + break; + case Output: + controllerItemOutput.setInventoryDisplayName(id, displayName); + break; + case Both: + controllerItemInput.setInventoryDisplayName(id, displayName); + controllerItemOutput.setInventoryDisplayName(id, displayName); + break; } - for (ItemStack item : itemsToOutput) { - int index = 0; - while (item != null && item.stackSize > 0 && index < inv.getSlots()) { - item = inv.insertItem(index++, item.copy(), false); - } - } - itemsToOutput = null; } - protected void setFluidOutputs(String tank, FluidStack... fluidOuputs) { - fluidsToOutput = fluidOuputs; - tankName = tank; - } + // #endregion Item - @Override - protected void setFluidOutputs(FluidStack... outputs) { - super.setFluidOutputs(outputs); - tankName = null; - } + // #region Energy + @Nonnull @Override - protected void outputFluids() { - if (fluidsToOutput == null) { - return; - } - - List<FluidTankGT> tanks = Arrays.asList(outputTanks); - for (FluidStack fluid : fluidsToOutput) { - int index = 0; - while (fluid != null && fluid.amount > 0 && index < tanks.size()) { - int filled = tanks.get(index++) - .fill(fluid, true); - fluid.amount -= filled; - } - } + public PowerLogic getPowerLogic() { + return getPowerLogic(ForgeDirection.UNKNOWN); } - @Override - protected void updateSlots() { - IItemHandlerModifiable inv = getInventoriesForInput(); - for (int i = 0; i < inv.getSlots(); i++) { - if (inv.getStackInSlot(i) != null && inv.getStackInSlot(i).stackSize <= 0) { - inv.setStackInSlot(i, null); - } - } - - for (FluidTankGT inputTank : getTanksForInput()) { - if (inputTank == null) { - continue; - } - - if (inputTank.get() != null && inputTank.get().amount <= 0) { - inputTank.setEmpty(); - continue; - } - - FluidStack afterRecipe = inputTank.get(); - FluidStack beforeRecipe = inputTank.get(Integer.MAX_VALUE); - if (afterRecipe == null || beforeRecipe == null) { - continue; - } - int difference = beforeRecipe.amount - afterRecipe.amount; - inputTank.remove(difference); - } - } + // #endregion Energy @Override - protected boolean checkRecipe() { - if (!(this instanceof ProcessingLogicHost)) { - return false; - } - ProcessingLogic logic = ((ProcessingLogicHost) this).getProcessingLogic(); - logic.clear(); - CheckRecipeResult result = CheckRecipeResultRegistry.NO_RECIPE; - if (isSeparateInputs()) { - // TODO: Add separation with fluids - for (Pair<ItemStack[], String> inventory : getItemInputsForEachInventory()) { - IItemHandlerModifiable outputInventory = multiBlockOutputInventory - .getOrDefault(inventory.getLeft(), null); - result = logic.setInputItems(inventory.getLeft()) - .setCurrentOutputItems(getOutputItems()) - .process(); - if (result.wasSuccessful()) { - inventoryName = inventory.getRight(); - break; - } - logic.clear(); - } - } else { - result = logic.setInputItems(getInputItems()) - .setCurrentOutputItems(getOutputItems()) - .setInputFluids(getInputFluids()) - .setCurrentOutputFluids(getOutputFluids()) - .process(); - } - setDuration(logic.getDuration()); - setEut(logic.getCalculatedEut()); - setItemOutputs(logic.getOutputItems()); - setFluidOutputs(logic.getOutputFluids()); - return result.wasSuccessful(); - } - - public IItemHandlerModifiable getOutputInventory() { - return outputInventory; - } - - public FluidTankGT[] getOutputTanks() { - return outputTanks; + protected void updateSlots() { + controllerItemInput.getAllInventoryLogics() + .update(shouldSort); + controllerItemOutput.getAllInventoryLogics() + .update(shouldSort); + controllerFluidInput.getAllInventoryLogics() + .update(); + controllerFluidOutput.getAllInventoryLogics() + .update(); } /* @@ -1838,24 +886,6 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public ModularWindow createWindow(UIBuildContext buildContext) { - System.out.println("MultiBlockController::createWindow"); - if (!useModularUI()) return null; - - buildContext.setValidator(getValidator()); - final ModularWindow.Builder builder = ModularWindow.builder(getGUIWidth(), getGUIHeight()); - builder.setBackground(getGUITextureSet().getMainBackground()); - builder.setGuiTint(getGUIColorization()); - if (doesBindPlayerInventory()) { - bindPlayerInventoryUI(builder, buildContext); - } - addUIWidgets(builder, buildContext); - addTitleToUI(builder); - addCoverTabs(builder, buildContext); - return builder.build(); - } - - @Override public boolean hasGui(ForgeDirection side) { return true; } @@ -1866,222 +896,6 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public int getGUIHeight() { - return 192; - } - - protected Widget getGregTechLogo() { - return new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo()) - .setSize(17, 17); - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - if (isServerSide()) { - for (UpgradeCasing tPart : upgradeCasings) { - if (!(tPart instanceof Inventory)) continue; - tPart.issueClientUpdate(); - } - } - int page = 0; - TabContainer tabs = new TabContainer().setButtonSize(20, 24); - tabs.addTabButton( - new TabButton(page++) - .setBackground( - false, - ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f), - new ItemDrawable(getStackForm(1)).withFixedSize(16, 16) - .withOffset(2, 4)) - .setBackground( - true, - ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f), - new ItemDrawable(getStackForm(1)).withFixedSize(16, 16) - .withOffset(2, 4)) - .addTooltip(getLocalName()) - .setPos(20 * (page - 1), -20)) - .addPage(createMainPage(builder).setSize(getGUIWidth(), getGUIHeight())); - if (hasItemInput()) { - tabs.addTabButton( - new TabButton(page++) - .setBackground( - false, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f), - GT_UITextures.PICTURE_ITEM_IN.withFixedSize(16, 16) - .withOffset(2, 4)) - .setBackground( - true, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f), - GT_UITextures.PICTURE_ITEM_IN.withFixedSize(16, 16) - .withOffset(2, 4)) - .setPos(20 * (page - 1), -20)) - .addPage( - new MultiChildWidget().addChild(getItemInventoryInputGUI()) - .addChild(getGregTechLogo().setPos(147, 86)) - .setSize(getGUIWidth(), getGUIHeight())); - } - - if (hasItemOutput()) { - tabs.addTabButton( - new TabButton(page++) - .setBackground( - false, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f), - GT_UITextures.PICTURE_ITEM_OUT.withFixedSize(16, 16) - .withOffset(2, 4)) - .setBackground( - true, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f), - GT_UITextures.PICTURE_ITEM_OUT.withFixedSize(16, 16) - .withOffset(2, 4)) - .setPos(20 * (page - 1), -20)) - .addPage( - new MultiChildWidget().addChild(getItemInventoryOutputGUI()) - .addChild(getGregTechLogo().setPos(147, 86)) - .setSize(getGUIWidth(), getGUIHeight())); - } - - if (hasFluidInput()) { - tabs.addTabButton( - new TabButton(page++) - .setBackground( - false, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f), - GT_UITextures.PICTURE_FLUID_IN.withFixedSize(16, 16) - .withOffset(2, 4)) - .setBackground( - true, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f), - GT_UITextures.PICTURE_FLUID_IN.withFixedSize(16, 16) - .withOffset(2, 4)) - .setPos(20 * (page - 1), -20)) - .addPage( - new MultiChildWidget().addChild(getFluidInventoryInputGUI()) - .addChild(getGregTechLogo().setPos(147, 86)) - .setSize(getGUIWidth(), getGUIHeight())); - } - - if (hasFluidOutput()) { - tabs.addTabButton( - new TabButton(page++) - .setBackground( - false, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f), - GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16) - .withOffset(2, 4)) - .setBackground( - true, - ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f), - GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16) - .withOffset(2, 4)) - .setPos(20 * (page - 1), -20)) - .addPage( - new MultiChildWidget().addChild(getFluidInventoryOutputGUI()) - .addChild(getGregTechLogo().setPos(147, 86)) - .setSize(getGUIWidth(), getGUIHeight())); - } - builder.widget(tabs); - } - - protected MultiChildWidget createMainPage(IWidgetBuilder<?> builder) { - MultiChildWidget page = new MultiChildWidget(); - page.addChild( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(7, 4) - .setSize(160, 75)) - .addChild(createButtons(builder)); - return page; - } - - protected MultiChildWidget createButtons(IWidgetBuilder<?> builder) { - MultiChildWidget buttons = new MultiChildWidget(); - buttons.setSize(16, 167) - .setPos(7, 86); - buttons.addChild(createPowerSwitchButton(builder)) - .addChild(createVoidExcessButton(builder)) - .addChild(createInputSeparationButton(builder)) - .addChild(createBatchModeButton(builder)) - .addChild(createLockToSingleRecipeButton(builder)); - - return buttons; - } - - protected Widget getItemInventoryInputGUI() { - final IItemHandlerModifiable inv = getInventoriesForInput(); - final Scrollable scrollable = new Scrollable().setVerticalScroll(); - for (int rows = 0; rows * 4 < Math.min(inv.getSlots(), 128); rows++) { - final 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)); - } - } - return scrollable.setSize(18 * 4 + 4, 18 * 5) - .setPos(52, 7); - } - - protected Widget getItemInventoryOutputGUI() { - final IItemHandlerModifiable inv = getInventoriesForOutput(); - final Scrollable scrollable = new Scrollable().setVerticalScroll(); - for (int rows = 0; rows * 4 < Math.min(inv.getSlots(), 128); rows++) { - final 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)); - } - } - return scrollable.setSize(18 * 4 + 4, 18 * 5) - .setPos(52, 7); - } - - protected IItemHandlerModifiable getInventoriesForInput() { - return new ListItemHandler(multiBlockInputInventory.values()); - } - - protected IItemHandlerModifiable getInventoriesForOutput() { - return new ListItemHandler(multiBlockOutputInventory.values()); - } - - protected Widget getFluidInventoryInputGUI() { - final IFluidTank[] tanks = getTanksForInput(); - final Scrollable scrollable = new Scrollable().setVerticalScroll(); - for (int rows = 0; rows * 4 < tanks.length; rows++) { - final int columnsToMake = Math.min(tanks.length - rows * 4, 4); - for (int column = 0; column < columnsToMake; column++) { - final FluidSlotWidget fluidSlot = new FluidSlotWidget(tanks[rows * 4 + column]); - scrollable.widget( - fluidSlot.setPos(column * 18, rows * 18) - .setSize(18, 18)); - } - } - return scrollable.setSize(18 * 4 + 4, 18 * 5) - .setPos(52, 7); - } - - protected Widget getFluidInventoryOutputGUI() { - final IFluidTank[] tanks = getTanksForOutput(); - final Scrollable scrollable = new Scrollable().setVerticalScroll(); - for (int rows = 0; rows * 4 < tanks.length; rows++) { - final int columnsToMake = Math.min(tanks.length - rows * 4, 4); - for (int column = 0; column < columnsToMake; column++) { - final FluidSlotWidget fluidSlot = new FluidSlotWidget(tanks[rows * 4 + column]); - fluidSlot.setInteraction(true, false); - scrollable.widget( - fluidSlot.setPos(column * 18, rows * 18) - .setSize(18, 18)); - } - } - return scrollable.setSize(18 * 4 + 4, 18 * 5) - .setPos(52, 7); - } - - @Override - public Pos2d getPowerSwitchButtonPos() { - return new Pos2d(144, 0); - } - - @Override public boolean supportsVoidProtection() { return true; } @@ -2097,23 +911,6 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public List<ItemStack> getItemOutputSlots(ItemStack[] toOutput) { - List<ItemStack> ret = new ArrayList<>(); - IItemHandler inv = getOutputInventory(); - if (inv != null && inv.getSlots() > 0) { - for (int i = 0; i < inv.getSlots(); i++) { - ret.add(inv.getStackInSlot(i)); - } - } - return ret; - } - - @Override - public List<? extends IFluidStore> getFluidOutputSlots(FluidStack[] toOutput) { - return Arrays.asList(getOutputTanks()); - } - - @Override public boolean canDumpItemToME() { return false; } @@ -2124,31 +921,21 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public Pos2d getVoidingModeButtonPos() { - return new Pos2d(54, 0); - } - - @Override public boolean supportsInputSeparation() { return true; } @Override - public boolean isInputSeparationEnabled() { + public boolean isInputSeparated() { return separateInputs; } @Override - public void setInputSeparation(boolean enabled) { + public void setInputSeparation(Boolean enabled) { this.separateInputs = enabled; } @Override - public Pos2d getInputSeparationButtonPos() { - return new Pos2d(36, 0); - } - - @Override public boolean supportsBatchMode() { return true; } @@ -2159,16 +946,11 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public void setBatchMode(boolean mode) { + public void setBatchMode(Boolean mode) { this.batchMode = mode; } @Override - public Pos2d getBatchModeButtonPos() { - return new Pos2d(18, 0); - } - - @Override public boolean supportsSingleRecipeLocking() { return false; } @@ -2179,32 +961,23 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } @Override - public void setRecipeLocking(boolean enabled) { + public void setRecipeLocking(Boolean enabled) { this.recipeLock = enabled; } @Override - public RecipeMap<?> getRecipeMap() { - return null; - } - - @Override - public Pos2d getRecipeLockingButtonPos() { - return new Pos2d(0, 0); - } - - @Override - public ModularWindow createWindowGUI(UIBuildContext buildContext) { - return createWindow(buildContext); - } - - @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.setLong("progress", progressTime); - tag.setLong("maxProgress", maxProgressTime); + P processing = getProcessingLogic(); + tag.setInteger("progress", processing.getProgress()); + tag.setInteger("maxProgress", processing.getDuration()); tag.setBoolean("structureOkay", structureOkay); + tag.setBoolean("isActive", isActive()); + if (isActive()) { + tag.setLong("energyUsage", getProcessingLogic().getCalculatedEut()); + tag.setLong("energyTier", tier); + } } @Override @@ -2219,8 +992,92 @@ public abstract class Controller<T extends Controller<T>> extends MultiTileBasic } if (isSimpleMachine) { boolean isActive = tag.getBoolean("isActive"); - currentTip - .add(GT_Waila.getMachineProgressString(isActive, tag.getLong("maxProgress"), tag.getLong("progress"))); + currentTip.add( + GT_Waila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); + } + boolean isActive = tag.getBoolean("isActive"); + if (isActive) { + long energyTier = tag.getLong("energyTier"); + long actualEnergyUsage = tag.getLong("energyUsage"); + if (actualEnergyUsage > 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.use_with_amperage", + GT_Utility.formatNumbers(actualEnergyUsage), + GT_Utility.getAmperageForTier(actualEnergyUsage, (byte) energyTier), + GT_Utility.getColoredTierNameFromTier((byte) energyTier))); + } else if (actualEnergyUsage < 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.produce_with_amperage", + GT_Utility.formatNumbers(-actualEnergyUsage), + GT_Utility.getAmperageForTier(-actualEnergyUsage, (byte) energyTier), + GT_Utility.getColoredTierNameFromTier((byte) energyTier))); + } } } + + @Override + public GT_Packet_MultiTileEntity getClientDataPacket() { + final GT_Packet_MultiTileEntity packet = super.getClientDataPacket(); + + return packet; + + } + + @Override + public void enableWorking() { + super.enableWorking(); + if (!structureOkay) { + checkStructure(true); + } + } + + @Override + public List<ItemStack> getItemOutputSlots(ItemStack[] toOutput) { + return new ArrayList<>(0); + } + + @Override + public List<? extends IFluidStore> getFluidOutputSlots(FluidStack[] toOutput) { + return new ArrayList<>(0); + } + + @Override + @Nonnull + public Set<Entry<UUID, FluidInventoryLogic>> getAllFluidInventoryLogics(@Nonnull InventoryType type) { + return switch (type) { + case Input -> controllerFluidInput.getAllInventoryLogicsAsEntrySet(); + case Output -> controllerFluidOutput.getAllInventoryLogicsAsEntrySet(); + default -> super.getAllFluidInventoryLogics(type); + }; + } + + @Override + @Nonnull + public Set<Entry<UUID, ItemInventoryLogic>> getAllItemInventoryLogics(@Nonnull InventoryType type) { + return switch (type) { + case Input -> controllerItemInput.getAllInventoryLogicsAsEntrySet(); + case Output -> controllerItemOutput.getAllInventoryLogicsAsEntrySet(); + default -> super.getAllItemInventoryLogics(type); + }; + } + + @Override + public void setWirelessSupport(boolean canUse) { + if (canUse) { + strongCheckOrAddUser(getOwnerUuid(), getOwnerName()); + } + power.setCanUseWireless(canUse, getOwnerUuid()); + } + + @Override + public void setLaserSupport(boolean canUse) { + power.setCanUseLaser(canUse); + } + + @Override + public void setMaxAmperage(long amperage) { + power.setMaxAmperage(amperage); + } } |