From 02bedd5c0a96a654c6692edd1b7f2765fd9c46b4 Mon Sep 17 00:00:00 2001 From: BlueWeabo Date: Sat, 6 Jan 2024 00:41:00 +0200 Subject: 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 Co-authored-by: BlueWeabo 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 * 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 * 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 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 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 Co-authored-by: Harry Co-authored-by: Eraldoe 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 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 * 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 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 Co-authored-by: RIONDY 'POPlol333' Adam <76914762+POPlol333@users.noreply.github.com> Co-authored-by: Jason Mitchell 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 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 Co-authored-by: Harry Co-authored-by: Eraldoe 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 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 Co-authored-by: boubou19 Co-authored-by: Jason Mitchell --- .../machine/MultiTileBasicMachine.java | 821 ++++++++------------- 1 file changed, 312 insertions(+), 509 deletions(-) (limited to 'src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java') diff --git a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java index 0b6d4f587d..19c052b96a 100644 --- a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java +++ b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java @@ -1,18 +1,19 @@ package gregtech.api.multitileentity.machine; -import static com.google.common.primitives.Ints.saturatedCast; -import static gregtech.api.enums.GT_Values.B; -import static gregtech.api.enums.GT_Values.VN; +import static gregtech.api.enums.GT_Values.*; +import static gregtech.api.enums.TickTime.MINUTE; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Objects; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; import net.minecraft.util.EnumChatFormatting; @@ -20,26 +21,32 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidTank; + +import org.jetbrains.annotations.ApiStatus.OverrideOnly; import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; import com.gtnewhorizons.modularui.api.forge.ItemStackHandler; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gregtech.api.enums.GT_Values; import gregtech.api.enums.GT_Values.NBT; +import gregtech.api.enums.InventoryType; import gregtech.api.enums.Mods; import gregtech.api.enums.SoundResource; import gregtech.api.enums.Textures; import gregtech.api.enums.Textures.BlockIcons.CustomIcon; import gregtech.api.enums.TickTime; -import gregtech.api.fluid.FluidTankGT; +import gregtech.api.enums.VoidingMode; +import gregtech.api.gui.GUIHost; +import gregtech.api.gui.GUIProvider; import gregtech.api.interfaces.ITexture; -import gregtech.api.logic.PollutionLogic; +import gregtech.api.logic.FluidInventoryLogic; +import gregtech.api.logic.ItemInventoryLogic; +import gregtech.api.logic.MuTEProcessingLogic; +import gregtech.api.logic.NullPowerLogic; import gregtech.api.logic.PowerLogic; -import gregtech.api.logic.ProcessingLogic; -import gregtech.api.logic.interfaces.PollutionLogicHost; import gregtech.api.logic.interfaces.PowerLogicHost; import gregtech.api.logic.interfaces.ProcessingLogicHost; import gregtech.api.metatileentity.GregTechTileClientEvents; @@ -47,13 +54,14 @@ import gregtech.api.multitileentity.MultiTileEntityRegistry; import gregtech.api.multitileentity.base.TickableMultiTileEntity; import gregtech.api.multitileentity.interfaces.IMultiTileMachine; import gregtech.api.net.GT_Packet_MultiTileEntity; -import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.render.TextureFactory; +import gregtech.api.task.tasks.ProcessingTask; import gregtech.api.util.GT_Utility; import gregtech.client.GT_SoundLoop; -import gregtech.common.GT_Pollution; +import gregtech.common.gui.MachineGUIProvider; -public abstract class MultiTileBasicMachine extends TickableMultiTileEntity implements IMultiTileMachine { +public abstract class MultiTileBasicMachine

> extends TickableMultiTileEntity + implements IMultiTileMachine, ProcessingLogicHost

, PowerLogicHost, GUIHost { protected static final int ACTIVE = B[0]; protected static final int TICKS_BETWEEN_RECIPE_CHECKS = 5 * TickTime.SECOND; @@ -70,22 +78,10 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl protected int maxParallel = 1; protected boolean active = false; - protected long storedEnergy = 0; - protected long voltage = 0; - protected long amperage = 2; - protected long eut = 0; protected int tier = 0; - protected long maxProgressTime = 0; - protected long progressTime = 0; protected long burnTime = 0; protected long totalBurnTime = 0; - protected FluidTankGT[] inputTanks = GT_Values.emptyFluidTankGT; - protected FluidTankGT[] outputTanks = GT_Values.emptyFluidTankGT; - protected FluidStack[] fluidsToOutput = GT_Values.emptyFluidStack; - protected ItemStack[] itemsToOutput = GT_Values.emptyItemStackArray; - protected IItemHandlerModifiable inputInventory = EMPTY_INVENTORY; - protected IItemHandlerModifiable outputInventory = EMPTY_INVENTORY; protected boolean outputInventoryChanged = false; protected boolean powerShutDown = false; protected boolean wasEnabled = false; @@ -93,13 +89,30 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl protected boolean isElectric = true; protected boolean isSteam = false; protected boolean acceptsFuel = false; - protected boolean isWireless = false; + protected byte soundEvent = 0; protected int soundEventValue = 0; + protected ItemInventoryLogic itemInput; + protected ItemInventoryLogic itemOutput; + protected FluidInventoryLogic fluidInput; + protected FluidInventoryLogic fluidOutput; + + protected P processingLogic; + @Nonnull + protected VoidingMode voidingMode = VoidingMode.VOID_NONE; + protected boolean processingUpdate = false; + @Nonnull + protected PowerLogic power = createPowerLogic(); + @Nonnull + protected GUIProvider guiProvider = createGUIProvider(); @SideOnly(Side.CLIENT) protected GT_SoundLoop activitySoundLoop; + public MultiTileBasicMachine() { + new ProcessingTask<>(this); + } + @Override public String getTileEntityName() { return "gt.multitileentity.machine.basic"; @@ -116,80 +129,34 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl nbt.setBoolean(NBT.ACTIVE, active); } - if (inputInventory != null && inputInventory.getSlots() > 0) { - writeInventory(nbt, inputInventory, NBT.INV_INPUT_LIST); - } - - if (outputInventory != null && outputInventory.getSlots() > 0) { - writeInventory(nbt, outputInventory, NBT.INV_OUTPUT_LIST); - } + saveItemLogic(nbt); + saveFluidLogic(nbt); - for (int i = 0; i < inputTanks.length; i++) { - inputTanks[i].writeToNBT(nbt, NBT.TANK_IN + i); - } - - for (int i = 0; i < outputTanks.length; i++) { - outputTanks[i].writeToNBT(nbt, NBT.TANK_OUT + i); - } - - if (fluidsToOutput != null && fluidsToOutput.length > 0) { - writeFluids(nbt, fluidsToOutput, NBT.FLUID_OUT); - } - - if (itemsToOutput != null) { - saveItemsToOutput(nbt); + if (processingLogic != null) { + NBTTagCompound processingLogicNBT = processingLogic.saveToNBT(); + nbt.setTag("processingLogic", processingLogicNBT); } nbt.setInteger(NBT.TIER, tier); - nbt.setLong(NBT.EUT_CONSUMPTION, eut); nbt.setLong(NBT.BURN_TIME_LEFT, burnTime); nbt.setLong(NBT.TOTAL_BURN_TIME, totalBurnTime); nbt.setBoolean(NBT.ALLOWED_WORK, canWork); nbt.setBoolean(NBT.ACTIVE, active); + power.saveToNBT(nbt); } - protected void writeFluids(NBTTagCompound nbt, FluidStack[] fluids, String fluidListTag) { - if (fluids != null && fluids.length > 0) { - final NBTTagList tList = new NBTTagList(); - for (final FluidStack tFluid : fluids) { - if (tFluid != null) { - final NBTTagCompound tag = new NBTTagCompound(); - tFluid.writeToNBT(tag); - tList.appendTag(tag); - } - } - nbt.setTag(fluidListTag, tList); - } - } - - protected void writeInventory(NBTTagCompound nbt, IItemHandlerModifiable inv, String invListTag) { - if (inv != null && inv.getSlots() > 0) { - final NBTTagList tList = new NBTTagList(); - for (int slot = 0; slot < inv.getSlots(); slot++) { - final ItemStack tStack = inv.getStackInSlot(slot); - if (tStack != null) { - final NBTTagCompound tag = new NBTTagCompound(); - tag.setByte("s", (byte) slot); - tStack.writeToNBT(tag); - tList.appendTag(tag); - } - } - nbt.setTag(invListTag, tList); - } + protected void saveItemLogic(NBTTagCompound nbt) { + NBTTagCompound nbtListInput = itemInput.saveToNBT(); + nbt.setTag(NBT.INV_INPUT_LIST, nbtListInput); + NBTTagCompound nbtListOutput = itemOutput.saveToNBT(); + nbt.setTag(NBT.INV_OUTPUT_LIST, nbtListOutput); } - protected void saveItemsToOutput(NBTTagCompound aNBT) { - final NBTTagList nbtList = new NBTTagList(); - for (int slot = 0; slot < itemsToOutput.length; slot++) { - final ItemStack itemStack = itemsToOutput[slot]; - if (itemStack != null) { - final NBTTagCompound tag = new NBTTagCompound(); - tag.setByte("s", (byte) slot); - itemStack.writeToNBT(tag); - nbtList.appendTag(tag); - } - } - aNBT.setTag(NBT.ITEM_OUT, nbtList); + protected void saveFluidLogic(NBTTagCompound nbt) { + NBTTagCompound fluidInputNBT = fluidInput.saveToNBT(); + nbt.setTag(NBT.TANK_IN, fluidInputNBT); + NBTTagCompound fluidOutputNBT = fluidOutput.saveToNBT(); + nbt.setTag(NBT.TANK_OUT, fluidOutputNBT); } @Override @@ -203,63 +170,48 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl active = nbt.getBoolean(NBT.ACTIVE); } - /* Inventories */ - inputInventory = new ItemStackHandler(Math.max(nbt.getInteger(NBT.INV_INPUT_SIZE), 0)); - outputInventory = new ItemStackHandler(Math.max(nbt.getInteger(NBT.INV_OUTPUT_SIZE), 0)); - loadInventory(nbt, inputInventory, NBT.INV_INPUT_LIST); - loadInventory(nbt, outputInventory, NBT.INV_OUTPUT_LIST); - - /* Tanks */ - long capacity = 1000; - if (nbt.hasKey(NBT.TANK_CAPACITY)) { - capacity = saturatedCast(nbt.getLong(NBT.TANK_CAPACITY)); - } - - inputTanks = new FluidTankGT[getFluidInputCount()]; - outputTanks = new FluidTankGT[getFluidOutputCount()]; - fluidsToOutput = new FluidStack[getFluidOutputCount()]; - - // TODO: See if we need the adjustable map here `.setCapacity(mRecipes, mParallel * 2L)` in place of the - // `setCapacityMultiplier` - for (int i = 0; i < inputTanks.length; i++) { - inputTanks[i] = new FluidTankGT(capacity).setCapacityMultiplier(maxParallel * 2L) - .readFromNBT(nbt, NBT.TANK_IN + i); - } - for (int i = 0; i < outputTanks.length; i++) { - outputTanks[i] = new FluidTankGT(capacity).setCapacityMultiplier(maxParallel * 2L) - .readFromNBT(nbt, NBT.TANK_OUT + i); - } + loadItemLogic(nbt); + loadFluidLogic(nbt); - for (int i = 0; i < fluidsToOutput.length; i++) { - fluidsToOutput[i] = FluidStack.loadFluidStackFromNBT(nbt.getCompoundTag(NBT.FLUID_OUT + "." + i)); + if (nbt.hasKey("processingLogic")) { + P processingLogic = getProcessingLogic(); + processingLogic.loadFromNBT(Objects.requireNonNull(nbt.getCompoundTag("processingLogic"))); } - loadItemsToOutput(nbt); - tier = nbt.getInteger(NBT.TIER); - eut = nbt.getLong(NBT.EUT_CONSUMPTION); burnTime = nbt.getLong(NBT.BURN_TIME_LEFT); totalBurnTime = nbt.getLong(NBT.TOTAL_BURN_TIME); canWork = nbt.getBoolean(NBT.ALLOWED_WORK); active = nbt.getBoolean(NBT.ACTIVE); + power.loadFromNBT(nbt); } - protected void loadInventory(NBTTagCompound aNBT, IItemHandlerModifiable inv, String invListTag) { - final NBTTagList tList = aNBT.getTagList(invListTag, 10); - for (int i = 0; i < tList.tagCount(); i++) { - final NBTTagCompound tNBT = tList.getCompoundTagAt(i); - final int tSlot = tNBT.getShort("s"); - if (tSlot >= 0 && tSlot < inv.getSlots()) inv.setStackInSlot(tSlot, GT_Utility.loadItem(tNBT)); + protected void loadItemLogic(NBTTagCompound nbt) { + itemInput = new ItemInventoryLogic(nbt.getInteger(NBT.INV_OUTPUT_SIZE), tier); + itemOutput = new ItemInventoryLogic(nbt.getInteger(NBT.INV_OUTPUT_SIZE), tier); + if (nbt.hasKey(NBT.INV_INPUT_LIST)) { + itemInput.loadFromNBT(nbt.getCompoundTag(NBT.INV_INPUT_LIST)); + } + if (nbt.hasKey(NBT.INV_OUTPUT_LIST)) { + itemOutput.loadFromNBT(nbt.getCompoundTag(NBT.INV_OUTPUT_LIST)); } } - protected void loadItemsToOutput(NBTTagCompound aNBT) { - final NBTTagList tList = aNBT.getTagList(NBT.ITEM_OUT, 10); - itemsToOutput = new ItemStack[tList.tagCount()]; - for (int i = 0; i < tList.tagCount(); i++) { - final NBTTagCompound tNBT = tList.getCompoundTagAt(i); - final int tSlot = tNBT.getByte("s"); - if (tSlot >= 0 && tSlot < itemsToOutput.length) itemsToOutput[tSlot] = GT_Utility.loadItem(tNBT); + protected void loadFluidLogic(NBTTagCompound nbt) { + fluidInput = new FluidInventoryLogic(16, 10000, tier); + fluidOutput = new FluidInventoryLogic(16, 10000, tier); + fluidInput.loadFromNBT(nbt.getCompoundTag(NBT.TANK_IN)); + fluidOutput.loadFromNBT(nbt.getCompoundTag(NBT.TANK_OUT)); + } + + public boolean checkTexture(String modID, String resourcePath) { + try { + Minecraft.getMinecraft() + .getResourceManager() + .getResource(new ResourceLocation(modID, resourcePath)); + return true; + } catch (IOException ignored) { + return false; } } @@ -268,17 +220,10 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl super.loadTextures(folder); for (StatusTextures textureName : StatusTextures.TEXTURES) { ITexture texture = null; - try { - Minecraft.getMinecraft() - .getResourceManager() - .getResource( - new ResourceLocation( - Mods.GregTech.ID, - "textures/blocks/multitileentity/" + folder + "/" + textureName.getName() + ".png")); - } catch (IOException ignored) { + String texturePath = "textures/blocks/multitileentity/" + folder + "/" + textureName.getName() + ".png"; + if (!checkTexture(Mods.GregTech.ID, texturePath)) { texture = TextureFactory.of(Textures.BlockIcons.VOID); - } - if (texture == null) { + } else { if (textureName.hasGlow()) { texture = TextureFactory.builder() .addIcon(new CustomIcon("multitileentity/" + folder + "/" + textureName.getName())) @@ -357,79 +302,6 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl @Override public void setLightValue(byte aLightValue) {} - @Override - public String getInventoryName() { - final String name = getCustomName(); - if (name != null) return name; - final MultiTileEntityRegistry tRegistry = MultiTileEntityRegistry.getRegistry(getMultiTileEntityRegistryID()); - return tRegistry == null ? getClass().getName() : tRegistry.getLocal(getMultiTileEntityID()); - } - - @Override - public boolean isUseableByPlayer(EntityPlayer aPlayer) { - return playerOwnsThis(aPlayer, false) && mTickTimer > 40 - && getTileEntityOffset(0, 0, 0) == this - && aPlayer.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64 - && allowInteraction(aPlayer); - } - - @Override - public boolean isLiquidInput(ForgeDirection side) { - return side != facing; - } - - @Override - public boolean isLiquidOutput(ForgeDirection side) { - return side != facing; - } - - @Override - protected IFluidTank[] getFluidTanks(ForgeDirection side) { - final boolean fluidInput = isLiquidInput(side); - final boolean fluidOutput = isLiquidOutput(side); - - if (fluidInput && fluidOutput) { - final IFluidTank[] rTanks = new IFluidTank[inputTanks.length + outputTanks.length]; - System.arraycopy(inputTanks, 0, rTanks, 0, inputTanks.length); - System.arraycopy(outputTanks, 0, rTanks, inputTanks.length, outputTanks.length); - return rTanks; - } else if (fluidInput) { - return inputTanks; - } else if (fluidOutput) { - return outputTanks; - } - return GT_Values.emptyFluidTank; - } - - @Override - public IFluidTank getFluidTankFillable(ForgeDirection side, FluidStack aFluidToFill) { - return getFluidTankFillable(facing, side, aFluidToFill); - } - - public IFluidTank getFluidTankFillable(ForgeDirection sideSource, ForgeDirection sideDestination, - FluidStack fluidToFill) { - if (sideSource.compareTo(sideDestination) != 0) return null; - for (FluidTankGT tankGT : inputTanks) if (tankGT.contains(fluidToFill)) return tankGT; - // if (!mRecipes.containsInput(aFluidToFill, this, slot(mRecipes.mInputItemsCount + - // mRecipes.mOutputItemsCount))) return null; - for (FluidTankGT fluidTankGT : inputTanks) if (fluidTankGT.isEmpty()) return fluidTankGT; - return null; - } - - @Override - protected IFluidTank getFluidTankDrainable(ForgeDirection side, FluidStack aFluidToDrain) { - return getFluidTankDrainable(facing, side, aFluidToDrain); - } - - protected IFluidTank getFluidTankDrainable(ForgeDirection sideSource, ForgeDirection sideDestination, - FluidStack fluidToDrain) { - if (sideSource.compareTo(sideDestination) != 0) return null; - for (FluidTankGT fluidTankGT : outputTanks) - if (fluidToDrain == null ? fluidTankGT.has() : fluidTankGT.contains(fluidToDrain)) return fluidTankGT; - - return null; - } - /* * Inventory */ @@ -453,16 +325,6 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl hasInventoryChanged = true; } - @Override - public boolean isItemValidForSlot(int aSlot, ItemStack aStack) { - return true; - } - - @Override - public int getInventoryStackLimit() { - return 64; - } - // #region Machine @Override @@ -480,28 +342,26 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl * @param tick The current tick of the machine */ protected void runMachine(long tick) { - if (acceptsFuel() && isActive()) { - if (!consumeFuel()) { - stopMachine(true); - return; - } + if (acceptsFuel() && isActive() && !consumeFuel()) { + stopMachine(true); + return; } if (hasThingsToDo()) { markDirty(); runningTick(tick); - } else { - if (tick % TICKS_BETWEEN_RECIPE_CHECKS == 0 || hasWorkJustBeenEnabled() || hasInventoryBeenModified()) { - if (isAllowedToWork()) { - wasEnabled = false; - if (checkRecipe()) { - setActive(true); - setSound(GregTechTileClientEvents.START_SOUND_LOOP, PROCESS_START_SOUND_INDEX); - updateSlots(); - markDirty(); - issueClientUpdate(); - } - } + return; + } + + if (tick % TICKS_BETWEEN_RECIPE_CHECKS == 0 || hasWorkJustBeenEnabled() + || hasInventoryBeenModified() && isAllowedToWork()) { + wasEnabled = false; + if (checkRecipe()) { + setActive(true); + setSound(GregTechTileClientEvents.START_SOUND_LOOP, PROCESS_START_SOUND_INDEX); + updateSlots(); + markDirty(); + issueClientUpdate(); } } } @@ -512,81 +372,25 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl * @param tick The current tick of the machine */ protected void runningTick(long tick) { - if (this instanceof PowerLogicHost) { - consumeEnergy(); - } - - if (maxProgressTime > 0 && ++progressTime >= maxProgressTime) { - progressTime = 0; - maxProgressTime = 0; - outputItems(); - outputFluids(); - if (isAllowedToWork()) { - if (!checkRecipe()) { - setActive(false); - issueClientUpdate(); - } - } - updateSlots(); - } - - if (this instanceof PollutionLogicHost && tick % POLLUTION_TICK == 0) { - doPollution(); - } - emitEnergy(); + consumeEnergy(); } /** * Runs only on server side */ protected boolean checkRecipe() { - if (!(this instanceof ProcessingLogicHost)) { - return false; - } - ProcessingLogic logic = ((ProcessingLogicHost) this).getProcessingLogic(); - logic.clear(); - CheckRecipeResult result = logic.setInputItems(getInputItems()) - .setInputFluids(getInputFluids()) - .setCurrentOutputItems( - outputInventory.getStacks() - .toArray(new ItemStack[0])) - .process(); - setDuration(logic.getDuration()); - setEut(logic.getCalculatedEut()); - setItemOutputs(logic.getOutputItems()); - setFluidOutputs(logic.getOutputFluids()); - return result.wasSuccessful(); - } - - /** - * Runs only on server side - */ - protected void doPollution() { - PollutionLogic logic = ((PollutionLogicHost) this).getPollutionLogic(); - - if (logic == null) { - return; - } - - GT_Pollution.addPollution(getWorld(), getXCoord() >> 4, getZCoord() >> 4, logic.getPollutionAmount()); + return false; } - /** - * Runs only on server side - */ - protected void emitEnergy() {} - /** * Runs only on server side */ protected void consumeEnergy() { - PowerLogic logic = ((PowerLogicHost) this).getPowerLogic(ForgeDirection.UNKNOWN); + PowerLogic logic = getPowerLogic(); - if (logic == null) { - return; - } + P processing = getProcessingLogic(); - if (!logic.removeEnergyUnsafe(eut)) { + if (!logic.removeEnergyUnsafe(processing.getCalculatedEut())) { stopMachine(true); } } @@ -603,9 +407,8 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl } public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { - if (aIndex == PROCESS_START_SOUND_INDEX) { - if (getProcessStartSound() != null) - GT_Utility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); + if (aIndex == PROCESS_START_SOUND_INDEX && getProcessStartSound() != null) { + GT_Utility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); } } @@ -619,18 +422,18 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl @SideOnly(Side.CLIENT) protected void doActivitySound(ResourceLocation activitySound) { - if (isActive() && activitySound != null) { - if (activitySoundLoop == null) { - activitySoundLoop = new GT_SoundLoop(activitySound, this, false, true); - Minecraft.getMinecraft() - .getSoundHandler() - .playSound(activitySoundLoop); - } - } else { - if (activitySoundLoop != null) { - activitySoundLoop = null; - } + if (isActive() && activitySound != null && activitySoundLoop == null) { + activitySoundLoop = new GT_SoundLoop(activitySound, this, false, true); + Minecraft.getMinecraft() + .getSoundHandler() + .playSound(activitySoundLoop); + return; } + + if (activitySoundLoop != null) { + activitySoundLoop = null; + } + } @SideOnly(Side.CLIENT) @@ -639,105 +442,69 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl } protected ItemStack[] getInputItems() { - return inputInventory.getStacks() - .toArray(new ItemStack[0]); + return itemInput.getStoredItems(); } protected FluidStack[] getInputFluids() { - return Arrays.stream(inputTanks) - .map(FluidTankGT::get) - .toArray(FluidStack[]::new); - } - - protected void outputItems() { - outputItems(itemsToOutput); - itemsToOutput = null; - } - - protected void outputItems(ItemStack... itemsToOutput) { - outputItems(outputInventory, itemsToOutput); + return fluidInput.getStoredFluids(); } - protected void outputItems(IItemHandlerModifiable inventory, ItemStack... itemsToOutput) { - if (itemsToOutput == null || inventory == null) { - return; - } - for (ItemStack item : itemsToOutput) { - int index = 0; - while (item != null && item.stackSize > 0 && index < inventory.getSlots()) { - item = inventory.insertItem(index++, item.copy(), false); - } - } - } - - protected void outputFluids() { - outputFluids(fluidsToOutput); - fluidsToOutput = null; - } - - protected void outputFluids(FluidStack... fluidsToOutput) { - outputFluids(outputTanks, fluidsToOutput); - } - - protected void outputFluids(FluidTankGT[] tankArray, FluidStack... fluidsToOutput) { - if (fluidsToOutput == null) { - return; - } - for (FluidStack fluid : fluidsToOutput) { - tryToFillTanks(fluid, tankArray); - } - } - - protected void tryToFillTanks(FluidStack fluid, FluidTankGT... tanks) { - for (FluidTankGT tank : tanks) { - if (tank.canFillAll(fluid)) { - fluid.amount -= tank.add(fluid.amount, fluid); - } - } - } - - public long getProgress() { - return progressTime; + @Override + public int getProgress() { + P processing = getProcessingLogic(); + return processing.getProgress(); } - public long getMaxProgress() { - return maxProgressTime; + @Override + public int getMaxProgress() { + P processing = getProcessingLogic(); + return processing.getDuration(); } - public boolean increaseProgress(int aProgressAmountInTicks) { - progressTime += aProgressAmountInTicks; + @Override + public boolean increaseProgress(int progressAmount) { + P processing = getProcessingLogic(); + processing.increaseProgress(progressAmount); return true; } + @Override public boolean hasThingsToDo() { return getMaxProgress() > 0; } + @Override public boolean hasWorkJustBeenEnabled() { return wasEnabled; } + @Override public void enableWorking() { wasEnabled = true; canWork = true; } + @Override public void disableWorking() { canWork = false; } + @Override public boolean wasShutdown() { return powerShutDown; } + @Override public boolean isAllowedToWork() { return canWork; } + @Override public boolean isActive() { return active; } + @Override public void setActive(boolean active) { this.active = active; } @@ -766,37 +533,18 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl this.acceptsFuel = acceptsFuel; } - protected boolean isWireless() { - return isWireless; - } - - protected void setWireless(boolean isWireless) { - this.isWireless = isWireless; - } - - protected boolean drainEut(long eut) { - return decreaseStoredEnergyUnits(eut, false); - } - - protected boolean generateEut(long eut) { - return increaseStoredEnergyUnits(eut, true); - } - - protected boolean isGenerator() { - return false; - } - protected boolean consumeFuel() { + if (isElectric() || isSteam()) return false; if (isActive() && burnTime <= 0) { - for (int i = 0; i < inputInventory.getSlots(); i++) { - if (inputInventory.getStackInSlot(i) != null) { - int checkBurnTime = TileEntityFurnace.getItemBurnTime(inputInventory.getStackInSlot(i)) / 10; - if (checkBurnTime <= 0) continue; - inputInventory.getStackInSlot(i).stackSize--; - burnTime = checkBurnTime; - totalBurnTime = checkBurnTime; - break; - } + for (int i = 0; i < itemInput.getSlots(); i++) { + ItemStack item = itemInput.getItemInSlot(i); + if (item == null) continue; + int checkBurnTime = TileEntityFurnace.getItemBurnTime(item) / 10; + if (checkBurnTime <= 0) continue; + item.stackSize--; + burnTime = checkBurnTime; + totalBurnTime = checkBurnTime; + break; } updateSlots(); } @@ -806,8 +554,7 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl totalBurnTime = 0; return false; } - - return true; + return false; } @Override @@ -826,38 +573,36 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl list.add("Fuel: " + EnumChatFormatting.GOLD + burnTime + "/" + totalBurnTime); } - if (this instanceof PowerLogicHost powerLogicHost) { - PowerLogic logic = powerLogicHost.getPowerLogic(facing); - if (isElectric) { - list.add( - StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " - + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(logic.getStoredEnergy()) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(logic.getCapacity()) - + EnumChatFormatting.RESET - + " EU"); - list.add( - StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " - + EnumChatFormatting.RED - + GT_Utility.formatNumbers(eut) - + EnumChatFormatting.RESET - + " EU/t"); - list.add( - StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(logic.getVoltage()) - + EnumChatFormatting.RESET - // TODO: Put ampere getter here, once that's variable - + " EU/t(*2A) " - + StatCollector.translateToLocal("GT5U.machines.tier") - + ": " - + EnumChatFormatting.YELLOW - + VN[GT_Utility.getTier(logic.getVoltage())] - + EnumChatFormatting.RESET); - } + PowerLogic logic = getPowerLogic(); + if (isElectric) { + list.add( + StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + + EnumChatFormatting.GREEN + + GT_Utility.formatNumbers(logic.getStoredEnergy()) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GT_Utility.formatNumbers(logic.getCapacity()) + + EnumChatFormatting.RESET + + " EU"); + list.add( + StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " + + EnumChatFormatting.RED + + GT_Utility.formatNumbers(getProcessingLogic().getCalculatedEut()) + + EnumChatFormatting.RESET + + " EU/t"); + list.add( + StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " + + EnumChatFormatting.YELLOW + + GT_Utility.formatNumbers(logic.getVoltage()) + + EnumChatFormatting.RESET + // TODO: Put ampere getter here, once that's variable + + " EU/t(*2A) " + + StatCollector.translateToLocal("GT5U.machines.tier") + + ": " + + EnumChatFormatting.YELLOW + + VN[GT_Utility.getTier(logic.getVoltage())] + + EnumChatFormatting.RESET); } addProgressStringToScanner(player, logLevel, list); @@ -873,6 +618,9 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl } protected void addProgressStringToScanner(EntityPlayer player, int logLevel, ArrayList list) { + P processing = getProcessingLogic(); + int progressTime = processing.getProgress(); + int maxProgressTime = processing.getDuration(); list.add( StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " + EnumChatFormatting.GREEN @@ -886,7 +634,6 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl } protected void stopMachine(boolean powerShutDown) { - progressTime = 0; setActive(false); disableWorking(); if (powerShutDown) { @@ -896,50 +643,10 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl } protected void updateSlots() { - for (int i = 0; i < inputInventory.getSlots(); i++) { - ItemStack item = inputInventory.getStackInSlot(i); - if (item != null && item.stackSize <= 0) { - inputInventory.setStackInSlot(i, null); - } - } - - for (FluidTankGT inputTank : inputTanks) { - 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); - } - } - - /** - * Must always be a positive. If the multi generates Eu/t isGenerator() should be overridden to true - */ - protected void setEut(long eut) { - if (eut < 0) { - eut = -eut; - } - - this.eut = eut; - } - - protected void setDuration(long duration) { - if (duration < 0) { - duration = -duration; - } - - maxProgressTime = duration; + itemInput.update(false); + itemOutput.update(false); + fluidInput.update(); + fluidOutput.update(); } @Override @@ -956,53 +663,149 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl setActive((booleans & ACTIVE) == ACTIVE); } - protected boolean hasItemInput() { + public boolean hasItemInput() { return true; } - protected boolean hasItemOutput() { + public boolean hasItemOutput() { return true; } - protected boolean hasFluidInput() { + public boolean hasFluidInput() { return true; } - protected boolean hasFluidOutput() { + public boolean hasFluidOutput() { return true; } - protected void setItemOutputs(ItemStack... outputs) { - itemsToOutput = outputs; - } - - protected void setFluidOutputs(FluidStack... outputs) { - fluidsToOutput = outputs; - } - @Override public void setSound(byte soundEvent, int soundEventValue) { this.soundEvent = soundEvent; this.soundEventValue = soundEventValue; - if (isClientSide()) { - switch (soundEventValue) { - case PROCESS_START_SOUND_INDEX -> { - if (getProcessStartSound() != null) GT_Utility.doSoundAtClient( - getProcessStartSound(), - getTimeBetweenProcessSounds(), - 1.0F, - getXCoord(), - getYCoord(), - getZCoord()); - } - case INTERRUPT_SOUND_INDEX -> GT_Utility.doSoundAtClient( - SoundResource.IC2_MACHINES_INTERRUPT_ONE, - 100, + if (isServerSide()) { + return; + } + + switch (soundEventValue) { + case PROCESS_START_SOUND_INDEX -> { + if (getProcessStartSound() != null) GT_Utility.doSoundAtClient( + getProcessStartSound(), + getTimeBetweenProcessSounds(), 1.0F, getXCoord(), getYCoord(), getZCoord()); } + case INTERRUPT_SOUND_INDEX -> GT_Utility.doSoundAtClient( + SoundResource.IC2_MACHINES_INTERRUPT_ONE, + 100, + 1.0F, + getXCoord(), + getYCoord(), + getZCoord()); } + + } + + @Nullable + public ItemInventoryLogic getItemLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type) { + if (side == facing) return null; + return switch (type) { + case Input -> itemInput; + case Output -> itemOutput; + default -> null; + }; + } + + @Nullable + public FluidInventoryLogic getFluidLogic(@Nonnull ForgeDirection side, @Nonnull InventoryType type) { + if (side == facing) return null; + return switch (type) { + case Input -> fluidInput; + case Output -> fluidOutput; + default -> null; + }; } + + @Override + @Nonnull + public P getProcessingLogic() { + if (processingLogic == null) { + processingLogic = createProcessingLogic().setMachineHost(this); + } + return Objects.requireNonNull(processingLogic); + } + + @OverrideOnly + @Nonnull + protected abstract P createProcessingLogic(); + + @Override + public boolean isInputSeparated() { + return false; + } + + @Nonnull + @Override + public VoidingMode getVoidMode() { + return voidingMode; + } + + @Override + public boolean needsUpdate() { + return processingUpdate; + } + + @Override + public void setProcessingUpdate(boolean update) { + processingUpdate = update; + } + + @Override + @Nonnull + public PowerLogic getPowerLogic(@Nonnull ForgeDirection side) { + if (side == facing) return new NullPowerLogic(); + return power; + } + + @Override + @Nonnull + public ForgeDirection getPowerOutputSide() { + return Objects.requireNonNull(facing.getOpposite()); + } + + protected void updatePowerLogic() { + power.setEnergyCapacity(GT_Values.V[tier] * power.getMaxAmperage() * 2 * MINUTE); + power.setMaxVoltage(GT_Values.V[tier]); + power.setMaxAmperage(1); + } + + @Nonnull + protected PowerLogic createPowerLogic() { + return new PowerLogic().setMaxAmperage(1) + .setType(PowerLogic.RECEIVER); + } + + @Nonnull + protected GUIProvider createGUIProvider() { + return new MachineGUIProvider<>(this); + } + + @Nonnull + public GUIProvider getGUI(@Nonnull UIBuildContext uiContext) { + return guiProvider; + } + + @Override + public ItemStack getAsItem() { + return MultiTileEntityRegistry.getRegistry(getMultiTileEntityRegistryID()) + .getItem(getMultiTileEntityID()); + } + + @Override + public String getMachineName() { + return StatCollector.translateToLocal(getAsItem().getUnlocalizedName()); + } + } -- cgit