From 1b820de08a05070909a267e17f033fcf58ac8710 Mon Sep 17 00:00:00 2001 From: NotAPenguin Date: Mon, 2 Sep 2024 23:17:17 +0200 Subject: The Great Renaming (#3014) * move kekztech to a single root dir * move detrav to a single root dir * move gtnh-lanthanides to a single root dir * move tectech and delete some gross reflection in gt++ * remove more reflection inside gt5u * delete more reflection in gt++ * fix imports * move bartworks and bwcrossmod * fix proxies * move galactigreg and ggfab * move gtneioreplugin * try to fix gt++ bee loader * apply the rename rules to BW * apply rename rules to bwcrossmod * apply rename rules to detrav scanner mod * apply rename rules to galacticgreg * apply rename rules to ggfab * apply rename rules to goodgenerator * apply rename rules to gtnh-lanthanides * apply rename rules to gt++ * apply rename rules to kekztech * apply rename rules to kubatech * apply rename rules to tectech * apply rename rules to gt apply the rename rules to gt * fix tt import * fix mui hopefully * fix coremod except intergalactic * rename assline recipe class * fix a class name i stumbled on * rename StructureUtility to GTStructureUtility to prevent conflict with structurelib * temporary rename of GTTooltipDataCache to old name * fix gt client/server proxy names --- src/main/java/gregtech/api/GregTechAPI.java | 982 ++++ src/main/java/gregtech/api/GregTech_API.java | 999 ---- .../api/damagesources/GTDamageSources.java | 119 + .../api/damagesources/GT_DamageSources.java | 119 - .../api/enchants/EnchantmentEnderDamage.java | 72 + .../gregtech/api/enchants/EnchantmentHazmat.java | 56 + .../api/enchants/EnchantmentRadioactivity.java | 68 + .../api/enchants/Enchantment_EnderDamage.java | 72 - .../gregtech/api/enchants/Enchantment_Hazmat.java | 56 - .../api/enchants/Enchantment_Radioactivity.java | 68 - src/main/java/gregtech/api/enums/Dyes.java | 8 +- .../gregtech/api/enums/GTNH_ExtraMaterials.java | 626 --- src/main/java/gregtech/api/enums/GTStones.java | 88 +- src/main/java/gregtech/api/enums/GTValues.java | 721 +++ .../java/gregtech/api/enums/GTVoltageIndex.java | 22 - .../java/gregtech/api/enums/GT_HatchElement.java | 112 - src/main/java/gregtech/api/enums/GT_Values.java | 720 --- src/main/java/gregtech/api/enums/HatchElement.java | 110 + .../java/gregtech/api/enums/HeatingCoilLevel.java | 4 +- src/main/java/gregtech/api/enums/ItemList.java | 72 +- .../java/gregtech/api/enums/MaterialBuilder.java | 4 +- src/main/java/gregtech/api/enums/Materials.java | 142 +- .../java/gregtech/api/enums/MaterialsBotania.java | 46 +- .../java/gregtech/api/enums/MaterialsGTNH.java | 626 +++ .../java/gregtech/api/enums/MaterialsKevlar.java | 64 +- .../java/gregtech/api/enums/MaterialsUEVplus.java | 20 +- .../java/gregtech/api/enums/MetaTileEntityIDs.java | 8 +- src/main/java/gregtech/api/enums/OreMixes.java | 16 +- src/main/java/gregtech/api/enums/OrePrefixes.java | 66 +- src/main/java/gregtech/api/enums/SmallOres.java | 72 +- .../java/gregtech/api/enums/SoundResource.java | 4 +- src/main/java/gregtech/api/enums/TAE.java | 30 +- src/main/java/gregtech/api/enums/TCAspects.java | 112 + src/main/java/gregtech/api/enums/TC_Aspects.java | 112 - src/main/java/gregtech/api/enums/Textures.java | 32 +- src/main/java/gregtech/api/enums/Tier.java | 2 +- src/main/java/gregtech/api/enums/TierEU.java | 62 +- src/main/java/gregtech/api/enums/VoidingMode.java | 11 +- src/main/java/gregtech/api/enums/VoltageIndex.java | 22 + src/main/java/gregtech/api/fluid/FluidTankGT.java | 485 -- .../java/gregtech/api/fluid/GTFluidFactory.java | 90 + src/main/java/gregtech/api/fluid/GTFluidTank.java | 485 ++ .../java/gregtech/api/fluid/GT_FluidFactory.java | 90 - .../java/gregtech/api/graphs/GenerateNodeMap.java | 2 +- .../gregtech/api/graphs/GenerateNodeMapPower.java | 9 +- .../api/graphs/consumers/NodeEnergyReceiver.java | 24 +- .../gregtech/api/graphs/paths/PowerNodePath.java | 14 +- .../java/gregtech/api/gui/GT_GUIColorOverride.java | 93 - .../java/gregtech/api/gui/GUIColorOverride.java | 93 + .../api/gui/modularui/CoverUIBuildContext.java | 74 + .../java/gregtech/api/gui/modularui/GTUIInfos.java | 188 + .../gregtech/api/gui/modularui/GTUITextures.java | 542 +++ .../api/gui/modularui/GT_CoverUIBuildContext.java | 74 - .../gregtech/api/gui/modularui/GT_UIInfos.java | 189 - .../gregtech/api/gui/modularui/GT_UITextures.java | 542 --- .../gregtech/api/gui/modularui/GUITextureSet.java | 31 +- .../api/gui/widgets/CoverTickRateButton.java | 82 + .../api/gui/widgets/GT_CoverTickRateButton.java | 82 - .../gui/widgets/GT_LockedWhileActiveButton.java | 90 - .../api/gui/widgets/GT_PhantomItemButton.java | 92 - .../api/gui/widgets/LockedWhileActiveButton.java | 90 + .../api/gui/widgets/PhantomItemButton.java | 92 + .../api/interfaces/ICleanroomReceiver.java | 4 +- .../interfaces/IConfigurationCircuitSupport.java | 4 +- .../java/gregtech/api/interfaces/IFoodStat.java | 14 +- .../interfaces/IGT_ItemWithMaterialRenderer.java | 10 +- .../gregtech/api/interfaces/IHatchElement.java | 29 +- .../gregtech/api/interfaces/IIconContainer.java | 2 +- .../gregtech/api/interfaces/IItemBehaviour.java | 4 +- .../api/interfaces/INetworkUpdatableItem.java | 4 +- .../java/gregtech/api/interfaces/IRecipeMap.java | 18 +- .../api/interfaces/IRedstoneCircuitBlock.java | 4 +- .../java/gregtech/api/interfaces/IToolStats.java | 4 +- .../gregtech/api/interfaces/fluid/IGTFluid.java | 14 + .../api/interfaces/fluid/IGTFluidBuilder.java | 96 + .../api/interfaces/fluid/IGTRegisteredFluid.java | 60 + .../gregtech/api/interfaces/fluid/IGT_Fluid.java | 14 - .../api/interfaces/fluid/IGT_FluidBuilder.java | 96 - .../api/interfaces/fluid/IGT_RegisteredFluid.java | 60 - .../api/interfaces/internal/IGTCraftingRecipe.java | 8 + .../gregtech/api/interfaces/internal/IGTMod.java | 50 + .../api/interfaces/internal/IGTRecipeAdder.java | 8 + .../interfaces/internal/IGT_CraftingRecipe.java | 8 - .../gregtech/api/interfaces/internal/IGT_Mod.java | 50 - .../api/interfaces/internal/IGT_RecipeAdder.java | 8 - .../api/interfaces/internal/IThaumcraftCompat.java | 8 +- .../interfaces/metatileentity/IMetaTileEntity.java | 8 +- .../modularui/ControllerWithOptionalFeatures.java | 393 -- .../modularui/IControllerWithOptionalFeatures.java | 393 ++ .../api/interfaces/modularui/IGetTitleColor.java | 4 +- .../interfaces/tileentity/IColoredTileEntity.java | 5 +- .../api/interfaces/tileentity/ICoverable.java | 8 +- .../interfaces/tileentity/IEnergyConnected.java | 14 +- .../interfaces/tileentity/IGregTechTileEntity.java | 4 +- .../gregtech/api/items/BlockLongDistancePipe.java | 125 + .../java/gregtech/api/items/GTGenericBlock.java | 22 + .../java/gregtech/api/items/GTGenericItem.java | 162 + .../api/items/GT_Block_LongDistancePipe.java | 125 - .../gregtech/api/items/GT_BreederCell_Item.java | 153 - .../gregtech/api/items/GT_CoolantCellIC_Item.java | 67 - .../gregtech/api/items/GT_CoolantCell_Item.java | 82 - .../gregtech/api/items/GT_EnergyArmor_Item.java | 332 -- .../java/gregtech/api/items/GT_Generic_Block.java | 22 - .../java/gregtech/api/items/GT_Generic_Item.java | 162 - .../java/gregtech/api/items/GT_MetaBase_Item.java | 622 --- .../gregtech/api/items/GT_MetaGenerated_Item.java | 415 -- .../api/items/GT_MetaGenerated_Item_X01.java | 213 - .../api/items/GT_MetaGenerated_Item_X32.java | 225 - .../gregtech/api/items/GT_MetaGenerated_Tool.java | 1013 ---- .../api/items/GT_RadioactiveCellIC_Item.java | 219 - .../api/items/GT_RadioactiveCell_Item.java | 159 - src/main/java/gregtech/api/items/GT_Tool_Item.java | 41 - .../java/gregtech/api/items/ItemBreederCell.java | 153 + .../java/gregtech/api/items/ItemCoolantCell.java | 82 + .../java/gregtech/api/items/ItemCoolantCellIC.java | 67 + .../java/gregtech/api/items/ItemEnergyArmor.java | 331 ++ .../gregtech/api/items/ItemRadioactiveCell.java | 159 + .../gregtech/api/items/ItemRadioactiveCellIC.java | 219 + src/main/java/gregtech/api/items/ItemTool.java | 41 + src/main/java/gregtech/api/items/MetaBaseItem.java | 622 +++ .../java/gregtech/api/items/MetaGeneratedItem.java | 415 ++ .../gregtech/api/items/MetaGeneratedItemX01.java | 210 + .../gregtech/api/items/MetaGeneratedItemX32.java | 225 + .../java/gregtech/api/items/MetaGeneratedTool.java | 1013 ++++ .../api/logic/AbstractProcessingLogic.java | 24 +- .../gregtech/api/logic/ItemInventoryLogic.java | 8 +- .../gregtech/api/logic/MuTEProcessingLogic.java | 24 +- src/main/java/gregtech/api/logic/PowerLogic.java | 10 +- .../java/gregtech/api/logic/ProcessingLogic.java | 24 +- .../api/metatileentity/BaseMetaPipeEntity.java | 130 +- .../api/metatileentity/BaseMetaTileEntity.java | 279 +- .../api/metatileentity/BaseTileEntity.java | 42 +- .../api/metatileentity/CommonMetaTileEntity.java | 30 +- .../api/metatileentity/CoverableTileEntity.java | 84 +- .../api/metatileentity/MetaPipeEntity.java | 62 +- .../api/metatileentity/MetaTileEntity.java | 83 +- .../api/metatileentity/TileIC2EnergySink.java | 10 +- .../implementations/GT_MetaPipeEntity_Cable.java | 649 --- .../implementations/GT_MetaPipeEntity_Fluid.java | 979 ---- .../implementations/GT_MetaPipeEntity_Frame.java | 119 - .../implementations/GT_MetaPipeEntity_Item.java | 530 --- .../GT_MetaTileEntity_BasicBatteryBuffer.java | 436 -- .../GT_MetaTileEntity_BasicGenerator.java | 339 -- .../GT_MetaTileEntity_BasicHull.java | 175 - .../GT_MetaTileEntity_BasicHull_NonElectric.java | 78 - .../GT_MetaTileEntity_BasicMachine.java | 1563 ------- .../GT_MetaTileEntity_BasicMachine_Bronze.java | 387 -- .../GT_MetaTileEntity_BasicMachine_GT_Recipe.java | 818 ---- .../GT_MetaTileEntity_BasicMachine_Steel.java | 150 - .../GT_MetaTileEntity_BasicTank.java | 331 -- .../implementations/GT_MetaTileEntity_Buffer.java | 563 --- .../GT_MetaTileEntity_CubicMultiBlockBase.java | 141 - .../GT_MetaTileEntity_EnhancedMultiBlockBase.java | 318 -- ...MetaTileEntity_ExtendedPowerMultiBlockBase.java | 242 - .../GT_MetaTileEntity_FilterBase.java | 106 - .../implementations/GT_MetaTileEntity_Hatch.java | 252 - .../GT_MetaTileEntity_Hatch_DataAccess.java | 170 - .../GT_MetaTileEntity_Hatch_Dynamo.java | 110 - .../GT_MetaTileEntity_Hatch_Energy.java | 125 - .../GT_MetaTileEntity_Hatch_Input.java | 196 - .../GT_MetaTileEntity_Hatch_InputBus.java | 318 -- .../GT_MetaTileEntity_Hatch_Maintenance.java | 459 -- .../GT_MetaTileEntity_Hatch_Muffler.java | 208 - .../GT_MetaTileEntity_Hatch_MultiInput.java | 300 -- .../GT_MetaTileEntity_Hatch_Output.java | 497 -- .../GT_MetaTileEntity_Hatch_OutputBus.java | 323 -- ...GT_MetaTileEntity_Hatch_QuadrupleHumongous.java | 27 - .../GT_MetaTileEntity_MagHatch.java | 103 - .../GT_MetaTileEntity_MultiBlockBase.java | 2754 ----------- .../GT_MetaTileEntity_SpecialFilter.java | 134 - .../GT_MetaTileEntity_TieredMachineBlock.java | 119 - .../GT_MetaTileEntity_TooltipMultiBlockBase.java | 57 - .../GT_MetaTileEntity_Transformer.java | 326 -- .../GT_MetaTileEntity_WetTransformer.java | 93 - .../GT_MetaTileEntity_Wireless_Dynamo.java | 146 - .../GT_MetaTileEntity_Wireless_Hatch.java | 168 - .../implementations/MTEBasicBatteryBuffer.java | 435 ++ .../implementations/MTEBasicGenerator.java | 338 ++ .../implementations/MTEBasicHull.java | 173 + .../implementations/MTEBasicHullNonElectric.java | 75 + .../implementations/MTEBasicMachine.java | 1563 +++++++ .../implementations/MTEBasicMachineBronze.java | 387 ++ .../implementations/MTEBasicMachineSteel.java | 149 + .../implementations/MTEBasicMachineWithRecipe.java | 817 ++++ .../implementations/MTEBasicTank.java | 328 ++ .../metatileentity/implementations/MTEBuffer.java | 559 +++ .../metatileentity/implementations/MTECable.java | 649 +++ .../implementations/MTECubicMultiBlockBase.java | 141 + .../implementations/MTEEnhancedMultiBlockBase.java | 318 ++ .../MTEExtendedPowerMultiBlockBase.java | 242 + .../implementations/MTEFilterBase.java | 104 + .../metatileentity/implementations/MTEFluid.java | 971 ++++ .../metatileentity/implementations/MTEFrame.java | 119 + .../metatileentity/implementations/MTEHatch.java | 250 + .../implementations/MTEHatchDataAccess.java | 169 + .../implementations/MTEHatchDynamo.java | 109 + .../implementations/MTEHatchEnergy.java | 123 + .../implementations/MTEHatchInput.java | 192 + .../implementations/MTEHatchInputBus.java | 315 ++ .../implementations/MTEHatchMagnet.java | 102 + .../implementations/MTEHatchMaintenance.java | 455 ++ .../implementations/MTEHatchMuffler.java | 208 + .../implementations/MTEHatchMultiInput.java | 299 ++ .../implementations/MTEHatchOutput.java | 493 ++ .../implementations/MTEHatchOutputBus.java | 320 ++ .../MTEHatchQuadrupleHumongous.java | 27 + .../metatileentity/implementations/MTEItem.java | 523 +++ .../implementations/MTEMultiBlockBase.java | 2742 +++++++++++ .../implementations/MTESpecialFilter.java | 132 + .../implementations/MTETieredMachineBlock.java | 119 + .../implementations/MTETooltipMultiBlockBase.java | 56 + .../implementations/MTETransformer.java | 325 ++ .../implementations/MTEWetTransformer.java | 92 + .../implementations/MTEWirelessDynamo.java | 144 + .../implementations/MTEWirelessEnergy.java | 167 + .../api/multitileentity/MultiTileEntityBlock.java | 35 +- .../MultiTileEntityClassContainer.java | 12 +- .../api/multitileentity/MultiTileEntityItem.java | 6 +- .../multitileentity/MultiTileEntityRegistry.java | 27 +- .../api/multitileentity/base/MultiTileEntity.java | 126 +- .../base/NonTickableMultiTileEntity.java | 6 +- .../base/TickableMultiTileEntity.java | 18 +- .../multitileentity/enums/GT_MultiTileCasing.java | 4 +- .../enums/GT_MultiTileComponentCasing.java | 4 +- .../multitileentity/enums/GT_MultiTileMachine.java | 4 +- .../enums/GT_MultiTileUpgradeCasing.java | 4 +- .../interfaces/SyncedMultiTileEntity.java | 14 +- .../machine/MultiTileBasicMachine.java | 50 +- .../multiblock/base/ComplexParallelController.java | 10 +- .../multiblock/base/Controller.java | 44 +- .../multiblock/base/MultiBlockPart.java | 12 +- .../multiblock/casing/FunctionalCasing.java | 4 +- .../multiblock/casing/UpgradeCasing.java | 4 +- src/main/java/gregtech/api/net/GTPacket.java | 59 + .../java/gregtech/api/net/GTPacketBlockEvent.java | 63 + .../gregtech/api/net/GTPacketClientPreference.java | 58 + .../gregtech/api/net/GTPacketMultiTileEntity.java | 254 + .../gregtech/api/net/GTPacketMusicSystemData.java | 58 + src/main/java/gregtech/api/net/GTPacketNew.java | 30 + .../java/gregtech/api/net/GTPacketPollution.java | 47 + .../gregtech/api/net/GTPacketRequestCoverData.java | 113 + .../gregtech/api/net/GTPacketSendCoverData.java | 107 + .../api/net/GTPacketSendOregenPattern.java | 56 + .../api/net/GTPacketSetConfigurationCircuit.java | 110 + src/main/java/gregtech/api/net/GTPacketSound.java | 73 + .../java/gregtech/api/net/GTPacketTileEntity.java | 157 + .../gregtech/api/net/GTPacketToolSwitchMode.java | 52 + src/main/java/gregtech/api/net/GTPacketTypes.java | 64 + .../java/gregtech/api/net/GTPacketUpdateItem.java | 64 + src/main/java/gregtech/api/net/GT_Packet.java | 59 - src/main/java/gregtech/api/net/GT_PacketTypes.java | 64 - .../gregtech/api/net/GT_Packet_Block_Event.java | 63 - .../api/net/GT_Packet_ClientPreference.java | 62 - .../api/net/GT_Packet_MultiTileEntity.java | 254 - .../api/net/GT_Packet_MusicSystemData.java | 58 - src/main/java/gregtech/api/net/GT_Packet_New.java | 30 - .../java/gregtech/api/net/GT_Packet_Pollution.java | 47 - .../api/net/GT_Packet_RequestCoverData.java | 113 - .../gregtech/api/net/GT_Packet_SendCoverData.java | 107 - .../api/net/GT_Packet_SendOregenPattern.java | 56 - .../api/net/GT_Packet_SetConfigurationCircuit.java | 110 - .../java/gregtech/api/net/GT_Packet_Sound.java | 73 - .../gregtech/api/net/GT_Packet_TileEntity.java | 157 - .../gregtech/api/net/GT_Packet_ToolSwitchMode.java | 52 - .../gregtech/api/net/GT_Packet_UpdateItem.java | 64 - .../java/gregtech/api/net/IGT_NetworkHandler.java | 10 +- .../api/objects/AE2DigitalChestHandler.java | 6 +- .../java/gregtech/api/objects/GTArrayList.java | 73 + .../java/gregtech/api/objects/GTChunkManager.java | 204 + .../gregtech/api/objects/GTCopiedBlockTexture.java | 36 + .../java/gregtech/api/objects/GTCoverDefault.java | 81 + .../java/gregtech/api/objects/GTCoverNone.java | 237 + src/main/java/gregtech/api/objects/GTFluid.java | 36 + src/main/java/gregtech/api/objects/GTHashSet.java | 91 + .../java/gregtech/api/objects/GTItemStack.java | 107 + .../java/gregtech/api/objects/GTItemStack2.java | 41 + .../java/gregtech/api/objects/GTMultiTexture.java | 27 + .../gregtech/api/objects/GTRenderedTexture.java | 33 + .../java/gregtech/api/objects/GTSidedTexture.java | 48 + .../gregtech/api/objects/GTStdRenderedTexture.java | 46 + .../java/gregtech/api/objects/GTUODimension.java | 54 + .../gregtech/api/objects/GTUODimensionList.java | 648 +++ src/main/java/gregtech/api/objects/GTUOFluid.java | 69 + .../java/gregtech/api/objects/GT_ArrayList.java | 73 - .../java/gregtech/api/objects/GT_ChunkManager.java | 204 - .../api/objects/GT_CopiedBlockTexture.java | 35 - .../gregtech/api/objects/GT_Cover_Default.java | 81 - .../java/gregtech/api/objects/GT_Cover_None.java | 237 - src/main/java/gregtech/api/objects/GT_Fluid.java | 36 - src/main/java/gregtech/api/objects/GT_HashSet.java | 91 - .../java/gregtech/api/objects/GT_ItemStack.java | 107 - .../java/gregtech/api/objects/GT_ItemStack2.java | 41 - .../java/gregtech/api/objects/GT_MultiTexture.java | 26 - .../gregtech/api/objects/GT_RenderedTexture.java | 33 - .../java/gregtech/api/objects/GT_SidedTexture.java | 48 - .../api/objects/GT_StdRenderedTexture.java | 46 - .../java/gregtech/api/objects/GT_UO_Dimension.java | 54 - .../gregtech/api/objects/GT_UO_DimensionList.java | 648 --- .../java/gregtech/api/objects/GT_UO_Fluid.java | 69 - src/main/java/gregtech/api/objects/ItemData.java | 2 +- .../java/gregtech/api/objects/MaterialStack.java | 4 +- .../overclockdescriber/EUNoOverclockDescriber.java | 38 +- .../overclockdescriber/EUOverclockDescriber.java | 34 +- .../FusionOverclockDescriber.java | 16 +- .../overclockdescriber/OverclockDescriber.java | 36 +- .../SteamOverclockDescriber.java | 20 +- .../api/recipe/BasicUIPropertiesBuilder.java | 4 +- .../java/gregtech/api/recipe/FindRecipeQuery.java | 18 +- .../gregtech/api/recipe/NEIRecipeProperties.java | 10 +- .../api/recipe/NEIRecipePropertiesBuilder.java | 6 +- src/main/java/gregtech/api/recipe/RecipeMap.java | 32 +- .../java/gregtech/api/recipe/RecipeMapBackend.java | 104 +- .../api/recipe/RecipeMapBackendProperties.java | 12 +- .../recipe/RecipeMapBackendPropertiesBuilder.java | 26 +- .../java/gregtech/api/recipe/RecipeMapBuilder.java | 30 +- .../gregtech/api/recipe/RecipeMapFrontend.java | 52 +- src/main/java/gregtech/api/recipe/RecipeMaps.java | 406 +- .../api/recipe/check/ResultInsufficientHeat.java | 4 +- .../check/ResultInsufficientMachineTier.java | 4 +- .../api/recipe/check/ResultInsufficientPower.java | 6 +- .../check/ResultInsufficientStartupPower.java | 4 +- .../ResultInsufficientStartupPowerBigInt.java | 2 +- .../api/recipe/check/SingleRecipeCheck.java | 59 +- .../gregtech/api/recipe/maps/AssemblerBackend.java | 4 +- .../api/recipe/maps/AssemblyLineFrontend.java | 8 +- .../api/recipe/maps/FluidCannerBackend.java | 24 +- .../api/recipe/maps/FormingPressBackend.java | 18 +- .../java/gregtech/api/recipe/maps/FuelBackend.java | 26 +- .../gregtech/api/recipe/maps/FurnaceBackend.java | 20 +- .../api/recipe/maps/LargeBoilerFuelBackend.java | 22 +- .../gregtech/api/recipe/maps/MicrowaveBackend.java | 83 +- .../gregtech/api/recipe/maps/NonGTBackend.java | 8 +- .../api/recipe/maps/OilCrackerBackend.java | 4 +- .../gregtech/api/recipe/maps/PrinterBackend.java | 32 +- .../maps/PurificationUnitClarifierFrontend.java | 12 +- .../maps/PurificationUnitFlocculatorFrontend.java | 27 +- .../recipe/maps/PurificationUnitLaserFrontend.java | 10 +- .../maps/PurificationUnitOzonationFrontend.java | 4 +- .../PurificationUnitParticleExtractorFrontend.java | 4 +- .../maps/PurificationUnitPhAdjustmentFrontend.java | 23 +- .../maps/PurificationUnitPlasmaHeaterFrontend.java | 14 +- .../gregtech/api/recipe/maps/RecyclerBackend.java | 22 +- .../api/recipe/maps/ReplicatorBackend.java | 36 +- .../api/recipe/maps/SpaceProjectFrontend.java | 18 +- .../maps/TranscendentPlasmaMixerFrontend.java | 8 +- .../api/recipe/maps/UnpackagerBackend.java | 12 +- .../api/recipe/metadata/CompressionTierKey.java | 2 +- .../api/recipe/metadata/PCBFactoryTierKey.java | 2 +- .../api/recipe/metadata/PCBFactoryUpgradeKey.java | 2 +- .../api/registries/LHECoolantRegistry.java | 8 +- .../java/gregtech/api/render/TextureFactory.java | 4 +- .../gregtech/api/task/tasks/PollutionTask.java | 4 +- .../api/threads/GT_Runnable_Cable_Update.java | 87 - .../threads/GT_Runnable_MachineBlockUpdate.java | 184 - .../gregtech/api/threads/GT_Runnable_Sound.java | 41 - .../gregtech/api/threads/RunnableCableUpdate.java | 87 + .../api/threads/RunnableMachineUpdate.java | 184 + .../java/gregtech/api/threads/RunnableSound.java | 41 + .../java/gregtech/api/util/AssemblyLineServer.java | 297 ++ .../java/gregtech/api/util/AssemblyLineUtils.java | 561 +++ .../gregtech/api/util/BlastFurnaceGasStat.java | 5 +- .../java/gregtech/api/util/CircuitryBehavior.java | 212 + .../gregtech/api/util/ColorsMetadataSection.java | 2 +- .../api/util/ColorsMetadataSectionSerializer.java | 12 +- src/main/java/gregtech/api/util/CoverBehavior.java | 402 ++ .../java/gregtech/api/util/CoverBehaviorBase.java | 839 ++++ .../gregtech/api/util/ExoticEnergyInputHelper.java | 103 + .../java/gregtech/api/util/FishPondFakeRecipe.java | 8 +- .../java/gregtech/api/util/GTApiaryModifier.java | 24 + .../java/gregtech/api/util/GTApiaryUpgrade.java | 224 + src/main/java/gregtech/api/util/GTBaseCrop.java | 311 ++ src/main/java/gregtech/api/util/GTBlockMap.java | 134 + src/main/java/gregtech/api/util/GTBlockSet.java | 39 + src/main/java/gregtech/api/util/GTCLSCompat.java | 157 + .../gregtech/api/util/GTChunkAssociatedData.java | 494 ++ .../java/gregtech/api/util/GTClientPreference.java | 43 + src/main/java/gregtech/api/util/GTConfig.java | 162 + src/main/java/gregtech/api/util/GTCreativeTab.java | 26 + src/main/java/gregtech/api/util/GTFoodStat.java | 122 + .../java/gregtech/api/util/GTForestryCompat.java | 193 + src/main/java/gregtech/api/util/GTGCCompat.java | 52 + .../java/gregtech/api/util/GTIBoxableWrapper.java | 13 + .../api/util/GTItsNotMyFaultException.java | 18 + .../java/gregtech/api/util/GTLanguageManager.java | 603 +++ src/main/java/gregtech/api/util/GTLog.java | 45 + src/main/java/gregtech/api/util/GTModHandler.java | 2435 ++++++++++ src/main/java/gregtech/api/util/GTMusicSystem.java | 667 +++ .../gregtech/api/util/GTOreDictUnificator.java | 578 +++ src/main/java/gregtech/api/util/GTPlayedSound.java | 31 + src/main/java/gregtech/api/util/GTRecipe.java | 1366 ++++++ .../java/gregtech/api/util/GTRecipeBuilder.java | 946 ++++ .../java/gregtech/api/util/GTRecipeConstants.java | 691 +++ .../java/gregtech/api/util/GTRecipeMapUtil.java | 198 + .../gregtech/api/util/GTRecipeRegistrator.java | 872 ++++ .../java/gregtech/api/util/GTRenderingWorld.java | 195 + .../java/gregtech/api/util/GTShapedRecipe.java | 100 + .../java/gregtech/api/util/GTShapelessRecipe.java | 100 + .../gregtech/api/util/GTSpawnEventHandler.java | 81 + src/main/java/gregtech/api/util/GTStreamUtil.java | 44 + .../java/gregtech/api/util/GTStructureUtility.java | 616 +++ .../gregtech/api/util/GTToolHarvestHelper.java | 71 + .../java/gregtech/api/util/GTTooltipDataCache.java | 104 + src/main/java/gregtech/api/util/GTUtil.java | 344 ++ src/main/java/gregtech/api/util/GTUtility.java | 4852 +++++++++++++++++++ .../java/gregtech/api/util/GTUtilityClient.java | 52 + src/main/java/gregtech/api/util/GTWaila.java | 23 + .../java/gregtech/api/util/GT_ApiaryModifier.java | 24 - .../java/gregtech/api/util/GT_ApiaryUpgrade.java | 225 - .../gregtech/api/util/GT_AssemblyLineUtils.java | 559 --- .../gregtech/api/util/GT_Assemblyline_Server.java | 297 -- src/main/java/gregtech/api/util/GT_BaseCrop.java | 311 -- src/main/java/gregtech/api/util/GT_BlockMap.java | 134 - src/main/java/gregtech/api/util/GT_BlockSet.java | 39 - src/main/java/gregtech/api/util/GT_CLS_Compat.java | 157 - .../gregtech/api/util/GT_ChunkAssociatedData.java | 494 -- .../gregtech/api/util/GT_CircuitryBehavior.java | 212 - .../gregtech/api/util/GT_ClientPreference.java | 43 - src/main/java/gregtech/api/util/GT_Config.java | 162 - .../java/gregtech/api/util/GT_CoverBehavior.java | 402 -- .../gregtech/api/util/GT_CoverBehaviorBase.java | 839 ---- .../java/gregtech/api/util/GT_CreativeTab.java | 26 - .../api/util/GT_ExoticEnergyInputHelper.java | 114 - src/main/java/gregtech/api/util/GT_FoodStat.java | 122 - .../java/gregtech/api/util/GT_Forestry_Compat.java | 193 - src/main/java/gregtech/api/util/GT_GC_Compat.java | 52 - .../gregtech/api/util/GT_HatchElementBuilder.java | 547 --- .../java/gregtech/api/util/GT_IBoxableWrapper.java | 13 - .../api/util/GT_ItsNotMyFaultException.java | 18 - .../gregtech/api/util/GT_JubilanceMegaApiary.java | 23 - .../java/gregtech/api/util/GT_LanguageManager.java | 603 --- src/main/java/gregtech/api/util/GT_Log.java | 45 - src/main/java/gregtech/api/util/GT_ModHandler.java | 2437 ---------- .../api/util/GT_Multiblock_Tooltip_Builder.java | 735 --- .../java/gregtech/api/util/GT_MusicSystem.java | 667 --- .../gregtech/api/util/GT_OreDictUnificator.java | 578 --- .../gregtech/api/util/GT_OverclockCalculator.java | 621 --- .../gregtech/api/util/GT_PCBFactoryManager.java | 25 - .../java/gregtech/api/util/GT_ParallelHelper.java | 713 --- .../java/gregtech/api/util/GT_PlayedSound.java | 31 - .../api/util/GT_ProcessingArray_Manager.java | 51 - src/main/java/gregtech/api/util/GT_Recipe.java | 1366 ------ .../java/gregtech/api/util/GT_RecipeBuilder.java | 946 ---- .../java/gregtech/api/util/GT_RecipeConstants.java | 692 --- .../java/gregtech/api/util/GT_RecipeMapUtil.java | 198 - .../gregtech/api/util/GT_RecipeRegistrator.java | 872 ---- .../java/gregtech/api/util/GT_RenderingWorld.java | 195 - .../java/gregtech/api/util/GT_Shaped_Recipe.java | 100 - .../gregtech/api/util/GT_Shapeless_Recipe.java | 100 - .../gregtech/api/util/GT_SpawnEventHandler.java | 81 - src/main/java/gregtech/api/util/GT_StreamUtil.java | 44 - .../gregtech/api/util/GT_StructureUtility.java | 618 --- .../gregtech/api/util/GT_StructureUtilityMuTE.java | 8 +- .../gregtech/api/util/GT_ToolHarvestHelper.java | 71 - .../gregtech/api/util/GT_TooltipDataCache.java | 9 +- src/main/java/gregtech/api/util/GT_Util.java | 347 -- src/main/java/gregtech/api/util/GT_Utility.java | 4859 -------------------- .../java/gregtech/api/util/GT_UtilityClient.java | 52 - src/main/java/gregtech/api/util/GT_Waila.java | 23 - .../gregtech/api/util/HatchElementBuilder.java | 546 +++ src/main/java/gregtech/api/util/IGTHatchAdder.java | 28 + .../java/gregtech/api/util/IGT_HatchAdder.java | 28 - .../gregtech/api/util/JubilanceMegaApiary.java | 23 + .../api/util/MultiblockTooltipBuilder.java | 735 +++ .../java/gregtech/api/util/OutputHatchWrapper.java | 6 +- .../gregtech/api/util/OverclockCalculator.java | 621 +++ .../java/gregtech/api/util/PCBFactoryManager.java | 25 + .../java/gregtech/api/util/ParallelHelper.java | 713 +++ .../gregtech/api/util/ProcessingArrayManager.java | 51 + .../gregtech/api/util/SemiFluidFuelHandler.java | 10 +- .../gregtech/api/util/VoidProtectionHelper.java | 2 +- .../java/gregtech/api/util/item/ItemHolder.java | 4 +- .../api/util/recipe/RecipeInputRequirements.java | 8 +- .../api/util/shutdown/ReasonOutOfFluid.java | 4 +- .../api/util/shutdown/ReasonOutOfItem.java | 2 +- .../api/util/shutdown/ReasonOutOfStuff.java | 2 +- .../api/util/shutdown/ShutDownReasonRegistry.java | 2 +- src/main/java/gregtech/api/world/GTWorldgen.java | 123 + src/main/java/gregtech/api/world/GT_Worldgen.java | 123 - 478 files changed, 51467 insertions(+), 51506 deletions(-) create mode 100644 src/main/java/gregtech/api/GregTechAPI.java delete mode 100644 src/main/java/gregtech/api/GregTech_API.java create mode 100644 src/main/java/gregtech/api/damagesources/GTDamageSources.java delete mode 100644 src/main/java/gregtech/api/damagesources/GT_DamageSources.java create mode 100644 src/main/java/gregtech/api/enchants/EnchantmentEnderDamage.java create mode 100644 src/main/java/gregtech/api/enchants/EnchantmentHazmat.java create mode 100644 src/main/java/gregtech/api/enchants/EnchantmentRadioactivity.java delete mode 100644 src/main/java/gregtech/api/enchants/Enchantment_EnderDamage.java delete mode 100644 src/main/java/gregtech/api/enchants/Enchantment_Hazmat.java delete mode 100644 src/main/java/gregtech/api/enchants/Enchantment_Radioactivity.java delete mode 100644 src/main/java/gregtech/api/enums/GTNH_ExtraMaterials.java create mode 100644 src/main/java/gregtech/api/enums/GTValues.java delete mode 100644 src/main/java/gregtech/api/enums/GTVoltageIndex.java delete mode 100644 src/main/java/gregtech/api/enums/GT_HatchElement.java delete mode 100644 src/main/java/gregtech/api/enums/GT_Values.java create mode 100644 src/main/java/gregtech/api/enums/HatchElement.java create mode 100644 src/main/java/gregtech/api/enums/MaterialsGTNH.java create mode 100644 src/main/java/gregtech/api/enums/TCAspects.java delete mode 100644 src/main/java/gregtech/api/enums/TC_Aspects.java create mode 100644 src/main/java/gregtech/api/enums/VoltageIndex.java delete mode 100644 src/main/java/gregtech/api/fluid/FluidTankGT.java create mode 100644 src/main/java/gregtech/api/fluid/GTFluidFactory.java create mode 100644 src/main/java/gregtech/api/fluid/GTFluidTank.java delete mode 100644 src/main/java/gregtech/api/fluid/GT_FluidFactory.java delete mode 100644 src/main/java/gregtech/api/gui/GT_GUIColorOverride.java create mode 100644 src/main/java/gregtech/api/gui/GUIColorOverride.java create mode 100644 src/main/java/gregtech/api/gui/modularui/CoverUIBuildContext.java create mode 100644 src/main/java/gregtech/api/gui/modularui/GTUIInfos.java create mode 100644 src/main/java/gregtech/api/gui/modularui/GTUITextures.java delete mode 100644 src/main/java/gregtech/api/gui/modularui/GT_CoverUIBuildContext.java delete mode 100644 src/main/java/gregtech/api/gui/modularui/GT_UIInfos.java delete mode 100644 src/main/java/gregtech/api/gui/modularui/GT_UITextures.java create mode 100644 src/main/java/gregtech/api/gui/widgets/CoverTickRateButton.java delete mode 100644 src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java delete mode 100644 src/main/java/gregtech/api/gui/widgets/GT_LockedWhileActiveButton.java delete mode 100644 src/main/java/gregtech/api/gui/widgets/GT_PhantomItemButton.java create mode 100644 src/main/java/gregtech/api/gui/widgets/LockedWhileActiveButton.java create mode 100644 src/main/java/gregtech/api/gui/widgets/PhantomItemButton.java create mode 100644 src/main/java/gregtech/api/interfaces/fluid/IGTFluid.java create mode 100644 src/main/java/gregtech/api/interfaces/fluid/IGTFluidBuilder.java create mode 100644 src/main/java/gregtech/api/interfaces/fluid/IGTRegisteredFluid.java delete mode 100644 src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java delete mode 100644 src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java delete mode 100644 src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java create mode 100644 src/main/java/gregtech/api/interfaces/internal/IGTCraftingRecipe.java create mode 100644 src/main/java/gregtech/api/interfaces/internal/IGTMod.java create mode 100644 src/main/java/gregtech/api/interfaces/internal/IGTRecipeAdder.java delete mode 100644 src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java delete mode 100644 src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java delete mode 100644 src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java delete mode 100644 src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java create mode 100644 src/main/java/gregtech/api/interfaces/modularui/IControllerWithOptionalFeatures.java create mode 100644 src/main/java/gregtech/api/items/BlockLongDistancePipe.java create mode 100644 src/main/java/gregtech/api/items/GTGenericBlock.java create mode 100644 src/main/java/gregtech/api/items/GTGenericItem.java delete mode 100644 src/main/java/gregtech/api/items/GT_Block_LongDistancePipe.java delete mode 100644 src/main/java/gregtech/api/items/GT_BreederCell_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_CoolantCellIC_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_CoolantCell_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_EnergyArmor_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_Generic_Block.java delete mode 100644 src/main/java/gregtech/api/items/GT_Generic_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_MetaBase_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_MetaGenerated_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X01.java delete mode 100644 src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X32.java delete mode 100644 src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java delete mode 100644 src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_RadioactiveCell_Item.java delete mode 100644 src/main/java/gregtech/api/items/GT_Tool_Item.java create mode 100644 src/main/java/gregtech/api/items/ItemBreederCell.java create mode 100644 src/main/java/gregtech/api/items/ItemCoolantCell.java create mode 100644 src/main/java/gregtech/api/items/ItemCoolantCellIC.java create mode 100644 src/main/java/gregtech/api/items/ItemEnergyArmor.java create mode 100644 src/main/java/gregtech/api/items/ItemRadioactiveCell.java create mode 100644 src/main/java/gregtech/api/items/ItemRadioactiveCellIC.java create mode 100644 src/main/java/gregtech/api/items/ItemTool.java create mode 100644 src/main/java/gregtech/api/items/MetaBaseItem.java create mode 100644 src/main/java/gregtech/api/items/MetaGeneratedItem.java create mode 100644 src/main/java/gregtech/api/items/MetaGeneratedItemX01.java create mode 100644 src/main/java/gregtech/api/items/MetaGeneratedItemX32.java create mode 100644 src/main/java/gregtech/api/items/MetaGeneratedTool.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicBatteryBuffer.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull_NonElectric.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_GT_Recipe.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Steel.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_FilterBase.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_DataAccess.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Dynamo.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Maintenance.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Muffler.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_QuadrupleHumongous.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MagHatch.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlock.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TooltipMultiBlockBase.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_WetTransformer.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java delete mode 100644 src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicBatteryBuffer.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHull.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHullNonElectric.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachine.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineBronze.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineSteel.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineWithRecipe.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBasicTank.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTECable.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTECubicMultiBlockBase.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEEnhancedMultiBlockBase.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEExtendedPowerMultiBlockBase.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEFilterBase.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEFluid.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEFrame.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatch.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDataAccess.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDynamo.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchEnergy.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInput.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInputBus.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMagnet.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMaintenance.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMultiInput.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutput.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutputBus.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchQuadrupleHumongous.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEItem.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTESpecialFilter.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTETieredMachineBlock.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTETooltipMultiBlockBase.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTETransformer.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEWetTransformer.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessDynamo.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessEnergy.java create mode 100644 src/main/java/gregtech/api/net/GTPacket.java create mode 100644 src/main/java/gregtech/api/net/GTPacketBlockEvent.java create mode 100644 src/main/java/gregtech/api/net/GTPacketClientPreference.java create mode 100644 src/main/java/gregtech/api/net/GTPacketMultiTileEntity.java create mode 100644 src/main/java/gregtech/api/net/GTPacketMusicSystemData.java create mode 100644 src/main/java/gregtech/api/net/GTPacketNew.java create mode 100644 src/main/java/gregtech/api/net/GTPacketPollution.java create mode 100644 src/main/java/gregtech/api/net/GTPacketRequestCoverData.java create mode 100644 src/main/java/gregtech/api/net/GTPacketSendCoverData.java create mode 100644 src/main/java/gregtech/api/net/GTPacketSendOregenPattern.java create mode 100644 src/main/java/gregtech/api/net/GTPacketSetConfigurationCircuit.java create mode 100644 src/main/java/gregtech/api/net/GTPacketSound.java create mode 100644 src/main/java/gregtech/api/net/GTPacketTileEntity.java create mode 100644 src/main/java/gregtech/api/net/GTPacketToolSwitchMode.java create mode 100644 src/main/java/gregtech/api/net/GTPacketTypes.java create mode 100644 src/main/java/gregtech/api/net/GTPacketUpdateItem.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet.java delete mode 100644 src/main/java/gregtech/api/net/GT_PacketTypes.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_Block_Event.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_ClientPreference.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_MusicSystemData.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_New.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_Pollution.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_SendOregenPattern.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_SetConfigurationCircuit.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_Sound.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_TileEntity.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_ToolSwitchMode.java delete mode 100644 src/main/java/gregtech/api/net/GT_Packet_UpdateItem.java create mode 100644 src/main/java/gregtech/api/objects/GTArrayList.java create mode 100644 src/main/java/gregtech/api/objects/GTChunkManager.java create mode 100644 src/main/java/gregtech/api/objects/GTCopiedBlockTexture.java create mode 100644 src/main/java/gregtech/api/objects/GTCoverDefault.java create mode 100644 src/main/java/gregtech/api/objects/GTCoverNone.java create mode 100644 src/main/java/gregtech/api/objects/GTFluid.java create mode 100644 src/main/java/gregtech/api/objects/GTHashSet.java create mode 100644 src/main/java/gregtech/api/objects/GTItemStack.java create mode 100644 src/main/java/gregtech/api/objects/GTItemStack2.java create mode 100644 src/main/java/gregtech/api/objects/GTMultiTexture.java create mode 100644 src/main/java/gregtech/api/objects/GTRenderedTexture.java create mode 100644 src/main/java/gregtech/api/objects/GTSidedTexture.java create mode 100644 src/main/java/gregtech/api/objects/GTStdRenderedTexture.java create mode 100644 src/main/java/gregtech/api/objects/GTUODimension.java create mode 100644 src/main/java/gregtech/api/objects/GTUODimensionList.java create mode 100644 src/main/java/gregtech/api/objects/GTUOFluid.java delete mode 100644 src/main/java/gregtech/api/objects/GT_ArrayList.java delete mode 100644 src/main/java/gregtech/api/objects/GT_ChunkManager.java delete mode 100644 src/main/java/gregtech/api/objects/GT_CopiedBlockTexture.java delete mode 100644 src/main/java/gregtech/api/objects/GT_Cover_Default.java delete mode 100644 src/main/java/gregtech/api/objects/GT_Cover_None.java delete mode 100644 src/main/java/gregtech/api/objects/GT_Fluid.java delete mode 100644 src/main/java/gregtech/api/objects/GT_HashSet.java delete mode 100644 src/main/java/gregtech/api/objects/GT_ItemStack.java delete mode 100644 src/main/java/gregtech/api/objects/GT_ItemStack2.java delete mode 100644 src/main/java/gregtech/api/objects/GT_MultiTexture.java delete mode 100644 src/main/java/gregtech/api/objects/GT_RenderedTexture.java delete mode 100644 src/main/java/gregtech/api/objects/GT_SidedTexture.java delete mode 100644 src/main/java/gregtech/api/objects/GT_StdRenderedTexture.java delete mode 100644 src/main/java/gregtech/api/objects/GT_UO_Dimension.java delete mode 100644 src/main/java/gregtech/api/objects/GT_UO_DimensionList.java delete mode 100644 src/main/java/gregtech/api/objects/GT_UO_Fluid.java delete mode 100644 src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java delete mode 100644 src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java delete mode 100644 src/main/java/gregtech/api/threads/GT_Runnable_Sound.java create mode 100644 src/main/java/gregtech/api/threads/RunnableCableUpdate.java create mode 100644 src/main/java/gregtech/api/threads/RunnableMachineUpdate.java create mode 100644 src/main/java/gregtech/api/threads/RunnableSound.java create mode 100644 src/main/java/gregtech/api/util/AssemblyLineServer.java create mode 100644 src/main/java/gregtech/api/util/AssemblyLineUtils.java create mode 100644 src/main/java/gregtech/api/util/CircuitryBehavior.java create mode 100644 src/main/java/gregtech/api/util/CoverBehavior.java create mode 100644 src/main/java/gregtech/api/util/CoverBehaviorBase.java create mode 100644 src/main/java/gregtech/api/util/ExoticEnergyInputHelper.java create mode 100644 src/main/java/gregtech/api/util/GTApiaryModifier.java create mode 100644 src/main/java/gregtech/api/util/GTApiaryUpgrade.java create mode 100644 src/main/java/gregtech/api/util/GTBaseCrop.java create mode 100644 src/main/java/gregtech/api/util/GTBlockMap.java create mode 100644 src/main/java/gregtech/api/util/GTBlockSet.java create mode 100644 src/main/java/gregtech/api/util/GTCLSCompat.java create mode 100644 src/main/java/gregtech/api/util/GTChunkAssociatedData.java create mode 100644 src/main/java/gregtech/api/util/GTClientPreference.java create mode 100644 src/main/java/gregtech/api/util/GTConfig.java create mode 100644 src/main/java/gregtech/api/util/GTCreativeTab.java create mode 100644 src/main/java/gregtech/api/util/GTFoodStat.java create mode 100644 src/main/java/gregtech/api/util/GTForestryCompat.java create mode 100644 src/main/java/gregtech/api/util/GTGCCompat.java create mode 100644 src/main/java/gregtech/api/util/GTIBoxableWrapper.java create mode 100644 src/main/java/gregtech/api/util/GTItsNotMyFaultException.java create mode 100644 src/main/java/gregtech/api/util/GTLanguageManager.java create mode 100644 src/main/java/gregtech/api/util/GTLog.java create mode 100644 src/main/java/gregtech/api/util/GTModHandler.java create mode 100644 src/main/java/gregtech/api/util/GTMusicSystem.java create mode 100644 src/main/java/gregtech/api/util/GTOreDictUnificator.java create mode 100644 src/main/java/gregtech/api/util/GTPlayedSound.java create mode 100644 src/main/java/gregtech/api/util/GTRecipe.java create mode 100644 src/main/java/gregtech/api/util/GTRecipeBuilder.java create mode 100644 src/main/java/gregtech/api/util/GTRecipeConstants.java create mode 100644 src/main/java/gregtech/api/util/GTRecipeMapUtil.java create mode 100644 src/main/java/gregtech/api/util/GTRecipeRegistrator.java create mode 100644 src/main/java/gregtech/api/util/GTRenderingWorld.java create mode 100644 src/main/java/gregtech/api/util/GTShapedRecipe.java create mode 100644 src/main/java/gregtech/api/util/GTShapelessRecipe.java create mode 100644 src/main/java/gregtech/api/util/GTSpawnEventHandler.java create mode 100644 src/main/java/gregtech/api/util/GTStreamUtil.java create mode 100644 src/main/java/gregtech/api/util/GTStructureUtility.java create mode 100644 src/main/java/gregtech/api/util/GTToolHarvestHelper.java create mode 100644 src/main/java/gregtech/api/util/GTTooltipDataCache.java create mode 100644 src/main/java/gregtech/api/util/GTUtil.java create mode 100644 src/main/java/gregtech/api/util/GTUtility.java create mode 100644 src/main/java/gregtech/api/util/GTUtilityClient.java create mode 100644 src/main/java/gregtech/api/util/GTWaila.java delete mode 100644 src/main/java/gregtech/api/util/GT_ApiaryModifier.java delete mode 100644 src/main/java/gregtech/api/util/GT_ApiaryUpgrade.java delete mode 100644 src/main/java/gregtech/api/util/GT_AssemblyLineUtils.java delete mode 100644 src/main/java/gregtech/api/util/GT_Assemblyline_Server.java delete mode 100644 src/main/java/gregtech/api/util/GT_BaseCrop.java delete mode 100644 src/main/java/gregtech/api/util/GT_BlockMap.java delete mode 100644 src/main/java/gregtech/api/util/GT_BlockSet.java delete mode 100644 src/main/java/gregtech/api/util/GT_CLS_Compat.java delete mode 100644 src/main/java/gregtech/api/util/GT_ChunkAssociatedData.java delete mode 100644 src/main/java/gregtech/api/util/GT_CircuitryBehavior.java delete mode 100644 src/main/java/gregtech/api/util/GT_ClientPreference.java delete mode 100644 src/main/java/gregtech/api/util/GT_Config.java delete mode 100644 src/main/java/gregtech/api/util/GT_CoverBehavior.java delete mode 100644 src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java delete mode 100644 src/main/java/gregtech/api/util/GT_CreativeTab.java delete mode 100644 src/main/java/gregtech/api/util/GT_ExoticEnergyInputHelper.java delete mode 100644 src/main/java/gregtech/api/util/GT_FoodStat.java delete mode 100644 src/main/java/gregtech/api/util/GT_Forestry_Compat.java delete mode 100644 src/main/java/gregtech/api/util/GT_GC_Compat.java delete mode 100644 src/main/java/gregtech/api/util/GT_HatchElementBuilder.java delete mode 100644 src/main/java/gregtech/api/util/GT_IBoxableWrapper.java delete mode 100644 src/main/java/gregtech/api/util/GT_ItsNotMyFaultException.java delete mode 100644 src/main/java/gregtech/api/util/GT_JubilanceMegaApiary.java delete mode 100644 src/main/java/gregtech/api/util/GT_LanguageManager.java delete mode 100644 src/main/java/gregtech/api/util/GT_Log.java delete mode 100644 src/main/java/gregtech/api/util/GT_ModHandler.java delete mode 100644 src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java delete mode 100644 src/main/java/gregtech/api/util/GT_MusicSystem.java delete mode 100644 src/main/java/gregtech/api/util/GT_OreDictUnificator.java delete mode 100644 src/main/java/gregtech/api/util/GT_OverclockCalculator.java delete mode 100644 src/main/java/gregtech/api/util/GT_PCBFactoryManager.java delete mode 100644 src/main/java/gregtech/api/util/GT_ParallelHelper.java delete mode 100644 src/main/java/gregtech/api/util/GT_PlayedSound.java delete mode 100644 src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java delete mode 100644 src/main/java/gregtech/api/util/GT_Recipe.java delete mode 100644 src/main/java/gregtech/api/util/GT_RecipeBuilder.java delete mode 100644 src/main/java/gregtech/api/util/GT_RecipeConstants.java delete mode 100644 src/main/java/gregtech/api/util/GT_RecipeMapUtil.java delete mode 100644 src/main/java/gregtech/api/util/GT_RecipeRegistrator.java delete mode 100644 src/main/java/gregtech/api/util/GT_RenderingWorld.java delete mode 100644 src/main/java/gregtech/api/util/GT_Shaped_Recipe.java delete mode 100644 src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java delete mode 100644 src/main/java/gregtech/api/util/GT_SpawnEventHandler.java delete mode 100644 src/main/java/gregtech/api/util/GT_StreamUtil.java delete mode 100644 src/main/java/gregtech/api/util/GT_StructureUtility.java delete mode 100644 src/main/java/gregtech/api/util/GT_ToolHarvestHelper.java delete mode 100644 src/main/java/gregtech/api/util/GT_Util.java delete mode 100644 src/main/java/gregtech/api/util/GT_Utility.java delete mode 100644 src/main/java/gregtech/api/util/GT_UtilityClient.java delete mode 100644 src/main/java/gregtech/api/util/GT_Waila.java create mode 100644 src/main/java/gregtech/api/util/HatchElementBuilder.java create mode 100644 src/main/java/gregtech/api/util/IGTHatchAdder.java delete mode 100644 src/main/java/gregtech/api/util/IGT_HatchAdder.java create mode 100644 src/main/java/gregtech/api/util/JubilanceMegaApiary.java create mode 100644 src/main/java/gregtech/api/util/MultiblockTooltipBuilder.java create mode 100644 src/main/java/gregtech/api/util/OverclockCalculator.java create mode 100644 src/main/java/gregtech/api/util/PCBFactoryManager.java create mode 100644 src/main/java/gregtech/api/util/ParallelHelper.java create mode 100644 src/main/java/gregtech/api/util/ProcessingArrayManager.java create mode 100644 src/main/java/gregtech/api/world/GTWorldgen.java delete mode 100644 src/main/java/gregtech/api/world/GT_Worldgen.java (limited to 'src/main/java/gregtech/api') diff --git a/src/main/java/gregtech/api/GregTechAPI.java b/src/main/java/gregtech/api/GregTechAPI.java new file mode 100644 index 0000000000..6cabb8e04c --- /dev/null +++ b/src/main/java/gregtech/api/GregTechAPI.java @@ -0,0 +1,982 @@ +package gregtech.api; + +import static gregtech.api.enums.GTValues.B; +import static gregtech.api.enums.Mods.IndustrialCraft2; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.SetMultimap; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Materials; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.IDamagableItem; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.internal.IGTRecipeAdder; +import gregtech.api.interfaces.internal.IThaumcraftCompat; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; +import gregtech.api.items.GTGenericItem; +import gregtech.api.items.ItemCoolantCell; +import gregtech.api.items.ItemCoolantCellIC; +import gregtech.api.items.ItemTool; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.objects.GTCoverDefault; +import gregtech.api.objects.GTCoverNone; +import gregtech.api.objects.GTHashSet; +import gregtech.api.objects.GTItemStack; +import gregtech.api.threads.RunnableCableUpdate; +import gregtech.api.threads.RunnableMachineUpdate; +import gregtech.api.util.CircuitryBehavior; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTConfig; +import gregtech.api.util.GTCreativeTab; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import gregtech.api.util.item.ItemHolder; +import gregtech.api.world.GTWorldgen; +import gregtech.common.GTDummyWorld; +import gregtech.common.items.ItemIntegratedCircuit; + +/** + * Please do not include this File in your Mod-download as it ruins compatibility, like with the IC2-API You may just + * copy those Functions into your Code, or better call them via reflection. + *

+ * The whole API is the basic construct of my Mod. Everything is dependent on it. I change things quite often so please + * don't include any File inside your Mod, even if it is an Interface. Since some Authors were stupid enough to break + * this simple Rule, I added Version checks to enforce it. + *

+ * In these Folders are many useful Functions. You can use them via reflection if you want. I know not everything is + * compilable due to APIs of other Mods, but these are easy to fix in your Setup. + *

+ * You can use this to learn about Modding, but I would recommend simpler Mods. You may even copy-paste Code from these + * API-Files into your Mod, as I have nothing against that, but you should look exactly at what you are copying. + * + * @author Gregorius Techneticies + */ +@SuppressWarnings("unused") // API class has legitimately unused methods and members +public class GregTechAPI { + + /** + * Fixes the HashMap Mappings for ItemStacks once the Server started + *
+ *
+ * NOTE: We use wildcards generics for the key because it could be for example {@link ItemStack} or + * {@link GTItemStack} + */ + public static final Collection> sItemStackMappings = new ArrayList<>(); + public static final Collection> itemStackMultiMaps = new ArrayList<>(); + + /** + * The MetaTileEntity-ID-List-Length + */ + public static final short MAXIMUM_METATILE_IDS = Short.MAX_VALUE - 1; + /** + * My Creative Tab + */ + public static final CreativeTabs TAB_GREGTECH = new GTCreativeTab("Main", "Main"), + TAB_GREGTECH_MATERIALS = new GTCreativeTab("Materials", "Materials"), + TAB_GREGTECH_ORES = new GTCreativeTab("Ores", "Ores"); + + public static final IMetaTileEntity[] METATILEENTITIES = new IMetaTileEntity[MAXIMUM_METATILE_IDS]; + /** + * The Icon List for Covers + */ + public static final Map sCovers = new ConcurrentHashMap<>(); + /** + * The List of Cover Behaviors for the Covers + */ + public static final Map> sCoverBehaviors = new ConcurrentHashMap<>(); + /** + * The List of Circuit Behaviors for the Redstone Circuit Block + */ + public static final Map sCircuitryBehaviors = new ConcurrentHashMap<>(); + /** + * The List of Blocks, which can conduct Machine Block Updates + */ + public static final Map sMachineIDs = new ConcurrentHashMap<>(); + /** + * The Redstone Frequencies + */ + public static final Map sWirelessRedstone = new ConcurrentHashMap<>(); + /** + * The Advanced Redstone Frequencies + */ + public static final Map>> sAdvancedWirelessRedstone = new ConcurrentHashMap<>(); + + /** + * The IDSU Frequencies + */ + public static final Map sIDSUList = new ConcurrentHashMap<>(); + /** + * A List of all Books, which were created using @GT_Utility.getWrittenBook the original Title is the Key Value + */ + public static final Map sBookList = new ConcurrentHashMap<>(); + /** + * The List of all Sounds used in GT, indices are in the static Block at the bottom + * + * @deprecated Use {@link SoundResource} + */ + @Deprecated + public static final Map sSoundList = SoundResource.asSoundList(); + /** + * The List of Tools, which can be used. Accepts regular damageable Items and Electric Items + */ + public static final GTHashSet sToolList = new GTHashSet<>(), sCrowbarList = new GTHashSet<>(), + sScrewdriverList = new GTHashSet<>(), sWrenchList = new GTHashSet<>(), sSoftHammerList = new GTHashSet<>(), + sHardHammerList = new GTHashSet<>(), sWireCutterList = new GTHashSet<>(), + sSolderingToolList = new GTHashSet<>(), sSolderingMetalList = new GTHashSet<>(), + sJackhammerList = new GTHashSet<>(); + /** + * The List of Hazmat Armors + */ + public static final GTHashSet sGasHazmatList = new GTHashSet<>(), sBioHazmatList = new GTHashSet<>(), + sFrostHazmatList = new GTHashSet<>(), sHeatHazmatList = new GTHashSet<>(), sRadioHazmatList = new GTHashSet<>(), + sElectroHazmatList = new GTHashSet<>(); + + private static final Multimap sRealConfigurationList = Multimaps + .newListMultimap(new TreeMap<>(), ArrayList::new); + private static final Map> sConfigurationLists = new ConcurrentHashMap<>(); + private static final Map, BiFunction> sRealCircuitProgrammerList = new LinkedHashMap<>(); + public static final Map, BiFunction> sCircuitProgrammerList = Collections + .unmodifiableMap(sRealCircuitProgrammerList); + + /** + * The List of Dimensions, which are Whitelisted for the Teleporter. This list should not contain other Planets. + * Mystcraft Dimensions and other Dimensional Things should be allowed. Mystcraft and Twilight Forest are + * automatically considered a Dimension, without being in this List. + */ + public static final Collection sDimensionalList = new HashSet<>(); + /** + * Lists of all the active World generation Features, these are getting Initialized in Postload! + */ + public static final List sWorldgenList = new ArrayList<>(); + /** + * A List containing all the Materials, which are somehow in use by GT and therefor receive a specific Set of Items. + */ + public static final Materials[] sGeneratedMaterials = new Materials[1000]; + /** + * This is the generic Cover behavior. Used for the default Covers, which have no Behavior. + */ + public static final CoverBehavior sDefaultBehavior = new GTCoverDefault(), sNoBehavior = new GTCoverNone(); + /** + * For the API Version check + */ + public static volatile int VERSION = 509; + + /** + * @deprecated Use {@link GTValues#RA} + */ + @SuppressWarnings("DeprecatedIsStillUsed") // Still need be initialized for backward compat + @Deprecated + public static IGTRecipeAdder sRecipeAdder; + /** + * Registers Aspects to Thaumcraft. This Object might be {@code null} if Thaumcraft isn't installed. + */ + public static IThaumcraftCompat sThaumcraftCompat; + /** + * The Lists below are executed at their respective timings. Useful to do things at a particular moment in time. + * The Lists are not Threaded - a native Java interface is used for their execution. + * Add your "commands" in the constructor or in the static-code-block of your mod's Main class. + * Implement the method {@code run()}, and everything should work. + */ + public static List sBeforeGTPreload = new ArrayList<>(), sAfterGTPreload = new ArrayList<>(), + sBeforeGTLoad = new ArrayList<>(), sAfterGTLoad = new ArrayList<>(), sBeforeGTPostload = new ArrayList<>(), + sAfterGTPostload = new ArrayList<>(), sFirstWorldTick = new ArrayList<>(), + sBeforeGTServerstart = new ArrayList<>(), sAfterGTServerstart = new ArrayList<>(), + sBeforeGTServerstop = new ArrayList<>(), sAfterGTServerstop = new ArrayList<>(), + sGTBlockIconload = new ArrayList<>(), sGTItemIconload = new ArrayList<>(), sGTCompleteLoad = new ArrayList<>(); + /** + * The Icon Registers from Blocks and Items. They will get set right before the corresponding Icon Load Phase as + * executed in the Runnable List above. + */ + @SideOnly(Side.CLIENT) + public static IIconRegister sBlockIcons, sItemIcons; + /** + * The Configuration Objects + */ + public static GTConfig NEIClientFIle; + + public static int TICKS_FOR_LAG_AVERAGING = 25, MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING = 100; + /** + * Initialized by the Block creation. + */ + public static Block sBlockMachines; + + public static Block sBlockOres1, sBlockOresUb1, sBlockOresUb2, sBlockOresUb3, + /* sBlockGem, */ + sBlockMetal1, sBlockMetal2, sBlockMetal3, sBlockMetal4, sBlockMetal5, sBlockMetal6, sBlockMetal7, sBlockMetal8, + sBlockMetal9, sBlockGem1, sBlockGem2, sBlockGem3, sBlockReinforced; + public static Block sBlockGranites, sBlockConcretes, sBlockStones; + public static Block sBlockCasings1, sBlockCasings2, sBlockCasings3, sBlockCasings4, sBlockCasings5, sBlockCasings6, + sBlockCasings8, sBlockCasings9, sBlockCasings10, sBlockCasings11, sSolenoidCoilCasings; + public static Block sBlockLongDistancePipes; + public static Block sDroneRender; + public static Block sBlockFrames; + public static Block sBlockGlass1; + public static Block sBlockTintedGlass; + public static Block sLaserRender; + public static Block sWormholeRender; + /** + * Getting assigned by the Config + */ + public static boolean sTimber = true, sDrinksAlwaysDrinkable = false, sMultiThreadedSounds = false, + sDoShowAllItemsInCreative = false, sColoredGUI = true, sMachineMetalGUI = false, sMachineExplosions = true, + sMachineFlammable = true, sMachineNonWrenchExplosions = true, sMachineRainExplosions = true, + sMachineThunderExplosions = true, sMachineFireExplosions = true, sMachineWireFire = true, mOutputRF = false, + mInputRF = false, mRFExplosions = false, mServerStarted = false; + + public static int mEUtoRF = 360, mRFtoEU = 20; + + /** + * Option to not use MACHINE_METAL mixing into colors + */ + public static boolean sUseMachineMetal = false; + + public static boolean mUseOnlyGoodSolderingMaterials = false; + + private static final String aTextIC2Lower = IndustrialCraft2.ID.toLowerCase(Locale.ENGLISH); + /** + * Getting assigned by the Mod loading + */ + public static boolean sUnificationEntriesRegistered = false, sPreloadStarted = false, sPreloadFinished = false, + sLoadStarted = false, sLoadFinished = false, sPostloadStarted = false, sPostloadFinished = false, + sFullLoadFinished = false; + + private static Class sBaseMetaTileEntityClass = null; + + @SuppressWarnings("unchecked") + private static final IntFunction[] teCreators = new IntFunction[16]; + + private static final Set> dummyWorlds = new HashSet<>(); + + static { + sItemStackMappings.add(sCovers); + sItemStackMappings.add(sCoverBehaviors); + + dummyWorlds.add(GTDummyWorld.class); + tryAddDummyWorld("blockrenderer6343.client.world.DummyWorld"); + } + + private static void tryAddDummyWorld(String className) { + ClassLoader cl = GregTechAPI.class.getClassLoader(); + Class clazz; + try { + clazz = Class.forName(className, false, cl); + } catch (ReflectiveOperationException ex) { + return; + } + dummyWorlds.add(clazz); + } + + public static void addDummyWorld(Class clazz) { + dummyWorlds.add(clazz); + } + + public static boolean isDummyWorld(@Nonnull World w) { + return dummyWorlds.contains(w.getClass()); + } + + /** + * You want OreDict-Unification for YOUR Mod/Addon, when GregTech is installed? This Function is especially for YOU. + * Call this Function after the load-Phase, as I register the most of the Unification at that Phase (Redpowers + * Storageblocks are registered at postload). A recommended use of this Function is inside your Recipe-System itself + * (if you have one), as the unification then makes 100% sure, that every added non-unificated Output gets + * automatically unificated. + *

+ * I will personally make sure, that only common prefixes of Ores get registered at the Unificator, as of now there + * are: pulp, dust, dustSmall, ingot, nugget, gem, ore and block If another Mod-Author messes these up, then it's + * not my fault, and it's especially not your fault. As these are commonly used prefixes. + *

+ * This Unificator-API-Function uses the same Functions I use, for unificating Items. So if there is something + * messed up (very unlikely), then everything is messed up. + *

+ * You shouldn't use this to unificate the Inputs of your Recipes, this is only meant for the Outputs. + * + * @param aOreStack the Stack you want to get unificated. It is stackSize Sensitive. + * @return Either an unificated Stack or the stack you toss in, but it should never be null, unless you throw a + * Null-Pointer into it. + */ + public static ItemStack getUnificatedOreDictStack(ItemStack aOreStack) { + if (!GregTechAPI.sPreloadFinished) GTLog.err.println( + "GregTechAPI ERROR: " + aOreStack.getItem() + + "." + + aOreStack.getItemDamage() + + " - OreDict Unification Entries are not registered now, please call it in the postload phase."); + return GTOreDictUnificator.get(true, aOreStack); + } + + /** + * Causes a Machineblock Update This update will cause surrounding MultiBlock Machines to update their + * Configuration. You should call this Function in @Block.breakBlock and in @Block.onBlockAdded of your Machine. + * + * @param aWorld is being the World + * @param aX is the X-Coord of the update causing Block + * @param aY is the Y-Coord of the update causing Block + * @param aZ is the Z-Coord of the update causing Block + */ + public static boolean causeMachineUpdate(World aWorld, int aX, int aY, int aZ) { + if (aWorld != null && !aWorld.isRemote && !isDummyWorld(aWorld)) { // World might be null during World-gen + RunnableMachineUpdate.setMachineUpdateValues(aWorld, aX, aY, aZ); + return true; + } + return false; + } + + @SuppressWarnings("UnusedReturnValue") // Retains API method signature + public static boolean causeCableUpdate(World aWorld, int aX, int aY, int aZ) { + if (aWorld == null || aWorld.isRemote || isDummyWorld(aWorld)) { + return false; + } // World might be null during World-gen + RunnableCableUpdate.setCableUpdateValues(aWorld, aX, aY, aZ); + return true; + } + + /** + * Adds a Multi-Machine Block, like my Machine Casings for example. You should call @causeMachineUpdate + * in @Block.breakBlock and in {@link Block#onBlockAdded} of your registered Block. You don't need to register + * TileEntities which implement {@link IMachineBlockUpdateable} + * + * @param aBlock the Block + * @param aMeta the Metadata of the Blocks as Bitmask! -1 or ~0 for all Meta-values + */ + @SuppressWarnings("UnusedReturnValue") // Retains API method signature + public static boolean registerMachineBlock(Block aBlock, int aMeta) { + if (aBlock == null) return false; + if (GregTechAPI.sThaumcraftCompat != null) + GregTechAPI.sThaumcraftCompat.registerPortholeBlacklistedBlock(aBlock); + sMachineIDs.put(aBlock, aMeta); + return true; + } + + /** + * Like above but with boolean Parameters instead of a BitMask + */ + public static boolean registerMachineBlock(Block aBlock, boolean... aMeta) { + if (aBlock == null || aMeta == null || aMeta.length == 0) return false; + if (GregTechAPI.sThaumcraftCompat != null) + GregTechAPI.sThaumcraftCompat.registerPortholeBlacklistedBlock(aBlock); + int rMeta = 0; + for (byte i = 0; i < aMeta.length && i < 16; i++) if (aMeta[i]) rMeta |= B[i]; + sMachineIDs.put(aBlock, rMeta); + return true; + } + + /** + * if this Block is a Machine Update Conducting Block + */ + public static boolean isMachineBlock(Block aBlock, int aMeta) { + if (aBlock != null) { + Integer id = sMachineIDs.get(aBlock); + return id != null && (id & B[aMeta]) != 0; + } + return false; + } + + /** + * Creates a new Coolant Cell Item for your Nuclear Reactor + */ + public static Item constructCoolantCellItem(String aUnlocalized, String aEnglish, int aMaxStore) { + try { + return new ItemCoolantCellIC(aUnlocalized, aEnglish, aMaxStore); + } catch (Throwable e) { + /* Do nothing */ + } + try { + return new ItemCoolantCell(aUnlocalized, aEnglish, aMaxStore); + } catch (Throwable e) { + /* Do nothing */ + } + return new GTGenericItem(aUnlocalized, aEnglish, "Doesn't work as intended, this is a Bug"); + } + + /** + * Creates a new Energy Armor Item + */ + public static Item constructElectricArmorItem(String aUnlocalized, String aEnglish, int aCharge, int aTransfer, + int aTier, int aDamageEnergyCost, int aSpecials, double aArmorAbsorbtionPercentage, boolean aChargeProvider, + int aType, int aArmorIndex) { + try { + return (Item) Class.forName("gregtechmod.api.items.GT_EnergyArmorIC_Item") + .getConstructors()[0].newInstance( + aUnlocalized, + aEnglish, + aCharge, + aTransfer, + aTier, + aDamageEnergyCost, + aSpecials, + aArmorAbsorbtionPercentage, + aChargeProvider, + aType, + aArmorIndex); + } catch (Throwable e) { + /* Do nothing */ + } + try { + return (Item) Class.forName("gregtechmod.api.items.GT_EnergyArmor_Item") + .getConstructors()[0].newInstance( + aUnlocalized, + aEnglish, + aCharge, + aTransfer, + aTier, + aDamageEnergyCost, + aSpecials, + aArmorAbsorbtionPercentage, + aChargeProvider, + aType, + aArmorIndex); + } catch (Throwable e) { + /* Do nothing */ + } + return new GTGenericItem(aUnlocalized, aEnglish, "Doesn't work as intended, this is a Bug"); + } + + /** + * Creates a new Energy Battery Item + */ + public static Item constructElectricEnergyStorageItem(String aUnlocalized, String aEnglish, int aCharge, + int aTransfer, int aTier, int aEmptyID, int aFullID) { + try { + return (Item) Class.forName("gregtechmod.api.items.GT_EnergyStoreIC_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aCharge, aTransfer, aTier, aEmptyID, aFullID); + } catch (Throwable e) { + /* Do nothing */ + } + try { + return (Item) Class.forName("gregtechmod.api.items.GT_EnergyStore_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aCharge, aTransfer, aTier, aEmptyID, aFullID); + } catch (Throwable e) { + /* Do nothing */ + } + return new GTGenericItem(aUnlocalized, aEnglish, "Doesn't work as intended, this is a Bug"); + } + + /** + * Creates a new Hard Hammer Item + */ + public static ItemTool constructHardHammerItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_HardHammer_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new Crowbar Item + */ + public static ItemTool constructCrowbarItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_CrowbarRC_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage); + } catch (Throwable e) { + /* Do nothing */ + } + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_Crowbar_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new Wrench Item + */ + public static ItemTool constructWrenchItem(String aUnlocalized, String aEnglish, int aMaxDamage, int aEntityDamage, + int aDisChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_Wrench_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new electric Screwdriver Item + */ + public static ItemTool constructElectricScrewdriverItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage, int aDisChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_ScrewdriverIC_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new electric Wrench Item + */ + public static ItemTool constructElectricWrenchItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage, int aDisChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_WrenchIC_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new electric Saw Item + */ + public static ItemTool constructElectricSawItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage, int aToolQuality, float aToolStrength, int aEnergyConsumptionPerBlockBreak, + int aDisChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_SawIC_Item") + .getConstructors()[0].newInstance( + aUnlocalized, + aEnglish, + aMaxDamage, + aEntityDamage, + aToolQuality, + aToolStrength, + aEnergyConsumptionPerBlockBreak, + aDisChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new electric Drill Item + */ + public static ItemTool constructElectricDrillItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage, int aToolQuality, float aToolStrength, int aEnergyConsumptionPerBlockBreak, + int aDisChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_DrillIC_Item") + .getConstructors()[0].newInstance( + aUnlocalized, + aEnglish, + aMaxDamage, + aEntityDamage, + aToolQuality, + aToolStrength, + aEnergyConsumptionPerBlockBreak, + aDisChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new electric Soldering Tool + */ + public static ItemTool constructElectricSolderingToolItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aEntityDamage, int aDisChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_SolderingToolIC_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool( + aUnlocalized, + aEnglish, + "Doesn't work as intended, this is a Bug", + aMaxDamage, + aEntityDamage, + false); + } + + /** + * Creates a new empty electric Tool + */ + public static ItemTool constructEmptyElectricToolItem(String aUnlocalized, String aEnglish, int aMaxDamage, + int aChargedGTID) { + try { + return (ItemTool) Class.forName("gregtechmod.api.items.GT_EmptyToolIC_Item") + .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aChargedGTID); + } catch (Throwable e) { + /* Do nothing */ + } + return new ItemTool(aUnlocalized, aEnglish, "Doesn't work as intended, this is a Bug", aMaxDamage, 0, false); + } + + /** + * Provides a new BaseMetaTileEntity. Because some interfaces are not always loaded (Buildcraft, Universal + * Electricity) we have to use invocation at the constructor of the BaseMetaTileEntity. + */ + public static BaseMetaTileEntity constructBaseMetaTileEntity() { + if (sBaseMetaTileEntityClass == null) { + try { + return (sBaseMetaTileEntityClass = BaseMetaTileEntity.class).getDeclaredConstructor() + .newInstance(); + } catch (Throwable ignored) {} + } + + try { + return sBaseMetaTileEntityClass.getDeclaredConstructor() + .newInstance(); + } catch (Throwable e) { + GTLog.err.println("GTMod: Fatal Error occurred while initializing TileEntities, crashing Minecraft."); + e.printStackTrace(GTLog.err); + throw new RuntimeException(e); + } + } + + /** + * Register a new ItemStack as configuration circuits. Duplicates or invalid stacks will be silently ignored. + */ + public static void registerConfigurationCircuit(ItemStack aStack) { + registerConfigurationCircuit(aStack, 0); + } + + /** + * Register a new ItemStack as configuration circuits. Duplicates or invalid stacks will be silently ignored. + * + * @param minTier the minimal tier this circuit can be offered for free, e.g. normal configuration circuit is + * available in LV+ single blocks, GT++ breakthrough circuit is offered in HV+ single blocks + */ + public static void registerConfigurationCircuit(ItemStack aStack, int minTier) { + if (GTUtility.isStackInvalid(aStack)) return; + for (ItemStack tRegistered : sRealConfigurationList.values()) + if (GTUtility.areStacksEqual(tRegistered, aStack)) return; + ItemStack stack = GTUtility.copyAmount(0, aStack); + sRealConfigurationList.put(minTier, stack); + for (Map.Entry> e : sConfigurationLists.entrySet()) { + if (e.getKey() >= minTier) { + e.getValue() + .add(stack); + e.getValue() + .sort(getConfigurationCircuitsComparator()); + } + } + } + + /** + * Get a list of Configuration circuits. These stacks will have a stack size of 0. Use + * {@link #registerConfigurationCircuit(ItemStack, int)} or its overload to add to this list. + * + * @param machineTier The voltage tier where this list will be used. use Integer.MAX_VALUE to get all circuits + * @return An unmodifiable view of actual list. DO NOT MODIFY THE ItemStacks! + */ + public static List getConfigurationCircuitList(int machineTier) { + return Collections.unmodifiableList( + sConfigurationLists.computeIfAbsent( + machineTier, + (t) -> sRealConfigurationList.entries() + .stream() + .filter(e -> e.getKey() <= machineTier) + .map(Map.Entry::getValue) + .sorted(getConfigurationCircuitsComparator()) + .collect(Collectors.toList()))); + } + + public static Comparator getConfigurationCircuitsComparator() { + return Comparator.comparingInt((ItemStack is) -> is.getItem() instanceof ItemIntegratedCircuit ? 0 : 1) + .thenComparing(ItemStack::getUnlocalizedName) + .thenComparing(ItemStack::getItemDamage); + } + + public static void registerCircuitProgrammer(ItemStack stack, boolean ignoreNBT, boolean useContainer) { + registerCircuitProgrammer(rhs -> GTUtility.areStacksEqual(stack, rhs, ignoreNBT), useContainer); + } + + public static void registerCircuitProgrammer(Predicate predicate, boolean useContainer) { + sRealCircuitProgrammerList.put( + predicate, + useContainer ? (s, p) -> s.getItem() + .getContainerItem(s) : (s, p) -> s); + } + + public static void registerCircuitProgrammer(Predicate predicate, + BiFunction doDamage) { + sRealCircuitProgrammerList.put(predicate, doDamage); + } + + public static void registerCover(ItemStack aStack, ITexture aCover, CoverBehavior aBehavior) { + registerCover(aStack, aCover, (CoverBehaviorBase) aBehavior); + } + + public static void registerCover(ItemStack aStack, ITexture aCover, CoverBehaviorBase aBehavior) { + if (!sCovers.containsKey(new GTItemStack(aStack))) sCovers.put( + new GTItemStack(aStack), + aCover == null || !aCover.isValidTexture() ? Textures.BlockIcons.ERROR_RENDERING[0] : aCover); + if (aBehavior != null) sCoverBehaviors.put(new GTItemStack(aStack), aBehavior); + } + + public static void registerCoverBehavior(ItemStack aStack, CoverBehavior aBehavior) { + registerCoverBehavior(aStack, (CoverBehaviorBase) aBehavior); + } + + public static void registerCoverBehavior(ItemStack aStack, CoverBehaviorBase aBehavior) { + sCoverBehaviors.put(new GTItemStack(aStack), aBehavior == null ? sDefaultBehavior : aBehavior); + } + + /** + * Registers multiple Cover Items. I use that for the OreDict Functionality. + * + * @param aBehavior can be null + */ + public static void registerCover(Collection aStackList, ITexture aCover, CoverBehavior aBehavior) { + registerCover(aStackList, aCover, (CoverBehaviorBase) aBehavior); + } + + /** + * Registers multiple Cover Items. I use that for the OreDict Functionality. + * + * @param aBehavior can be null + */ + public static void registerCover(Collection aStackList, ITexture aCover, + CoverBehaviorBase aBehavior) { + if (aCover.isValidTexture()) aStackList.forEach(tStack -> GregTechAPI.registerCover(tStack, aCover, aBehavior)); + } + + /** + * returns a Cover behavior, guaranteed to not return null after preload + * + * @return The Cover behavior + */ + public static CoverBehaviorBase getCoverBehaviorNew(ItemStack aStack) { + if (aStack == null || aStack.getItem() == null) return sNoBehavior; + CoverBehaviorBase rCover = sCoverBehaviors.get(new GTItemStack(aStack)); + if (rCover != null) return rCover; + rCover = sCoverBehaviors.get(new GTItemStack(aStack, true)); + if (rCover != null) return rCover; + return sDefaultBehavior; + } + + /** + * returns a Cover behavior, guaranteed to not return null + */ + public static CoverBehaviorBase getCoverBehaviorNew(int aStack) { + if (aStack == 0) return sNoBehavior; + return getCoverBehaviorNew(GTUtility.intToStack(aStack)); + } + + /** + * Register a Wrench to be usable on GregTech Machines. The Wrench MUST have some kind of Durability unlike certain + * Buildcraft Wrenches. + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + *

+ * ----- + *

+ * Returning true at isDamageable was a great Idea, KingLemming. Well played. Since the OmniWrench is just a + * Single-Item-Mod, people can choose if they want your infinite durability or not. So that's not really a Problem. + * I even have a new Config to auto-disable most infinite BC Wrenches (but that one is turned off). + *

+ * One last Bug for you to fix: My Auto-registration detects Railcraft's Crowbars, Buildcraft's Wrenches and alike, + * due to their Interfaces. Guess what now became a Crowbar by accident. Try registering the Wrench at the load + * phase to prevent things like that from happening. Yes, I know that "You need to register Tools in the Load + * Phase"-Part wasn't there before this. Sorry about that. + */ + public static boolean registerWrench(ItemStack aTool) { + return registerTool(aTool, sWrenchList); + } + + /** + * Register a Crowbar to extract Covers from Machines Crowbars are NOT Wrenches btw. + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + public static boolean registerCrowbar(ItemStack aTool) { + return registerTool(aTool, sCrowbarList); + } + + /** + * Register a Screwdriver to interact directly with Machines and Covers Did I mention, that it is intentionally not + * possible to make a Multi-tool, which doesn't switch ItemID (like a Mode) all the time? + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + @SuppressWarnings("UnusedReturnValue") // Retains API method signature + public static boolean registerScrewdriver(ItemStack aTool) { + return registerTool(aTool, sScrewdriverList); + } + + /** + * Register a Soft Hammer to interact with Machines + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + public static boolean registerSoftHammer(ItemStack aTool) { + return registerTool(aTool, sSoftHammerList); + } + + /** + * Register a Hard Hammer to interact with Machines + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + public static boolean registerHardHammer(ItemStack aTool) { + return registerTool(aTool, sHardHammerList); + } + + /** + * Register a Wire Cutter to interact with Machines + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + public static boolean registerWireCutter(ItemStack aTool) { + return registerTool(aTool, sWireCutterList); + } + + /** + * Register a Soldering Tool to interact with Machines + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + @SuppressWarnings("UnusedReturnValue") // Retains API method signature + public static boolean registerSolderingTool(ItemStack aTool) { + return registerTool(aTool, sSolderingToolList); + } + + /** + * Register a Soldering Tin to interact with Soldering Tools + *

+ * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in + * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). + */ + @SuppressWarnings("UnusedReturnValue") // Retains API method signature + public static boolean registerSolderingMetal(ItemStack aTool) { + return registerTool(aTool, sSolderingMetalList); + } + + /** + * Generic Function to add Tools to the Lists. Contains all sanity Checks for Tools, like preventing one Tool from + * being registered for multiple purposes as controls would override each other. + */ + public static boolean registerTool(ItemStack aTool, Collection aToolList) { + if (aTool == null || GTUtility.isStackInList(aTool, sToolList) + || (!aTool.getItem() + .isDamageable() && !GTModHandler.isElectricItem(aTool) && !(aTool.getItem() instanceof IDamagableItem))) + return false; + aToolList.add(new GTItemStack(GTUtility.copyAmount(1, aTool))); + sToolList.add(new GTItemStack(GTUtility.copyAmount(1, aTool))); + return true; + } + + /** + * Sets the {@link IIconRegister} for Block Icons + * + * @param aIconRegister The {@link IIconRegister} Icon Register + */ + @SideOnly(Side.CLIENT) + public static void setBlockIconRegister(IIconRegister aIconRegister) { + sBlockIcons = aIconRegister; + } + + /** + * Sets the {@link IIconRegister} for Items Icons + * + * @param aIconRegister The {@link IIconRegister} Icon Register + */ + @SideOnly(Side.CLIENT) + public static void setItemIconRegister(IIconRegister aIconRegister) { + GregTechAPI.sItemIcons = aIconRegister; + } + + public static void registerTileEntityConstructor(int meta, IntFunction constructor) { + if (meta < 0 || meta > 15 || constructor == null) throw new IllegalArgumentException(); + if (teCreators[meta] != null) throw new IllegalStateException( + "previous constructor: " + teCreators[meta] + " new constructor: " + constructor + " meta:" + meta); + teCreators[meta] = constructor; + } + + public static TileEntity createTileEntity(int meta) { + meta = GTUtility.clamp(meta, 0, 15); + if (teCreators[meta] == null) return null; + return teCreators[meta].apply(meta); + } +} diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java deleted file mode 100644 index 51bf250659..0000000000 --- a/src/main/java/gregtech/api/GregTech_API.java +++ /dev/null @@ -1,999 +0,0 @@ -package gregtech.api; - -import static gregtech.api.enums.GT_Values.B; -import static gregtech.api.enums.Mods.IndustrialCraft2; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; -import java.util.function.IntFunction; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import javax.annotation.Nonnull; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; - -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.google.common.collect.SetMultimap; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.Materials; -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.IDamagableItem; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.internal.IGT_RecipeAdder; -import gregtech.api.interfaces.internal.IThaumcraftCompat; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; -import gregtech.api.items.GT_CoolantCellIC_Item; -import gregtech.api.items.GT_CoolantCell_Item; -import gregtech.api.items.GT_Tool_Item; -import gregtech.api.metatileentity.BaseMetaTileEntity; -import gregtech.api.objects.GT_Cover_Default; -import gregtech.api.objects.GT_Cover_None; -import gregtech.api.objects.GT_HashSet; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.threads.GT_Runnable_Cable_Update; -import gregtech.api.threads.GT_Runnable_MachineBlockUpdate; -import gregtech.api.util.GT_CircuitryBehavior; -import gregtech.api.util.GT_Config; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_CreativeTab; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.item.ItemHolder; -import gregtech.api.world.GT_Worldgen; -import gregtech.common.GT_DummyWorld; -import gregtech.common.items.GT_IntegratedCircuit_Item; - -/** - * Please do not include this File in your Mod-download as it ruins compatibility, like with the IC2-API You may just - * copy those Functions into your Code, or better call them via reflection. - *

- * The whole API is the basic construct of my Mod. Everything is dependent on it. I change things quite often so please - * don't include any File inside your Mod, even if it is an Interface. Since some Authors were stupid enough to break - * this simple Rule, I added Version checks to enforce it. - *

- * In these Folders are many useful Functions. You can use them via reflection if you want. I know not everything is - * compilable due to APIs of other Mods, but these are easy to fix in your Setup. - *

- * You can use this to learn about Modding, but I would recommend simpler Mods. You may even copy-paste Code from these - * API-Files into your Mod, as I have nothing against that, but you should look exactly at what you are copying. - * - * @author Gregorius Techneticies - */ -@SuppressWarnings("unused") // API class has legitimately unused methods and members -public class GregTech_API { - - /** - * Fixes the HashMap Mappings for ItemStacks once the Server started - *
- *
- * NOTE: We use wildcards generics for the key because it could be for example {@link ItemStack} or - * {@link GT_ItemStack} - */ - public static final Collection> sItemStackMappings = new ArrayList<>(); - public static final Collection> itemStackMultiMaps = new ArrayList<>(); - - /** - * The MetaTileEntity-ID-List-Length - */ - public static final short MAXIMUM_METATILE_IDS = Short.MAX_VALUE - 1; - /** - * My Creative Tab - */ - public static final CreativeTabs TAB_GREGTECH = new GT_CreativeTab("Main", "Main"), - TAB_GREGTECH_MATERIALS = new GT_CreativeTab("Materials", "Materials"), - TAB_GREGTECH_ORES = new GT_CreativeTab("Ores", "Ores"); - - public static final IMetaTileEntity[] METATILEENTITIES = new IMetaTileEntity[MAXIMUM_METATILE_IDS]; - /** - * The Icon List for Covers - */ - public static final Map sCovers = new ConcurrentHashMap<>(); - /** - * The List of Cover Behaviors for the Covers - */ - public static final Map> sCoverBehaviors = new ConcurrentHashMap<>(); - /** - * The List of Circuit Behaviors for the Redstone Circuit Block - */ - public static final Map sCircuitryBehaviors = new ConcurrentHashMap<>(); - /** - * The List of Blocks, which can conduct Machine Block Updates - */ - public static final Map sMachineIDs = new ConcurrentHashMap<>(); - /** - * The Redstone Frequencies - */ - public static final Map sWirelessRedstone = new ConcurrentHashMap<>(); - /** - * The Advanced Redstone Frequencies - */ - public static final Map>> sAdvancedWirelessRedstone = new ConcurrentHashMap<>(); - - /** - * The IDSU Frequencies - */ - public static final Map sIDSUList = new ConcurrentHashMap<>(); - /** - * A List of all Books, which were created using @GT_Utility.getWrittenBook the original Title is the Key Value - */ - public static final Map sBookList = new ConcurrentHashMap<>(); - /** - * The List of all Sounds used in GT, indices are in the static Block at the bottom - * - * @deprecated Use {@link SoundResource} - */ - @Deprecated - public static final Map sSoundList = SoundResource.asSoundList(); - /** - * The List of Tools, which can be used. Accepts regular damageable Items and Electric Items - */ - public static final GT_HashSet sToolList = new GT_HashSet<>(), sCrowbarList = new GT_HashSet<>(), - sScrewdriverList = new GT_HashSet<>(), sWrenchList = new GT_HashSet<>(), sSoftHammerList = new GT_HashSet<>(), - sHardHammerList = new GT_HashSet<>(), sWireCutterList = new GT_HashSet<>(), - sSolderingToolList = new GT_HashSet<>(), sSolderingMetalList = new GT_HashSet<>(), - sJackhammerList = new GT_HashSet<>(); - /** - * The List of Hazmat Armors - */ - public static final GT_HashSet sGasHazmatList = new GT_HashSet<>(), - sBioHazmatList = new GT_HashSet<>(), sFrostHazmatList = new GT_HashSet<>(), - sHeatHazmatList = new GT_HashSet<>(), sRadioHazmatList = new GT_HashSet<>(), - sElectroHazmatList = new GT_HashSet<>(); - - private static final Multimap sRealConfigurationList = Multimaps - .newListMultimap(new TreeMap<>(), ArrayList::new); - private static final Map> sConfigurationLists = new ConcurrentHashMap<>(); - private static final Map, BiFunction> sRealCircuitProgrammerList = new LinkedHashMap<>(); - public static final Map, BiFunction> sCircuitProgrammerList = Collections - .unmodifiableMap(sRealCircuitProgrammerList); - - /** - * The List of Dimensions, which are Whitelisted for the Teleporter. This list should not contain other Planets. - * Mystcraft Dimensions and other Dimensional Things should be allowed. Mystcraft and Twilight Forest are - * automatically considered a Dimension, without being in this List. - */ - public static final Collection sDimensionalList = new HashSet<>(); - /** - * Lists of all the active World generation Features, these are getting Initialized in Postload! - */ - public static final List sWorldgenList = new ArrayList<>(); - /** - * A List containing all the Materials, which are somehow in use by GT and therefor receive a specific Set of Items. - */ - public static final Materials[] sGeneratedMaterials = new Materials[1000]; - /** - * This is the generic Cover behavior. Used for the default Covers, which have no Behavior. - */ - public static final GT_CoverBehavior sDefaultBehavior = new GT_Cover_Default(), sNoBehavior = new GT_Cover_None(); - /** - * For the API Version check - */ - public static volatile int VERSION = 509; - - /** - * @deprecated Use {@link GT_Values#RA} - */ - @SuppressWarnings("DeprecatedIsStillUsed") // Still need be initialized for backward compat - @Deprecated - public static IGT_RecipeAdder sRecipeAdder; - /** - * Registers Aspects to Thaumcraft. This Object might be {@code null} if Thaumcraft isn't installed. - */ - public static IThaumcraftCompat sThaumcraftCompat; - /** - * The Lists below are executed at their respective timings. Useful to do things at a particular moment in time. - * The Lists are not Threaded - a native Java interface is used for their execution. - * Add your "commands" in the constructor or in the static-code-block of your mod's Main class. - * Implement the method {@code run()}, and everything should work. - */ - public static List sBeforeGTPreload = new ArrayList<>(), sAfterGTPreload = new ArrayList<>(), - sBeforeGTLoad = new ArrayList<>(), sAfterGTLoad = new ArrayList<>(), sBeforeGTPostload = new ArrayList<>(), - sAfterGTPostload = new ArrayList<>(), sFirstWorldTick = new ArrayList<>(), - sBeforeGTServerstart = new ArrayList<>(), sAfterGTServerstart = new ArrayList<>(), - sBeforeGTServerstop = new ArrayList<>(), sAfterGTServerstop = new ArrayList<>(), - sGTBlockIconload = new ArrayList<>(), sGTItemIconload = new ArrayList<>(), sGTCompleteLoad = new ArrayList<>(); - /** - * The Icon Registers from Blocks and Items. They will get set right before the corresponding Icon Load Phase as - * executed in the Runnable List above. - */ - @SideOnly(Side.CLIENT) - public static IIconRegister sBlockIcons, sItemIcons; - /** - * The Configuration Objects - */ - public static GT_Config NEIClientFIle; - - public static int TICKS_FOR_LAG_AVERAGING = 25, MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING = 100; - /** - * Initialized by the Block creation. - */ - public static Block sBlockMachines; - - public static Block sBlockOres1, sBlockOresUb1, sBlockOresUb2, sBlockOresUb3, - /* sBlockGem, */ - sBlockMetal1, sBlockMetal2, sBlockMetal3, sBlockMetal4, sBlockMetal5, sBlockMetal6, sBlockMetal7, sBlockMetal8, - sBlockMetal9, sBlockGem1, sBlockGem2, sBlockGem3, sBlockReinforced; - public static Block sBlockGranites, sBlockConcretes, sBlockStones; - public static Block sBlockCasings1, sBlockCasings2, sBlockCasings3, sBlockCasings4, sBlockCasings5, sBlockCasings6, - sBlockCasings8, sBlockCasings9, sBlockCasings10, sBlockCasings11, sSolenoidCoilCasings; - public static Block sBlockLongDistancePipes; - public static Block sDroneRender; - public static Block sBlockFrames; - public static Block sBlockGlass1; - public static Block sBlockTintedGlass; - public static Block sLaserRender; - public static Block sWormholeRender; - /** - * Getting assigned by the Config - */ - public static boolean sTimber = true, sDrinksAlwaysDrinkable = false, sMultiThreadedSounds = false, - sDoShowAllItemsInCreative = false, sColoredGUI = true, sMachineMetalGUI = false, sMachineExplosions = true, - sMachineFlammable = true, sMachineNonWrenchExplosions = true, sMachineRainExplosions = true, - sMachineThunderExplosions = true, sMachineFireExplosions = true, sMachineWireFire = true, mOutputRF = false, - mInputRF = false, mRFExplosions = false, mServerStarted = false; - - public static int mEUtoRF = 360, mRFtoEU = 20; - - /** - * Option to not use MACHINE_METAL mixing into colors - */ - public static boolean sUseMachineMetal = false; - - public static boolean mUseOnlyGoodSolderingMaterials = false; - - private static final String aTextIC2Lower = IndustrialCraft2.ID.toLowerCase(Locale.ENGLISH); - /** - * Getting assigned by the Mod loading - */ - public static boolean sUnificationEntriesRegistered = false, sPreloadStarted = false, sPreloadFinished = false, - sLoadStarted = false, sLoadFinished = false, sPostloadStarted = false, sPostloadFinished = false, - sFullLoadFinished = false; - - private static Class sBaseMetaTileEntityClass = null; - - @SuppressWarnings("unchecked") - private static final IntFunction[] teCreators = new IntFunction[16]; - - private static final Set> dummyWorlds = new HashSet<>(); - - static { - sItemStackMappings.add(sCovers); - sItemStackMappings.add(sCoverBehaviors); - - dummyWorlds.add(GT_DummyWorld.class); - tryAddDummyWorld("blockrenderer6343.client.world.DummyWorld"); - } - - private static void tryAddDummyWorld(String className) { - ClassLoader cl = GregTech_API.class.getClassLoader(); - Class clazz; - try { - clazz = Class.forName(className, false, cl); - } catch (ReflectiveOperationException ex) { - return; - } - dummyWorlds.add(clazz); - } - - public static void addDummyWorld(Class clazz) { - dummyWorlds.add(clazz); - } - - public static boolean isDummyWorld(@Nonnull World w) { - return dummyWorlds.contains(w.getClass()); - } - - /** - * You want OreDict-Unification for YOUR Mod/Addon, when GregTech is installed? This Function is especially for YOU. - * Call this Function after the load-Phase, as I register the most of the Unification at that Phase (Redpowers - * Storageblocks are registered at postload). A recommended use of this Function is inside your Recipe-System itself - * (if you have one), as the unification then makes 100% sure, that every added non-unificated Output gets - * automatically unificated. - *

- * I will personally make sure, that only common prefixes of Ores get registered at the Unificator, as of now there - * are: pulp, dust, dustSmall, ingot, nugget, gem, ore and block If another Mod-Author messes these up, then it's - * not my fault, and it's especially not your fault. As these are commonly used prefixes. - *

- * This Unificator-API-Function uses the same Functions I use, for unificating Items. So if there is something - * messed up (very unlikely), then everything is messed up. - *

- * You shouldn't use this to unificate the Inputs of your Recipes, this is only meant for the Outputs. - * - * @param aOreStack the Stack you want to get unificated. It is stackSize Sensitive. - * @return Either an unificated Stack or the stack you toss in, but it should never be null, unless you throw a - * Null-Pointer into it. - */ - public static ItemStack getUnificatedOreDictStack(ItemStack aOreStack) { - if (!GregTech_API.sPreloadFinished) GT_Log.err.println( - "GregTech_API ERROR: " + aOreStack.getItem() - + "." - + aOreStack.getItemDamage() - + " - OreDict Unification Entries are not registered now, please call it in the postload phase."); - return GT_OreDictUnificator.get(true, aOreStack); - } - - /** - * Causes a Machineblock Update This update will cause surrounding MultiBlock Machines to update their - * Configuration. You should call this Function in @Block.breakBlock and in @Block.onBlockAdded of your Machine. - * - * @param aWorld is being the World - * @param aX is the X-Coord of the update causing Block - * @param aY is the Y-Coord of the update causing Block - * @param aZ is the Z-Coord of the update causing Block - */ - public static boolean causeMachineUpdate(World aWorld, int aX, int aY, int aZ) { - if (aWorld != null && !aWorld.isRemote && !isDummyWorld(aWorld)) { // World might be null during World-gen - GT_Runnable_MachineBlockUpdate.setMachineUpdateValues(aWorld, aX, aY, aZ); - return true; - } - return false; - } - - @SuppressWarnings("UnusedReturnValue") // Retains API method signature - public static boolean causeCableUpdate(World aWorld, int aX, int aY, int aZ) { - if (aWorld == null || aWorld.isRemote || isDummyWorld(aWorld)) { - return false; - } // World might be null during World-gen - GT_Runnable_Cable_Update.setCableUpdateValues(aWorld, aX, aY, aZ); - return true; - } - - /** - * Adds a Multi-Machine Block, like my Machine Casings for example. You should call @causeMachineUpdate - * in @Block.breakBlock and in {@link Block#onBlockAdded} of your registered Block. You don't need to register - * TileEntities which implement {@link IMachineBlockUpdateable} - * - * @param aBlock the Block - * @param aMeta the Metadata of the Blocks as Bitmask! -1 or ~0 for all Meta-values - */ - @SuppressWarnings("UnusedReturnValue") // Retains API method signature - public static boolean registerMachineBlock(Block aBlock, int aMeta) { - if (aBlock == null) return false; - if (GregTech_API.sThaumcraftCompat != null) - GregTech_API.sThaumcraftCompat.registerPortholeBlacklistedBlock(aBlock); - sMachineIDs.put(aBlock, aMeta); - return true; - } - - /** - * Like above but with boolean Parameters instead of a BitMask - */ - public static boolean registerMachineBlock(Block aBlock, boolean... aMeta) { - if (aBlock == null || aMeta == null || aMeta.length == 0) return false; - if (GregTech_API.sThaumcraftCompat != null) - GregTech_API.sThaumcraftCompat.registerPortholeBlacklistedBlock(aBlock); - int rMeta = 0; - for (byte i = 0; i < aMeta.length && i < 16; i++) if (aMeta[i]) rMeta |= B[i]; - sMachineIDs.put(aBlock, rMeta); - return true; - } - - /** - * if this Block is a Machine Update Conducting Block - */ - public static boolean isMachineBlock(Block aBlock, int aMeta) { - if (aBlock != null) { - Integer id = sMachineIDs.get(aBlock); - return id != null && (id & B[aMeta]) != 0; - } - return false; - } - - /** - * Creates a new Coolant Cell Item for your Nuclear Reactor - */ - public static Item constructCoolantCellItem(String aUnlocalized, String aEnglish, int aMaxStore) { - try { - return new GT_CoolantCellIC_Item(aUnlocalized, aEnglish, aMaxStore); - } catch (Throwable e) { - /* Do nothing */ - } - try { - return new GT_CoolantCell_Item(aUnlocalized, aEnglish, aMaxStore); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Generic_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug"); - } - - /** - * Creates a new Energy Armor Item - */ - public static Item constructElectricArmorItem(String aUnlocalized, String aEnglish, int aCharge, int aTransfer, - int aTier, int aDamageEnergyCost, int aSpecials, double aArmorAbsorbtionPercentage, boolean aChargeProvider, - int aType, int aArmorIndex) { - try { - return (Item) Class.forName("gregtechmod.api.items.GT_EnergyArmorIC_Item") - .getConstructors()[0].newInstance( - aUnlocalized, - aEnglish, - aCharge, - aTransfer, - aTier, - aDamageEnergyCost, - aSpecials, - aArmorAbsorbtionPercentage, - aChargeProvider, - aType, - aArmorIndex); - } catch (Throwable e) { - /* Do nothing */ - } - try { - return (Item) Class.forName("gregtechmod.api.items.GT_EnergyArmor_Item") - .getConstructors()[0].newInstance( - aUnlocalized, - aEnglish, - aCharge, - aTransfer, - aTier, - aDamageEnergyCost, - aSpecials, - aArmorAbsorbtionPercentage, - aChargeProvider, - aType, - aArmorIndex); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Generic_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug"); - } - - /** - * Creates a new Energy Battery Item - */ - public static Item constructElectricEnergyStorageItem(String aUnlocalized, String aEnglish, int aCharge, - int aTransfer, int aTier, int aEmptyID, int aFullID) { - try { - return (Item) Class.forName("gregtechmod.api.items.GT_EnergyStoreIC_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aCharge, aTransfer, aTier, aEmptyID, aFullID); - } catch (Throwable e) { - /* Do nothing */ - } - try { - return (Item) Class.forName("gregtechmod.api.items.GT_EnergyStore_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aCharge, aTransfer, aTier, aEmptyID, aFullID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Generic_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug"); - } - - /** - * Creates a new Hard Hammer Item - */ - public static GT_Tool_Item constructHardHammerItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_HardHammer_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new Crowbar Item - */ - public static GT_Tool_Item constructCrowbarItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_CrowbarRC_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage); - } catch (Throwable e) { - /* Do nothing */ - } - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_Crowbar_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new Wrench Item - */ - public static GT_Tool_Item constructWrenchItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage, int aDisChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_Wrench_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new electric Screwdriver Item - */ - public static GT_Tool_Item constructElectricScrewdriverItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage, int aDisChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_ScrewdriverIC_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new electric Wrench Item - */ - public static GT_Tool_Item constructElectricWrenchItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage, int aDisChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_WrenchIC_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new electric Saw Item - */ - public static GT_Tool_Item constructElectricSawItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage, int aToolQuality, float aToolStrength, int aEnergyConsumptionPerBlockBreak, - int aDisChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_SawIC_Item") - .getConstructors()[0].newInstance( - aUnlocalized, - aEnglish, - aMaxDamage, - aEntityDamage, - aToolQuality, - aToolStrength, - aEnergyConsumptionPerBlockBreak, - aDisChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new electric Drill Item - */ - public static GT_Tool_Item constructElectricDrillItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage, int aToolQuality, float aToolStrength, int aEnergyConsumptionPerBlockBreak, - int aDisChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_DrillIC_Item") - .getConstructors()[0].newInstance( - aUnlocalized, - aEnglish, - aMaxDamage, - aEntityDamage, - aToolQuality, - aToolStrength, - aEnergyConsumptionPerBlockBreak, - aDisChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new electric Soldering Tool - */ - public static GT_Tool_Item constructElectricSolderingToolItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aEntityDamage, int aDisChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_SolderingToolIC_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aEntityDamage, aDisChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - aEntityDamage, - false); - } - - /** - * Creates a new empty electric Tool - */ - public static GT_Tool_Item constructEmptyElectricToolItem(String aUnlocalized, String aEnglish, int aMaxDamage, - int aChargedGTID) { - try { - return (GT_Tool_Item) Class.forName("gregtechmod.api.items.GT_EmptyToolIC_Item") - .getConstructors()[0].newInstance(aUnlocalized, aEnglish, aMaxDamage, aChargedGTID); - } catch (Throwable e) { - /* Do nothing */ - } - return new gregtech.api.items.GT_Tool_Item( - aUnlocalized, - aEnglish, - "Doesn't work as intended, this is a Bug", - aMaxDamage, - 0, - false); - } - - /** - * Provides a new BaseMetaTileEntity. Because some interfaces are not always loaded (Buildcraft, Universal - * Electricity) we have to use invocation at the constructor of the BaseMetaTileEntity. - */ - public static BaseMetaTileEntity constructBaseMetaTileEntity() { - if (sBaseMetaTileEntityClass == null) { - try { - return (sBaseMetaTileEntityClass = BaseMetaTileEntity.class).getDeclaredConstructor() - .newInstance(); - } catch (Throwable ignored) {} - } - - try { - return sBaseMetaTileEntityClass.getDeclaredConstructor() - .newInstance(); - } catch (Throwable e) { - GT_Log.err.println("GT_Mod: Fatal Error occurred while initializing TileEntities, crashing Minecraft."); - e.printStackTrace(GT_Log.err); - throw new RuntimeException(e); - } - } - - /** - * Register a new ItemStack as configuration circuits. Duplicates or invalid stacks will be silently ignored. - */ - public static void registerConfigurationCircuit(ItemStack aStack) { - registerConfigurationCircuit(aStack, 0); - } - - /** - * Register a new ItemStack as configuration circuits. Duplicates or invalid stacks will be silently ignored. - * - * @param minTier the minimal tier this circuit can be offered for free, e.g. normal configuration circuit is - * available in LV+ single blocks, GT++ breakthrough circuit is offered in HV+ single blocks - */ - public static void registerConfigurationCircuit(ItemStack aStack, int minTier) { - if (GT_Utility.isStackInvalid(aStack)) return; - for (ItemStack tRegistered : sRealConfigurationList.values()) - if (GT_Utility.areStacksEqual(tRegistered, aStack)) return; - ItemStack stack = GT_Utility.copyAmount(0, aStack); - sRealConfigurationList.put(minTier, stack); - for (Map.Entry> e : sConfigurationLists.entrySet()) { - if (e.getKey() >= minTier) { - e.getValue() - .add(stack); - e.getValue() - .sort(getConfigurationCircuitsComparator()); - } - } - } - - /** - * Get a list of Configuration circuits. These stacks will have a stack size of 0. Use - * {@link #registerConfigurationCircuit(ItemStack, int)} or its overload to add to this list. - * - * @param machineTier The voltage tier where this list will be used. use Integer.MAX_VALUE to get all circuits - * @return An unmodifiable view of actual list. DO NOT MODIFY THE ItemStacks! - */ - public static List getConfigurationCircuitList(int machineTier) { - return Collections.unmodifiableList( - sConfigurationLists.computeIfAbsent( - machineTier, - (t) -> sRealConfigurationList.entries() - .stream() - .filter(e -> e.getKey() <= machineTier) - .map(Map.Entry::getValue) - .sorted(getConfigurationCircuitsComparator()) - .collect(Collectors.toList()))); - } - - public static Comparator getConfigurationCircuitsComparator() { - return Comparator.comparingInt((ItemStack is) -> is.getItem() instanceof GT_IntegratedCircuit_Item ? 0 : 1) - .thenComparing(ItemStack::getUnlocalizedName) - .thenComparing(ItemStack::getItemDamage); - } - - public static void registerCircuitProgrammer(ItemStack stack, boolean ignoreNBT, boolean useContainer) { - registerCircuitProgrammer(rhs -> GT_Utility.areStacksEqual(stack, rhs, ignoreNBT), useContainer); - } - - public static void registerCircuitProgrammer(Predicate predicate, boolean useContainer) { - sRealCircuitProgrammerList.put( - predicate, - useContainer ? (s, p) -> s.getItem() - .getContainerItem(s) : (s, p) -> s); - } - - public static void registerCircuitProgrammer(Predicate predicate, - BiFunction doDamage) { - sRealCircuitProgrammerList.put(predicate, doDamage); - } - - public static void registerCover(ItemStack aStack, ITexture aCover, GT_CoverBehavior aBehavior) { - registerCover(aStack, aCover, (GT_CoverBehaviorBase) aBehavior); - } - - public static void registerCover(ItemStack aStack, ITexture aCover, GT_CoverBehaviorBase aBehavior) { - if (!sCovers.containsKey(new GT_ItemStack(aStack))) sCovers.put( - new GT_ItemStack(aStack), - aCover == null || !aCover.isValidTexture() ? Textures.BlockIcons.ERROR_RENDERING[0] : aCover); - if (aBehavior != null) sCoverBehaviors.put(new GT_ItemStack(aStack), aBehavior); - } - - public static void registerCoverBehavior(ItemStack aStack, GT_CoverBehavior aBehavior) { - registerCoverBehavior(aStack, (GT_CoverBehaviorBase) aBehavior); - } - - public static void registerCoverBehavior(ItemStack aStack, GT_CoverBehaviorBase aBehavior) { - sCoverBehaviors.put(new GT_ItemStack(aStack), aBehavior == null ? sDefaultBehavior : aBehavior); - } - - /** - * Registers multiple Cover Items. I use that for the OreDict Functionality. - * - * @param aBehavior can be null - */ - public static void registerCover(Collection aStackList, ITexture aCover, GT_CoverBehavior aBehavior) { - registerCover(aStackList, aCover, (GT_CoverBehaviorBase) aBehavior); - } - - /** - * Registers multiple Cover Items. I use that for the OreDict Functionality. - * - * @param aBehavior can be null - */ - public static void registerCover(Collection aStackList, ITexture aCover, - GT_CoverBehaviorBase aBehavior) { - if (aCover.isValidTexture()) - aStackList.forEach(tStack -> GregTech_API.registerCover(tStack, aCover, aBehavior)); - } - - /** - * returns a Cover behavior, guaranteed to not return null after preload - * - * @return The Cover behavior - */ - public static GT_CoverBehaviorBase getCoverBehaviorNew(ItemStack aStack) { - if (aStack == null || aStack.getItem() == null) return sNoBehavior; - GT_CoverBehaviorBase rCover = sCoverBehaviors.get(new GT_ItemStack(aStack)); - if (rCover != null) return rCover; - rCover = sCoverBehaviors.get(new GT_ItemStack(aStack, true)); - if (rCover != null) return rCover; - return sDefaultBehavior; - } - - /** - * returns a Cover behavior, guaranteed to not return null - */ - public static GT_CoverBehaviorBase getCoverBehaviorNew(int aStack) { - if (aStack == 0) return sNoBehavior; - return getCoverBehaviorNew(GT_Utility.intToStack(aStack)); - } - - /** - * Register a Wrench to be usable on GregTech Machines. The Wrench MUST have some kind of Durability unlike certain - * Buildcraft Wrenches. - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - *

- * ----- - *

- * Returning true at isDamageable was a great Idea, KingLemming. Well played. Since the OmniWrench is just a - * Single-Item-Mod, people can choose if they want your infinite durability or not. So that's not really a Problem. - * I even have a new Config to auto-disable most infinite BC Wrenches (but that one is turned off). - *

- * One last Bug for you to fix: My Auto-registration detects Railcraft's Crowbars, Buildcraft's Wrenches and alike, - * due to their Interfaces. Guess what now became a Crowbar by accident. Try registering the Wrench at the load - * phase to prevent things like that from happening. Yes, I know that "You need to register Tools in the Load - * Phase"-Part wasn't there before this. Sorry about that. - */ - public static boolean registerWrench(ItemStack aTool) { - return registerTool(aTool, sWrenchList); - } - - /** - * Register a Crowbar to extract Covers from Machines Crowbars are NOT Wrenches btw. - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - public static boolean registerCrowbar(ItemStack aTool) { - return registerTool(aTool, sCrowbarList); - } - - /** - * Register a Screwdriver to interact directly with Machines and Covers Did I mention, that it is intentionally not - * possible to make a Multi-tool, which doesn't switch ItemID (like a Mode) all the time? - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - @SuppressWarnings("UnusedReturnValue") // Retains API method signature - public static boolean registerScrewdriver(ItemStack aTool) { - return registerTool(aTool, sScrewdriverList); - } - - /** - * Register a Soft Hammer to interact with Machines - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - public static boolean registerSoftHammer(ItemStack aTool) { - return registerTool(aTool, sSoftHammerList); - } - - /** - * Register a Hard Hammer to interact with Machines - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - public static boolean registerHardHammer(ItemStack aTool) { - return registerTool(aTool, sHardHammerList); - } - - /** - * Register a Wire Cutter to interact with Machines - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - public static boolean registerWireCutter(ItemStack aTool) { - return registerTool(aTool, sWireCutterList); - } - - /** - * Register a Soldering Tool to interact with Machines - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - @SuppressWarnings("UnusedReturnValue") // Retains API method signature - public static boolean registerSolderingTool(ItemStack aTool) { - return registerTool(aTool, sSolderingToolList); - } - - /** - * Register a Soldering Tin to interact with Soldering Tools - *

- * You need to register Tools in the Load Phase, because otherwise the Auto-detection will assign a Tool Type in - * certain Cases during postload (When IToolWrench or similar Interfaces are implemented). - */ - @SuppressWarnings("UnusedReturnValue") // Retains API method signature - public static boolean registerSolderingMetal(ItemStack aTool) { - return registerTool(aTool, sSolderingMetalList); - } - - /** - * Generic Function to add Tools to the Lists. Contains all sanity Checks for Tools, like preventing one Tool from - * being registered for multiple purposes as controls would override each other. - */ - public static boolean registerTool(ItemStack aTool, Collection aToolList) { - if (aTool == null || GT_Utility.isStackInList(aTool, sToolList) - || (!aTool.getItem() - .isDamageable() && !GT_ModHandler.isElectricItem(aTool) - && !(aTool.getItem() instanceof IDamagableItem))) - return false; - aToolList.add(new GT_ItemStack(GT_Utility.copyAmount(1, aTool))); - sToolList.add(new GT_ItemStack(GT_Utility.copyAmount(1, aTool))); - return true; - } - - /** - * Sets the {@link IIconRegister} for Block Icons - * - * @param aIconRegister The {@link IIconRegister} Icon Register - */ - @SideOnly(Side.CLIENT) - public static void setBlockIconRegister(IIconRegister aIconRegister) { - sBlockIcons = aIconRegister; - } - - /** - * Sets the {@link IIconRegister} for Items Icons - * - * @param aIconRegister The {@link IIconRegister} Icon Register - */ - @SideOnly(Side.CLIENT) - public static void setItemIconRegister(IIconRegister aIconRegister) { - GregTech_API.sItemIcons = aIconRegister; - } - - public static void registerTileEntityConstructor(int meta, IntFunction constructor) { - if (meta < 0 || meta > 15 || constructor == null) throw new IllegalArgumentException(); - if (teCreators[meta] != null) throw new IllegalStateException( - "previous constructor: " + teCreators[meta] + " new constructor: " + constructor + " meta:" + meta); - teCreators[meta] = constructor; - } - - public static TileEntity createTileEntity(int meta) { - meta = GT_Utility.clamp(meta, 0, 15); - if (teCreators[meta] == null) return null; - return teCreators[meta].apply(meta); - } -} diff --git a/src/main/java/gregtech/api/damagesources/GTDamageSources.java b/src/main/java/gregtech/api/damagesources/GTDamageSources.java new file mode 100644 index 0000000000..44b80a57c9 --- /dev/null +++ b/src/main/java/gregtech/api/damagesources/GTDamageSources.java @@ -0,0 +1,119 @@ +package gregtech.api.damagesources; + +import javax.annotation.Nullable; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EntityDamageSource; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; + +public class GTDamageSources { + + public static DamageSource getElectricDamage() { + return ic2.api.info.Info.DMG_ELECTRIC; + } + + public static DamageSource getRadioactiveDamage() { + return ic2.api.info.Info.DMG_RADIATION; + } + + public static DamageSource getNukeExplosionDamage() { + return ic2.api.info.Info.DMG_NUKE_EXPLOSION; + } + + public static DamageSource getExplodingDamage() { + return new DamageSourceExploding(); + } + + public static DamageSource getCombatDamage(String aType, EntityLivingBase aPlayer, IChatComponent aDeathMessage) { + return new DamageSourceCombat(aType, aPlayer, aDeathMessage); + } + + public static DamageSource getHeatDamage() { + return new DamageSourceHeat(); + } + + public static DamageSource getFrostDamage() { + return new DamageSourceFrost(); + } + + private static class DamageSourceCombat extends EntityDamageSource { + + private final IChatComponent mDeathMessage; + + public DamageSourceCombat(String aType, EntityLivingBase aPlayer, IChatComponent aDeathMessage) { + super(aType, aPlayer); + mDeathMessage = aDeathMessage; + } + + @Override + public IChatComponent func_151519_b(EntityLivingBase aTarget) { + return mDeathMessage == null ? super.func_151519_b(aTarget) : mDeathMessage; + } + } + + private static class DamageSourceFrost extends DamageSource { + + public DamageSourceFrost() { + super("frost"); + setDifficultyScaled(); + } + + @Override + public IChatComponent func_151519_b(EntityLivingBase aTarget) { + return new ChatComponentText( + EnumChatFormatting.RED + aTarget.getCommandSenderName() + EnumChatFormatting.WHITE + " got frozen"); + } + } + + private static class DamageSourceHeat extends DamageSource { + + public DamageSourceHeat() { + super("steam"); + setFireDamage(); + setDifficultyScaled(); + } + + @Override + public IChatComponent func_151519_b(EntityLivingBase aTarget) { + return new ChatComponentText( + EnumChatFormatting.RED + aTarget.getCommandSenderName() + + EnumChatFormatting.WHITE + + " was boiled alive"); + } + } + + public static class DamageSourceHotItem extends DamageSourceHeat { + + @Nullable + private final ItemStack stack; + + public DamageSourceHotItem(@Nullable ItemStack cause) { + this.stack = cause; + } + + @Nullable + public ItemStack getDamagingStack() { + return stack; + } + } + + public static class DamageSourceExploding extends DamageSource { + + public DamageSourceExploding() { + super("exploded"); + setDamageAllowedInCreativeMode(); + setDamageBypassesArmor(); + setDamageIsAbsolute(); + } + + @Override + public IChatComponent func_151519_b(EntityLivingBase aTarget) { + return new ChatComponentText( + EnumChatFormatting.RED + aTarget.getCommandSenderName() + EnumChatFormatting.WHITE + " exploded"); + } + } +} diff --git a/src/main/java/gregtech/api/damagesources/GT_DamageSources.java b/src/main/java/gregtech/api/damagesources/GT_DamageSources.java deleted file mode 100644 index 65a2519001..0000000000 --- a/src/main/java/gregtech/api/damagesources/GT_DamageSources.java +++ /dev/null @@ -1,119 +0,0 @@ -package gregtech.api.damagesources; - -import javax.annotation.Nullable; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.DamageSource; -import net.minecraft.util.EntityDamageSource; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.IChatComponent; - -public class GT_DamageSources { - - public static DamageSource getElectricDamage() { - return ic2.api.info.Info.DMG_ELECTRIC; - } - - public static DamageSource getRadioactiveDamage() { - return ic2.api.info.Info.DMG_RADIATION; - } - - public static DamageSource getNukeExplosionDamage() { - return ic2.api.info.Info.DMG_NUKE_EXPLOSION; - } - - public static DamageSource getExplodingDamage() { - return new DamageSourceExploding(); - } - - public static DamageSource getCombatDamage(String aType, EntityLivingBase aPlayer, IChatComponent aDeathMessage) { - return new DamageSourceCombat(aType, aPlayer, aDeathMessage); - } - - public static DamageSource getHeatDamage() { - return new DamageSourceHeat(); - } - - public static DamageSource getFrostDamage() { - return new DamageSourceFrost(); - } - - private static class DamageSourceCombat extends EntityDamageSource { - - private final IChatComponent mDeathMessage; - - public DamageSourceCombat(String aType, EntityLivingBase aPlayer, IChatComponent aDeathMessage) { - super(aType, aPlayer); - mDeathMessage = aDeathMessage; - } - - @Override - public IChatComponent func_151519_b(EntityLivingBase aTarget) { - return mDeathMessage == null ? super.func_151519_b(aTarget) : mDeathMessage; - } - } - - private static class DamageSourceFrost extends DamageSource { - - public DamageSourceFrost() { - super("frost"); - setDifficultyScaled(); - } - - @Override - public IChatComponent func_151519_b(EntityLivingBase aTarget) { - return new ChatComponentText( - EnumChatFormatting.RED + aTarget.getCommandSenderName() + EnumChatFormatting.WHITE + " got frozen"); - } - } - - private static class DamageSourceHeat extends DamageSource { - - public DamageSourceHeat() { - super("steam"); - setFireDamage(); - setDifficultyScaled(); - } - - @Override - public IChatComponent func_151519_b(EntityLivingBase aTarget) { - return new ChatComponentText( - EnumChatFormatting.RED + aTarget.getCommandSenderName() - + EnumChatFormatting.WHITE - + " was boiled alive"); - } - } - - public static class DamageSourceHotItem extends DamageSourceHeat { - - @Nullable - private final ItemStack stack; - - public DamageSourceHotItem(@Nullable ItemStack cause) { - this.stack = cause; - } - - @Nullable - public ItemStack getDamagingStack() { - return stack; - } - } - - public static class DamageSourceExploding extends DamageSource { - - public DamageSourceExploding() { - super("exploded"); - setDamageAllowedInCreativeMode(); - setDamageBypassesArmor(); - setDamageIsAbsolute(); - } - - @Override - public IChatComponent func_151519_b(EntityLivingBase aTarget) { - return new ChatComponentText( - EnumChatFormatting.RED + aTarget.getCommandSenderName() + EnumChatFormatting.WHITE + " exploded"); - } - } -} diff --git a/src/main/java/gregtech/api/enchants/EnchantmentEnderDamage.java b/src/main/java/gregtech/api/enchants/EnchantmentEnderDamage.java new file mode 100644 index 0000000000..6c26a54976 --- /dev/null +++ b/src/main/java/gregtech/api/enchants/EnchantmentEnderDamage.java @@ -0,0 +1,72 @@ +package gregtech.api.enchants; + +import net.minecraft.enchantment.EnchantmentDamage; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.monster.EntityEnderman; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; + +import gregtech.api.enums.ConfigCategories; +import gregtech.api.enums.Materials; +import gregtech.api.util.GTConfig; +import gregtech.api.util.GTLanguageManager; + +public class EnchantmentEnderDamage extends EnchantmentDamage { + + public static EnchantmentEnderDamage INSTANCE; + + public EnchantmentEnderDamage() { + super(GTConfig.addIDConfig(ConfigCategories.IDs.enchantments, "Disjunction", 15), 2, -1); + GTLanguageManager.addStringLocalization(getName(), "Disjunction"); + Materials.Silver.setEnchantmentForTools(this, 2); + Materials.Mercury.setEnchantmentForTools(this, 3); + Materials.Electrum.setEnchantmentForTools(this, 3); + Materials.SterlingSilver.setEnchantmentForTools(this, 4); + Materials.AstralSilver.setEnchantmentForTools(this, 5); + INSTANCE = this; + } + + @Override + public int getMinEnchantability(int aLevel) { + return 5 + (aLevel - 1) * 8; + } + + @Override + public int getMaxEnchantability(int aLevel) { + return this.getMinEnchantability(aLevel) + 20; + } + + @Override + public int getMaxLevel() { + return 5; + } + + @Override + public void func_151367_b(EntityLivingBase aHurtEntity, Entity aDamagingEntity, int aLevel) { + if ((aHurtEntity instanceof EntityEnderman || aHurtEntity instanceof EntityDragon + || (aHurtEntity.getClass() + .getName() + .contains(".") + && aHurtEntity.getClass() + .getName() + .substring( + aHurtEntity.getClass() + .getName() + .lastIndexOf(".")) + .contains("Ender")))) { + // Weakness causes Endermen to not be able to teleport with GT being installed. + aHurtEntity + .addPotionEffect(new PotionEffect(Potion.weakness.id, aLevel * 200, Math.max(1, (5 * aLevel) / 7))); + // They also get Poisoned. If you have this Enchant on an Arrow, you can kill the Ender Dragon easier. + aHurtEntity + .addPotionEffect(new PotionEffect(Potion.poison.id, aLevel * 200, Math.max(1, (5 * aLevel) / 7))); + } + } + + @Override + public String getName() { + return "enchantment.damage.endermen"; + } +} diff --git a/src/main/java/gregtech/api/enchants/EnchantmentHazmat.java b/src/main/java/gregtech/api/enchants/EnchantmentHazmat.java new file mode 100644 index 0000000000..bbac780b71 --- /dev/null +++ b/src/main/java/gregtech/api/enchants/EnchantmentHazmat.java @@ -0,0 +1,56 @@ +package gregtech.api.enchants; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnumEnchantmentType; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.ConfigCategories; +import gregtech.api.util.GTConfig; +import gregtech.api.util.GTLanguageManager; + +public class EnchantmentHazmat extends Enchantment { + + public static EnchantmentHazmat INSTANCE; + + public EnchantmentHazmat() { + super(GTConfig.addIDConfig(ConfigCategories.IDs.enchantments, "Hazmat", 13), 0, EnumEnchantmentType.armor); + GTLanguageManager.addStringLocalization(getName(), "Hazmat"); + INSTANCE = this; + } + + @Override + public int getMinEnchantability(int aLevel) { + return 50; + } + + @Override + public int getMaxEnchantability(int aLevel) { + return 100; + } + + @Override + public int getMaxLevel() { + return 1; + } + + @Override + public boolean canApply(ItemStack aStack) { + return aStack != null && (aStack.getItem() instanceof ItemArmor); + } + + @Override + public boolean canApplyAtEnchantingTable(ItemStack itemStack) { + return false; + } + + @Override + public boolean isAllowedOnBooks() { + return false; + } + + @Override + public String getName() { + return "enchantment.protection.hazmat"; + } +} diff --git a/src/main/java/gregtech/api/enchants/EnchantmentRadioactivity.java b/src/main/java/gregtech/api/enchants/EnchantmentRadioactivity.java new file mode 100644 index 0000000000..77e6f52702 --- /dev/null +++ b/src/main/java/gregtech/api/enchants/EnchantmentRadioactivity.java @@ -0,0 +1,68 @@ +package gregtech.api.enchants; + +import net.minecraft.enchantment.EnchantmentDamage; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.ConfigCategories; +import gregtech.api.enums.Materials; +import gregtech.api.util.GTConfig; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTUtility; + +public class EnchantmentRadioactivity extends EnchantmentDamage { + + public static EnchantmentRadioactivity INSTANCE; + + public EnchantmentRadioactivity() { + super(GTConfig.addIDConfig(ConfigCategories.IDs.enchantments, "Radioactivity", 14), 0, -1); + GTLanguageManager.addStringLocalization(getName(), "Radioactivity"); + Materials.Plutonium.setEnchantmentForTools(this, 1) + .setEnchantmentForArmors(this, 1); + Materials.Uranium235.setEnchantmentForTools(this, 2) + .setEnchantmentForArmors(this, 2); + Materials.Plutonium241.setEnchantmentForTools(this, 3) + .setEnchantmentForArmors(this, 3); + Materials.NaquadahEnriched.setEnchantmentForTools(this, 4) + .setEnchantmentForArmors(this, 4); + Materials.Naquadria.setEnchantmentForTools(this, 5) + .setEnchantmentForArmors(this, 5); + INSTANCE = this; + } + + @Override + public int getMinEnchantability(int aLevel) { + return Integer.MAX_VALUE; + } + + @Override + public int getMaxEnchantability(int aLevel) { + return 0; + } + + @Override + public int getMaxLevel() { + return 5; + } + + @Override + public boolean canApply(ItemStack itemStack) { + return false; + } + + @Override + public boolean isAllowedOnBooks() { + return false; + } + + @Override + public void func_151367_b(EntityLivingBase aHurtEntity, Entity aDamagingEntity, int aLevel) { + GTUtility.applyRadioactivity(aHurtEntity, aLevel, 1); + } + + @Override + public String getName() { + return "enchantment.damage.radioactivity"; + } +} diff --git a/src/main/java/gregtech/api/enchants/Enchantment_EnderDamage.java b/src/main/java/gregtech/api/enchants/Enchantment_EnderDamage.java deleted file mode 100644 index 07c13b3509..0000000000 --- a/src/main/java/gregtech/api/enchants/Enchantment_EnderDamage.java +++ /dev/null @@ -1,72 +0,0 @@ -package gregtech.api.enchants; - -import net.minecraft.enchantment.EnchantmentDamage; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.boss.EntityDragon; -import net.minecraft.entity.monster.EntityEnderman; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; - -import gregtech.api.enums.ConfigCategories; -import gregtech.api.enums.Materials; -import gregtech.api.util.GT_Config; -import gregtech.api.util.GT_LanguageManager; - -public class Enchantment_EnderDamage extends EnchantmentDamage { - - public static Enchantment_EnderDamage INSTANCE; - - public Enchantment_EnderDamage() { - super(GT_Config.addIDConfig(ConfigCategories.IDs.enchantments, "Disjunction", 15), 2, -1); - GT_LanguageManager.addStringLocalization(getName(), "Disjunction"); - Materials.Silver.setEnchantmentForTools(this, 2); - Materials.Mercury.setEnchantmentForTools(this, 3); - Materials.Electrum.setEnchantmentForTools(this, 3); - Materials.SterlingSilver.setEnchantmentForTools(this, 4); - Materials.AstralSilver.setEnchantmentForTools(this, 5); - INSTANCE = this; - } - - @Override - public int getMinEnchantability(int aLevel) { - return 5 + (aLevel - 1) * 8; - } - - @Override - public int getMaxEnchantability(int aLevel) { - return this.getMinEnchantability(aLevel) + 20; - } - - @Override - public int getMaxLevel() { - return 5; - } - - @Override - public void func_151367_b(EntityLivingBase aHurtEntity, Entity aDamagingEntity, int aLevel) { - if ((aHurtEntity instanceof EntityEnderman || aHurtEntity instanceof EntityDragon - || (aHurtEntity.getClass() - .getName() - .contains(".") - && aHurtEntity.getClass() - .getName() - .substring( - aHurtEntity.getClass() - .getName() - .lastIndexOf(".")) - .contains("Ender")))) { - // Weakness causes Endermen to not be able to teleport with GT being installed. - aHurtEntity - .addPotionEffect(new PotionEffect(Potion.weakness.id, aLevel * 200, Math.max(1, (5 * aLevel) / 7))); - // They also get Poisoned. If you have this Enchant on an Arrow, you can kill the Ender Dragon easier. - aHurtEntity - .addPotionEffect(new PotionEffect(Potion.poison.id, aLevel * 200, Math.max(1, (5 * aLevel) / 7))); - } - } - - @Override - public String getName() { - return "enchantment.damage.endermen"; - } -} diff --git a/src/main/java/gregtech/api/enchants/Enchantment_Hazmat.java b/src/main/java/gregtech/api/enchants/Enchantment_Hazmat.java deleted file mode 100644 index ecbe654698..0000000000 --- a/src/main/java/gregtech/api/enchants/Enchantment_Hazmat.java +++ /dev/null @@ -1,56 +0,0 @@ -package gregtech.api.enchants; - -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnumEnchantmentType; -import net.minecraft.item.ItemArmor; -import net.minecraft.item.ItemStack; - -import gregtech.api.enums.ConfigCategories; -import gregtech.api.util.GT_Config; -import gregtech.api.util.GT_LanguageManager; - -public class Enchantment_Hazmat extends Enchantment { - - public static Enchantment_Hazmat INSTANCE; - - public Enchantment_Hazmat() { - super(GT_Config.addIDConfig(ConfigCategories.IDs.enchantments, "Hazmat", 13), 0, EnumEnchantmentType.armor); - GT_LanguageManager.addStringLocalization(getName(), "Hazmat"); - INSTANCE = this; - } - - @Override - public int getMinEnchantability(int aLevel) { - return 50; - } - - @Override - public int getMaxEnchantability(int aLevel) { - return 100; - } - - @Override - public int getMaxLevel() { - return 1; - } - - @Override - public boolean canApply(ItemStack aStack) { - return aStack != null && (aStack.getItem() instanceof ItemArmor); - } - - @Override - public boolean canApplyAtEnchantingTable(ItemStack itemStack) { - return false; - } - - @Override - public boolean isAllowedOnBooks() { - return false; - } - - @Override - public String getName() { - return "enchantment.protection.hazmat"; - } -} diff --git a/src/main/java/gregtech/api/enchants/Enchantment_Radioactivity.java b/src/main/java/gregtech/api/enchants/Enchantment_Radioactivity.java deleted file mode 100644 index e68e55cd6a..0000000000 --- a/src/main/java/gregtech/api/enchants/Enchantment_Radioactivity.java +++ /dev/null @@ -1,68 +0,0 @@ -package gregtech.api.enchants; - -import net.minecraft.enchantment.EnchantmentDamage; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.item.ItemStack; - -import gregtech.api.enums.ConfigCategories; -import gregtech.api.enums.Materials; -import gregtech.api.util.GT_Config; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_Utility; - -public class Enchantment_Radioactivity extends EnchantmentDamage { - - public static Enchantment_Radioactivity INSTANCE; - - public Enchantment_Radioactivity() { - super(GT_Config.addIDConfig(ConfigCategories.IDs.enchantments, "Radioactivity", 14), 0, -1); - GT_LanguageManager.addStringLocalization(getName(), "Radioactivity"); - Materials.Plutonium.setEnchantmentForTools(this, 1) - .setEnchantmentForArmors(this, 1); - Materials.Uranium235.setEnchantmentForTools(this, 2) - .setEnchantmentForArmors(this, 2); - Materials.Plutonium241.setEnchantmentForTools(this, 3) - .setEnchantmentForArmors(this, 3); - Materials.NaquadahEnriched.setEnchantmentForTools(this, 4) - .setEnchantmentForArmors(this, 4); - Materials.Naquadria.setEnchantmentForTools(this, 5) - .setEnchantmentForArmors(this, 5); - INSTANCE = this; - } - - @Override - public int getMinEnchantability(int aLevel) { - return Integer.MAX_VALUE; - } - - @Override - public int getMaxEnchantability(int aLevel) { - return 0; - } - - @Override - public int getMaxLevel() { - return 5; - } - - @Override - public boolean canApply(ItemStack itemStack) { - return false; - } - - @Override - public boolean isAllowedOnBooks() { - return false; - } - - @Override - public void func_151367_b(EntityLivingBase aHurtEntity, Entity aDamagingEntity, int aLevel) { - GT_Utility.applyRadioactivity(aHurtEntity, aLevel, 1); - } - - @Override - public String getName() { - return "enchantment.damage.radioactivity"; - } -} diff --git a/src/main/java/gregtech/api/enums/Dyes.java b/src/main/java/gregtech/api/enums/Dyes.java index 3f1bc31c21..1dedcb6af0 100644 --- a/src/main/java/gregtech/api/enums/Dyes.java +++ b/src/main/java/gregtech/api/enums/Dyes.java @@ -7,8 +7,8 @@ import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import gregtech.api.interfaces.IColorModulationContainer; -import gregtech.api.objects.GT_ArrayList; -import gregtech.api.util.GT_Utility; +import gregtech.api.objects.GTArrayList; +import gregtech.api.util.GTUtility; public enum Dyes implements IColorModulationContainer { @@ -50,7 +50,7 @@ public enum Dyes implements IColorModulationContainer { public final short[] mRGBa; public final short[] mOriginalRGBa; public final EnumChatFormatting formatting; - private final ArrayList mFluidDyes = new GT_ArrayList<>(false, 1); + private final ArrayList mFluidDyes = new GTArrayList<>(false, 1); Dyes(int aIndex, int aR, int aG, int aB, String aName) { this(aIndex, aR, aG, aB, aName, EnumChatFormatting.GRAY); @@ -75,7 +75,7 @@ public enum Dyes implements IColorModulationContainer { } public static Dyes get(String aColor) { - Object tObject = GT_Utility.getFieldContent(Dyes.class, aColor, false, false); + Object tObject = GTUtility.getFieldContent(Dyes.class, aColor, false, false); if (tObject instanceof Dyes) return (Dyes) tObject; return _NULL; } diff --git a/src/main/java/gregtech/api/enums/GTNH_ExtraMaterials.java b/src/main/java/gregtech/api/enums/GTNH_ExtraMaterials.java deleted file mode 100644 index b65ac53499..0000000000 --- a/src/main/java/gregtech/api/enums/GTNH_ExtraMaterials.java +++ /dev/null @@ -1,626 +0,0 @@ -package gregtech.api.enums; - -import static gregtech.GT_Mod.GT_FML_LOGGER; - -import gregtech.api.interfaces.IMaterialHandler; - -public class GTNH_ExtraMaterials implements IMaterialHandler { - - public GTNH_ExtraMaterials() { - GT_FML_LOGGER.info("Registering GTNH-Materials (post Java 64kb limit)"); - Materials.add(this); - } - - /** - * This Class is for adding new Materials since Java has a Limiation of 64kb per Method / Class header - */ - public static Materials Signalum = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "Signalum", - "Signalum", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - - public static Materials Lumium = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "Lumium", - "Lumium", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials EnrichedCopper = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "EnrichedCopper", - "Enriched Copper", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials DiamondCopper = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "DiamondCopper", - "Diamond Copper", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials TarPitch = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "TarPitch", - "Tar Pitch", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials LimePure = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 0, - 0, - 255, - 255, - 255, - 0, - "LimePure", - "Pure Lime", - 0, - 0, - -1, - 0, - false, - false, - 1, - 1, - 1, - Dyes.dyeLime); - public static Materials Wimalite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 8, - 255, - 255, - 255, - 0, - "Wimalite", - "Wimalite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes.dyeYellow); - public static Materials Yellorite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 8, - 255, - 255, - 255, - 0, - "Yellorite", - "Yellorite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes.dyeYellow); - public static Materials Quantum = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 0, - 0, - 255, - 255, - 255, - 0, - "Quantum", - "Quantum", - 0, - 0, - -1, - 0, - false, - false, - 1, - 1, - 1, - Dyes.dyeWhite); - public static Materials Turquoise = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1, - 255, - 255, - 255, - 0, - "Turquoise", - "Turquoise", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Tapazite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1, - 255, - 255, - 255, - 0, - "Tapazite", - "Tapazite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes.dyeGreen); - public static Materials Thyrium = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1 | 2 | 8, - 255, - 255, - 255, - 0, - "Thyrium", - "Thyrium", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Tourmaline = new Materials( - -1, - TextureSet.SET_RUBY, - 1.0F, - 0, - 1, - 1, - 255, - 255, - 255, - 0, - "Tourmaline", - "Tourmaline", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Spinel = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 0, - 255, - 255, - 255, - 0, - "Spinel", - "Spinel", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Starconium = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1 | 2 | 8, - 255, - 255, - 255, - 0, - "Starconium", - "Starconium", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Sugilite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1, - 255, - 255, - 255, - 0, - "Sugilite", - "Sugilite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Prismarine = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 4, - 255, - 255, - 255, - 0, - "Prismarine", - "Prismarine", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials GraveyardDirt = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1, - 255, - 255, - 255, - 0, - "GraveyardDirt", - "Graveyard Dirt", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Tennantite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1, - 255, - 255, - 255, - 0, - "Tennantite", - "Tennantite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Fairy = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "Fairy", - "Fairy", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Ludicrite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 1 | 2, - 255, - 255, - 255, - 0, - "Ludicrite", - "Ludicrite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials AquaRegia = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 0, - 255, - 255, - 255, - 0, - "AquaRegia", - "Aqua Regia", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials SolutionBlueVitriol = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 0, - 255, - 255, - 255, - 0, - "SolutionBlueVitriol", - "Blue Vitriol Solution", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials SolutionNickelSulfate = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 2, - 0, - 255, - 255, - 255, - 0, - "SolutionNickelSulfate", - "Nickel Sulfate Solution", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes._NULL); - public static Materials Lodestone = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1 | 8, - 255, - 255, - 255, - 0, - "Lodestone", - "Lodestone", - 0, - 0, - -1, - 0, - false, - false, - 1, - 1, - 1, - Dyes._NULL); - public static Materials Luminite = new Materials( - -1, - TextureSet.SET_NONE, - 1.0F, - 0, - 1, - 1 | 8, - 250, - 250, - 250, - 0, - "Luminite", - "Luminite", - 0, - 0, - -1, - 0, - false, - false, - 3, - 1, - 1, - Dyes.dyeWhite); - - private static void initSubTags() { - SubTag.METAL.addTo(Signalum, Lumium, EnrichedCopper, DiamondCopper); - SubTag.NO_SMASHING.addTo(TarPitch); - } - - @Override - public void onMaterialsInit() { - initSubTags(); - } -} diff --git a/src/main/java/gregtech/api/enums/GTStones.java b/src/main/java/gregtech/api/enums/GTStones.java index 82d7cb90ce..af14301a5d 100644 --- a/src/main/java/gregtech/api/enums/GTStones.java +++ b/src/main/java/gregtech/api/enums/GTStones.java @@ -1,14 +1,14 @@ package gregtech.api.enums; -import gregtech.api.GregTech_API; -import gregtech.common.GT_Worldgen_Stone; +import gregtech.api.GregTechAPI; import gregtech.common.StoneBuilder; +import gregtech.common.WorldgenStone; public enum GTStones { NetherBlackgraniteTiny(new StoneBuilder().name("nether.stone.blackgranite.tiny") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(-1) .size(50) @@ -18,7 +18,7 @@ public enum GTStones { NetherBlackgraniteSmall(new StoneBuilder().name("nether.stone.blackgranite.small") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(-1) .size(100) @@ -28,7 +28,7 @@ public enum GTStones { NetherBlackgraniteMedium(new StoneBuilder().name("nether.stone.blackgranite.medium") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(-1) .size(200) @@ -38,7 +38,7 @@ public enum GTStones { NetherBlackgraniteLarge(new StoneBuilder().name("nether.stone.blackgranite.large") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(-1) .size(300) @@ -48,7 +48,7 @@ public enum GTStones { NetherBlackgraniteHuge(new StoneBuilder().name("nether.stone.blackgranite.huge") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(-1) .size(400) @@ -58,7 +58,7 @@ public enum GTStones { NetherRedgraniteTiny(new StoneBuilder().name("nether.stone.redgranite.tiny") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(-1) .size(50) @@ -68,7 +68,7 @@ public enum GTStones { NetherRedgraniteSmall(new StoneBuilder().name("nether.stone.redgranite.small") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(-1) .size(100) @@ -78,7 +78,7 @@ public enum GTStones { NetherRedgraniteMedium(new StoneBuilder().name("nether.stone.redgranite.medium") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(-1) .size(200) @@ -88,7 +88,7 @@ public enum GTStones { NetherRedgraniteLarge(new StoneBuilder().name("nether.stone.redgranite.large") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(-1) .size(300) @@ -98,7 +98,7 @@ public enum GTStones { NetherRedgraniteHuge(new StoneBuilder().name("nether.stone.redgranite.huge") .disabledByDefault() - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(-1) .size(400) @@ -108,7 +108,7 @@ public enum GTStones { NetherMarbleTiny(new StoneBuilder().name("nether.stone.marble.tiny") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(-1) .size(50) @@ -118,7 +118,7 @@ public enum GTStones { NetherMarbleSmall(new StoneBuilder().name("nether.stone.marble.small") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(-1) .size(100) @@ -128,7 +128,7 @@ public enum GTStones { NetherMarbleMedium(new StoneBuilder().name("nether.stone.marble.medium") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(-1) .size(200) @@ -138,7 +138,7 @@ public enum GTStones { NetherMarbleLarge(new StoneBuilder().name("nether.stone.marble.large") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(-1) .size(300) @@ -148,7 +148,7 @@ public enum GTStones { NetherMarbleHuge(new StoneBuilder().name("nether.stone.marble.huge") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(-1) .size(400) @@ -158,7 +158,7 @@ public enum GTStones { NetherBasaltTiny(new StoneBuilder().name("nether.stone.basalt.tiny") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(-1) .size(50) @@ -168,7 +168,7 @@ public enum GTStones { NetherBasaltSmall(new StoneBuilder().name("nether.stone.basalt.small") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(-1) .size(100) @@ -178,7 +178,7 @@ public enum GTStones { NetherBasaltMedium(new StoneBuilder().name("nether.stone.basalt.medium") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(-1) .size(200) @@ -188,7 +188,7 @@ public enum GTStones { NetherBasaltLarge(new StoneBuilder().name("nether.stone.basalt.large") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(-1) .size(300) @@ -198,7 +198,7 @@ public enum GTStones { NetherBasaltHuge(new StoneBuilder().name("nether.stone.basalt.huge") .disabledByDefault() - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(-1) .size(400) @@ -206,7 +206,7 @@ public enum GTStones { .heightRange(0, 120) .generationInVoidEnabled(false)), OverworldBlackgraniteTiny(new StoneBuilder().name("overworld.stone.blackgranite.tiny") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(0) .size(75) @@ -215,7 +215,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBlackgraniteSmall(new StoneBuilder().name("overworld.stone.blackgranite.small") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(0) .size(100) @@ -224,7 +224,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBlackgraniteMedium(new StoneBuilder().name("overworld.stone.blackgranite.medium") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(0) .size(200) @@ -233,7 +233,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBlackgraniteLarge(new StoneBuilder().name("overworld.stone.blackgranite.large") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(0) .size(300) @@ -242,7 +242,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBlackgraniteHuge(new StoneBuilder().name("overworld.stone.blackgranite.huge") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(0) .dimension(0) .size(400) @@ -251,7 +251,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldRedgraniteTiny(new StoneBuilder().name("overworld.stone.redgranite.tiny") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(0) .size(75) @@ -260,7 +260,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldRedgraniteSmall(new StoneBuilder().name("overworld.stone.redgranite.small") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(0) .size(100) @@ -269,7 +269,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldRedgraniteMedium(new StoneBuilder().name("overworld.stone.redgranite.medium") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(0) .size(200) @@ -278,7 +278,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldRedgraniteLarge(new StoneBuilder().name("overworld.stone.redgranite.large") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(0) .size(300) @@ -287,7 +287,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldRedgraniteHuge(new StoneBuilder().name("overworld.stone.redgranite.huge") - .block(GregTech_API.sBlockGranites) + .block(GregTechAPI.sBlockGranites) .blockMeta(8) .dimension(0) .size(400) @@ -296,7 +296,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldMarbleTiny(new StoneBuilder().name("overworld.stone.marble.tiny") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(0) .size(75) @@ -305,7 +305,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldMarbleSmall(new StoneBuilder().name("overworld.stone.marble.small") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(0) .size(100) @@ -314,7 +314,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldMarbleMedium(new StoneBuilder().name("overworld.stone.marble.medium") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(0) .size(200) @@ -323,7 +323,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldMarbleLarge(new StoneBuilder().name("overworld.stone.marble.large") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(0) .size(300) @@ -332,7 +332,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldMarbleHuge(new StoneBuilder().name("overworld.stone.marble.huge") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(0) .dimension(0) .size(400) @@ -341,7 +341,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBasaltTiny(new StoneBuilder().name("overworld.stone.basalt.tiny") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(0) .size(75) @@ -350,7 +350,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBasaltSmall(new StoneBuilder().name("overworld.stone.basalt.small") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(0) .size(100) @@ -359,7 +359,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBasaltMedium(new StoneBuilder().name("overworld.stone.basalt.medium") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(0) .size(200) @@ -368,7 +368,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBasaltLarge(new StoneBuilder().name("overworld.stone.basalt.large") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(0) .size(300) @@ -377,7 +377,7 @@ public enum GTStones { .generationInVoidEnabled(false)), OverworldBasaltHuge(new StoneBuilder().name("overworld.stone.basalt.huge") - .block(GregTech_API.sBlockStones) + .block(GregTechAPI.sBlockStones) .blockMeta(8) .dimension(0) .size(400) @@ -391,8 +391,8 @@ public enum GTStones { this.stone = stone; } - public GT_Worldgen_Stone addGTStone() { - return new GT_Worldgen_Stone(this.stone); + public WorldgenStone addGTStone() { + return new WorldgenStone(this.stone); } } diff --git a/src/main/java/gregtech/api/enums/GTValues.java b/src/main/java/gregtech/api/enums/GTValues.java new file mode 100644 index 0000000000..eaca14b3ee --- /dev/null +++ b/src/main/java/gregtech/api/enums/GTValues.java @@ -0,0 +1,721 @@ +package gregtech.api.enums; + +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.AQUA; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.BOLD; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.DARK_AQUA; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.OBFUSCATED; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.RESET; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.animatedText; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.chain; +import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.text; +import static gregtech.api.enums.Mods.GregTech; +import static gregtech.api.enums.Mods.IndustrialCraft2; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Supplier; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.oredict.OreDictionary; + +import gregtech.api.fluid.GTFluidTank; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.internal.IGTMod; +import gregtech.api.interfaces.internal.IGTRecipeAdder; +import gregtech.api.net.IGT_NetworkHandler; +import gregtech.api.util.GTChunkAssociatedData; + +/** + * Made for static imports, this Class is just a Helper. + *

+ * I am doing this to have a better Table alike view on my Code, so I can change things faster using the Block Selection + * Mode of eclipse. + *

+ * Go to "Window > Preferences > Java > Editor > Content Assist > Favorites" to set static importable Constant Classes + * such as this one as AutoCompleteable. + */ +@SuppressWarnings("unused") // API Legitimately has unused fields and methods +public class GTValues { + // unused: A, C, D, G, H, I, J, K, N, O, Q, R, S, T + + // TODO: Rename Material Units to 'U' + // TODO: Rename OrePrefixes Class to 'P' + // TODO: Rename Materials Class to 'M' + + /** + * Empty String for an easier Call Hierarchy + */ + public static final String E = ""; + + /** + * The first 32 Bits + */ + @SuppressWarnings("PointlessBitwiseExpression") // Nicer source layout this way + public static final int[] B = new int[] { 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8, + 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, + 1 << 21, 1 << 22, 1 << 23, 1 << 24, 1 << 25, 1 << 26, 1 << 27, 1 << 28, 1 << 29, 1 << 30, 1 << 31 }; + + /** + * Renamed from "MATERIAL_UNIT" to just "M" + *

+ * This is worth exactly one normal Item. This Constant can be divided by many commonly used Numbers such as 1, 2, + * 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, ... 64 or 81 without losing precision and is for that + * reason used as Unit of Amount. But it is also small enough to be multiplied with larger Numbers. + *

+ * This is used to determine the amount of Material contained inside a prefixed Ore. For example Nugget = M / 9 as + * it contains out of 1/9 of an Ingot. + */ + public static final long M = 3628800; + + /** + * Renamed from "FLUID_MATERIAL_UNIT" to just "L" + *

+ * Fluid per Material Unit (Prime Factors: 3 * 3 * 2 * 2 * 2 * 2) + */ + public static final long L = 144; + + /** + * The Item WildCard Tag. Even shorter than the "-1" of the past + */ + public static final short W = OreDictionary.WILDCARD_VALUE; + + /** + * The Voltage Tiers. Use this Array instead of the old named Voltage Variables + */ + public static final long[] V = new long[] { 8L, 32L, 128L, 512L, 2048L, 8192L, 32_768L, 131_072L, 524_288L, + 2_097_152L, 8_388_608L, 33_554_432L, 134_217_728L, 536_870_912L, Integer.MAX_VALUE - 7, + // Error tier to prevent out of bounds errors. Not really a real tier (for now). + 8_589_934_592L }; + + /** + * The Voltage Practical. These are recipe voltage you should use if you expect the recipe to use a full amp of that + * tier. These leave a bit of headroom for cable and transformer losses, but not enough to make it a great gain. + */ + // this will correctly map ULV to 7. + public static final long[] VP = Arrays.stream(V) + .map( + i -> BigInteger.valueOf(i) + .multiply(BigInteger.valueOf(30)) + .divide(BigInteger.valueOf(32)) + .longValueExact()) + .toArray(); + // TODO:Adding that in coremod!!! + // TODO:tier 14,15 wires and transformers only (not even cables !!!) + // TODO:tier 12,13 the above + batteries, battery buffers, (maybe cables,12 also works for machines) + // TODO:tier 10,11 the above + chargers and other machines, (cables would be nice) + // TODO:tier 9 machines and batteries + + // TODO:AND ALL THE MATERIALS... for that + // TODO:LIST OF MACHINES WITH POINTLESS TIERS (unless you implement some other tiering mechanism like reducing eu + // cost if time=1tick) + // Macerator/Compressor/Furnace... and for cheap recipes any + + /** + * Array of Maximum Amperes at given Tier index + *

+ * keeping Voltage*Amps < Integer.MAX_VALUE-7 for machines (and tier logic 4x EUt 2/ time) + *

+ *

+ * AMV[4]= max amps at tier 4 + *

+ */ + public static final long[] AatV = new long[] { 268435455, 67108863, 16777215, 4194303, 1048575, 262143, 65535, + 16383, 4095, 1023, 255, 63, 15, 3, 1, 1 }; + /** + * The short Names for the Voltages + */ + public static final String[] VN = new String[] { "ULV", // 0 + "LV", // 1 + "MV", // 2 + "HV", // 3 + "EV", // 4 + "IV", // 5 + "LuV", // 6 + "ZPM", // 7 + "UV", // 8 + "UHV", // 9 + "UEV", // 10 + "UIV", // 11 + "UMV", // 12 + "UXV", // 13 + "MAX", // 14 + "MAX+" // 15 + }; + + /** + * The long Names for the Voltages + */ + public static final String[] VOLTAGE_NAMES = new String[] { "Ultra Low Voltage", // 0 + "Low Voltage", // 1 + "Medium Voltage", // 2 + "High Voltage", // 3 + "Extreme Voltage", // 4 + "Insane Voltage", // 5 + "Ludicrous Voltage", // 6 + "ZPM Voltage", // 7 + "Ultimate Voltage", // 8 + "Ultimate High Voltage", // 9 + "Ultimate Extreme Voltage", // 10 + "Ultimate Insane Voltage", // 11 + "Ultimate Mega Voltage", // 12 + "Ultimate Extended Mega Voltage", // 13 + "Maximum Voltage", // 14 + "Error Voltage, report this" // 15 + }; + + public static final String[] TIER_COLORS = new String[] { EnumChatFormatting.RED.toString(), // ULV, 0 + EnumChatFormatting.GRAY.toString(), // LV, 1 + EnumChatFormatting.GOLD.toString(), // MV, 2 + EnumChatFormatting.YELLOW.toString(), // HV, 3 + EnumChatFormatting.DARK_GRAY.toString(), // EV, 4 + EnumChatFormatting.GREEN.toString(), // IV, 5 + EnumChatFormatting.LIGHT_PURPLE.toString(), // LuV, 6 + EnumChatFormatting.AQUA.toString(), // ZPM, 7 + EnumChatFormatting.DARK_GREEN.toString(), // UV, 8 + EnumChatFormatting.DARK_RED.toString(), // UHV, 9 + EnumChatFormatting.DARK_PURPLE.toString(), // UEV, 10 + EnumChatFormatting.DARK_BLUE.toString() + EnumChatFormatting.BOLD, // UIV, 11 + EnumChatFormatting.RED.toString() + EnumChatFormatting.BOLD + EnumChatFormatting.UNDERLINE, // UMV, 12 + EnumChatFormatting.DARK_RED.toString() + EnumChatFormatting.BOLD + EnumChatFormatting.UNDERLINE, // UXV, 13 + EnumChatFormatting.WHITE.toString() + EnumChatFormatting.BOLD + EnumChatFormatting.UNDERLINE, // MAX, 14 + EnumChatFormatting.WHITE.toString() + EnumChatFormatting.BOLD + + EnumChatFormatting.UNDERLINE + + EnumChatFormatting.ITALIC, // MAX+, 15 + }; + + /** + * This way it is possible to have a Call Hierarchy of NullPointers in ItemStack based Functions, and also because + * most of the time I don't know what kind of Data Type the "null" stands for + */ + public static final ItemStack NI = null; + /** + * This way it is possible to have a Call Hierarchy of NullPointers in FluidStack based Functions, and also because + * most of the time I don't know what kind of Data Type the "null" stands for + */ + public static final FluidStack NF = null; + + /** + * File Paths and Resource Paths + */ + @Deprecated + public static final String TEX_DIR = "textures/"; + @Deprecated + public static final String RES_PATH = GregTech.getResourcePath(TEX_DIR); + @Deprecated + public static final String RES_PATH_GUI = GregTech.getResourcePath("textures", "gui/"); + @Deprecated + public static final String RES_PATH_ITEM = GregTech.getResourcePath(); + @Deprecated + public static final String RES_PATH_BLOCK = GregTech.getResourcePath(); + @Deprecated + public static final String RES_PATH_ENTITY = GregTech.getResourcePath("textures", "entity/"); + @Deprecated + public static final String RES_PATH_ASPECTS = GregTech.getResourcePath("textures", "aspects/"); + @Deprecated + public static final String RES_PATH_MODEL = GregTech.getResourcePath("textures", "models/"); + @Deprecated + public static final String RES_PATH_IC2 = IndustrialCraft2.getResourcePath(); + + /** + * NBT String Keys + */ + public static final class NBT { + + public static final String COLOR = "gt.color", // Integer + COVERS = "gt.covers", // String + CUSTOM_NAME = "name", // String + DISPLAY = "gt.display", // String + TIER = "gt.tier", // Number + FACING = "gt.facing", // Byte + LOCK_UPGRADE = "gt.locked", // Boolean + MATERIAL = "gt.material", // String containing the Material Name. + MODE = "gt.mode", // Number + ALLOWED_MODES = "gt.amode", // Number + MTE_ID = "gt.mte.id", // Containing the MTE ID + MTE_REG = "gt.mte.reg", // Containing the MTE Registry ID + OWNER = "gt.owner", // String + OWNER_UUID = "gt.ownerUuid", // UUID (String) + + // Machines + ACTIVE = "gt.active", // Boolean + FLUID_OUT = "gt.fluidout", // Output Fluid + ITEM_OUT = "gt.itemout", // Output Item + PARALLEL = "gt.parallel", // Number + TANK_CAPACITY = "gt.tankcap", // Number + TANK_IN = "gt.tank.in.", // FluidStack + TANK_OUT = "gt.tank.out.", // FluidStack + TEXTURE_FOLDER = "gt.texture.folder", // String + INV_INPUT_SIZE = "gt.invsize.in", // Number + INV_OUTPUT_SIZE = "gt.invsize.out", // Number + INV_INPUT_LIST = "gt.invlist.in", // NBT List + INV_OUTPUT_LIST = "gt.invlist.out", // NBT List + VOLTAGE = "gt.voltage", // Number + AMPERAGE = "gt.amperage", // Number + STORED_ENERGY = "gt.stored.energy", // Number + MAXIMUM_ENERGY = "gt.maximum.energy", // Number + EUT_CONSUMPTION = "gt.eut.consumption", // Number + BURN_TIME_LEFT = "gt.burn.time.left", // Number + TOTAL_BURN_TIME = "gt.total.burn.time", // Number + ALLOWED_WORK = "gt.allowed.work", // Boolean + TASKS = "gt.tasks", // Compound + + // MultiBlock + STRUCTURE_OK = "gt.structure.ok", ROTATION = "gt.eRotation", FLIP = "gt.eFlip", TARGET = "gt.target", // Boolean + TARGET_X = "gt.target.x", // Number + TARGET_Y = "gt.target.y", // Number + TARGET_Z = "gt.target.z", // Number + LOCKED_FLUID = "gt.locked.fluid", // String + LOCKED_INVENTORY = "gt.locked.inv", // String + LOCKED_INVENTORY_INDEX = "gt.locked.inv.index", // Number + UPGRADE_INVENTORY_SIZE = "gt.invsize.upg", // String + UPGRADE_INVENTORY_UUID = "gt.invuuid.upg", // String + UPGRADE_INVENTORY_NAME = "gt.invname.upg", // String + UPGRADE_INVENTORIES_INPUT = "gt.invlist.upg.in", // NBT List + UPGRADE_INVENTORIES_OUTPUT = "gt.invlist.upg.out", // NBT List + UPGRADE_TANK_CAPACITY = "gt.tank.cap.upg", // Long + UPGRADE_TANK_COUNT = "gt.tank.ct.upg", // Int + UPGRADE_TANK_CAPACITY_MULTIPLIER = "gt.tank.cap.mult.upg", // Long + UPGRADE_TANK_UUID = "gt.tankuuid.upg", // String + UPGRADE_TANK_NAME = "gt.tankname.upg", // String + UPGRADE_TANKS_INPUT = "gt.tanklist.upg.in", // NBT List + UPGRADE_TANKS_OUTPUT = "gt.tanklist.upg.out", // NBT List + UPGRADE_TANKS_PREFIX = "gt.tank.upg", // NBT Tag + UPGRADE_AMPERAGE = "gt.amp.upg", // Long + SEPARATE_INPUTS = "gt.separate.inputs", // Boolean + VOIDING_MODE = "gt.voiding.mode", // String + BATCH_MODE = "gt.batch.mode", // Boolean + RECIPE_LOCK = "gt.recipe.lock", // Boolean + + // Logic + POWER_LOGIC = "gt.pow.logic", // NBT Tag + POWER_LOGIC_STORED_ENERGY = "gt.pow.energy", // Number + POWER_LOGIC_ENERGY_CAPACITY = "gt.pow.energy.cap", // Number + POWER_LOGIC_VOLTAGE = "gt.pow.volt", // Number + POWER_LOGIC_AMPERAGE = "gt.pow.amp", // Number + POWER_LOGIC_TYPE = "gt.pow.type", // Number + empty_ = ""; + } + + /** The Color White as RGB Short Array. */ + public static final short[] UNCOLORED_RGBA = { 255, 255, 255, 255 }; + /** The Color White as simple Integer (0x00ffffff). */ + public static final int UNCOLORED = 0x00ffffff; + + /** + * Sides + */ + public static final byte SIDE_BOTTOM = 0, SIDE_DOWN = 0, SIDE_TOP = 1, SIDE_UP = 1, SIDE_NORTH = 2, // Also a Side + // with a + // stupidly + // mirrored + // Texture + SIDE_SOUTH = 3, SIDE_WEST = 4, SIDE_EAST = 5, // Also a Side with a stupidly mirrored Texture + SIDE_ANY = 6, SIDE_UNKNOWN = 6, SIDE_INVALID = 6, SIDE_INSIDE = 6, SIDE_UNDEFINED = 6; + + /** Compass alike Array for the proper ordering of North, East, South and West. */ + public static final byte[] COMPASS_DIRECTIONS = { SIDE_NORTH, SIDE_EAST, SIDE_SOUTH, SIDE_WEST }; + + /** + * An Array containing all Sides which follow the Condition, in order to iterate over them for example. + */ + public static final byte[] ALL_SIDES = { 0, 1, 2, 3, 4, 5, 6 }, ALL_VALID_SIDES = { 0, 1, 2, 3, 4, 5 }; + + /** + * For Facing Checks. + */ + public static final boolean[] INVALID_SIDES = { false, false, false, false, false, false, true }, + VALID_SIDES = { true, true, true, true, true, true, false }; + + /** + * Side->Offset Mappings. + */ + public static final byte[] OFFX = { 0, 0, 0, 0, -1, +1, 0 }, OFFY = { -1, +1, 0, 0, 0, 0, 0 }, + OFFZ = { 0, 0, -1, +1, 0, 0, 0 }; + + /** + * Side->Opposite Mappings. + **/ + public static final byte[] OPOS = { 1, 0, 3, 2, 5, 4, 6 }; + + /** + * [Facing,Side]->Side Mappings for Blocks, which don't face up- and downwards. 0 = bottom, 1 = top, 2 = left, 3 = + * front, 4 = right, 5 = back, 6 = undefined. + */ + public static final byte[][] FACING_ROTATIONS = { { 0, 1, 2, 3, 4, 5, 6 }, { 0, 1, 2, 3, 4, 5, 6 }, + { 0, 1, 3, 5, 4, 2, 6 }, { 0, 1, 5, 3, 2, 4, 6 }, { 0, 1, 2, 4, 3, 5, 6 }, { 0, 1, 4, 2, 5, 3, 6 }, + { 0, 1, 2, 3, 4, 5, 6 } }; + + /** + * The Mod Object itself. That is the GTMod-Object. It's needed to open GUI's and similar. + */ + public static IGTMod GT; + /** + * Use this Object to add Recipes. (Recipe Adder) + */ + public static IGTRecipeAdder RA; + /** + * For Internal Usage (Network) + */ + public static IGT_NetworkHandler NW; + /** + * Control percentage of filled 3x3 chunks. Lower number means less oreveins spawn + */ + public static int oreveinPercentage; + /** + * Control number of attempts to find a valid orevein. Generally this maximum limit isn't hit, selecting a vein is + * cheap + */ + public static int oreveinAttempts; + /** + * Control number of attempts to place a valid ore vein. + *

+ * If a vein wasn't placed due to height restrictions, completely in the water, etc, another attempt is tried. + *

+ */ + public static int oreveinMaxPlacementAttempts; + /** + * Whether to place small ores as placer ores for an orevein + */ + public static boolean oreveinPlacerOres; + /** + * Multiplier to control how many placer ores get generated. + */ + public static int oreveinPlacerOresMultiplier; + /** + * Not really Constants, but they set using the Config and therefore should be constant (those are for the Debug + * Mode) + */ + public static boolean D1 = false, D2 = false; + /** + * Debug parameter for cleanroom testing. + */ + public static boolean debugCleanroom = false; + /** + * Debug parameter for driller testing. + */ + public static boolean debugDriller = false; + /** + * Debug parameter for world generation. Tracks chunks added/removed from run queue. + */ + public static boolean debugWorldGen = false; + /** + * Debug parameter for orevein generation. + */ + public static boolean debugOrevein = false; + /** + * Debug parameter for small ore generation. + */ + public static boolean debugSmallOres = false; + /** + * Debug parameter for stones generation. + */ + public static boolean debugStones = false; + /** + * Debug parameter for single block pump + */ + public static boolean debugBlockPump = false; + /** + * Debug parameter for single block miner + */ + public static boolean debugBlockMiner = false; + /** + * Debug parameter for entity cramming reduction + */ + public static boolean debugEntityCramming = false; + /** + * Debug parameter for {@link GTChunkAssociatedData} + */ + public static boolean debugWorldData = false; + /** + * Parameter if multi tile entities (MuTEs) should be enabled in the pack. Turned off by default until + * implementation is done. + */ + public static boolean enableMultiTileEntities = false; + /** + * Number of ticks between sending sound packets to clients for electric machines. Default is 1.5 seconds. Trying to + * mitigate lag and FPS drops. + */ + public static int ticksBetweenSounds = 30; + /** + * If you have to give something a World Parameter but there is no World... (Dummy World) + */ + public static World DW; + + /** + * This will prevent NEI from crashing but spams the Log. + */ + public static boolean allow_broken_recipemap = false; + /** + * This will set the blacklist for the world accelerator in TE mode. + */ + public static String[] blacklistedTileEntiyClassNamesForWA = new String[] { + "com.rwtema.extrautils.tileentity.enderquarry.TileEntityEnderQuarry", + "advsolar.common.tiles.TileEntityUltimateSolarPanel", "advsolar.common.tiles.TileEntitySolarPanel", + "advsolar.common.tiles.TileEntityQuantumSolarPanel", "advsolar.common.tiles.TileEntityHybridSolarPanel", + "advsolar.common.tiles.TileEntityAdvancedSolarPanel", "com.supsolpans.tiles.TileAdminSolarPanel", + "com.supsolpans.tiles.TilePhotonicSolarPanel", "com.supsolpans.tiles.TileSingularSolarPanel", + "com.supsolpans.tiles.TileSpectralSolarPanel", "emt.tile.solar.air.TileEntityAirSolar", + "emt.tile.solar.air.TileEntityDoubleAirSolar", "emt.tile.solar.air.TileEntityTripleAirSolar", + "emt.tile.solar.air.TileEntityQuadrupleAirSolar", "emt.tile.solar.air.TileEntityQuintupleAirSolar", + "emt.tile.solar.air.TileEntitySextupleAirSolar", "emt.tile.solar.air.TileEntitySeptupleAirSolar", + "emt.tile.solar.air.TileEntityOctupleAirSolar", "emt.tile.solar.compressed.TileEntityCompressedSolar", + "emt.tile.solar.compressed.TileEntityDoubleCompressedSolar", + "emt.tile.solar.compressed.TileEntityTripleCompressedSolar", + "emt.tile.solar.compressed.TileEntityQuadrupleAirSolar", + "emt.tile.solar.compressed.TileEntityQuintupleAirSolar", "emt.tile.solar.compressed.TileEntitySextupleAirSolar", + "emt.tile.solar.compressed.TileEntitySeptupleAirSolar", "emt.tile.solar.compressed.TileEntityOctupleAirSolar", + "emt.tile.solar.dark.TileEntityDarkSolar", "emt.tile.solar.dark.TileEntityDoubleDarkSolar", + "emt.tile.solar.dark.TileEntityTripleDarkSolar", "emt.tile.solar.dark.TileEntityQuadrupleAirSolar", + "emt.tile.solar.dark.TileEntityQuintupleAirSolar", "emt.tile.solar.dark.TileEntitySextupleAirSolar", + "emt.tile.solar.dark.TileEntitySeptupleAirSolar", "emt.tile.solar.dark.TileEntityOctupleAirSolar", + "emt.tile.solar.earth.TileEntityDoubleEarthSolar", "emt.tile.solar.earth.TileEntityEarthSolar", + "emt.tile.solar.earth.TileEntityTripleEarthSolar", "emt.tile.solar.earth.TileEntityQuadrupleAirSolar", + "emt.tile.solar.earth.TileEntityQuintupleAirSolar", "emt.tile.solar.earth.TileEntitySextupleAirSolar", + "emt.tile.solar.earth.TileEntitySeptupleAirSolar", "emt.tile.solar.earth.TileEntityOctupleAirSolar", + "emt.tile.solar.fire.TileEntityDoubleFireSolar", "emt.tile.solar.fire.TileEntityFireSolar", + "emt.tile.solar.fire.TileEntityTripleFireSolar", "emt.tile.solar.fire.TileEntityQuadrupleAirSolar", + "emt.tile.solar.fire.TileEntityQuintupleAirSolar", "emt.tile.solar.fire.TileEntitySextupleAirSolar", + "emt.tile.solar.fire.TileEntitySeptupleAirSolar", "emt.tile.solar.fire.TileEntityOctupleAirSolar", + "emt.tile.solar.order.TileEntityDoubleOrderSolar", "emt.tile.solar.order.TileEntityOrderSolar", + "emt.tile.solar.order.TileEntityTripleOrderSolar", "emt.tile.solar.order.TileEntityQuadrupleAirSolar", + "emt.tile.solar.order.TileEntityQuintupleAirSolar", "emt.tile.solar.order.TileEntitySextupleAirSolar", + "emt.tile.solar.order.TileEntitySeptupleAirSolar", "emt.tile.solar.order.TileEntityOctupleAirSolar", + "emt.tile.solar.water.TileEntityDoubleWaterSolar", "emt.tile.solar.water.TileEntityTripleWaterSolar", + "emt.tile.solar.water.TileEntityWaterSolar", "emt.tile.solar.water.TileEntityQuadrupleAirSolar", + "emt.tile.solar.water.TileEntityQuintupleAirSolar", "emt.tile.solar.water.TileEntitySextupleAirSolar", + "emt.tile.solar.water.TileEntitySeptupleAirSolar", "emt.tile.solar.water.TileEntityOctupleAirSolar", + "com.lulan.compactkineticgenerators.tileentity.TileCkgE", + "com.lulan.compactkineticgenerators.tileentity.TileCkgH", + "com.lulan.compactkineticgenerators.tileentity.TileCkgL", + "com.lulan.compactkineticgenerators.tileentity.TileCkgM", + "com.lulan.compactkineticgenerators.tileentity.TileCkwaE", + "com.lulan.compactkineticgenerators.tileentity.TileCkwaH", + "com.lulan.compactkineticgenerators.tileentity.TileCkwaL", + "com.lulan.compactkineticgenerators.tileentity.TileCkwaM", + "com.lulan.compactkineticgenerators.tileentity.TileCkwmE", + "com.lulan.compactkineticgenerators.tileentity.TileCkwmH", + "com.lulan.compactkineticgenerators.tileentity.TileCkwmL", + "com.lulan.compactkineticgenerators.tileentity.TileCkwmM", "com.supsolpans.tiles.TileSpectralSolarPanel", + "com.supsolpans.tiles.TileSingularSolarPanel", "com.supsolpans.tiles.TileAdminSolarPanel", + "com.supsolpans.tiles.TilePhotonicSolarPanel", "gtPlusPlus.core.tileentities.general.TileEntityFishTrap", + "gtPlusPlus.core.tileentities.general.TileEntityDecayablesChest", + "net.bdew.gendustry.machines.apiary.TileApiary", "goodgenerator.blocks.tileEntity.EssentiaHatch", + "magicbees.tileentity.TileEntityApimancersDrainerCommon", + "magicbees.tileentity.TileEntityApimancersDrainerGT" }; + /** + * This will set the percentage how much ReinforcedGlass is Allowed in Cleanroom Walls. + */ + public static float cleanroomGlass = 5.0f; + /** + * This will let machines such as drills and pumps chunkload their work area. + */ + public static boolean enableChunkloaders = true; + /** + * This will make all chunkloading machines act as World Anchors (true) or Passive Anchors (false) + */ + public static boolean alwaysReloadChunkloaders = false; + + public static boolean debugChunkloaders = false; + public static boolean cls_enabled; + public static final Set mCTMEnabledBlock = new HashSet<>(); + public static final Set mCTMDisabledBlock = new HashSet<>(); + + public static final int STEAM_PER_WATER = 160; + /** + * If true, then digital chest with AE2 storage bus will be accessible only through AE2 + */ + public static boolean disableDigitalChestsExternalAccess = false; + + public static boolean lateConfigSave = true; + public static boolean worldTickHappened = false; + + public static final int[] emptyIntArray = new int[0]; + + public static final IFluidTank[] emptyFluidTank = new IFluidTank[0]; + public static final GTFluidTank[] emptyFluidTankGT = new GTFluidTank[0]; + public static final FluidTankInfo[] emptyFluidTankInfo = new FluidTankInfo[0]; + public static final FluidStack[] emptyFluidStack = new FluidStack[0]; + public static final ItemStack[] emptyItemStackArray = new ItemStack[0]; + public static final IIconContainer[] emptyIconContainerArray = new IIconContainer[3]; + + /** + * Pretty formatting for author names. + */ + public static final String Colen = "" + EnumChatFormatting.DARK_RED + + EnumChatFormatting.BOLD + + EnumChatFormatting.ITALIC + + EnumChatFormatting.UNDERLINE + + "C" + + EnumChatFormatting.GOLD + + EnumChatFormatting.BOLD + + EnumChatFormatting.ITALIC + + EnumChatFormatting.UNDERLINE + + "o" + + EnumChatFormatting.GREEN + + EnumChatFormatting.BOLD + + EnumChatFormatting.ITALIC + + EnumChatFormatting.UNDERLINE + + "l" + + EnumChatFormatting.DARK_AQUA + + EnumChatFormatting.BOLD + + EnumChatFormatting.ITALIC + + EnumChatFormatting.UNDERLINE + + "e" + + EnumChatFormatting.DARK_PURPLE + + EnumChatFormatting.BOLD + + EnumChatFormatting.ITALIC + + EnumChatFormatting.UNDERLINE + + "n"; + + public static final String AuthorColen = "Author: " + Colen; + public static final String AuthorKuba = "Author: " + EnumChatFormatting.DARK_RED + + EnumChatFormatting.BOLD + + "k" + + EnumChatFormatting.RED + + EnumChatFormatting.BOLD + + "u" + + EnumChatFormatting.GOLD + + EnumChatFormatting.BOLD + + "b" + + EnumChatFormatting.YELLOW + + EnumChatFormatting.BOLD + + "a" + + EnumChatFormatting.DARK_GREEN + + EnumChatFormatting.BOLD + + "6" + + EnumChatFormatting.GREEN + + EnumChatFormatting.BOLD + + "0" + + EnumChatFormatting.AQUA + + EnumChatFormatting.BOLD + + "0" + + EnumChatFormatting.DARK_AQUA + + EnumChatFormatting.BOLD + + "0"; + + public static final String AuthorBlueWeabo = "Author: " + EnumChatFormatting.BLUE + + EnumChatFormatting.BOLD + + "Blue" + + EnumChatFormatting.AQUA + + EnumChatFormatting.BOLD + + "Weabo"; + + public static final String Authorminecraft7771 = "Author: " + EnumChatFormatting.BLUE + + EnumChatFormatting.LIGHT_PURPLE + + "minecraft7771"; + + public static final Supplier AuthorCloud = chain( + text("Author: " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD), + animatedText( + "C", + 1, + 500, + DARK_AQUA + OBFUSCATED + BOLD + "X" + RESET + AQUA + BOLD, + DARK_AQUA + "\u238B" + RESET + AQUA + BOLD, + DARK_AQUA + OBFUSCATED + BOLD + "X" + RESET + AQUA + BOLD, + DARK_AQUA + "\u0B83" + RESET + AQUA + BOLD, + DARK_AQUA + OBFUSCATED + BOLD + "X" + RESET + AQUA + BOLD, + DARK_AQUA + BOLD + "\u29BC" + RESET + AQUA + BOLD), + text(EnumChatFormatting.AQUA + EnumChatFormatting.BOLD.toString() + "loud" + EnumChatFormatting.RESET), + animatedText( + " ", + 1, + 500, + DARK_AQUA + OBFUSCATED + BOLD + "X", + DARK_AQUA + "\u238B", + DARK_AQUA + OBFUSCATED + BOLD + "X", + DARK_AQUA + "\u0B83", + DARK_AQUA + OBFUSCATED + BOLD + "X", + DARK_AQUA + BOLD + "\u29BC")); + + public static final String AuthorQuerns = "Author: " + EnumChatFormatting.RED + "Querns"; + public static final String AuthorSilverMoon = "Author: " + EnumChatFormatting.AQUA + "SilverMoon"; + public static final String AuthorTheEpicGamer274 = "Author: " + "TheEpicGamer274"; + public static final String AuthorFourIsTheNumber = "Author: " + EnumChatFormatting.LIGHT_PURPLE + + EnumChatFormatting.ITALIC + + "Four" + + EnumChatFormatting.WHITE + + EnumChatFormatting.ITALIC + + "Is" + + EnumChatFormatting.LIGHT_PURPLE + + EnumChatFormatting.ITALIC + + "The" + + EnumChatFormatting.WHITE + + EnumChatFormatting.ITALIC + + "Number"; + public static final String Ollie = "" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Ollie"; + public static final String authorBaps = "Author: " + EnumChatFormatting.GOLD + + "Ba" + + EnumChatFormatting.LIGHT_PURPLE + + "ps"; + + public static final String AuthorEvgenWarGold = "" + EnumChatFormatting.RED + + EnumChatFormatting.BOLD + + "Evgen" + + EnumChatFormatting.BLUE + + EnumChatFormatting.BOLD + + "War" + + EnumChatFormatting.GOLD + + EnumChatFormatting.BOLD + + "Gold"; + public static final String AuthorVolence = "Author: " + EnumChatFormatting.AQUA + "Volence"; + + public static final String AuthorEigenRaven = "Author: " + EnumChatFormatting.DARK_PURPLE + + "Eigen" + + EnumChatFormatting.BOLD + + "Raven"; + + public static final String AuthorNotAPenguin = "Author: " + EnumChatFormatting.WHITE + + EnumChatFormatting.BOLD + + "Not" + + EnumChatFormatting.AQUA + + EnumChatFormatting.BOLD + + "APenguin"; + + // 7.5F comes from GT_Tool_Turbine_Large#getBaseDamage() given huge turbines are the most efficient now. + public static double getMaxPlasmaTurbineEfficiencyFromMaterial(Materials material) { + return (5F + (7.5F + material.mToolQuality)) / 10.0; + } + + // Called once in GT_Client on world load, has to be called late so that Materials is populated. + public static void calculateMaxPlasmaTurbineEfficiency() { + + ArrayList effArray = new ArrayList<>(); + + // Iteration seems to work but need to check turbine as all items appear null. + for (Materials material : Materials.values()) { + effArray.add(getMaxPlasmaTurbineEfficiencyFromMaterial(material)); + } + + maxPlasmaTurbineEfficiency = Collections.max(effArray); + } + + private static double maxPlasmaTurbineEfficiency; + + public static double getMaxPlasmaTurbineEfficiency() { + return maxPlasmaTurbineEfficiency; + } + + private static final long[] EXPLOSION_LOOKUP_V = new long[] { V[0], V[1], V[2], V[3], V[4], V[4] * 2, V[5], V[6], + V[7], V[8], V[8] * 2, V[9], V[10], V[11], V[12], V[12] * 2, V[13], V[14], V[15] }; + private static final float[] EXPLOSION_LOOKUP_POWER = new float[] { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F, 8.0F, + 9.0F, 10.0F, 11.0F, 12.0F, 13.0F, 14.0F, 15.0F, 16.0F, 17.0F, 18.0F, 19.0F, 20.0F }; + + public static float getExplosionPowerForVoltage(long voltage) { + for (int i = 0; i < EXPLOSION_LOOKUP_V.length; i++) { + if (voltage < EXPLOSION_LOOKUP_V[i]) { + return EXPLOSION_LOOKUP_POWER[i]; + } + } + return EXPLOSION_LOOKUP_POWER[EXPLOSION_LOOKUP_POWER.length - 1]; + } +} diff --git a/src/main/java/gregtech/api/enums/GTVoltageIndex.java b/src/main/java/gregtech/api/enums/GTVoltageIndex.java deleted file mode 100644 index c5c2c215b0..0000000000 --- a/src/main/java/gregtech/api/enums/GTVoltageIndex.java +++ /dev/null @@ -1,22 +0,0 @@ -package gregtech.api.enums; - -public class GTVoltageIndex { - - public final static int ULV = 0; - public final static int LV = 1; - public final static int MV = 2; - public final static int HV = 3; - public final static int EV = 4; - public final static int IV = 5; - public final static int LuV = 6; - public final static int ZPM = 7; - public final static int UV = 8; - public final static int UHV = 9; - public final static int UEV = 10; - public final static int UIV = 11; - public final static int UMV = 12; - public final static int UXV = 13; - public final static int MAX = 14; - - private GTVoltageIndex() {} -} diff --git a/src/main/java/gregtech/api/enums/GT_HatchElement.java b/src/main/java/gregtech/api/enums/GT_HatchElement.java deleted file mode 100644 index 3a21d5a2eb..0000000000 --- a/src/main/java/gregtech/api/enums/GT_HatchElement.java +++ /dev/null @@ -1,112 +0,0 @@ -package gregtech.api.enums; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import gregtech.api.interfaces.IHatchElement; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Dynamo; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Input; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Maintenance; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Muffler; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Output; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_OutputBus; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase; -import gregtech.api.util.GT_ExoticEnergyInputHelper; -import gregtech.api.util.IGT_HatchAdder; - -public enum GT_HatchElement implements IHatchElement { - - Muffler(GT_MetaTileEntity_MultiBlockBase::addMufflerToMachineList, GT_MetaTileEntity_Hatch_Muffler.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mMufflerHatches.size(); - } - }, - Maintenance(GT_MetaTileEntity_MultiBlockBase::addMaintenanceToMachineList, - GT_MetaTileEntity_Hatch_Maintenance.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mMaintenanceHatches.size(); - } - }, - InputHatch(GT_MetaTileEntity_MultiBlockBase::addInputHatchToMachineList, GT_MetaTileEntity_Hatch_Input.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mInputHatches.size(); - } - }, - InputBus(GT_MetaTileEntity_MultiBlockBase::addInputBusToMachineList, GT_MetaTileEntity_Hatch_InputBus.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mInputBusses.size(); - } - }, - OutputHatch(GT_MetaTileEntity_MultiBlockBase::addOutputHatchToMachineList, GT_MetaTileEntity_Hatch_Output.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mOutputHatches.size(); - } - }, - OutputBus(GT_MetaTileEntity_MultiBlockBase::addOutputBusToMachineList, GT_MetaTileEntity_Hatch_OutputBus.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mOutputBusses.size(); - } - }, - Energy(GT_MetaTileEntity_MultiBlockBase::addEnergyInputToMachineList, GT_MetaTileEntity_Hatch_Energy.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mEnergyHatches.size(); - } - }, - Dynamo(GT_MetaTileEntity_MultiBlockBase::addDynamoToMachineList, GT_MetaTileEntity_Hatch_Dynamo.class) { - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.mDynamoHatches.size(); - } - }, - ExoticEnergy(GT_MetaTileEntity_MultiBlockBase::addExoticEnergyInputToMachineList) { - - @Override - public List> mteClasses() { - return GT_ExoticEnergyInputHelper.getAllClasses(); - } - - @Override - public long count(GT_MetaTileEntity_MultiBlockBase t) { - return t.getExoticEnergyHatches() - .size(); - } - },; - - private final List> mteClasses; - private final IGT_HatchAdder adder; - - @SafeVarargs - GT_HatchElement(IGT_HatchAdder adder, - Class... mteClasses) { - this.mteClasses = Collections.unmodifiableList(Arrays.asList(mteClasses)); - this.adder = adder; - } - - @Override - public List> mteClasses() { - return mteClasses; - } - - public IGT_HatchAdder adder() { - return adder; - } -} diff --git a/src/main/java/gregtech/api/enums/GT_Values.java b/src/main/java/gregtech/api/enums/GT_Values.java deleted file mode 100644 index 88972e45fc..0000000000 --- a/src/main/java/gregtech/api/enums/GT_Values.java +++ /dev/null @@ -1,720 +0,0 @@ -package gregtech.api.enums; - -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.AQUA; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.BOLD; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.DARK_AQUA; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.OBFUSCATED; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.RESET; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.animatedText; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.chain; -import static com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler.text; -import static gregtech.api.enums.Mods.GregTech; -import static gregtech.api.enums.Mods.IndustrialCraft2; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Supplier; - -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.world.World; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.oredict.OreDictionary; - -import gregtech.api.fluid.FluidTankGT; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.interfaces.internal.IGT_Mod; -import gregtech.api.interfaces.internal.IGT_RecipeAdder; -import gregtech.api.net.IGT_NetworkHandler; - -/** - * Made for static imports, this Class is just a Helper. - *

- * I am doing this to have a better Table alike view on my Code, so I can change things faster using the Block Selection - * Mode of eclipse. - *

- * Go to "Window > Preferences > Java > Editor > Content Assist > Favorites" to set static importable Constant Classes - * such as this one as AutoCompleteable. - */ -@SuppressWarnings("unused") // API Legitimately has unused fields and methods -public class GT_Values { - // unused: A, C, D, G, H, I, J, K, N, O, Q, R, S, T - - // TODO: Rename Material Units to 'U' - // TODO: Rename OrePrefixes Class to 'P' - // TODO: Rename Materials Class to 'M' - - /** - * Empty String for an easier Call Hierarchy - */ - public static final String E = ""; - - /** - * The first 32 Bits - */ - @SuppressWarnings("PointlessBitwiseExpression") // Nicer source layout this way - public static final int[] B = new int[] { 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8, - 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, - 1 << 21, 1 << 22, 1 << 23, 1 << 24, 1 << 25, 1 << 26, 1 << 27, 1 << 28, 1 << 29, 1 << 30, 1 << 31 }; - - /** - * Renamed from "MATERIAL_UNIT" to just "M" - *

- * This is worth exactly one normal Item. This Constant can be divided by many commonly used Numbers such as 1, 2, - * 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, ... 64 or 81 without losing precision and is for that - * reason used as Unit of Amount. But it is also small enough to be multiplied with larger Numbers. - *

- * This is used to determine the amount of Material contained inside a prefixed Ore. For example Nugget = M / 9 as - * it contains out of 1/9 of an Ingot. - */ - public static final long M = 3628800; - - /** - * Renamed from "FLUID_MATERIAL_UNIT" to just "L" - *

- * Fluid per Material Unit (Prime Factors: 3 * 3 * 2 * 2 * 2 * 2) - */ - public static final long L = 144; - - /** - * The Item WildCard Tag. Even shorter than the "-1" of the past - */ - public static final short W = OreDictionary.WILDCARD_VALUE; - - /** - * The Voltage Tiers. Use this Array instead of the old named Voltage Variables - */ - public static final long[] V = new long[] { 8L, 32L, 128L, 512L, 2048L, 8192L, 32_768L, 131_072L, 524_288L, - 2_097_152L, 8_388_608L, 33_554_432L, 134_217_728L, 536_870_912L, Integer.MAX_VALUE - 7, - // Error tier to prevent out of bounds errors. Not really a real tier (for now). - 8_589_934_592L }; - - /** - * The Voltage Practical. These are recipe voltage you should use if you expect the recipe to use a full amp of that - * tier. These leave a bit of headroom for cable and transformer losses, but not enough to make it a great gain. - */ - // this will correctly map ULV to 7. - public static final long[] VP = Arrays.stream(V) - .map( - i -> BigInteger.valueOf(i) - .multiply(BigInteger.valueOf(30)) - .divide(BigInteger.valueOf(32)) - .longValueExact()) - .toArray(); - // TODO:Adding that in coremod!!! - // TODO:tier 14,15 wires and transformers only (not even cables !!!) - // TODO:tier 12,13 the above + batteries, battery buffers, (maybe cables,12 also works for machines) - // TODO:tier 10,11 the above + chargers and other machines, (cables would be nice) - // TODO:tier 9 machines and batteries - - // TODO:AND ALL THE MATERIALS... for that - // TODO:LIST OF MACHINES WITH POINTLESS TIERS (unless you implement some other tiering mechanism like reducing eu - // cost if time=1tick) - // Macerator/Compressor/Furnace... and for cheap recipes any - - /** - * Array of Maximum Amperes at given Tier index - *

- * keeping Voltage*Amps < Integer.MAX_VALUE-7 for machines (and tier logic 4x EUt 2/ time) - *

- *

- * AMV[4]= max amps at tier 4 - *

- */ - public static final long[] AatV = new long[] { 268435455, 67108863, 16777215, 4194303, 1048575, 262143, 65535, - 16383, 4095, 1023, 255, 63, 15, 3, 1, 1 }; - /** - * The short Names for the Voltages - */ - public static final String[] VN = new String[] { "ULV", // 0 - "LV", // 1 - "MV", // 2 - "HV", // 3 - "EV", // 4 - "IV", // 5 - "LuV", // 6 - "ZPM", // 7 - "UV", // 8 - "UHV", // 9 - "UEV", // 10 - "UIV", // 11 - "UMV", // 12 - "UXV", // 13 - "MAX", // 14 - "MAX+" // 15 - }; - - /** - * The long Names for the Voltages - */ - public static final String[] VOLTAGE_NAMES = new String[] { "Ultra Low Voltage", // 0 - "Low Voltage", // 1 - "Medium Voltage", // 2 - "High Voltage", // 3 - "Extreme Voltage", // 4 - "Insane Voltage", // 5 - "Ludicrous Voltage", // 6 - "ZPM Voltage", // 7 - "Ultimate Voltage", // 8 - "Ultimate High Voltage", // 9 - "Ultimate Extreme Voltage", // 10 - "Ultimate Insane Voltage", // 11 - "Ultimate Mega Voltage", // 12 - "Ultimate Extended Mega Voltage", // 13 - "Maximum Voltage", // 14 - "Error Voltage, report this" // 15 - }; - - public static final String[] TIER_COLORS = new String[] { EnumChatFormatting.RED.toString(), // ULV, 0 - EnumChatFormatting.GRAY.toString(), // LV, 1 - EnumChatFormatting.GOLD.toString(), // MV, 2 - EnumChatFormatting.YELLOW.toString(), // HV, 3 - EnumChatFormatting.DARK_GRAY.toString(), // EV, 4 - EnumChatFormatting.GREEN.toString(), // IV, 5 - EnumChatFormatting.LIGHT_PURPLE.toString(), // LuV, 6 - EnumChatFormatting.AQUA.toString(), // ZPM, 7 - EnumChatFormatting.DARK_GREEN.toString(), // UV, 8 - EnumChatFormatting.DARK_RED.toString(), // UHV, 9 - EnumChatFormatting.DARK_PURPLE.toString(), // UEV, 10 - EnumChatFormatting.DARK_BLUE.toString() + EnumChatFormatting.BOLD, // UIV, 11 - EnumChatFormatting.RED.toString() + EnumChatFormatting.BOLD + EnumChatFormatting.UNDERLINE, // UMV, 12 - EnumChatFormatting.DARK_RED.toString() + EnumChatFormatting.BOLD + EnumChatFormatting.UNDERLINE, // UXV, 13 - EnumChatFormatting.WHITE.toString() + EnumChatFormatting.BOLD + EnumChatFormatting.UNDERLINE, // MAX, 14 - EnumChatFormatting.WHITE.toString() + EnumChatFormatting.BOLD - + EnumChatFormatting.UNDERLINE - + EnumChatFormatting.ITALIC, // MAX+, 15 - }; - - /** - * This way it is possible to have a Call Hierarchy of NullPointers in ItemStack based Functions, and also because - * most of the time I don't know what kind of Data Type the "null" stands for - */ - public static final ItemStack NI = null; - /** - * This way it is possible to have a Call Hierarchy of NullPointers in FluidStack based Functions, and also because - * most of the time I don't know what kind of Data Type the "null" stands for - */ - public static final FluidStack NF = null; - - /** - * File Paths and Resource Paths - */ - @Deprecated - public static final String TEX_DIR = "textures/"; - @Deprecated - public static final String RES_PATH = GregTech.getResourcePath(TEX_DIR); - @Deprecated - public static final String RES_PATH_GUI = GregTech.getResourcePath("textures", "gui/"); - @Deprecated - public static final String RES_PATH_ITEM = GregTech.getResourcePath(); - @Deprecated - public static final String RES_PATH_BLOCK = GregTech.getResourcePath(); - @Deprecated - public static final String RES_PATH_ENTITY = GregTech.getResourcePath("textures", "entity/"); - @Deprecated - public static final String RES_PATH_ASPECTS = GregTech.getResourcePath("textures", "aspects/"); - @Deprecated - public static final String RES_PATH_MODEL = GregTech.getResourcePath("textures", "models/"); - @Deprecated - public static final String RES_PATH_IC2 = IndustrialCraft2.getResourcePath(); - - /** - * NBT String Keys - */ - public static final class NBT { - - public static final String COLOR = "gt.color", // Integer - COVERS = "gt.covers", // String - CUSTOM_NAME = "name", // String - DISPLAY = "gt.display", // String - TIER = "gt.tier", // Number - FACING = "gt.facing", // Byte - LOCK_UPGRADE = "gt.locked", // Boolean - MATERIAL = "gt.material", // String containing the Material Name. - MODE = "gt.mode", // Number - ALLOWED_MODES = "gt.amode", // Number - MTE_ID = "gt.mte.id", // Containing the MTE ID - MTE_REG = "gt.mte.reg", // Containing the MTE Registry ID - OWNER = "gt.owner", // String - OWNER_UUID = "gt.ownerUuid", // UUID (String) - - // Machines - ACTIVE = "gt.active", // Boolean - FLUID_OUT = "gt.fluidout", // Output Fluid - ITEM_OUT = "gt.itemout", // Output Item - PARALLEL = "gt.parallel", // Number - TANK_CAPACITY = "gt.tankcap", // Number - TANK_IN = "gt.tank.in.", // FluidStack - TANK_OUT = "gt.tank.out.", // FluidStack - TEXTURE_FOLDER = "gt.texture.folder", // String - INV_INPUT_SIZE = "gt.invsize.in", // Number - INV_OUTPUT_SIZE = "gt.invsize.out", // Number - INV_INPUT_LIST = "gt.invlist.in", // NBT List - INV_OUTPUT_LIST = "gt.invlist.out", // NBT List - VOLTAGE = "gt.voltage", // Number - AMPERAGE = "gt.amperage", // Number - STORED_ENERGY = "gt.stored.energy", // Number - MAXIMUM_ENERGY = "gt.maximum.energy", // Number - EUT_CONSUMPTION = "gt.eut.consumption", // Number - BURN_TIME_LEFT = "gt.burn.time.left", // Number - TOTAL_BURN_TIME = "gt.total.burn.time", // Number - ALLOWED_WORK = "gt.allowed.work", // Boolean - TASKS = "gt.tasks", // Compound - - // MultiBlock - STRUCTURE_OK = "gt.structure.ok", ROTATION = "gt.eRotation", FLIP = "gt.eFlip", TARGET = "gt.target", // Boolean - TARGET_X = "gt.target.x", // Number - TARGET_Y = "gt.target.y", // Number - TARGET_Z = "gt.target.z", // Number - LOCKED_FLUID = "gt.locked.fluid", // String - LOCKED_INVENTORY = "gt.locked.inv", // String - LOCKED_INVENTORY_INDEX = "gt.locked.inv.index", // Number - UPGRADE_INVENTORY_SIZE = "gt.invsize.upg", // String - UPGRADE_INVENTORY_UUID = "gt.invuuid.upg", // String - UPGRADE_INVENTORY_NAME = "gt.invname.upg", // String - UPGRADE_INVENTORIES_INPUT = "gt.invlist.upg.in", // NBT List - UPGRADE_INVENTORIES_OUTPUT = "gt.invlist.upg.out", // NBT List - UPGRADE_TANK_CAPACITY = "gt.tank.cap.upg", // Long - UPGRADE_TANK_COUNT = "gt.tank.ct.upg", // Int - UPGRADE_TANK_CAPACITY_MULTIPLIER = "gt.tank.cap.mult.upg", // Long - UPGRADE_TANK_UUID = "gt.tankuuid.upg", // String - UPGRADE_TANK_NAME = "gt.tankname.upg", // String - UPGRADE_TANKS_INPUT = "gt.tanklist.upg.in", // NBT List - UPGRADE_TANKS_OUTPUT = "gt.tanklist.upg.out", // NBT List - UPGRADE_TANKS_PREFIX = "gt.tank.upg", // NBT Tag - UPGRADE_AMPERAGE = "gt.amp.upg", // Long - SEPARATE_INPUTS = "gt.separate.inputs", // Boolean - VOIDING_MODE = "gt.voiding.mode", // String - BATCH_MODE = "gt.batch.mode", // Boolean - RECIPE_LOCK = "gt.recipe.lock", // Boolean - - // Logic - POWER_LOGIC = "gt.pow.logic", // NBT Tag - POWER_LOGIC_STORED_ENERGY = "gt.pow.energy", // Number - POWER_LOGIC_ENERGY_CAPACITY = "gt.pow.energy.cap", // Number - POWER_LOGIC_VOLTAGE = "gt.pow.volt", // Number - POWER_LOGIC_AMPERAGE = "gt.pow.amp", // Number - POWER_LOGIC_TYPE = "gt.pow.type", // Number - empty_ = ""; - } - - /** The Color White as RGB Short Array. */ - public static final short[] UNCOLORED_RGBA = { 255, 255, 255, 255 }; - /** The Color White as simple Integer (0x00ffffff). */ - public static final int UNCOLORED = 0x00ffffff; - - /** - * Sides - */ - public static final byte SIDE_BOTTOM = 0, SIDE_DOWN = 0, SIDE_TOP = 1, SIDE_UP = 1, SIDE_NORTH = 2, // Also a Side - // with a - // stupidly - // mirrored - // Texture - SIDE_SOUTH = 3, SIDE_WEST = 4, SIDE_EAST = 5, // Also a Side with a stupidly mirrored Texture - SIDE_ANY = 6, SIDE_UNKNOWN = 6, SIDE_INVALID = 6, SIDE_INSIDE = 6, SIDE_UNDEFINED = 6; - - /** Compass alike Array for the proper ordering of North, East, South and West. */ - public static final byte[] COMPASS_DIRECTIONS = { SIDE_NORTH, SIDE_EAST, SIDE_SOUTH, SIDE_WEST }; - - /** - * An Array containing all Sides which follow the Condition, in order to iterate over them for example. - */ - public static final byte[] ALL_SIDES = { 0, 1, 2, 3, 4, 5, 6 }, ALL_VALID_SIDES = { 0, 1, 2, 3, 4, 5 }; - - /** - * For Facing Checks. - */ - public static final boolean[] INVALID_SIDES = { false, false, false, false, false, false, true }, - VALID_SIDES = { true, true, true, true, true, true, false }; - - /** - * Side->Offset Mappings. - */ - public static final byte[] OFFX = { 0, 0, 0, 0, -1, +1, 0 }, OFFY = { -1, +1, 0, 0, 0, 0, 0 }, - OFFZ = { 0, 0, -1, +1, 0, 0, 0 }; - - /** - * Side->Opposite Mappings. - **/ - public static final byte[] OPOS = { 1, 0, 3, 2, 5, 4, 6 }; - - /** - * [Facing,Side]->Side Mappings for Blocks, which don't face up- and downwards. 0 = bottom, 1 = top, 2 = left, 3 = - * front, 4 = right, 5 = back, 6 = undefined. - */ - public static final byte[][] FACING_ROTATIONS = { { 0, 1, 2, 3, 4, 5, 6 }, { 0, 1, 2, 3, 4, 5, 6 }, - { 0, 1, 3, 5, 4, 2, 6 }, { 0, 1, 5, 3, 2, 4, 6 }, { 0, 1, 2, 4, 3, 5, 6 }, { 0, 1, 4, 2, 5, 3, 6 }, - { 0, 1, 2, 3, 4, 5, 6 } }; - - /** - * The Mod Object itself. That is the GT_Mod-Object. It's needed to open GUI's and similar. - */ - public static IGT_Mod GT; - /** - * Use this Object to add Recipes. (Recipe Adder) - */ - public static IGT_RecipeAdder RA; - /** - * For Internal Usage (Network) - */ - public static IGT_NetworkHandler NW; - /** - * Control percentage of filled 3x3 chunks. Lower number means less oreveins spawn - */ - public static int oreveinPercentage; - /** - * Control number of attempts to find a valid orevein. Generally this maximum limit isn't hit, selecting a vein is - * cheap - */ - public static int oreveinAttempts; - /** - * Control number of attempts to place a valid ore vein. - *

- * If a vein wasn't placed due to height restrictions, completely in the water, etc, another attempt is tried. - *

- */ - public static int oreveinMaxPlacementAttempts; - /** - * Whether to place small ores as placer ores for an orevein - */ - public static boolean oreveinPlacerOres; - /** - * Multiplier to control how many placer ores get generated. - */ - public static int oreveinPlacerOresMultiplier; - /** - * Not really Constants, but they set using the Config and therefore should be constant (those are for the Debug - * Mode) - */ - public static boolean D1 = false, D2 = false; - /** - * Debug parameter for cleanroom testing. - */ - public static boolean debugCleanroom = false; - /** - * Debug parameter for driller testing. - */ - public static boolean debugDriller = false; - /** - * Debug parameter for world generation. Tracks chunks added/removed from run queue. - */ - public static boolean debugWorldGen = false; - /** - * Debug parameter for orevein generation. - */ - public static boolean debugOrevein = false; - /** - * Debug parameter for small ore generation. - */ - public static boolean debugSmallOres = false; - /** - * Debug parameter for stones generation. - */ - public static boolean debugStones = false; - /** - * Debug parameter for single block pump - */ - public static boolean debugBlockPump = false; - /** - * Debug parameter for single block miner - */ - public static boolean debugBlockMiner = false; - /** - * Debug parameter for entity cramming reduction - */ - public static boolean debugEntityCramming = false; - /** - * Debug parameter for {@link gregtech.api.util.GT_ChunkAssociatedData} - */ - public static boolean debugWorldData = false; - /** - * Parameter if multi tile entities (MuTEs) should be enabled in the pack. Turned off by default until - * implementation is done. - */ - public static boolean enableMultiTileEntities = false; - /** - * Number of ticks between sending sound packets to clients for electric machines. Default is 1.5 seconds. Trying to - * mitigate lag and FPS drops. - */ - public static int ticksBetweenSounds = 30; - /** - * If you have to give something a World Parameter but there is no World... (Dummy World) - */ - public static World DW; - - /** - * This will prevent NEI from crashing but spams the Log. - */ - public static boolean allow_broken_recipemap = false; - /** - * This will set the blacklist for the world accelerator in TE mode. - */ - public static String[] blacklistedTileEntiyClassNamesForWA = new String[] { - "com.rwtema.extrautils.tileentity.enderquarry.TileEntityEnderQuarry", - "advsolar.common.tiles.TileEntityUltimateSolarPanel", "advsolar.common.tiles.TileEntitySolarPanel", - "advsolar.common.tiles.TileEntityQuantumSolarPanel", "advsolar.common.tiles.TileEntityHybridSolarPanel", - "advsolar.common.tiles.TileEntityAdvancedSolarPanel", "com.supsolpans.tiles.TileAdminSolarPanel", - "com.supsolpans.tiles.TilePhotonicSolarPanel", "com.supsolpans.tiles.TileSingularSolarPanel", - "com.supsolpans.tiles.TileSpectralSolarPanel", "emt.tile.solar.air.TileEntityAirSolar", - "emt.tile.solar.air.TileEntityDoubleAirSolar", "emt.tile.solar.air.TileEntityTripleAirSolar", - "emt.tile.solar.air.TileEntityQuadrupleAirSolar", "emt.tile.solar.air.TileEntityQuintupleAirSolar", - "emt.tile.solar.air.TileEntitySextupleAirSolar", "emt.tile.solar.air.TileEntitySeptupleAirSolar", - "emt.tile.solar.air.TileEntityOctupleAirSolar", "emt.tile.solar.compressed.TileEntityCompressedSolar", - "emt.tile.solar.compressed.TileEntityDoubleCompressedSolar", - "emt.tile.solar.compressed.TileEntityTripleCompressedSolar", - "emt.tile.solar.compressed.TileEntityQuadrupleAirSolar", - "emt.tile.solar.compressed.TileEntityQuintupleAirSolar", "emt.tile.solar.compressed.TileEntitySextupleAirSolar", - "emt.tile.solar.compressed.TileEntitySeptupleAirSolar", "emt.tile.solar.compressed.TileEntityOctupleAirSolar", - "emt.tile.solar.dark.TileEntityDarkSolar", "emt.tile.solar.dark.TileEntityDoubleDarkSolar", - "emt.tile.solar.dark.TileEntityTripleDarkSolar", "emt.tile.solar.dark.TileEntityQuadrupleAirSolar", - "emt.tile.solar.dark.TileEntityQuintupleAirSolar", "emt.tile.solar.dark.TileEntitySextupleAirSolar", - "emt.tile.solar.dark.TileEntitySeptupleAirSolar", "emt.tile.solar.dark.TileEntityOctupleAirSolar", - "emt.tile.solar.earth.TileEntityDoubleEarthSolar", "emt.tile.solar.earth.TileEntityEarthSolar", - "emt.tile.solar.earth.TileEntityTripleEarthSolar", "emt.tile.solar.earth.TileEntityQuadrupleAirSolar", - "emt.tile.solar.earth.TileEntityQuintupleAirSolar", "emt.tile.solar.earth.TileEntitySextupleAirSolar", - "emt.tile.solar.earth.TileEntitySeptupleAirSolar", "emt.tile.solar.earth.TileEntityOctupleAirSolar", - "emt.tile.solar.fire.TileEntityDoubleFireSolar", "emt.tile.solar.fire.TileEntityFireSolar", - "emt.tile.solar.fire.TileEntityTripleFireSolar", "emt.tile.solar.fire.TileEntityQuadrupleAirSolar", - "emt.tile.solar.fire.TileEntityQuintupleAirSolar", "emt.tile.solar.fire.TileEntitySextupleAirSolar", - "emt.tile.solar.fire.TileEntitySeptupleAirSolar", "emt.tile.solar.fire.TileEntityOctupleAirSolar", - "emt.tile.solar.order.TileEntityDoubleOrderSolar", "emt.tile.solar.order.TileEntityOrderSolar", - "emt.tile.solar.order.TileEntityTripleOrderSolar", "emt.tile.solar.order.TileEntityQuadrupleAirSolar", - "emt.tile.solar.order.TileEntityQuintupleAirSolar", "emt.tile.solar.order.TileEntitySextupleAirSolar", - "emt.tile.solar.order.TileEntitySeptupleAirSolar", "emt.tile.solar.order.TileEntityOctupleAirSolar", - "emt.tile.solar.water.TileEntityDoubleWaterSolar", "emt.tile.solar.water.TileEntityTripleWaterSolar", - "emt.tile.solar.water.TileEntityWaterSolar", "emt.tile.solar.water.TileEntityQuadrupleAirSolar", - "emt.tile.solar.water.TileEntityQuintupleAirSolar", "emt.tile.solar.water.TileEntitySextupleAirSolar", - "emt.tile.solar.water.TileEntitySeptupleAirSolar", "emt.tile.solar.water.TileEntityOctupleAirSolar", - "com.lulan.compactkineticgenerators.tileentity.TileCkgE", - "com.lulan.compactkineticgenerators.tileentity.TileCkgH", - "com.lulan.compactkineticgenerators.tileentity.TileCkgL", - "com.lulan.compactkineticgenerators.tileentity.TileCkgM", - "com.lulan.compactkineticgenerators.tileentity.TileCkwaE", - "com.lulan.compactkineticgenerators.tileentity.TileCkwaH", - "com.lulan.compactkineticgenerators.tileentity.TileCkwaL", - "com.lulan.compactkineticgenerators.tileentity.TileCkwaM", - "com.lulan.compactkineticgenerators.tileentity.TileCkwmE", - "com.lulan.compactkineticgenerators.tileentity.TileCkwmH", - "com.lulan.compactkineticgenerators.tileentity.TileCkwmL", - "com.lulan.compactkineticgenerators.tileentity.TileCkwmM", "com.supsolpans.tiles.TileSpectralSolarPanel", - "com.supsolpans.tiles.TileSingularSolarPanel", "com.supsolpans.tiles.TileAdminSolarPanel", - "com.supsolpans.tiles.TilePhotonicSolarPanel", "gtPlusPlus.core.tileentities.general.TileEntityFishTrap", - "gtPlusPlus.core.tileentities.general.TileEntityDecayablesChest", - "net.bdew.gendustry.machines.apiary.TileApiary", "goodgenerator.blocks.tileEntity.EssentiaHatch", - "magicbees.tileentity.TileEntityApimancersDrainerCommon", - "magicbees.tileentity.TileEntityApimancersDrainerGT" }; - /** - * This will set the percentage how much ReinforcedGlass is Allowed in Cleanroom Walls. - */ - public static float cleanroomGlass = 5.0f; - /** - * This will let machines such as drills and pumps chunkload their work area. - */ - public static boolean enableChunkloaders = true; - /** - * This will make all chunkloading machines act as World Anchors (true) or Passive Anchors (false) - */ - public static boolean alwaysReloadChunkloaders = false; - - public static boolean debugChunkloaders = false; - public static boolean cls_enabled; - public static final Set mCTMEnabledBlock = new HashSet<>(); - public static final Set mCTMDisabledBlock = new HashSet<>(); - - public static final int STEAM_PER_WATER = 160; - /** - * If true, then digital chest with AE2 storage bus will be accessible only through AE2 - */ - public static boolean disableDigitalChestsExternalAccess = false; - - public static boolean lateConfigSave = true; - public static boolean worldTickHappened = false; - - public static final int[] emptyIntArray = new int[0]; - - public static final IFluidTank[] emptyFluidTank = new IFluidTank[0]; - public static final FluidTankGT[] emptyFluidTankGT = new FluidTankGT[0]; - public static final FluidTankInfo[] emptyFluidTankInfo = new FluidTankInfo[0]; - public static final FluidStack[] emptyFluidStack = new FluidStack[0]; - public static final ItemStack[] emptyItemStackArray = new ItemStack[0]; - public static final IIconContainer[] emptyIconContainerArray = new IIconContainer[3]; - - /** - * Pretty formatting for author names. - */ - public static final String Colen = "" + EnumChatFormatting.DARK_RED - + EnumChatFormatting.BOLD - + EnumChatFormatting.ITALIC - + EnumChatFormatting.UNDERLINE - + "C" - + EnumChatFormatting.GOLD - + EnumChatFormatting.BOLD - + EnumChatFormatting.ITALIC - + EnumChatFormatting.UNDERLINE - + "o" - + EnumChatFormatting.GREEN - + EnumChatFormatting.BOLD - + EnumChatFormatting.ITALIC - + EnumChatFormatting.UNDERLINE - + "l" - + EnumChatFormatting.DARK_AQUA - + EnumChatFormatting.BOLD - + EnumChatFormatting.ITALIC - + EnumChatFormatting.UNDERLINE - + "e" - + EnumChatFormatting.DARK_PURPLE - + EnumChatFormatting.BOLD - + EnumChatFormatting.ITALIC - + EnumChatFormatting.UNDERLINE - + "n"; - - public static final String AuthorColen = "Author: " + Colen; - public static final String AuthorKuba = "Author: " + EnumChatFormatting.DARK_RED - + EnumChatFormatting.BOLD - + "k" - + EnumChatFormatting.RED - + EnumChatFormatting.BOLD - + "u" - + EnumChatFormatting.GOLD - + EnumChatFormatting.BOLD - + "b" - + EnumChatFormatting.YELLOW - + EnumChatFormatting.BOLD - + "a" - + EnumChatFormatting.DARK_GREEN - + EnumChatFormatting.BOLD - + "6" - + EnumChatFormatting.GREEN - + EnumChatFormatting.BOLD - + "0" - + EnumChatFormatting.AQUA - + EnumChatFormatting.BOLD - + "0" - + EnumChatFormatting.DARK_AQUA - + EnumChatFormatting.BOLD - + "0"; - - public static final String AuthorBlueWeabo = "Author: " + EnumChatFormatting.BLUE - + EnumChatFormatting.BOLD - + "Blue" - + EnumChatFormatting.AQUA - + EnumChatFormatting.BOLD - + "Weabo"; - - public static final String Authorminecraft7771 = "Author: " + EnumChatFormatting.BLUE - + EnumChatFormatting.LIGHT_PURPLE - + "minecraft7771"; - - public static final Supplier AuthorCloud = chain( - text("Author: " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD), - animatedText( - "C", - 1, - 500, - DARK_AQUA + OBFUSCATED + BOLD + "X" + RESET + AQUA + BOLD, - DARK_AQUA + "\u238B" + RESET + AQUA + BOLD, - DARK_AQUA + OBFUSCATED + BOLD + "X" + RESET + AQUA + BOLD, - DARK_AQUA + "\u0B83" + RESET + AQUA + BOLD, - DARK_AQUA + OBFUSCATED + BOLD + "X" + RESET + AQUA + BOLD, - DARK_AQUA + BOLD + "\u29BC" + RESET + AQUA + BOLD), - text(EnumChatFormatting.AQUA + EnumChatFormatting.BOLD.toString() + "loud" + EnumChatFormatting.RESET), - animatedText( - " ", - 1, - 500, - DARK_AQUA + OBFUSCATED + BOLD + "X", - DARK_AQUA + "\u238B", - DARK_AQUA + OBFUSCATED + BOLD + "X", - DARK_AQUA + "\u0B83", - DARK_AQUA + OBFUSCATED + BOLD + "X", - DARK_AQUA + BOLD + "\u29BC")); - - public static final String AuthorQuerns = "Author: " + EnumChatFormatting.RED + "Querns"; - public static final String AuthorSilverMoon = "Author: " + EnumChatFormatting.AQUA + "SilverMoon"; - public static final String AuthorTheEpicGamer274 = "Author: " + "TheEpicGamer274"; - public static final String AuthorFourIsTheNumber = "Author: " + EnumChatFormatting.LIGHT_PURPLE - + EnumChatFormatting.ITALIC - + "Four" - + EnumChatFormatting.WHITE - + EnumChatFormatting.ITALIC - + "Is" - + EnumChatFormatting.LIGHT_PURPLE - + EnumChatFormatting.ITALIC - + "The" - + EnumChatFormatting.WHITE - + EnumChatFormatting.ITALIC - + "Number"; - public static final String Ollie = "" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Ollie"; - public static final String authorBaps = "Author: " + EnumChatFormatting.GOLD - + "Ba" - + EnumChatFormatting.LIGHT_PURPLE - + "ps"; - - public static final String AuthorEvgenWarGold = "" + EnumChatFormatting.RED - + EnumChatFormatting.BOLD - + "Evgen" - + EnumChatFormatting.BLUE - + EnumChatFormatting.BOLD - + "War" - + EnumChatFormatting.GOLD - + EnumChatFormatting.BOLD - + "Gold"; - public static final String AuthorVolence = "Author: " + EnumChatFormatting.AQUA + "Volence"; - - public static final String AuthorEigenRaven = "Author: " + EnumChatFormatting.DARK_PURPLE - + "Eigen" - + EnumChatFormatting.BOLD - + "Raven"; - - public static final String AuthorNotAPenguin = "Author: " + EnumChatFormatting.WHITE - + EnumChatFormatting.BOLD - + "Not" - + EnumChatFormatting.AQUA - + EnumChatFormatting.BOLD - + "APenguin"; - - // 7.5F comes from GT_Tool_Turbine_Large#getBaseDamage() given huge turbines are the most efficient now. - public static double getMaxPlasmaTurbineEfficiencyFromMaterial(Materials material) { - return (5F + (7.5F + material.mToolQuality)) / 10.0; - } - - // Called once in GT_Client on world load, has to be called late so that Materials is populated. - public static void calculateMaxPlasmaTurbineEfficiency() { - - ArrayList effArray = new ArrayList<>(); - - // Iteration seems to work but need to check turbine as all items appear null. - for (Materials material : Materials.values()) { - effArray.add(getMaxPlasmaTurbineEfficiencyFromMaterial(material)); - } - - maxPlasmaTurbineEfficiency = Collections.max(effArray); - } - - private static double maxPlasmaTurbineEfficiency; - - public static double getMaxPlasmaTurbineEfficiency() { - return maxPlasmaTurbineEfficiency; - } - - private static final long[] EXPLOSION_LOOKUP_V = new long[] { V[0], V[1], V[2], V[3], V[4], V[4] * 2, V[5], V[6], - V[7], V[8], V[8] * 2, V[9], V[10], V[11], V[12], V[12] * 2, V[13], V[14], V[15] }; - private static final float[] EXPLOSION_LOOKUP_POWER = new float[] { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F, 8.0F, - 9.0F, 10.0F, 11.0F, 12.0F, 13.0F, 14.0F, 15.0F, 16.0F, 17.0F, 18.0F, 19.0F, 20.0F }; - - public static float getExplosionPowerForVoltage(long voltage) { - for (int i = 0; i < EXPLOSION_LOOKUP_V.length; i++) { - if (voltage < EXPLOSION_LOOKUP_V[i]) { - return EXPLOSION_LOOKUP_POWER[i]; - } - } - return EXPLOSION_LOOKUP_POWER[EXPLOSION_LOOKUP_POWER.length - 1]; - } -} diff --git a/src/main/java/gregtech/api/enums/HatchElement.java b/src/main/java/gregtech/api/enums/HatchElement.java new file mode 100644 index 0000000000..ae38d2a2ff --- /dev/null +++ b/src/main/java/gregtech/api/enums/HatchElement.java @@ -0,0 +1,110 @@ +package gregtech.api.enums; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import gregtech.api.interfaces.IHatchElement; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatchDynamo; +import gregtech.api.metatileentity.implementations.MTEHatchEnergy; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.metatileentity.implementations.MTEHatchInputBus; +import gregtech.api.metatileentity.implementations.MTEHatchMaintenance; +import gregtech.api.metatileentity.implementations.MTEHatchMuffler; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; +import gregtech.api.metatileentity.implementations.MTEHatchOutputBus; +import gregtech.api.metatileentity.implementations.MTEMultiBlockBase; +import gregtech.api.util.ExoticEnergyInputHelper; +import gregtech.api.util.IGTHatchAdder; + +public enum HatchElement implements IHatchElement { + + Muffler(MTEMultiBlockBase::addMufflerToMachineList, MTEHatchMuffler.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mMufflerHatches.size(); + } + }, + Maintenance(MTEMultiBlockBase::addMaintenanceToMachineList, MTEHatchMaintenance.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mMaintenanceHatches.size(); + } + }, + InputHatch(MTEMultiBlockBase::addInputHatchToMachineList, MTEHatchInput.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mInputHatches.size(); + } + }, + InputBus(MTEMultiBlockBase::addInputBusToMachineList, MTEHatchInputBus.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mInputBusses.size(); + } + }, + OutputHatch(MTEMultiBlockBase::addOutputHatchToMachineList, MTEHatchOutput.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mOutputHatches.size(); + } + }, + OutputBus(MTEMultiBlockBase::addOutputBusToMachineList, MTEHatchOutputBus.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mOutputBusses.size(); + } + }, + Energy(MTEMultiBlockBase::addEnergyInputToMachineList, MTEHatchEnergy.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mEnergyHatches.size(); + } + }, + Dynamo(MTEMultiBlockBase::addDynamoToMachineList, MTEHatchDynamo.class) { + + @Override + public long count(MTEMultiBlockBase t) { + return t.mDynamoHatches.size(); + } + }, + ExoticEnergy(MTEMultiBlockBase::addExoticEnergyInputToMachineList) { + + @Override + public List> mteClasses() { + return ExoticEnergyInputHelper.getAllClasses(); + } + + @Override + public long count(MTEMultiBlockBase t) { + return t.getExoticEnergyHatches() + .size(); + } + },; + + private final List> mteClasses; + private final IGTHatchAdder adder; + + @SafeVarargs + HatchElement(IGTHatchAdder adder, Class... mteClasses) { + this.mteClasses = Collections.unmodifiableList(Arrays.asList(mteClasses)); + this.adder = adder; + } + + @Override + public List> mteClasses() { + return mteClasses; + } + + public IGTHatchAdder adder() { + return adder; + } +} diff --git a/src/main/java/gregtech/api/enums/HeatingCoilLevel.java b/src/main/java/gregtech/api/enums/HeatingCoilLevel.java index f281695d5a..4d770710cc 100644 --- a/src/main/java/gregtech/api/enums/HeatingCoilLevel.java +++ b/src/main/java/gregtech/api/enums/HeatingCoilLevel.java @@ -79,14 +79,14 @@ public enum HeatingCoilLevel { if (heatLevel.getHeat() >= heat) { String name = heatLevel.getName(); if (applyColor) { - name = GT_Values.TIER_COLORS[heatLevel.getTier() + 1] + name; + name = GTValues.TIER_COLORS[heatLevel.getTier() + 1] + name; } return name; } } String name = HeatingCoilLevel.MAX.getName() + "+"; if (applyColor) { - name = GT_Values.TIER_COLORS[HeatingCoilLevel.MAX.getTier() + 1] + name; + name = GTValues.TIER_COLORS[HeatingCoilLevel.MAX.getTier() + 1] + name; } return name; } diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java index 74f169681c..dba8f510b9 100644 --- a/src/main/java/gregtech/api/enums/ItemList.java +++ b/src/main/java/gregtech/api/enums/ItemList.java @@ -1,7 +1,7 @@ package gregtech.api.enums; -import static gregtech.api.enums.GT_Values.NI; -import static gregtech.api.enums.GT_Values.W; +import static gregtech.api.enums.GTValues.NI; +import static gregtech.api.enums.GTValues.W; import java.util.Locale; @@ -11,11 +11,11 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.Fluid; import gregtech.api.interfaces.IItemContainer; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; /** * Class containing all non-OreDict Items of GregTech. @@ -2615,14 +2615,14 @@ public enum ItemList implements IItemContainer { mHasNotBeenSet = false; if (aItem == null) return this; ItemStack aStack = new ItemStack(aItem, 1, 0); - mStack = GT_Utility.copyAmount(1, aStack); + mStack = GTUtility.copyAmount(1, aStack); return this; } @Override public IItemContainer set(ItemStack aStack) { mHasNotBeenSet = false; - mStack = GT_Utility.copyAmount(1, aStack); + mStack = GTUtility.copyAmount(1, aStack); return this; } @@ -2635,14 +2635,14 @@ public enum ItemList implements IItemContainer { @Override public Item getItem() { sanityCheck(); - if (GT_Utility.isStackInvalid(mStack)) return null; + if (GTUtility.isStackInvalid(mStack)) return null; return mStack.getItem(); } @Override public Block getBlock() { sanityCheck(); - return GT_Utility.getBlockFromItem(getItem()); + return GTUtility.getBlockFromItem(getItem()); } @Override @@ -2658,50 +2658,50 @@ public enum ItemList implements IItemContainer { @Override public boolean isStackEqual(Object aStack, boolean aWildcard, boolean aIgnoreNBT) { if (mDeprecated && !mWarned) { - new Exception(this + " is now deprecated").printStackTrace(GT_Log.err); + new Exception(this + " is now deprecated").printStackTrace(GTLog.err); // warn only once mWarned = true; } - if (GT_Utility.isStackInvalid(aStack)) return false; - return GT_Utility.areUnificationsEqual((ItemStack) aStack, aWildcard ? getWildcard(1) : get(1), aIgnoreNBT); + if (GTUtility.isStackInvalid(aStack)) return false; + return GTUtility.areUnificationsEqual((ItemStack) aStack, aWildcard ? getWildcard(1) : get(1), aIgnoreNBT); } @Override public ItemStack get(long aAmount, Object... aReplacements) { sanityCheck(); - if (GT_Utility.isStackInvalid(mStack)) { - GT_Log.out.println("Object in the ItemList is null at:"); - new NullPointerException().printStackTrace(GT_Log.out); - return GT_Utility.copyAmount(aAmount, aReplacements); + if (GTUtility.isStackInvalid(mStack)) { + GTLog.out.println("Object in the ItemList is null at:"); + new NullPointerException().printStackTrace(GTLog.out); + return GTUtility.copyAmount(aAmount, aReplacements); } - return GT_Utility.copyAmount(aAmount, GT_OreDictUnificator.get(mStack)); + return GTUtility.copyAmount(aAmount, GTOreDictUnificator.get(mStack)); } @Override public ItemStack getWildcard(long aAmount, Object... aReplacements) { sanityCheck(); - if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements); - return GT_Utility.copyAmountAndMetaData(aAmount, W, GT_OreDictUnificator.get(mStack)); + if (GTUtility.isStackInvalid(mStack)) return GTUtility.copyAmount(aAmount, aReplacements); + return GTUtility.copyAmountAndMetaData(aAmount, W, GTOreDictUnificator.get(mStack)); } @Override public ItemStack getUndamaged(long aAmount, Object... aReplacements) { sanityCheck(); - if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements); - return GT_Utility.copyAmountAndMetaData(aAmount, 0, GT_OreDictUnificator.get(mStack)); + if (GTUtility.isStackInvalid(mStack)) return GTUtility.copyAmount(aAmount, aReplacements); + return GTUtility.copyAmountAndMetaData(aAmount, 0, GTOreDictUnificator.get(mStack)); } @Override public ItemStack getAlmostBroken(long aAmount, Object... aReplacements) { sanityCheck(); - if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements); - return GT_Utility.copyAmountAndMetaData(aAmount, mStack.getMaxDamage() - 1, GT_OreDictUnificator.get(mStack)); + if (GTUtility.isStackInvalid(mStack)) return GTUtility.copyAmount(aAmount, aReplacements); + return GTUtility.copyAmountAndMetaData(aAmount, mStack.getMaxDamage() - 1, GTOreDictUnificator.get(mStack)); } @Override public ItemStack getWithName(long aAmount, String aDisplayName, Object... aReplacements) { ItemStack rStack = get(1, aReplacements); - if (GT_Utility.isStackInvalid(rStack)) return NI; + if (GTUtility.isStackInvalid(rStack)) return NI; // CamelCase alphanumeric words from aDisplayName StringBuilder tCamelCasedDisplayNameBuilder = new StringBuilder(); @@ -2722,36 +2722,36 @@ public enum ItemList implements IItemContainer { // Construct a translation key from UnlocalizedName and CamelCased DisplayName final String tKey = rStack.getUnlocalizedName() + ".with." + tCamelCasedDisplayNameBuilder + ".name"; - rStack.setStackDisplayName(GT_LanguageManager.addStringLocalization(tKey, aDisplayName)); - return GT_Utility.copyAmount(aAmount, rStack); + rStack.setStackDisplayName(GTLanguageManager.addStringLocalization(tKey, aDisplayName)); + return GTUtility.copyAmount(aAmount, rStack); } @Override public ItemStack getWithCharge(long aAmount, int aEnergy, Object... aReplacements) { ItemStack rStack = get(1, aReplacements); - if (GT_Utility.isStackInvalid(rStack)) return null; - GT_ModHandler.chargeElectricItem(rStack, aEnergy, Integer.MAX_VALUE, true, false); - return GT_Utility.copyAmount(aAmount, rStack); + if (GTUtility.isStackInvalid(rStack)) return null; + GTModHandler.chargeElectricItem(rStack, aEnergy, Integer.MAX_VALUE, true, false); + return GTUtility.copyAmount(aAmount, rStack); } @Override public ItemStack getWithDamage(long aAmount, long aMetaValue, Object... aReplacements) { sanityCheck(); - if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements); - return GT_Utility.copyAmountAndMetaData(aAmount, aMetaValue, GT_OreDictUnificator.get(mStack)); + if (GTUtility.isStackInvalid(mStack)) return GTUtility.copyAmount(aAmount, aReplacements); + return GTUtility.copyAmountAndMetaData(aAmount, aMetaValue, GTOreDictUnificator.get(mStack)); } @Override public IItemContainer registerOre(Object... aOreNames) { sanityCheck(); - for (Object tOreName : aOreNames) GT_OreDictUnificator.registerOre(tOreName, get(1)); + for (Object tOreName : aOreNames) GTOreDictUnificator.registerOre(tOreName, get(1)); return this; } @Override public IItemContainer registerWildcardAsOre(Object... aOreNames) { sanityCheck(); - for (Object tOreName : aOreNames) GT_OreDictUnificator.registerOre(tOreName, getWildcard(1)); + for (Object tOreName : aOreNames) GTOreDictUnificator.registerOre(tOreName, getWildcard(1)); return this; } @@ -2767,7 +2767,7 @@ public enum ItemList implements IItemContainer { if (mHasNotBeenSet) throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!"); if (mDeprecated && !mWarned) { - new Exception(this + " is now deprecated").printStackTrace(GT_Log.err); + new Exception(this + " is now deprecated").printStackTrace(GTLog.err); // warn only once mWarned = true; } diff --git a/src/main/java/gregtech/api/enums/MaterialBuilder.java b/src/main/java/gregtech/api/enums/MaterialBuilder.java index 98ed5fa3f7..89104d6e96 100644 --- a/src/main/java/gregtech/api/enums/MaterialBuilder.java +++ b/src/main/java/gregtech/api/enums/MaterialBuilder.java @@ -31,7 +31,7 @@ public class MaterialBuilder { private Dyes color = Dyes._NULL; private int extraData = 0; private List materialList = new ArrayList<>(); - private List aspects = new ArrayList<>(); + private List aspects = new ArrayList<>(); private boolean hasCorrespondingFluid = false; private boolean hasCorrespondingGas = false; private boolean canBeCracked = false; @@ -242,7 +242,7 @@ public class MaterialBuilder { return this; } - public MaterialBuilder setAspects(List aspects) { + public MaterialBuilder setAspects(List aspects) { this.aspects = aspects; return this; } diff --git a/src/main/java/gregtech/api/enums/Materials.java b/src/main/java/gregtech/api/enums/Materials.java index 3d314c4742..3a963ca322 100644 --- a/src/main/java/gregtech/api/enums/Materials.java +++ b/src/main/java/gregtech/api/enums/Materials.java @@ -1,7 +1,7 @@ package gregtech.api.enums; import static gregtech.api.enums.FluidState.GAS; -import static gregtech.api.enums.GT_Values.M; +import static gregtech.api.enums.GTValues.M; import static gregtech.api.enums.Mods.Thaumcraft; import java.util.ArrayList; @@ -24,20 +24,20 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.TC_Aspects.TC_AspectStack; -import gregtech.api.fluid.GT_FluidFactory; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.TCAspects.TC_AspectStack; +import gregtech.api.fluid.GTFluidFactory; import gregtech.api.interfaces.IColorModulationContainer; import gregtech.api.interfaces.IMaterialHandler; import gregtech.api.interfaces.ISubTagContainer; import gregtech.api.objects.MaterialStack; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; import gregtech.common.config.gregtech.ConfigHarvestLevel; import gregtech.common.render.items.CosmicNeutroniumRenderer; -import gregtech.common.render.items.GT_GeneratedMaterial_Renderer; import gregtech.common.render.items.GaiaSpiritRenderer; +import gregtech.common.render.items.GeneratedMaterialRenderer; import gregtech.common.render.items.GlitchEffectRenderer; import gregtech.common.render.items.InfinityRenderer; import gregtech.common.render.items.TranscendentMetalRenderer; @@ -67,7 +67,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { // Spotless breaks the table below into many, many lines // spotless:off - public static Materials _NULL = new Materials(-1, TextureSet.SET_NONE, 1.0F, 0, 0, 0, 255, 255, 255, 0, "NULL", "NULL", 0, 0, 0, 0, false, false, 1, 1, 1, Dyes._NULL, Element._NULL, Collections.singletonList(new TC_AspectStack(TC_Aspects.VACUOS, 1))); + public static Materials _NULL = new Materials(-1, TextureSet.SET_NONE, 1.0F, 0, 0, 0, 255, 255, 255, 0, "NULL", "NULL", 0, 0, 0, 0, false, false, 1, 1, 1, Dyes._NULL, Element._NULL, Collections.singletonList(new TC_AspectStack(TCAspects.VACUOS, 1))); /** * Direct Elements */ @@ -352,37 +352,37 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { public static Materials Vyroxeres; public static Materials Yellorium; public static Materials Zectium; - public static Materials Ultimate = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Ultimate" , "Ultimate" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 8))); - public static Materials Advanced = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Advanced" , "Advanced" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 4))); + public static Materials Ultimate = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Ultimate" , "Ultimate" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 8))); + public static Materials Advanced = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Advanced" , "Advanced" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 4))); /** * Tiered materials, primarily Circuitry, Batteries and other Technical things */ - public static Materials ULV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Primitive" , "Primitive" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 1))); - public static Materials LV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Basic" , "Basic" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 2))); - public static Materials MV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Good" , "Good" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 3))); - public static Materials HV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Advanced" , "Advanced" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 4))); - public static Materials EV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Data" , "Data" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 5))); - public static Materials IV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Elite" , "Elite" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 6))); - public static Materials LuV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Master" , "Master" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 7))); - public static Materials ZPM = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Ultimate" , "Ultimate" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 8))); - public static Materials UV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Superconductor" , "Superconductor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.MACHINA, 9))); - public static Materials UHV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Infinite" , "Infinite" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 10))); - public static Materials UEV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Bio" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 11))); - public static Materials UIV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Optical" , "Optical" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 12))); - public static Materials UMV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Exotic" , "Exotic" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 13))); - public static Materials UXV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Cosmic" , "Cosmic" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 14))); - public static Materials MAX = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Transcendent" , "Transcendent" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 15))); - - public static Materials Resistor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Resistor" , "Resistor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 1))); - public static Materials Diode = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Diode" , "Diode" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 1))); - public static Materials Transistor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Transistor" , "Transistor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 1))); - public static Materials Capacitor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Capacitor" , "Capacitor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 1))); - public static Materials Inductor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Inductor" , "Inductor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 1))); - - public static Materials Nano = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Nano" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 11))); - public static Materials Piko = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Piko" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 12))); - public static Materials Quantum = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Quantum" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TC_Aspects.ELECTRUM, 13))); + public static Materials ULV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Primitive" , "Primitive" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 1))); + public static Materials LV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Basic" , "Basic" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 2))); + public static Materials MV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Good" , "Good" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 3))); + public static Materials HV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Advanced" , "Advanced" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 4))); + public static Materials EV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Data" , "Data" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 5))); + public static Materials IV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Elite" , "Elite" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 6))); + public static Materials LuV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Master" , "Master" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 7))); + public static Materials ZPM = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Ultimate" , "Ultimate" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 8))); + public static Materials UV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Superconductor" , "Superconductor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.MACHINA, 9))); + public static Materials UHV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Infinite" , "Infinite" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 10))); + public static Materials UEV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Bio" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 11))); + public static Materials UIV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Optical" , "Optical" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 12))); + public static Materials UMV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Exotic" , "Exotic" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 13))); + public static Materials UXV = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Cosmic" , "Cosmic" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 14))); + public static Materials MAX = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Transcendent" , "Transcendent" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 15))); + + public static Materials Resistor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Resistor" , "Resistor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 1))); + public static Materials Diode = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Diode" , "Diode" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 1))); + public static Materials Transistor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Transistor" , "Transistor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 1))); + public static Materials Capacitor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Capacitor" , "Capacitor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 1))); + public static Materials Inductor = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Inductor" , "Inductor" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 1))); + + public static Materials Nano = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Nano" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 11))); + public static Materials Piko = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Piko" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 12))); + public static Materials Quantum = new Materials( -1, TextureSet.SET_NONE , 1.0F, 0, 0, 0 , 255, 255, 255, 0, "Quantum" , "Bio" , 0, 0, -1, 0, false, false, 1, 1, 1, Dyes.dyeLightGray , Collections.singletonList(new TC_AspectStack(TCAspects.ELECTRUM, 13))); /** @@ -1029,10 +1029,10 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { public final short[] mRGBa = new short[] { 255, 255, 255, 0 }, mMoltenRGBa = new short[] { 255, 255, 255, 0 }; public TextureSet mIconSet; - public GT_GeneratedMaterial_Renderer renderer; + public GeneratedMaterialRenderer renderer; public List mMaterialList = new ArrayList<>(); public List mOreByProducts = new ArrayList<>(), mOreReRegistrations = new ArrayList<>(); - public List mAspects = new ArrayList<>(); + public List mAspects = new ArrayList<>(); public ArrayList mMaterialItems = new ArrayList<>(); public Collection mSubTags = new LinkedHashSet<>(); public Enchantment mEnchantmentTools = null, mEnchantmentArmors = null; @@ -1256,7 +1256,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { int aTypes, int aR, int aG, int aB, int aA, String aName, String aDefaultLocalName, int aFuelType, int aFuelPower, int aMeltingPoint, int aBlastFurnaceTemp, boolean aBlastFurnaceRequired, boolean aTransparent, int aOreValue, int aDensityMultiplier, int aDensityDivider, Dyes aColor, - List aAspects) { + List aAspects) { this( aMetaItemSubID, aIconSet, @@ -1287,7 +1287,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { int aTypes, int aR, int aG, int aB, int aA, String aName, String aDefaultLocalName, int aFuelType, int aFuelPower, int aMeltingPoint, int aBlastFurnaceTemp, boolean aBlastFurnaceRequired, boolean aTransparent, int aOreValue, int aDensityMultiplier, int aDensityDivider, Dyes aColor, Element aElement, - List aAspects) { + List aAspects) { this( aMetaItemSubID, aIconSet, @@ -1359,7 +1359,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { int aTypes, int aR, int aG, int aB, int aA, String aName, String aDefaultLocalName, int aFuelType, int aFuelPower, int aMeltingPoint, int aBlastFurnaceTemp, boolean aBlastFurnaceRequired, boolean aTransparent, int aOreValue, int aDensityMultiplier, int aDensityDivider, Dyes aColor, int aExtraData, - List aMaterialList, List aAspects) { + List aMaterialList, List aAspects) { this( aMetaItemSubID, aIconSet, @@ -1397,15 +1397,15 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { tAmountOfComponents += tMaterial.mAmount; if (tMaterial.mMaterial.mMeltingPoint > 0) tMeltingPoint += tMaterial.mMaterial.mMeltingPoint * tMaterial.mAmount; - if (aAspects == null) for (TC_Aspects.TC_AspectStack tAspect : tMaterial.mMaterial.mAspects) - tAspect.addToAspectList(mAspects); + if (aAspects == null) + for (TCAspects.TC_AspectStack tAspect : tMaterial.mMaterial.mAspects) tAspect.addToAspectList(mAspects); } if (mMeltingPoint < 0) mMeltingPoint = (short) (tMeltingPoint / tAmountOfComponents); tAmountOfComponents *= aDensityMultiplier; tAmountOfComponents /= aDensityDivider; - if (aAspects == null) for (TC_Aspects.TC_AspectStack tAspect : mAspects) + if (aAspects == null) for (TCAspects.TC_AspectStack tAspect : mAspects) tAspect.mAmount = Math.max(1, tAspect.mAmount / Math.max(1, tAmountOfComponents)); else mAspects.addAll(aAspects); } @@ -2478,7 +2478,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { public static void init() { new ProcessingConfig(); - if (!GT_Mod.gregtechproxy.mEnableAllMaterials) new ProcessingModSupport(); + if (!GTMod.gregtechproxy.mEnableAllMaterials) new ProcessingModSupport(); mMaterialHandlers.forEach(IMaterialHandler::onMaterialsInit); // This is where addon mods can add/manipulate // materials initMaterialProperties(); // No more material addition or manipulation should be done past this point! @@ -2538,8 +2538,8 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { if (aMaterial.mMetaItemSubID >= 0) { if (aMaterial.mMetaItemSubID < 1000) { if (aMaterial.mHasParentMod) { - if (GregTech_API.sGeneratedMaterials[aMaterial.mMetaItemSubID] == null) { - GregTech_API.sGeneratedMaterials[aMaterial.mMetaItemSubID] = aMaterial; + if (GregTechAPI.sGeneratedMaterials[aMaterial.mMetaItemSubID] == null) { + GregTechAPI.sGeneratedMaterials[aMaterial.mMetaItemSubID] = aMaterial; } else throw new IllegalArgumentException( "The Material Index " + aMaterial.mMetaItemSubID + " for " @@ -2556,7 +2556,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { } private static void addToolValues(Materials aMaterial) { - // Moved from GT_Proxy? (Not sure) + // Moved from GTProxy? (Not sure) aMaterial.mHandleMaterial = (aMaterial == Desh ? aMaterial.mHandleMaterial : aMaterial == Diamond || aMaterial == Thaumium ? Wood : aMaterial.contains(SubTag.BURNING) ? Blaze @@ -2596,10 +2596,10 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { } if (aMaterial.mHasPlasma) { - GT_Mod.gregtechproxy.addAutogeneratedPlasmaFluid(aMaterial); + GTMod.gregtechproxy.addAutogeneratedPlasmaFluid(aMaterial); } if (aMaterial.mHasGas) { - GT_FluidFactory + GTFluidFactory .of(aMaterial.mName.toLowerCase(), aMaterial.mDefaultLocalName, aMaterial, GAS, aMaterial.mGasTemp); } } @@ -2610,18 +2610,18 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { } private static void addHarvestLevelNerfs(Materials aMaterial) { - /* Moved the harvest level changes from GT_Mod to have fewer things iterating over MATERIALS_ARRAY */ - if (GT_Mod.gregtechproxy.mChangeHarvestLevels && aMaterial.mToolQuality > 0 - && aMaterial.mMetaItemSubID < GT_Mod.gregtechproxy.mHarvestLevel.length + /* Moved the harvest level changes from GTMod to have fewer things iterating over MATERIALS_ARRAY */ + if (GTMod.gregtechproxy.mChangeHarvestLevels && aMaterial.mToolQuality > 0 + && aMaterial.mMetaItemSubID < GTMod.gregtechproxy.mHarvestLevel.length && aMaterial.mMetaItemSubID >= 0) { - GT_Mod.gregtechproxy.mHarvestLevel[aMaterial.mMetaItemSubID] = aMaterial.mToolQuality; + GTMod.gregtechproxy.mHarvestLevel[aMaterial.mMetaItemSubID] = aMaterial.mToolQuality; } } private static void addHarvestLevels() { - GT_Mod.gregtechproxy.mChangeHarvestLevels = ConfigHarvestLevel.activateHarvestLevelChange; - GT_Mod.gregtechproxy.mMaxHarvestLevel = Math.min(15, ConfigHarvestLevel.maxHarvestLevel); - GT_Mod.gregtechproxy.mGraniteHavestLevel = ConfigHarvestLevel.graniteHarvestLevel; + GTMod.gregtechproxy.mChangeHarvestLevels = ConfigHarvestLevel.activateHarvestLevelChange; + GTMod.gregtechproxy.mMaxHarvestLevel = Math.min(15, ConfigHarvestLevel.maxHarvestLevel); + GTMod.gregtechproxy.mGraniteHavestLevel = ConfigHarvestLevel.graniteHarvestLevel; } public static void initMaterialProperties() { @@ -2690,7 +2690,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { public static String getLocalizedNameForItem(String aFormat, int aMaterialID) { if (aMaterialID >= 0 && aMaterialID < 1000) { - Materials aMaterial = GregTech_API.sGeneratedMaterials[aMaterialID]; + Materials aMaterial = GregTechAPI.sGeneratedMaterials[aMaterialID]; if (aMaterial != null) return aMaterial.getLocalizedNameForItem(aFormat); } return aFormat; @@ -2814,7 +2814,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { return mMaterialItems.stream() .anyMatch( tStack -> Arrays.stream(aStacks) - .anyMatch(aStack -> GT_Utility.areStacksEqual(aStack, tStack, !tStack.hasTagCompound()))); + .anyMatch(aStack -> GTUtility.areStacksEqual(aStack, tStack, !tStack.hasTagCompound()))); } /** @@ -2824,7 +2824,7 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { if (aStack == null) return false; boolean temp = false; int mMaterialItems_sS = mMaterialItems.size(); - for (int i = 0; i < mMaterialItems_sS; i++) if (GT_Utility.areStacksEqual(aStack, mMaterialItems.get(i))) { + for (int i = 0; i < mMaterialItems_sS; i++) if (GTUtility.areStacksEqual(aStack, mMaterialItems.get(i))) { mMaterialItems.remove(i--); temp = true; } @@ -3136,43 +3136,43 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { */ public boolean isProperSolderingFluid() { return mStandardMoltenFluid != null && contains(SubTag.SOLDERING_MATERIAL) - && !(GregTech_API.mUseOnlyGoodSolderingMaterials && !contains(SubTag.SOLDERING_MATERIAL_GOOD)); + && !(GregTechAPI.mUseOnlyGoodSolderingMaterials && !contains(SubTag.SOLDERING_MATERIAL_GOOD)); } public ItemStack getCells(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.cell, this, amount); + return GTOreDictUnificator.get(OrePrefixes.cell, this, amount); } public ItemStack getDust(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.dust, this, amount); + return GTOreDictUnificator.get(OrePrefixes.dust, this, amount); } public ItemStack getDustSmall(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.dustSmall, this, amount); + return GTOreDictUnificator.get(OrePrefixes.dustSmall, this, amount); } public ItemStack getDustTiny(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.dustTiny, this, amount); + return GTOreDictUnificator.get(OrePrefixes.dustTiny, this, amount); } public ItemStack getGems(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.gem, this, amount); + return GTOreDictUnificator.get(OrePrefixes.gem, this, amount); } public ItemStack getIngots(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.ingot, this, amount); + return GTOreDictUnificator.get(OrePrefixes.ingot, this, amount); } public ItemStack getNuggets(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.nugget, this, amount); + return GTOreDictUnificator.get(OrePrefixes.nugget, this, amount); } public ItemStack getBlocks(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.block, this, amount); + return GTOreDictUnificator.get(OrePrefixes.block, this, amount); } public ItemStack getPlates(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.plate, this, amount); + return GTOreDictUnificator.get(OrePrefixes.plate, this, amount); } public static Materials getGtMaterialFromFluid(Fluid fluid) { @@ -3180,6 +3180,6 @@ public class Materials implements IColorModulationContainer, ISubTagContainer { } public ItemStack getNanite(int amount) { - return GT_OreDictUnificator.get(OrePrefixes.nanite, this, amount); + return GTOreDictUnificator.get(OrePrefixes.nanite, this, amount); } } diff --git a/src/main/java/gregtech/api/enums/MaterialsBotania.java b/src/main/java/gregtech/api/enums/MaterialsBotania.java index 6fe538a0bc..6373595e91 100644 --- a/src/main/java/gregtech/api/enums/MaterialsBotania.java +++ b/src/main/java/gregtech/api/enums/MaterialsBotania.java @@ -9,7 +9,7 @@ import static gregtech.api.enums.OrePrefixes.rotor; import java.util.Arrays; -import gregtech.api.enums.TC_Aspects.TC_AspectStack; +import gregtech.api.enums.TCAspects.TC_AspectStack; public class MaterialsBotania { @@ -28,7 +28,7 @@ public class MaterialsBotania { .setBlastFurnaceTemp(1500) .setBlastFurnaceRequired(true) .setAspects( - Arrays.asList(new TC_AspectStack(TC_Aspects.METALLUM, 3), new TC_AspectStack(TC_Aspects.PRAECANTATIO, 1))) + Arrays.asList(new TC_AspectStack(TCAspects.METALLUM, 3), new TC_AspectStack(TCAspects.PRAECANTATIO, 1))) .constructMaterial(); public static Materials Terrasteel = new MaterialBuilder(202, TextureSet.SET_METALLIC, "Terrasteel") .setName("Terrasteel") @@ -45,9 +45,9 @@ public class MaterialsBotania { .setBlastFurnaceRequired(true) .setAspects( Arrays.asList( - new TC_AspectStack(TC_Aspects.METALLUM, 2), - new TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_AspectStack(TC_Aspects.PRAECANTATIO, 1))) + new TC_AspectStack(TCAspects.METALLUM, 2), + new TC_AspectStack(TCAspects.TERRA, 1), + new TC_AspectStack(TCAspects.PRAECANTATIO, 1))) .constructMaterial(); public static Materials ElvenElementium = new MaterialBuilder(203, TextureSet.SET_METALLIC, "Elven Elementium") .setName("ElvenElementium") @@ -64,9 +64,9 @@ public class MaterialsBotania { .setBlastFurnaceRequired(true) .setAspects( Arrays.asList( - new TC_AspectStack(TC_Aspects.METALLUM, 3), - new TC_AspectStack(TC_Aspects.PRAECANTATIO, 2), - new TC_AspectStack(TC_Aspects.AURAM, 1))) + new TC_AspectStack(TCAspects.METALLUM, 3), + new TC_AspectStack(TCAspects.PRAECANTATIO, 2), + new TC_AspectStack(TCAspects.AURAM, 1))) .constructMaterial(); public static Materials Livingrock = new MaterialBuilder(204, new TextureSet("Livingrock", true), "Livingrock") .setName("Livingrock") @@ -79,7 +79,7 @@ public class MaterialsBotania { .setOreValue(3) .setDensityMultiplier(1) .setDensityDivider(1) - .setAspects(Arrays.asList(new TC_AspectStack(TC_Aspects.TERRA, 2), new TC_AspectStack(TC_Aspects.VICTUS, 2))) + .setAspects(Arrays.asList(new TC_AspectStack(TCAspects.TERRA, 2), new TC_AspectStack(TCAspects.VICTUS, 2))) .constructMaterial(); public static Materials GaiaSpirit = new Materials( 205, @@ -105,10 +105,10 @@ public class MaterialsBotania { 1, Dyes._NULL, Arrays.asList( - new TC_AspectStack(TC_Aspects.PRAECANTATIO, 27), - new TC_AspectStack(TC_Aspects.AURAM, 24), - new TC_AspectStack(TC_Aspects.VICTUS, 24), - new TC_AspectStack(TC_Aspects.METALLUM, 1))); + new TC_AspectStack(TCAspects.PRAECANTATIO, 27), + new TC_AspectStack(TCAspects.AURAM, 24), + new TC_AspectStack(TCAspects.VICTUS, 24), + new TC_AspectStack(TCAspects.METALLUM, 1))); public static Materials Livingwood = new MaterialBuilder(206, new TextureSet("Livingwood", true), "Livingwood") .setName("Livingwood") .addDustItems() @@ -121,7 +121,7 @@ public class MaterialsBotania { .setOreValue(3) .setDensityMultiplier(1) .setDensityDivider(1) - .setAspects(Arrays.asList(new TC_AspectStack(TC_Aspects.ARBOR, 4), new TC_AspectStack(TC_Aspects.VICTUS, 2))) + .setAspects(Arrays.asList(new TC_AspectStack(TCAspects.ARBOR, 4), new TC_AspectStack(TCAspects.VICTUS, 2))) .constructMaterial(); public static Materials Dreamwood = new MaterialBuilder(207, new TextureSet("Dreamwood", true), "Dreamwood") .setName("Dreamwood") @@ -137,9 +137,9 @@ public class MaterialsBotania { .setDensityDivider(1) .setAspects( Arrays.asList( - new TC_AspectStack(TC_Aspects.ARBOR, 4), - new TC_AspectStack(TC_Aspects.AURAM, 2), - new TC_AspectStack(TC_Aspects.PRAECANTATIO, 1))) + new TC_AspectStack(TCAspects.ARBOR, 4), + new TC_AspectStack(TCAspects.AURAM, 2), + new TC_AspectStack(TCAspects.PRAECANTATIO, 1))) .constructMaterial(); public static Materials ManaDiamond = new Materials( 208, @@ -165,9 +165,9 @@ public class MaterialsBotania { 1, Dyes._NULL, Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.PRAECANTATIO, 4), - new TC_Aspects.TC_AspectStack(TC_Aspects.VITREUS, 4), - new TC_Aspects.TC_AspectStack(TC_Aspects.LUCRUM, 4))); + new TCAspects.TC_AspectStack(TCAspects.PRAECANTATIO, 4), + new TCAspects.TC_AspectStack(TCAspects.VITREUS, 4), + new TCAspects.TC_AspectStack(TCAspects.LUCRUM, 4))); public static Materials BotaniaDragonstone = new Materials( 209, TextureSet.SET_DIAMOND, @@ -192,9 +192,9 @@ public class MaterialsBotania { 1, Dyes._NULL, Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.PRAECANTATIO, 6), - new TC_Aspects.TC_AspectStack(TC_Aspects.VITREUS, 6), - new TC_Aspects.TC_AspectStack(TC_Aspects.AURAM, 4))); + new TCAspects.TC_AspectStack(TCAspects.PRAECANTATIO, 6), + new TCAspects.TC_AspectStack(TCAspects.VITREUS, 6), + new TCAspects.TC_AspectStack(TCAspects.AURAM, 4))); public static void init() { GaiaSpirit.mChemicalFormula = "Gs"; diff --git a/src/main/java/gregtech/api/enums/MaterialsGTNH.java b/src/main/java/gregtech/api/enums/MaterialsGTNH.java new file mode 100644 index 0000000000..12a53f6b86 --- /dev/null +++ b/src/main/java/gregtech/api/enums/MaterialsGTNH.java @@ -0,0 +1,626 @@ +package gregtech.api.enums; + +import static gregtech.GTMod.GT_FML_LOGGER; + +import gregtech.api.interfaces.IMaterialHandler; + +public class MaterialsGTNH implements IMaterialHandler { + + public MaterialsGTNH() { + GT_FML_LOGGER.info("Registering GTNH-Materials (post Java 64kb limit)"); + Materials.add(this); + } + + /** + * This Class is for adding new Materials since Java has a Limiation of 64kb per Method / Class header + */ + public static Materials Signalum = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "Signalum", + "Signalum", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + + public static Materials Lumium = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "Lumium", + "Lumium", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials EnrichedCopper = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "EnrichedCopper", + "Enriched Copper", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials DiamondCopper = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "DiamondCopper", + "Diamond Copper", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials TarPitch = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "TarPitch", + "Tar Pitch", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials LimePure = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 0, + 0, + 255, + 255, + 255, + 0, + "LimePure", + "Pure Lime", + 0, + 0, + -1, + 0, + false, + false, + 1, + 1, + 1, + Dyes.dyeLime); + public static Materials Wimalite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 8, + 255, + 255, + 255, + 0, + "Wimalite", + "Wimalite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes.dyeYellow); + public static Materials Yellorite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 8, + 255, + 255, + 255, + 0, + "Yellorite", + "Yellorite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes.dyeYellow); + public static Materials Quantum = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 0, + 0, + 255, + 255, + 255, + 0, + "Quantum", + "Quantum", + 0, + 0, + -1, + 0, + false, + false, + 1, + 1, + 1, + Dyes.dyeWhite); + public static Materials Turquoise = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1, + 255, + 255, + 255, + 0, + "Turquoise", + "Turquoise", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Tapazite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1, + 255, + 255, + 255, + 0, + "Tapazite", + "Tapazite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes.dyeGreen); + public static Materials Thyrium = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1 | 2 | 8, + 255, + 255, + 255, + 0, + "Thyrium", + "Thyrium", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Tourmaline = new Materials( + -1, + TextureSet.SET_RUBY, + 1.0F, + 0, + 1, + 1, + 255, + 255, + 255, + 0, + "Tourmaline", + "Tourmaline", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Spinel = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 0, + 255, + 255, + 255, + 0, + "Spinel", + "Spinel", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Starconium = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1 | 2 | 8, + 255, + 255, + 255, + 0, + "Starconium", + "Starconium", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Sugilite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1, + 255, + 255, + 255, + 0, + "Sugilite", + "Sugilite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Prismarine = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 4, + 255, + 255, + 255, + 0, + "Prismarine", + "Prismarine", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials GraveyardDirt = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1, + 255, + 255, + 255, + 0, + "GraveyardDirt", + "Graveyard Dirt", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Tennantite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1, + 255, + 255, + 255, + 0, + "Tennantite", + "Tennantite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Fairy = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "Fairy", + "Fairy", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Ludicrite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 1 | 2, + 255, + 255, + 255, + 0, + "Ludicrite", + "Ludicrite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials AquaRegia = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 0, + 255, + 255, + 255, + 0, + "AquaRegia", + "Aqua Regia", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials SolutionBlueVitriol = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 0, + 255, + 255, + 255, + 0, + "SolutionBlueVitriol", + "Blue Vitriol Solution", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials SolutionNickelSulfate = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 2, + 0, + 255, + 255, + 255, + 0, + "SolutionNickelSulfate", + "Nickel Sulfate Solution", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes._NULL); + public static Materials Lodestone = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1 | 8, + 255, + 255, + 255, + 0, + "Lodestone", + "Lodestone", + 0, + 0, + -1, + 0, + false, + false, + 1, + 1, + 1, + Dyes._NULL); + public static Materials Luminite = new Materials( + -1, + TextureSet.SET_NONE, + 1.0F, + 0, + 1, + 1 | 8, + 250, + 250, + 250, + 0, + "Luminite", + "Luminite", + 0, + 0, + -1, + 0, + false, + false, + 3, + 1, + 1, + Dyes.dyeWhite); + + private static void initSubTags() { + SubTag.METAL.addTo(Signalum, Lumium, EnrichedCopper, DiamondCopper); + SubTag.NO_SMASHING.addTo(TarPitch); + } + + @Override + public void onMaterialsInit() { + initSubTags(); + } +} diff --git a/src/main/java/gregtech/api/enums/MaterialsKevlar.java b/src/main/java/gregtech/api/enums/MaterialsKevlar.java index 6612bc8b65..bea0c0d244 100644 --- a/src/main/java/gregtech/api/enums/MaterialsKevlar.java +++ b/src/main/java/gregtech/api/enums/MaterialsKevlar.java @@ -21,8 +21,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VENENUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.TERRA, 1), + new TCAspects.TC_AspectStack(TCAspects.VENENUM, 1))) .constructMaterial(); // C15H10N2O2 public static Materials DiaminodiphenylmethanMixture = new MaterialBuilder( 795, @@ -39,8 +39,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Nitrogen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VENENUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.VENENUM, 1))) .constructMaterial(); // C13H14N2 public static Materials DiphenylmethaneDiisocyanateMixture = new MaterialBuilder( 794, @@ -58,8 +58,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VENENUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.VENENUM, 1))) .constructMaterial(); // C15H10N2O2 public static Materials Butyraldehyde = new MaterialBuilder(793, TextureSet.SET_FLUID, "Butyraldehyde") .setName("Butyraldehyde") @@ -74,8 +74,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 1)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.IGNIS, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.IGNIS, 1))) .constructMaterial(); // C4H8O public static Materials Isobutyraldehyde = new MaterialBuilder(792, TextureSet.SET_FLUID, "Isobutyraldehyde") .setName("Isobutyraldehyde") @@ -91,8 +91,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 1)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.IGNIS, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.IGNIS, 1))) .constructMaterial(); // C4H8O public static Materials NickelTetracarbonyl = new MaterialBuilder(791, TextureSet.SET_FLUID, "Nickel Tetracarbonyl") .setName("NickelTetracarbonyl") @@ -107,8 +107,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 4)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.METALLUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.METALLUM, 1))) .constructMaterial(); // C4NiO4 public static Materials KevlarCatalyst = new MaterialBuilder(790, TextureSet.SET_DULL, "Polyurethane Catalyst A") .setName("PolyurethaneCatalystADust") @@ -118,8 +118,8 @@ public class MaterialsKevlar { .setMeltingPoint(300) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.LUCRUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.LUCRUM, 1))) .constructMaterial(); public static Materials EthyleneOxide = new MaterialBuilder(789, TextureSet.SET_FLUID, "Ethylene Oxide") .setName("EthyleneOxide") @@ -134,8 +134,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 1)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.IGNIS, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.IGNIS, 1))) .constructMaterial(); // C2H4O public static Materials SiliconOil = new MaterialBuilder(788, TextureSet.SET_FLUID, "Silicon Oil") .setName("SiliconOil") @@ -146,8 +146,8 @@ public class MaterialsKevlar { .setMeltingPoint(473) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.MACHINA, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.MACHINA, 1))) .constructMaterial(); public static Materials Ethyleneglycol = new MaterialBuilder(787, TextureSet.SET_FLUID, "Ethylene Glycol") .setName("EthyleneGlycol") @@ -162,8 +162,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.IGNIS, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.IGNIS, 1))) .constructMaterial(); // C2H6O2 public static Materials Acetaldehyde = new MaterialBuilder(786, TextureSet.SET_FLUID, "Acetaldehyde") .setName("Acetaldehyde") @@ -178,8 +178,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 1)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.IGNIS, 1))) + new TCAspects.TC_AspectStack(TCAspects.AQUA, 1), + new TCAspects.TC_AspectStack(TCAspects.IGNIS, 1))) .constructMaterial(); // C2H4O public static Materials Pentaerythritol = new MaterialBuilder(785, TextureSet.SET_DULL, "Pentaerythritol") .setName("Pentaerythritol") @@ -193,8 +193,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 4)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.LUCRUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.TERRA, 1), + new TCAspects.TC_AspectStack(TCAspects.LUCRUM, 1))) .constructMaterial(); // C5H12O4 public static Materials PolyurethaneResin = new MaterialBuilder(784, TextureSet.SET_FLUID, "Polyurethane Resin") .setName("PolyurethaneResin") @@ -219,8 +219,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 1)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VENENUM, 1))) + new TCAspects.TC_AspectStack(TCAspects.TERRA, 1), + new TCAspects.TC_AspectStack(TCAspects.VENENUM, 1))) .constructMaterial(); // C5H9NO public static Materials TerephthaloylChloride = new MaterialBuilder( 782, @@ -237,8 +237,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VITREUS, 1))) + new TCAspects.TC_AspectStack(TCAspects.TERRA, 1), + new TCAspects.TC_AspectStack(TCAspects.VITREUS, 1))) .constructMaterial(); // C8H4Cl2O2 public static Materials Acetylene = new MaterialBuilder(781, TextureSet.SET_FLUID, "Acetylene").setName("Acetylene") .addCell() @@ -274,8 +274,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Oxygen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VITREUS, 1))) + new TCAspects.TC_AspectStack(TCAspects.TERRA, 1), + new TCAspects.TC_AspectStack(TCAspects.VITREUS, 1))) .constructMaterial(); // C6H6N2O2 public static Materials ParaPhenylenediamine = new MaterialBuilder( 779, @@ -291,8 +291,8 @@ public class MaterialsKevlar { new MaterialStack(Materials.Nitrogen, 2)) .setAspects( Arrays.asList( - new TC_Aspects.TC_AspectStack(TC_Aspects.TERRA, 1), - new TC_Aspects.TC_AspectStack(TC_Aspects.VITREUS, 1))) + new TCAspects.TC_AspectStack(TCAspects.TERRA, 1), + new TCAspects.TC_AspectStack(TCAspects.VITREUS, 1))) .constructMaterial(); // C6H6N2 public static Materials Methylamine = new MaterialBuilder(778, TextureSet.SET_FLUID, "Methylamine") .setName("Methylamine") diff --git a/src/main/java/gregtech/api/enums/MaterialsUEVplus.java b/src/main/java/gregtech/api/enums/MaterialsUEVplus.java index 7542e1f600..49ab432c5f 100644 --- a/src/main/java/gregtech/api/enums/MaterialsUEVplus.java +++ b/src/main/java/gregtech/api/enums/MaterialsUEVplus.java @@ -283,7 +283,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.AQUA, 1))) .setProcessingMaterialTierEU(TierEU.RECIPE_UEV) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe(); @@ -310,7 +310,7 @@ public class MaterialsUEVplus { 1000, 1000, Dyes.dyeBlack, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.AQUA, 1))) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe() .setProcessingMaterialTierEU(TierEU.RECIPE_UHV); @@ -337,7 +337,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.AQUA, 1))) .setProcessingMaterialTierEU(TierEU.RECIPE_UIV); public static Materials RawStarMatter = new Materials( 584, @@ -485,7 +485,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.AQUA, 1))) .setProcessingMaterialTierEU(TierEU.RECIPE_UMV); public static Materials Eternity = new Materials( @@ -511,7 +511,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.AQUA, 1))) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe() .setProcessingMaterialTierEU(TierEU.RECIPE_UMV); @@ -563,7 +563,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.AQUA, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.AQUA, 1))) .setProcessingMaterialTierEU(TierEU.RECIPE_UMV); public static Materials QuarkGluonPlasma = new Materials( @@ -661,7 +661,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.ITER, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.ITER, 1))) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe() .setProcessingMaterialTierEU(TierEU.RECIPE_UEV); @@ -689,7 +689,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.SENSUS, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.SENSUS, 1))) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe() .setProcessingMaterialTierEU(TierEU.RECIPE_UEV); @@ -717,7 +717,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.SENSUS, 1))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.SENSUS, 1))) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe() .setProcessingMaterialTierEU(TierEU.RECIPE_UEV) @@ -746,7 +746,7 @@ public class MaterialsUEVplus { 1, 1, Dyes._NULL, - Collections.singletonList(new TC_Aspects.TC_AspectStack(TC_Aspects.VACUOS, 150))) + Collections.singletonList(new TCAspects.TC_AspectStack(TCAspects.VACUOS, 150))) .disableAutoGeneratedBlastFurnaceRecipes() .disableAutoGeneratedVacuumFreezerRecipe(); diff --git a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java index 04a61c713e..4d11475ac4 100644 --- a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java +++ b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java @@ -560,10 +560,10 @@ public enum MetaTileEntityIDs { GT_Dehydrator_IV(814), GT_Dehydrator_LuV(815), GT_Dehydrator_ZPM(816), - GT_FluidTank_ULV(817), - GT_FluidTank_LV(818), - GT_FluidTank_MV(819), - GT_FluidTank_HV(820), + GTFluidTank_ULV(817), + GTFluidTank_LV(818), + GTFluidTank_MV(819), + GTFluidTank_HV(820), COMET_Cyclotron(828), Industrial_FishingPond(829), Geothermal_Engine_EV(830), diff --git a/src/main/java/gregtech/api/enums/OreMixes.java b/src/main/java/gregtech/api/enums/OreMixes.java index c5c306baab..0a4b2fbc4e 100644 --- a/src/main/java/gregtech/api/enums/OreMixes.java +++ b/src/main/java/gregtech/api/enums/OreMixes.java @@ -1,15 +1,15 @@ package gregtech.api.enums; -import static bloodasp.galacticgreg.api.enums.DimensionDef.*; +import static galacticgreg.api.enums.DimensionDef.*; import static gregtech.common.OreMixBuilder.NETHER; import static gregtech.common.OreMixBuilder.OW; import static gregtech.common.OreMixBuilder.THE_END; import static gregtech.common.OreMixBuilder.TWILIGHT_FOREST; -import bloodasp.galacticgreg.GT_Worldgen_GT_Ore_Layer_Space; -import bloodasp.galacticgreg.api.enums.DimensionDef; -import gregtech.common.GT_Worldgen_GT_Ore_Layer; +import galacticgreg.WorldgenOreLayerSpace; +import galacticgreg.api.enums.DimensionDef; import gregtech.common.OreMixBuilder; +import gregtech.common.WorldgenGTOreLayer; public enum OreMixes { @@ -972,11 +972,11 @@ public enum OreMixes { this.oreMixBuilder = oreMixBuilder; } - public GT_Worldgen_GT_Ore_Layer addGTOreLayer() { - return new GT_Worldgen_GT_Ore_Layer(this.oreMixBuilder); + public WorldgenGTOreLayer addGTOreLayer() { + return new WorldgenGTOreLayer(this.oreMixBuilder); } - public GT_Worldgen_GT_Ore_Layer_Space addGaGregOreLayer() { - return new GT_Worldgen_GT_Ore_Layer_Space(this.oreMixBuilder); + public WorldgenOreLayerSpace addGaGregOreLayer() { + return new WorldgenOreLayerSpace(this.oreMixBuilder); } } diff --git a/src/main/java/gregtech/api/enums/OrePrefixes.java b/src/main/java/gregtech/api/enums/OrePrefixes.java index 7beaea9254..5f1ca97e83 100644 --- a/src/main/java/gregtech/api/enums/OrePrefixes.java +++ b/src/main/java/gregtech/api/enums/OrePrefixes.java @@ -1,8 +1,8 @@ package gregtech.api.enums; -import static gregtech.api.enums.GT_Values.B; -import static gregtech.api.enums.GT_Values.D2; -import static gregtech.api.enums.GT_Values.M; +import static gregtech.api.enums.GTValues.B; +import static gregtech.api.enums.GTValues.D2; +import static gregtech.api.enums.GTValues.M; import java.util.ArrayList; import java.util.Arrays; @@ -15,16 +15,16 @@ import net.minecraft.item.ItemStack; import com.google.common.collect.ImmutableList; -import gregtech.api.enums.TC_Aspects.TC_AspectStack; +import gregtech.api.enums.TCAspects.TC_AspectStack; import gregtech.api.interfaces.ICondition; import gregtech.api.interfaces.IOreRecipeRegistrator; import gregtech.api.interfaces.ISubTagContainer; -import gregtech.api.objects.GT_ArrayList; -import gregtech.api.objects.GT_ItemStack; +import gregtech.api.objects.GTArrayList; +import gregtech.api.objects.GTItemStack; import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtility; import gregtech.loaders.materialprocessing.ProcessingModSupport; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import it.unimi.dsi.fastutil.objects.ObjectSet; @@ -932,7 +932,7 @@ public enum OrePrefixes { bulletGtLarge.mSecondaryMaterial = new MaterialStack(Materials.Brass, ingot.mMaterialAmount / 3); } - public final ArrayList mPrefixedItems = new GT_ArrayList<>(false, 16); + public final ArrayList mPrefixedItems = new GTArrayList<>(false, 16); public final short mTextureIndex; public final String mRegularLocalName, mLocalizedMaterialPre, mLocalizedMaterialPost; public final boolean mIsUsedForOreProcessing, mIsEnchantable, mIsUnificatable, mIsMaterialBased, mIsSelfReferencing, @@ -957,7 +957,7 @@ public enum OrePrefixes { private final ObjectSet mContainsTestCache = new ObjectOpenCustomHashSet<>( 512, 0.5f, - GT_ItemStack.ITEMSTACK_HASH_STRATEGY2); + GTItemStack.ITEMSTACK_HASH_STRATEGY2); public static final List mPreventableComponents = new LinkedList<>( Arrays.asList( OrePrefixes.gem, @@ -1037,36 +1037,36 @@ public enum OrePrefixes { mTextureIndex = (short) aTextureindex; if (name().startsWith("ore")) { - new TC_AspectStack(TC_Aspects.TERRA, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.TERRA, 1).addToAspectList(mAspects); } else if (name().startsWith("wire") || name().startsWith("cable")) { - new TC_AspectStack(TC_Aspects.ELECTRUM, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.ELECTRUM, 1).addToAspectList(mAspects); } else if (name().startsWith("dust")) { - new TC_AspectStack(TC_Aspects.PERDITIO, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.PERDITIO, 1).addToAspectList(mAspects); } else if (name().startsWith("crushed")) { - new TC_AspectStack(TC_Aspects.PERFODIO, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.PERFODIO, 1).addToAspectList(mAspects); } else if (name().startsWith("ingot") || name().startsWith("nugget")) { - new TC_AspectStack(TC_Aspects.METALLUM, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.METALLUM, 1).addToAspectList(mAspects); } else if (name().startsWith("armor")) { - new TC_AspectStack(TC_Aspects.TUTAMEN, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.TUTAMEN, 1).addToAspectList(mAspects); } else if (name().startsWith("stone")) { - new TC_AspectStack(TC_Aspects.TERRA, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.TERRA, 1).addToAspectList(mAspects); } else if (name().startsWith("pipe")) { - new TC_AspectStack(TC_Aspects.ITER, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.ITER, 1).addToAspectList(mAspects); } else if (name().startsWith("gear")) { - new TC_AspectStack(TC_Aspects.MOTUS, 1).addToAspectList(mAspects); - new TC_AspectStack(TC_Aspects.MACHINA, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.MOTUS, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.MACHINA, 1).addToAspectList(mAspects); } else if (name().startsWith("frame") || name().startsWith("plate")) { - new TC_AspectStack(TC_Aspects.FABRICO, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.FABRICO, 1).addToAspectList(mAspects); } else if (name().startsWith("tool")) { - new TC_AspectStack(TC_Aspects.INSTRUMENTUM, 2).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.INSTRUMENTUM, 2).addToAspectList(mAspects); } else if (name().startsWith("gem") || name().startsWith("crystal") || name().startsWith("lens")) { - new TC_AspectStack(TC_Aspects.VITREUS, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.VITREUS, 1).addToAspectList(mAspects); } else if (name().startsWith("circuit")) { - new TC_AspectStack(TC_Aspects.COGNITIO, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.COGNITIO, 1).addToAspectList(mAspects); } else if (name().startsWith("computer")) { - new TC_AspectStack(TC_Aspects.COGNITIO, 4).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.COGNITIO, 4).addToAspectList(mAspects); } else if (name().startsWith("battery")) { - new TC_AspectStack(TC_Aspects.ELECTRUM, 1).addToAspectList(mAspects); + new TC_AspectStack(TCAspects.ELECTRUM, 1).addToAspectList(mAspects); } } @@ -1113,7 +1113,7 @@ public enum OrePrefixes { } public static OrePrefixes getPrefix(String aPrefixName, OrePrefixes aReplacement) { - Object tObject = GT_Utility.getFieldContent(OrePrefixes.class, aPrefixName, false, false); + Object tObject = GTUtility.getFieldContent(OrePrefixes.class, aPrefixName, false, false); if (tObject instanceof OrePrefixes) return (OrePrefixes) tObject; return aReplacement; } @@ -1145,13 +1145,13 @@ public enum OrePrefixes { } public boolean contains(ItemStack aStack) { - return !GT_Utility.isStackInvalid(aStack) && mContainsTestCache.contains(aStack); + return !GTUtility.isStackInvalid(aStack) && mContainsTestCache.contains(aStack); } public boolean containsUnCached(ItemStack aStack) { // In case someone needs this for (ItemStack tStack : mPrefixedItems) { - if (GT_Utility.areStacksEqual(aStack, tStack, !tStack.hasTagCompound())) { + if (GTUtility.areStacksEqual(aStack, tStack, !tStack.hasTagCompound())) { return true; } } @@ -1197,20 +1197,20 @@ public enum OrePrefixes { } if (!((aMaterial != Materials._NULL || mIsSelfReferencing || !mIsMaterialBased) - && GT_Utility.isStackValid(aStack))) { + && GTUtility.isStackValid(aStack))) { return; } for (IOreRecipeRegistrator tRegistrator : mOreProcessing) { - if (D2) GT_Log.ore.println( + if (D2) GTLog.ore.println( "Processing '" + aOreDictName + "' with the Prefix '" + name() + "' and the Material '" + aMaterial.mName + "' at " - + GT_Utility.getClassName(tRegistrator)); - tRegistrator.registerOre(this, aMaterial, aOreDictName, aModName, GT_Utility.copyAmount(1, aStack)); + + GTUtility.getClassName(tRegistrator)); + tRegistrator.registerOre(this, aMaterial, aOreDictName, aModName, GTUtility.copyAmount(1, aStack)); } } diff --git a/src/main/java/gregtech/api/enums/SmallOres.java b/src/main/java/gregtech/api/enums/SmallOres.java index 6de67bc3b9..3cd15b5f86 100644 --- a/src/main/java/gregtech/api/enums/SmallOres.java +++ b/src/main/java/gregtech/api/enums/SmallOres.java @@ -1,43 +1,43 @@ package gregtech.api.enums; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Anubis; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Asteroids; -import static bloodasp.galacticgreg.api.enums.DimensionDef.BarnardE; -import static bloodasp.galacticgreg.api.enums.DimensionDef.BarnardF; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Callisto; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Ceres; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Deimos; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Enceladus; -import static bloodasp.galacticgreg.api.enums.DimensionDef.EndAsteroids; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Ganymede; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Haumea; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Horus; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Io; -import static bloodasp.galacticgreg.api.enums.DimensionDef.KuiperBelt; -import static bloodasp.galacticgreg.api.enums.DimensionDef.MakeMake; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Mars; -import static bloodasp.galacticgreg.api.enums.DimensionDef.MehenBelt; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Mercury; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Miranda; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Moon; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Oberon; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Phobos; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Pluto; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Proteus; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Seth; -import static bloodasp.galacticgreg.api.enums.DimensionDef.TcetiE; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Titan; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Triton; -import static bloodasp.galacticgreg.api.enums.DimensionDef.VegaB; -import static bloodasp.galacticgreg.api.enums.DimensionDef.Venus; +import static galacticgreg.api.enums.DimensionDef.Anubis; +import static galacticgreg.api.enums.DimensionDef.Asteroids; +import static galacticgreg.api.enums.DimensionDef.BarnardE; +import static galacticgreg.api.enums.DimensionDef.BarnardF; +import static galacticgreg.api.enums.DimensionDef.Callisto; +import static galacticgreg.api.enums.DimensionDef.Ceres; +import static galacticgreg.api.enums.DimensionDef.Deimos; +import static galacticgreg.api.enums.DimensionDef.Enceladus; +import static galacticgreg.api.enums.DimensionDef.EndAsteroids; +import static galacticgreg.api.enums.DimensionDef.Ganymede; +import static galacticgreg.api.enums.DimensionDef.Haumea; +import static galacticgreg.api.enums.DimensionDef.Horus; +import static galacticgreg.api.enums.DimensionDef.Io; +import static galacticgreg.api.enums.DimensionDef.KuiperBelt; +import static galacticgreg.api.enums.DimensionDef.MakeMake; +import static galacticgreg.api.enums.DimensionDef.Mars; +import static galacticgreg.api.enums.DimensionDef.MehenBelt; +import static galacticgreg.api.enums.DimensionDef.Mercury; +import static galacticgreg.api.enums.DimensionDef.Miranda; +import static galacticgreg.api.enums.DimensionDef.Moon; +import static galacticgreg.api.enums.DimensionDef.Oberon; +import static galacticgreg.api.enums.DimensionDef.Phobos; +import static galacticgreg.api.enums.DimensionDef.Pluto; +import static galacticgreg.api.enums.DimensionDef.Proteus; +import static galacticgreg.api.enums.DimensionDef.Seth; +import static galacticgreg.api.enums.DimensionDef.TcetiE; +import static galacticgreg.api.enums.DimensionDef.Titan; +import static galacticgreg.api.enums.DimensionDef.Triton; +import static galacticgreg.api.enums.DimensionDef.VegaB; +import static galacticgreg.api.enums.DimensionDef.Venus; import static gregtech.common.SmallOreBuilder.NETHER; import static gregtech.common.SmallOreBuilder.OW; import static gregtech.common.SmallOreBuilder.THE_END; import static gregtech.common.SmallOreBuilder.TWILIGHT_FOREST; -import bloodasp.galacticgreg.GT_Worldgen_GT_Ore_SmallPieces_Space; -import gregtech.common.GT_Worldgen_GT_Ore_SmallPieces; +import galacticgreg.WorldgenOreSmallSpace; import gregtech.common.SmallOreBuilder; +import gregtech.common.WorldgenGTOreSmallPieces; public enum SmallOres { @@ -545,11 +545,11 @@ public enum SmallOres { this.smallOreBuilder = smallOreBuilder; } - public GT_Worldgen_GT_Ore_SmallPieces addGTSmallOre() { - return new GT_Worldgen_GT_Ore_SmallPieces(this.smallOreBuilder); + public WorldgenGTOreSmallPieces addGTSmallOre() { + return new WorldgenGTOreSmallPieces(this.smallOreBuilder); } - public GT_Worldgen_GT_Ore_SmallPieces_Space addGaGregSmallOre() { - return new GT_Worldgen_GT_Ore_SmallPieces_Space(this.smallOreBuilder); + public WorldgenOreSmallSpace addGaGregSmallOre() { + return new WorldgenOreSmallSpace(this.smallOreBuilder); } } diff --git a/src/main/java/gregtech/api/enums/SoundResource.java b/src/main/java/gregtech/api/enums/SoundResource.java index 712c1b5016..e2a6b2630a 100644 --- a/src/main/java/gregtech/api/enums/SoundResource.java +++ b/src/main/java/gregtech/api/enums/SoundResource.java @@ -12,6 +12,8 @@ import net.minecraft.util.ResourceLocation; import com.google.common.collect.Maps; +import gregtech.api.GregTechAPI; + /** * Enumerates known sounds with id and resource-location * @@ -361,7 +363,7 @@ public enum SoundResource { /** * Provides a backward-compatible Sounds {@code Map} sound list * - * @return The map for the deprecated {@link gregtech.api.GregTech_API#sSoundList} + * @return The map for the deprecated {@link GregTechAPI#sSoundList} * @deprecated This method is planned for removal. *

* Use this {@link SoundResource} enum instead. diff --git a/src/main/java/gregtech/api/enums/TAE.java b/src/main/java/gregtech/api/enums/TAE.java index 246b2006ea..79d3037a5a 100644 --- a/src/main/java/gregtech/api/enums/TAE.java +++ b/src/main/java/gregtech/api/enums/TAE.java @@ -8,9 +8,9 @@ import gregtech.api.interfaces.ITexture; import gtPlusPlus.api.objects.Logger; import gtPlusPlus.api.objects.data.AutoMap; import gtPlusPlus.core.block.ModBlocks; -import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.lib.GTPPCore; import gtPlusPlus.core.util.reflect.ReflectionUtils; -import gtPlusPlus.xmod.gregtech.api.objects.GTPP_CopiedBlockTexture; +import gtPlusPlus.xmod.gregtech.api.objects.GTPPCopiedBlockTexture; public class TAE { @@ -19,7 +19,7 @@ public class TAE { public static int gtPPLastUsedIndex = 64; public static int secondaryIndex = 0; - public static HashMap mTAE = new HashMap<>(); + public static HashMap mTAE = new HashMap<>(); private static final HashSet mFreeSlots = new HashSet<>(64); static { @@ -31,23 +31,23 @@ public class TAE { /** * - * @param aPage - The Texture page (0-3) - * @param aID - The ID on the specified page (0-15) - * @param GTPP_CopiedBlockTexture - The Texture to register + * @param aPage - The Texture page (0-3) + * @param aID - The ID on the specified page (0-15) + * @param GTPPCopiedBlockTexture - The Texture to register * @return - Did it register correctly? */ - public static boolean registerTexture(int aPage, int aID, GTPP_CopiedBlockTexture GTPP_CopiedBlockTexture) { + public static boolean registerTexture(int aPage, int aID, GTPPCopiedBlockTexture GTPPCopiedBlockTexture) { int aRealID = aID + (aPage * 16); - return registerTexture(64 + aRealID, GTPP_CopiedBlockTexture); + return registerTexture(64 + aRealID, GTPPCopiedBlockTexture); } - public static boolean registerTexture(int aID, GTPP_CopiedBlockTexture GTPP_CopiedBlockTexture) { + public static boolean registerTexture(int aID, GTPPCopiedBlockTexture GTPPCopiedBlockTexture) { if (mFreeSlots.contains(aID)) { mFreeSlots.remove(aID); - mTAE.put(aID, GTPP_CopiedBlockTexture); + mTAE.put(aID, GTPPCopiedBlockTexture); return true; } else { - CORE.crash("Tried to register texture with ID " + aID + " to TAE, but it is already in use."); + GTPPCore.crash("Tried to register texture with ID " + aID + " to TAE, but it is already in use."); return false; // Dead Code } } @@ -69,7 +69,7 @@ public class TAE { Logger.INFO("Free Page slots within TAE: " + aPageAndSlotFree); Logger.INFO("Filling them with ERROR textures."); for (int aFreeSlot : aTemp.values()) { - registerTexture(aFreeSlot, new GTPP_CopiedBlockTexture(ModBlocks.blockCasingsTieredGTPP, 1, 15)); + registerTexture(aFreeSlot, new GTPPCopiedBlockTexture(ModBlocks.blockCasingsTieredGTPP, 1, 15)); } Logger.INFO("Finalising TAE."); for (int aKeyTae : mTAE.keySet()) { @@ -78,7 +78,7 @@ public class TAE { Logger.INFO("Finalised TAE."); } - private static boolean registerTextures(GTPP_CopiedBlockTexture GTPP_CopiedBlockTexture) { + private static boolean registerTextures(GTPPCopiedBlockTexture GTPPCopiedBlockTexture) { try { // Handle page 2. Logger.INFO("[TAE} Registering Texture, Last used casing ID is " + gtPPLastUsedIndex + "."); @@ -87,7 +87,7 @@ public class TAE { if (x != null) { ITexture[][] h = (ITexture[][]) x.get(null); if (h != null) { - h[64][secondaryIndex++] = GTPP_CopiedBlockTexture; + h[64][secondaryIndex++] = GTPPCopiedBlockTexture; x.set(null, h); Logger .INFO("[TAE} Registered Texture with ID " + (secondaryIndex - 1) + " in secondary index."); @@ -98,7 +98,7 @@ public class TAE { // set to page 1. else { - Textures.BlockIcons.setCasingTextureForId(gtPPLastUsedIndex, GTPP_CopiedBlockTexture); + Textures.BlockIcons.setCasingTextureForId(gtPPLastUsedIndex, GTPPCopiedBlockTexture); Logger.INFO("[TAE} Registered Texture with ID " + (gtPPLastUsedIndex) + " in main index."); gtPPLastUsedIndex++; return true; diff --git a/src/main/java/gregtech/api/enums/TCAspects.java b/src/main/java/gregtech/api/enums/TCAspects.java new file mode 100644 index 0000000000..31ec9c0bc8 --- /dev/null +++ b/src/main/java/gregtech/api/enums/TCAspects.java @@ -0,0 +1,112 @@ +package gregtech.api.enums; + +import java.util.List; + +public enum TCAspects { + + AER(1), + ALIENIS(20), + AQUA(3), + ARBOR(1), + AURAM(16), + BESTIA(6), + COGNITIO(2), + CORPUS(2), + ELECTRUM(24), + EXANIMIS(32), + FABRICO(2), + FAMES(2), + GELUM(1), + GRANUM(4), + HERBA(2), + HUMANUS(8), + IGNIS(4), + INSTRUMENTUM(4), + ITER(6), + LIMUS(3), + LUCRUM(32), + LUX(4), + MACHINA(16), + MAGNETO(24), + MESSIS(3), + METALLUM(8), + METO(2), + MORTUUS(16), + MOTUS(4), + NEBRISUM(48), + ORDO(8), + PANNUS(6), + PERDITIO(2), + PERFODIO(4), + PERMUTATIO(12), + POTENTIA(16), + PRAECANTATIO(16), + RADIO(48), + SANO(24), + SENSUS(4), + SPIRITUS(24), + STRONTIO(64), + TELUM(6), + TERRA(1), + TEMPESTAS(64), + TENEBRAE(24), + TUTAMEN(12), + VACUOS(6), + VENENUM(16), + VICTUS(4), + VINCULUM(16), + VITIUM(48), + VITREUS(3), + VOLATUS(12); + + /** + * The Thaumcraft Aspect Object of the Mod itself. + */ + public Object mAspect; + + public final int mValue; + + TCAspects(int aValue) { + mValue = aValue; + } + + public static class TC_AspectStack { + + public TCAspects mAspect; + public long mAmount; + + public TC_AspectStack(TCAspects aAspect, long aAmount) { + mAspect = aAspect; + mAmount = aAmount; + } + + public TC_AspectStack copy() { + return new TC_AspectStack(mAspect, mAmount); + } + + public TC_AspectStack copy(long aAmount) { + return new TC_AspectStack(mAspect, aAmount); + } + + public List addToAspectList(List aList) { + if (mAmount == 0) return aList; + for (TC_AspectStack tAspect : aList) if (tAspect.mAspect == mAspect) { + tAspect.mAmount += mAmount; + return aList; + } + aList.add(copy()); + return aList; + } + + public boolean removeFromAspectList(List aList) { + for (TC_AspectStack tAspect : aList) if (tAspect.mAspect == mAspect) { + if (tAspect.mAmount >= mAmount) { + tAspect.mAmount -= mAmount; + if (tAspect.mAmount == 0) aList.remove(tAspect); + return true; + } + } + return false; + } + } +} diff --git a/src/main/java/gregtech/api/enums/TC_Aspects.java b/src/main/java/gregtech/api/enums/TC_Aspects.java deleted file mode 100644 index 24d19b0b73..0000000000 --- a/src/main/java/gregtech/api/enums/TC_Aspects.java +++ /dev/null @@ -1,112 +0,0 @@ -package gregtech.api.enums; - -import java.util.List; - -public enum TC_Aspects { - - AER(1), - ALIENIS(20), - AQUA(3), - ARBOR(1), - AURAM(16), - BESTIA(6), - COGNITIO(2), - CORPUS(2), - ELECTRUM(24), - EXANIMIS(32), - FABRICO(2), - FAMES(2), - GELUM(1), - GRANUM(4), - HERBA(2), - HUMANUS(8), - IGNIS(4), - INSTRUMENTUM(4), - ITER(6), - LIMUS(3), - LUCRUM(32), - LUX(4), - MACHINA(16), - MAGNETO(24), - MESSIS(3), - METALLUM(8), - METO(2), - MORTUUS(16), - MOTUS(4), - NEBRISUM(48), - ORDO(8), - PANNUS(6), - PERDITIO(2), - PERFODIO(4), - PERMUTATIO(12), - POTENTIA(16), - PRAECANTATIO(16), - RADIO(48), - SANO(24), - SENSUS(4), - SPIRITUS(24), - STRONTIO(64), - TELUM(6), - TERRA(1), - TEMPESTAS(64), - TENEBRAE(24), - TUTAMEN(12), - VACUOS(6), - VENENUM(16), - VICTUS(4), - VINCULUM(16), - VITIUM(48), - VITREUS(3), - VOLATUS(12); - - /** - * The Thaumcraft Aspect Object of the Mod itself. - */ - public Object mAspect; - - public final int mValue; - - TC_Aspects(int aValue) { - mValue = aValue; - } - - public static class TC_AspectStack { - - public TC_Aspects mAspect; - public long mAmount; - - public TC_AspectStack(TC_Aspects aAspect, long aAmount) { - mAspect = aAspect; - mAmount = aAmount; - } - - public TC_AspectStack copy() { - return new TC_AspectStack(mAspect, mAmount); - } - - public TC_AspectStack copy(long aAmount) { - return new TC_AspectStack(mAspect, aAmount); - } - - public List addToAspectList(List aList) { - if (mAmount == 0) return aList; - for (TC_AspectStack tAspect : aList) if (tAspect.mAspect == mAspect) { - tAspect.mAmount += mAmount; - return aList; - } - aList.add(copy()); - return aList; - } - - public boolean removeFromAspectList(List aList) { - for (TC_AspectStack tAspect : aList) if (tAspect.mAspect == mAspect) { - if (tAspect.mAmount >= mAmount) { - tAspect.mAmount -= mAmount; - if (tAspect.mAmount == 0) aList.remove(tAspect); - return true; - } - } - return false; - } - } -} diff --git a/src/main/java/gregtech/api/enums/Textures.java b/src/main/java/gregtech/api/enums/Textures.java index 7caa8f41e5..7e5aedbcea 100644 --- a/src/main/java/gregtech/api/enums/Textures.java +++ b/src/main/java/gregtech/api/enums/Textures.java @@ -9,11 +9,11 @@ import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; import gregtech.api.interfaces.IIconContainer; import gregtech.api.interfaces.ITexture; import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class Textures { @@ -1762,17 +1762,17 @@ public class Textures { Dyes.getModulation(j - 1, Dyes.MACHINE_METAL.mRGBa)); casingTexturePages[0] = new ITexture[128]; // adds some known pages, modders also can do it... - GT_Utility.addTexturePage((byte) 1); - GT_Utility.addTexturePage((byte) 2); - GT_Utility.addTexturePage((byte) 8); - GT_Utility.addTexturePage((byte) 16); + GTUtility.addTexturePage((byte) 1); + GTUtility.addTexturePage((byte) 2); + GTUtility.addTexturePage((byte) 8); + GTUtility.addTexturePage((byte) 16); setCasingTextureForId(ERROR_TEXTURE_INDEX, ERROR_RENDERING[0]); } IIcon mIcon; BlockIcons() { - GregTech_API.sGTBlockIconload.add(this); + GregTechAPI.sGTBlockIconload.add(this); } public static ITexture getCasingTextureForId(int id) { @@ -1813,7 +1813,7 @@ public class Textures { @Override public void run() { - mIcon = GregTech_API.sBlockIcons.registerIcon(GregTech.getResourcePath("iconsets", this.toString())); + mIcon = GregTechAPI.sBlockIcons.registerIcon(GregTech.getResourcePath("iconsets", this.toString())); } public static class CustomIcon implements IIconContainer, Runnable { @@ -1823,12 +1823,12 @@ public class Textures { public CustomIcon(String aIconName) { mIconName = !aIconName.contains(":") ? GregTech.getResourcePath(aIconName) : aIconName; - GregTech_API.sGTBlockIconload.add(this); + GregTechAPI.sGTBlockIconload.add(this); } @Override public void run() { - mIcon = GregTech_API.sBlockIcons.registerIcon(mIconName); + mIcon = GregTechAPI.sBlockIcons.registerIcon(mIconName); } @Override @@ -1918,7 +1918,7 @@ public class Textures { IIcon mIcon, mOverlay; ItemIcons() { - GregTech_API.sGTItemIconload.add(this); + GregTechAPI.sGTItemIconload.add(this); } @Override @@ -1938,8 +1938,8 @@ public class Textures { @Override public void run() { - mIcon = GregTech_API.sItemIcons.registerIcon(GregTech.getResourcePath("iconsets", this.toString())); - mOverlay = GregTech_API.sItemIcons.registerIcon(GregTech.getResourcePath("iconsets", this + "_OVERLAY")); + mIcon = GregTechAPI.sItemIcons.registerIcon(GregTech.getResourcePath("iconsets", this.toString())); + mOverlay = GregTechAPI.sItemIcons.registerIcon(GregTech.getResourcePath("iconsets", this + "_OVERLAY")); } public static class CustomIcon implements IIconContainer, Runnable { @@ -1949,7 +1949,7 @@ public class Textures { public CustomIcon(String aIconName) { mIconName = aIconName; - GregTech_API.sGTItemIconload.add(this); + GregTechAPI.sGTItemIconload.add(this); } @Override @@ -1969,8 +1969,8 @@ public class Textures { @Override public void run() { - mIcon = GregTech_API.sItemIcons.registerIcon(GregTech.getResourcePath(mIconName)); - mOverlay = GregTech_API.sItemIcons.registerIcon(GregTech.getResourcePath(mIconName + "_OVERLAY")); + mIcon = GregTechAPI.sItemIcons.registerIcon(GregTech.getResourcePath(mIconName)); + mOverlay = GregTechAPI.sItemIcons.registerIcon(GregTech.getResourcePath(mIconName + "_OVERLAY")); } } } diff --git a/src/main/java/gregtech/api/enums/Tier.java b/src/main/java/gregtech/api/enums/Tier.java index 2d64444283..572f2e8b2a 100644 --- a/src/main/java/gregtech/api/enums/Tier.java +++ b/src/main/java/gregtech/api/enums/Tier.java @@ -1,6 +1,6 @@ package gregtech.api.enums; -import static gregtech.api.enums.GT_Values.V; +import static gregtech.api.enums.GTValues.V; /** * Experimental Class for later diff --git a/src/main/java/gregtech/api/enums/TierEU.java b/src/main/java/gregtech/api/enums/TierEU.java index 26b6393115..713f48b3ff 100644 --- a/src/main/java/gregtech/api/enums/TierEU.java +++ b/src/main/java/gregtech/api/enums/TierEU.java @@ -1,40 +1,40 @@ package gregtech.api.enums; -import static gregtech.api.enums.GT_Values.V; +import static gregtech.api.enums.GTValues.V; public class TierEU { // Do NOT use these for crafting recipes as they are exactly 1A! Use RECIPE_ULV etc. - public static final long ULV = V[GTVoltageIndex.ULV]; - public static final long LV = V[GTVoltageIndex.LV]; - public static final long MV = V[GTVoltageIndex.MV]; - public static final long HV = V[GTVoltageIndex.HV]; - public static final long EV = V[GTVoltageIndex.EV]; - public static final long IV = V[GTVoltageIndex.IV]; - public static final long LuV = V[GTVoltageIndex.LuV]; - public static final long ZPM = V[GTVoltageIndex.ZPM]; - public static final long UV = V[GTVoltageIndex.UV]; - public static final long UHV = V[GTVoltageIndex.UHV]; - public static final long UEV = V[GTVoltageIndex.UEV]; - public static final long UIV = V[GTVoltageIndex.UIV]; - public static final long UMV = V[GTVoltageIndex.UMV]; - public static final long UXV = V[GTVoltageIndex.UXV]; - public static final long MAX = V[GTVoltageIndex.MAX]; + public static final long ULV = V[VoltageIndex.ULV]; + public static final long LV = V[VoltageIndex.LV]; + public static final long MV = V[VoltageIndex.MV]; + public static final long HV = V[VoltageIndex.HV]; + public static final long EV = V[VoltageIndex.EV]; + public static final long IV = V[VoltageIndex.IV]; + public static final long LuV = V[VoltageIndex.LuV]; + public static final long ZPM = V[VoltageIndex.ZPM]; + public static final long UV = V[VoltageIndex.UV]; + public static final long UHV = V[VoltageIndex.UHV]; + public static final long UEV = V[VoltageIndex.UEV]; + public static final long UIV = V[VoltageIndex.UIV]; + public static final long UMV = V[VoltageIndex.UMV]; + public static final long UXV = V[VoltageIndex.UXV]; + public static final long MAX = V[VoltageIndex.MAX]; // Use me for recipes. - public static final long RECIPE_ULV = GT_Values.VP[GTVoltageIndex.ULV]; - public static final long RECIPE_LV = GT_Values.VP[GTVoltageIndex.LV]; - public static final long RECIPE_MV = GT_Values.VP[GTVoltageIndex.MV]; - public static final long RECIPE_HV = GT_Values.VP[GTVoltageIndex.HV]; - public static final long RECIPE_EV = GT_Values.VP[GTVoltageIndex.EV]; - public static final long RECIPE_IV = GT_Values.VP[GTVoltageIndex.IV]; - public static final long RECIPE_LuV = GT_Values.VP[GTVoltageIndex.LuV]; - public static final long RECIPE_ZPM = GT_Values.VP[GTVoltageIndex.ZPM]; - public static final long RECIPE_UV = GT_Values.VP[GTVoltageIndex.UV]; - public static final long RECIPE_UHV = GT_Values.VP[GTVoltageIndex.UHV]; - public static final long RECIPE_UEV = GT_Values.VP[GTVoltageIndex.UEV]; - public static final long RECIPE_UIV = GT_Values.VP[GTVoltageIndex.UIV]; - public static final long RECIPE_UMV = GT_Values.VP[GTVoltageIndex.UMV]; - public static final long RECIPE_UXV = GT_Values.VP[GTVoltageIndex.UXV]; - public static final long RECIPE_MAX = GT_Values.VP[GTVoltageIndex.MAX]; + public static final long RECIPE_ULV = GTValues.VP[VoltageIndex.ULV]; + public static final long RECIPE_LV = GTValues.VP[VoltageIndex.LV]; + public static final long RECIPE_MV = GTValues.VP[VoltageIndex.MV]; + public static final long RECIPE_HV = GTValues.VP[VoltageIndex.HV]; + public static final long RECIPE_EV = GTValues.VP[VoltageIndex.EV]; + public static final long RECIPE_IV = GTValues.VP[VoltageIndex.IV]; + public static final long RECIPE_LuV = GTValues.VP[VoltageIndex.LuV]; + public static final long RECIPE_ZPM = GTValues.VP[VoltageIndex.ZPM]; + public static final long RECIPE_UV = GTValues.VP[VoltageIndex.UV]; + public static final long RECIPE_UHV = GTValues.VP[VoltageIndex.UHV]; + public static final long RECIPE_UEV = GTValues.VP[VoltageIndex.UEV]; + public static final long RECIPE_UIV = GTValues.VP[VoltageIndex.UIV]; + public static final long RECIPE_UMV = GTValues.VP[VoltageIndex.UMV]; + public static final long RECIPE_UXV = GTValues.VP[VoltageIndex.UXV]; + public static final long RECIPE_MAX = GTValues.VP[VoltageIndex.MAX]; } diff --git a/src/main/java/gregtech/api/enums/VoidingMode.java b/src/main/java/gregtech/api/enums/VoidingMode.java index 8ae9dda57d..c41236c8ab 100644 --- a/src/main/java/gregtech/api/enums/VoidingMode.java +++ b/src/main/java/gregtech/api/enums/VoidingMode.java @@ -8,28 +8,27 @@ import javax.annotation.Nonnull; import com.gtnewhorizons.modularui.api.drawable.UITexture; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; public enum VoidingMode { /** * Voids nothing, protects both item and fluid */ - VOID_NONE(true, true, GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_BUTTON_VOID_EXCESS_NONE, "none"), + VOID_NONE(true, true, GTUITextures.BUTTON_STANDARD, GTUITextures.OVERLAY_BUTTON_VOID_EXCESS_NONE, "none"), /** * Voids item, protects fluid */ - VOID_ITEM(false, true, GT_UITextures.BUTTON_STANDARD_PRESSED, GT_UITextures.OVERLAY_BUTTON_VOID_EXCESS_ITEM, - "item"), + VOID_ITEM(false, true, GTUITextures.BUTTON_STANDARD_PRESSED, GTUITextures.OVERLAY_BUTTON_VOID_EXCESS_ITEM, "item"), /** * Voids fluid, protects item */ - VOID_FLUID(true, false, GT_UITextures.BUTTON_STANDARD_PRESSED, GT_UITextures.OVERLAY_BUTTON_VOID_EXCESS_FLUID, + VOID_FLUID(true, false, GTUITextures.BUTTON_STANDARD_PRESSED, GTUITextures.OVERLAY_BUTTON_VOID_EXCESS_FLUID, "fluid"), /** * Voids all, protects nothing */ - VOID_ALL(false, false, GT_UITextures.BUTTON_STANDARD_PRESSED, GT_UITextures.OVERLAY_BUTTON_VOID_EXCESS_ALL, "all"); + VOID_ALL(false, false, GTUITextures.BUTTON_STANDARD_PRESSED, GTUITextures.OVERLAY_BUTTON_VOID_EXCESS_ALL, "all"); /** * Default set of voiding mode you will probably support. diff --git a/src/main/java/gregtech/api/enums/VoltageIndex.java b/src/main/java/gregtech/api/enums/VoltageIndex.java new file mode 100644 index 0000000000..f0303b27b0 --- /dev/null +++ b/src/main/java/gregtech/api/enums/VoltageIndex.java @@ -0,0 +1,22 @@ +package gregtech.api.enums; + +public class VoltageIndex { + + public final static int ULV = 0; + public final static int LV = 1; + public final static int MV = 2; + public final static int HV = 3; + public final static int EV = 4; + public final static int IV = 5; + public final static int LuV = 6; + public final static int ZPM = 7; + public final static int UV = 8; + public final static int UHV = 9; + public final static int UEV = 10; + public final static int UIV = 11; + public final static int UMV = 12; + public final static int UXV = 13; + public final static int MAX = 14; + + private VoltageIndex() {} +} diff --git a/src/main/java/gregtech/api/fluid/FluidTankGT.java b/src/main/java/gregtech/api/fluid/FluidTankGT.java deleted file mode 100644 index 0c224985e6..0000000000 --- a/src/main/java/gregtech/api/fluid/FluidTankGT.java +++ /dev/null @@ -1,485 +0,0 @@ -package gregtech.api.fluid; - -import static com.google.common.primitives.Ints.saturatedCast; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidTank; - -import gregtech.api.interfaces.fluid.IFluidStore; -import gregtech.api.util.GT_Utility; - -public class FluidTankGT implements IFluidTank, IFluidStore { - - public final FluidTankGT[] AS_ARRAY = new FluidTankGT[] { this }; - private FluidStack mFluid; - private long mCapacity = 0, mAmount = 0; - private boolean mPreventDraining = false, mVoidExcess = false, mChangedFluids = false; - /** HashMap of adjustable Tank Sizes based on Fluids if needed. */ - private Map mAdjustableCapacity = null; - - private long mAdjustableMultiplier = 1; - /** Gives you a Tank Index in case there is multiple Tanks on a TileEntity that cares. */ - public int mIndex = 0; - - public FluidTankGT() { - mCapacity = Long.MAX_VALUE; - } - - public FluidTankGT(long aCapacity) { - mCapacity = aCapacity; - } - - public FluidTankGT(FluidStack aFluid) { - mFluid = aFluid; - if (aFluid != null) { - mCapacity = aFluid.amount; - mAmount = aFluid.amount; - } - } - - public FluidTankGT(FluidStack aFluid, long aCapacity) { - mFluid = aFluid; - mCapacity = aCapacity; - mAmount = (aFluid == null ? 0 : aFluid.amount); - } - - public FluidTankGT(FluidStack aFluid, long aAmount, long aCapacity) { - mFluid = aFluid; - mCapacity = aCapacity; - mAmount = (aFluid == null ? 0 : aAmount); - } - - public FluidTankGT(Fluid aFluid, long aAmount) { - this(new FluidStack(aFluid, saturatedCast(aAmount))); - mAmount = aAmount; - } - - public FluidTankGT(Fluid aFluid, long aAmount, long aCapacity) { - this(new FluidStack(aFluid, saturatedCast(aAmount)), aCapacity); - mAmount = aAmount; - } - - public FluidTankGT(NBTTagCompound aNBT, String aKey, long aCapacity) { - this(aNBT.hasKey(aKey) ? aNBT.getCompoundTag(aKey) : null, aCapacity); - } - - public FluidTankGT(NBTTagCompound aNBT, long aCapacity) { - mCapacity = aCapacity; - if (aNBT != null && !aNBT.hasNoTags()) { - mFluid = FluidStack.loadFluidStackFromNBT(aNBT); - mAmount = (isEmpty() ? 0 : aNBT.hasKey("LAmount") ? aNBT.getLong("LAmount") : mFluid.amount); - } - } - - public FluidTankGT readFromNBT(NBTTagCompound aNBT, String aKey) { - if (aNBT.hasKey(aKey)) { - aNBT = aNBT.getCompoundTag(aKey); - if (aNBT != null && !aNBT.hasNoTags()) { - mFluid = FluidStack.loadFluidStackFromNBT(aNBT); - mAmount = (isEmpty() ? 0 : aNBT.hasKey("LAmount") ? aNBT.getLong("LAmount") : mFluid.amount); - } - } - return this; - } - - public NBTTagCompound writeToNBT(NBTTagCompound aNBT, String aKey) { - if (mFluid != null && (mPreventDraining || mAmount > 0)) { - final NBTTagCompound tNBT = new NBTTagCompound(); - mFluid.amount = (int) mAmount; - aNBT.setTag(aKey, mFluid.writeToNBT(tNBT)); - if (mAmount > Integer.MAX_VALUE) tNBT.setLong("LAmount", mAmount); - } else { - aNBT.removeTag(aKey); - } - return aNBT; - } - - public FluidStack drain(int aDrained) { - return drain(aDrained, true); - } - - @Override - public FluidStack drain(int aDrained, boolean aDoDrain) { - if (isEmpty() || aDrained <= 0) return null; - if (mAmount < aDrained) aDrained = (int) mAmount; - final FluidStack rFluid = new FluidStack(mFluid, aDrained); - if (aDoDrain) { - mAmount -= aDrained; - if (mAmount <= 0) { - if (mPreventDraining) { - mAmount = 0; - } else { - setEmpty(); - } - } - } - return rFluid; - } - - public boolean drainAll(long aDrained) { - if (isEmpty() || mAmount < aDrained) return false; - mAmount -= aDrained; - if (mAmount <= 0) { - if (mPreventDraining) { - mAmount = 0; - } else { - setEmpty(); - } - } - return true; - } - - public long remove(long aDrained) { - if (isEmpty() || mAmount <= 0 || aDrained <= 0) return 0; - if (mAmount < aDrained) aDrained = mAmount; - mAmount -= aDrained; - if (mAmount <= 0) { - if (mPreventDraining) { - mAmount = 0; - } else { - setEmpty(); - } - } - return aDrained; - } - - public long add(long aFilled) { - if (isEmpty() || aFilled <= 0) return 0; - final long tCapacity = capacity(); - if (mAmount + aFilled > tCapacity) { - if (!mVoidExcess) aFilled = tCapacity - mAmount; - mAmount = tCapacity; - return aFilled; - } - mAmount += aFilled; - return aFilled; - } - - public long add(long aFilled, FluidStack aFluid) { - if (aFluid == null || aFilled <= 0) return 0; - if (isEmpty()) { - mFluid = aFluid.copy(); - mChangedFluids = true; - mAmount = Math.min(capacity(aFluid), aFilled); - return mVoidExcess ? aFilled : mAmount; - } - return contains(aFluid) ? add(aFilled) : 0; - } - - public int fill(FluidStack aFluid) { - return fill(aFluid, true); - } - - @Override - public int fill(FluidStack aFluid, boolean aDoFill) { - if (aFluid == null) return 0; - if (aDoFill) { - if (isEmpty()) { - mFluid = aFluid.copy(); - mChangedFluids = true; - mAmount = Math.min(capacity(aFluid), aFluid.amount); - return mVoidExcess ? aFluid.amount : (int) mAmount; - } - if (!contains(aFluid)) return 0; - final long tCapacity = capacity(aFluid); - long tFilled = tCapacity - mAmount; - if (aFluid.amount < tFilled) { - mAmount += aFluid.amount; - tFilled = aFluid.amount; - } else mAmount = tCapacity; - return mVoidExcess ? aFluid.amount : (int) tFilled; - } - return saturatedCast( - isEmpty() ? mVoidExcess ? aFluid.amount : Math.min(capacity(aFluid), aFluid.amount) - : contains(aFluid) ? mVoidExcess ? aFluid.amount : Math.min(capacity(aFluid) - mAmount, aFluid.amount) - : 0); - } - - public boolean canFillAll(FluidStack aFluid) { - return aFluid == null || aFluid.amount <= 0 - || (isEmpty() ? mVoidExcess || aFluid.amount <= capacity(aFluid) - : contains(aFluid) && (mVoidExcess || mAmount + aFluid.amount <= capacity(aFluid))); - } - - public boolean canFillAll(long aAmount) { - return aAmount <= 0 || mVoidExcess || mAmount + aAmount <= capacity(); - } - - public boolean fillAll(FluidStack aFluid) { - if (aFluid == null || aFluid.amount <= 0) return true; - if (isEmpty()) { - final long tCapacity = capacity(aFluid); - if (aFluid.amount <= tCapacity || mVoidExcess) { - mFluid = aFluid.copy(); - mChangedFluids = true; - mAmount = aFluid.amount; - if (mAmount > tCapacity) mAmount = tCapacity; - return true; - } - return false; - } - if (contains(aFluid)) { - if (mAmount + aFluid.amount <= capacity()) { - mAmount += aFluid.amount; - return true; - } - if (mVoidExcess) { - mAmount = capacity(); - return true; - } - } - return false; - } - - public boolean fillAll(FluidStack aFluid, long aMultiplier) { - if (aMultiplier <= 0) return true; - if (aMultiplier == 1) return fillAll(aFluid); - if (aFluid == null || aFluid.amount <= 0) return true; - if (isEmpty()) { - final long tCapacity = capacity(aFluid); - if (aFluid.amount * aMultiplier <= tCapacity || mVoidExcess) { - mFluid = aFluid.copy(); - mChangedFluids = true; - mAmount = aFluid.amount * aMultiplier; - if (mAmount > tCapacity) mAmount = tCapacity; - return true; - } - return false; - } - if (contains(aFluid)) { - if (mAmount + aFluid.amount * aMultiplier <= capacity()) { - mAmount += aFluid.amount * aMultiplier; - return true; - } - if (mVoidExcess) { - mAmount = capacity(); - return true; - } - } - return false; - } - - /** Resets Tank Contents entirely */ - public FluidTankGT setEmpty() { - mFluid = null; - mChangedFluids = true; - mAmount = 0; - return this; - } - - /** Sets Fluid Content, taking Amount from the Fluid Parameter */ - public FluidTankGT setFluid(FluidStack aFluid) { - mFluid = aFluid; - mChangedFluids = true; - mAmount = (aFluid == null ? 0 : aFluid.amount); - return this; - } - - /** Sets Fluid Content and Amount */ - public FluidTankGT setFluid(FluidStack aFluid, long aAmount) { - mFluid = aFluid; - mChangedFluids = true; - mAmount = (aFluid == null ? 0 : aAmount); - return this; - } - - /** Sets Fluid Content, taking Amount from the Tank Parameter */ - public FluidTankGT setFluid(FluidTankGT aTank) { - mFluid = new FluidStack(aTank.mFluid, saturatedCast(aTank.mAmount)); - mChangedFluids = true; - mAmount = aTank.mAmount; - return this; - } - - /** Sets the Tank Index for easier Reverse Mapping. */ - public FluidTankGT setIndex(int aIndex) { - mIndex = aIndex; - return this; - } - - /** Sets the Capacity */ - public FluidTankGT setCapacity(long aCapacity) { - if (aCapacity >= 0) mCapacity = aCapacity; - return this; - } - - /** Sets the Capacity Multiplier */ - public FluidTankGT setCapacityMultiplier(long aCapacityMultiplier) { - if (aCapacityMultiplier >= 0) mAdjustableMultiplier = aCapacityMultiplier; - return this; - } - - /** Sets Tank capacity Map, should it be needed. */ - public FluidTankGT setCapacity(Map aMap, long aCapacityMultiplier) { - mAdjustableCapacity = aMap; - mAdjustableMultiplier = aCapacityMultiplier; - return this; - } - - /** Always keeps at least 0 Liters of Fluid instead of setting it to null */ - public FluidTankGT setPreventDraining() { - return setPreventDraining(true); - } - - /** Always keeps at least 0 Liters of Fluid instead of setting it to null */ - public FluidTankGT setPreventDraining(boolean aPrevent) { - mPreventDraining = aPrevent; - return this; - } - - /** Voids any Overlow */ - public FluidTankGT setVoidExcess() { - return setVoidExcess(true); - } - - /** Voids any Overlow */ - public FluidTankGT setVoidExcess(boolean aVoidExcess) { - mVoidExcess = aVoidExcess; - return this; - } - - public boolean isFull() { - return mFluid != null && mAmount >= capacity(); - } - - public long capacity() { - return capacity(mFluid); - } - - public long capacity(FluidStack aFluid) { - if (mAdjustableCapacity == null || aFluid == null) return mCapacity; - return capacity(aFluid.getFluid()); - } - - public long capacity(Fluid aFluid) { - if (mAdjustableCapacity == null || aFluid == null) return mCapacity; - return capacity(aFluid.getName()); - } - - public long capacity(String aFluid) { - if (mAdjustableCapacity == null || aFluid == null) return mCapacity; - - final Long tSize = mAdjustableCapacity.get(aFluid); - return tSize == null ? Math.max(mAmount, mCapacity) - : Math.max(tSize * mAdjustableMultiplier, Math.max(mAmount, mCapacity)); - } - - public boolean isHalf() { - return mFluid != null && mAmount * 2 >= capacity(); - } - - public boolean contains(Fluid aFluid) { - return mFluid != null && mFluid.getFluid() == aFluid; - } - - public boolean contains(FluidStack aFluid) { - return GT_Utility.areFluidsEqual(mFluid, aFluid); - } - - public boolean has(long aAmount) { - return mAmount >= aAmount; - } - - public boolean has() { - return mAmount > 0; - } - - public boolean check() { - if (mChangedFluids) { - mChangedFluids = false; - return true; - } - return false; - } - - public boolean update() { - return mChangedFluids = true; - } - - public boolean changed() { - return mChangedFluids; - } - - public long amount() { - return isEmpty() ? 0 : mAmount; - } - - public boolean isEmpty() { - return mFluid == null; - } - - public long amount(long aMax) { - return isEmpty() || aMax <= 0 ? 0 : Math.min(mAmount, aMax); - } - - public String name() { - return mFluid == null ? null - : mFluid.getFluid() - .getName(); - } - - public FluidStack get() { - return mFluid; - } - - public FluidStack get(long aMax) { - return isEmpty() || aMax <= 0 ? null : new FluidStack(mFluid, saturatedCast(Math.min(mAmount, aMax))); - } - - @Override - public FluidStack getFluid() { - if (mFluid != null) mFluid.amount = saturatedCast(mAmount); - return mFluid; - } - - @Override - public int getFluidAmount() { - return saturatedCast(mAmount); - } - - @Override - public int getCapacity() { - return saturatedCast(capacity()); - } - - public long getCapacityMultiplier() { - return mAdjustableMultiplier; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(isEmpty() ? null : mFluid.copy(), saturatedCast(capacity())); - } - - public static FluidStack[] getFluidsFromTanks(FluidTankGT[] tanks) { - if (tanks == null) { - return null; - } - List fluidStacks = new ArrayList<>(); - for (FluidTankGT tank : tanks) { - if (tank.getFluid() != null) { - fluidStacks.add(tank.getFluid()); - } - } - return fluidStacks.toArray(new FluidStack[0]); - } - - @Override - public boolean isEmptyAndAcceptsAnyFluid() { - return getFluidAmount() == 0; - } - - @Override - public boolean canStoreFluid(@Nonnull FluidStack fluidStack) { - return GT_Utility.areFluidsEqual(mFluid, fluidStack); - } -} diff --git a/src/main/java/gregtech/api/fluid/GTFluidFactory.java b/src/main/java/gregtech/api/fluid/GTFluidFactory.java new file mode 100644 index 0000000000..291cdf3384 --- /dev/null +++ b/src/main/java/gregtech/api/fluid/GTFluidFactory.java @@ -0,0 +1,90 @@ +package gregtech.api.fluid; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidRegistry; + +import gregtech.api.enums.FluidState; +import gregtech.api.enums.Materials; +import gregtech.api.interfaces.fluid.IGTFluid; +import gregtech.api.interfaces.fluid.IGTFluidBuilder; +import gregtech.common.fluid.GTFluidBuilder; + +/** + *

+ * This class contains helpers factory methods to: + *

+ *
    + *
  1. + *

    + * Build {@link IGTFluid} instances. + *

    + *
  2. + *
  3. + *

    + * Register the corresponding {@link Fluid}, built from an {@link IGTFluid}, to the {@link FluidRegistry}: + *

    + *
      + *
    • + *

      + * Register the optionally associated containers to the {@link FluidContainerRegistry}. + *

      + *
    • + *
    • + *

      + * Add the needed Fluid Canner recipes. + *

      + *
    • + *
    + *
  4. + *
+ */ +@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope +public class GTFluidFactory { + + /** + * Helper for quick fluid creation and registration + * + * @param fluidName The name key of the {@link Fluid} to register in the {@link FluidRegistry} + * @param localizedName The localized name of this {@link IGTFluid} + * @param material The {@link Materials} of this {@link IGTFluid} + * @param state The {@link FluidState} of this {@link IGTFluid} + * @param temperature The fluid temperature in Kelvin + * @return the registered {@link Fluid} + */ + public static Fluid of(final String fluidName, final String localizedName, final Materials material, + final FluidState state, final int temperature) { + return builder(fluidName).withLocalizedName(localizedName) + .withStateAndTemperature(state, temperature) + .buildAndRegister() + .configureMaterials(material) + .asFluid(); + } + + /** + * Helper for quick fluid creation and registration + * + * @param fluidName The name key of the {@link Fluid} to register in the {@link FluidRegistry} + * @param localizedName The localized name of this {@link IGTFluid} + * @param state The {@link FluidState} of this {@link IGTFluid} + * @param temperature The fluid temperature in Kelvin + * @return the registered {@link Fluid} + */ + public static Fluid of(final String fluidName, final String localizedName, final FluidState state, + final int temperature) { + return builder(fluidName).withLocalizedName(localizedName) + .withStateAndTemperature(state, temperature) + .buildAndRegister() + .asFluid(); + } + + /** + * Gets an {@link IGTFluid} builder instance + * + * @param fluidName The name key of the {@link Fluid} to register in the {@link FluidRegistry} + * @return the {@link IGTFluidBuilder} instance + */ + public static IGTFluidBuilder builder(final String fluidName) { + return new GTFluidBuilder(fluidName); + } +} diff --git a/src/main/java/gregtech/api/fluid/GTFluidTank.java b/src/main/java/gregtech/api/fluid/GTFluidTank.java new file mode 100644 index 0000000000..46fc098000 --- /dev/null +++ b/src/main/java/gregtech/api/fluid/GTFluidTank.java @@ -0,0 +1,485 @@ +package gregtech.api.fluid; + +import static com.google.common.primitives.Ints.saturatedCast; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nonnull; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; + +import gregtech.api.interfaces.fluid.IFluidStore; +import gregtech.api.util.GTUtility; + +public class GTFluidTank implements IFluidTank, IFluidStore { + + public final GTFluidTank[] AS_ARRAY = new GTFluidTank[] { this }; + private FluidStack mFluid; + private long mCapacity = 0, mAmount = 0; + private boolean mPreventDraining = false, mVoidExcess = false, mChangedFluids = false; + /** HashMap of adjustable Tank Sizes based on Fluids if needed. */ + private Map mAdjustableCapacity = null; + + private long mAdjustableMultiplier = 1; + /** Gives you a Tank Index in case there is multiple Tanks on a TileEntity that cares. */ + public int mIndex = 0; + + public GTFluidTank() { + mCapacity = Long.MAX_VALUE; + } + + public GTFluidTank(long aCapacity) { + mCapacity = aCapacity; + } + + public GTFluidTank(FluidStack aFluid) { + mFluid = aFluid; + if (aFluid != null) { + mCapacity = aFluid.amount; + mAmount = aFluid.amount; + } + } + + public GTFluidTank(FluidStack aFluid, long aCapacity) { + mFluid = aFluid; + mCapacity = aCapacity; + mAmount = (aFluid == null ? 0 : aFluid.amount); + } + + public GTFluidTank(FluidStack aFluid, long aAmount, long aCapacity) { + mFluid = aFluid; + mCapacity = aCapacity; + mAmount = (aFluid == null ? 0 : aAmount); + } + + public GTFluidTank(Fluid aFluid, long aAmount) { + this(new FluidStack(aFluid, saturatedCast(aAmount))); + mAmount = aAmount; + } + + public GTFluidTank(Fluid aFluid, long aAmount, long aCapacity) { + this(new FluidStack(aFluid, saturatedCast(aAmount)), aCapacity); + mAmount = aAmount; + } + + public GTFluidTank(NBTTagCompound aNBT, String aKey, long aCapacity) { + this(aNBT.hasKey(aKey) ? aNBT.getCompoundTag(aKey) : null, aCapacity); + } + + public GTFluidTank(NBTTagCompound aNBT, long aCapacity) { + mCapacity = aCapacity; + if (aNBT != null && !aNBT.hasNoTags()) { + mFluid = FluidStack.loadFluidStackFromNBT(aNBT); + mAmount = (isEmpty() ? 0 : aNBT.hasKey("LAmount") ? aNBT.getLong("LAmount") : mFluid.amount); + } + } + + public GTFluidTank readFromNBT(NBTTagCompound aNBT, String aKey) { + if (aNBT.hasKey(aKey)) { + aNBT = aNBT.getCompoundTag(aKey); + if (aNBT != null && !aNBT.hasNoTags()) { + mFluid = FluidStack.loadFluidStackFromNBT(aNBT); + mAmount = (isEmpty() ? 0 : aNBT.hasKey("LAmount") ? aNBT.getLong("LAmount") : mFluid.amount); + } + } + return this; + } + + public NBTTagCompound writeToNBT(NBTTagCompound aNBT, String aKey) { + if (mFluid != null && (mPreventDraining || mAmount > 0)) { + final NBTTagCompound tNBT = new NBTTagCompound(); + mFluid.amount = (int) mAmount; + aNBT.setTag(aKey, mFluid.writeToNBT(tNBT)); + if (mAmount > Integer.MAX_VALUE) tNBT.setLong("LAmount", mAmount); + } else { + aNBT.removeTag(aKey); + } + return aNBT; + } + + public FluidStack drain(int aDrained) { + return drain(aDrained, true); + } + + @Override + public FluidStack drain(int aDrained, boolean aDoDrain) { + if (isEmpty() || aDrained <= 0) return null; + if (mAmount < aDrained) aDrained = (int) mAmount; + final FluidStack rFluid = new FluidStack(mFluid, aDrained); + if (aDoDrain) { + mAmount -= aDrained; + if (mAmount <= 0) { + if (mPreventDraining) { + mAmount = 0; + } else { + setEmpty(); + } + } + } + return rFluid; + } + + public boolean drainAll(long aDrained) { + if (isEmpty() || mAmount < aDrained) return false; + mAmount -= aDrained; + if (mAmount <= 0) { + if (mPreventDraining) { + mAmount = 0; + } else { + setEmpty(); + } + } + return true; + } + + public long remove(long aDrained) { + if (isEmpty() || mAmount <= 0 || aDrained <= 0) return 0; + if (mAmount < aDrained) aDrained = mAmount; + mAmount -= aDrained; + if (mAmount <= 0) { + if (mPreventDraining) { + mAmount = 0; + } else { + setEmpty(); + } + } + return aDrained; + } + + public long add(long aFilled) { + if (isEmpty() || aFilled <= 0) return 0; + final long tCapacity = capacity(); + if (mAmount + aFilled > tCapacity) { + if (!mVoidExcess) aFilled = tCapacity - mAmount; + mAmount = tCapacity; + return aFilled; + } + mAmount += aFilled; + return aFilled; + } + + public long add(long aFilled, FluidStack aFluid) { + if (aFluid == null || aFilled <= 0) return 0; + if (isEmpty()) { + mFluid = aFluid.copy(); + mChangedFluids = true; + mAmount = Math.min(capacity(aFluid), aFilled); + return mVoidExcess ? aFilled : mAmount; + } + return contains(aFluid) ? add(aFilled) : 0; + } + + public int fill(FluidStack aFluid) { + return fill(aFluid, true); + } + + @Override + public int fill(FluidStack aFluid, boolean aDoFill) { + if (aFluid == null) return 0; + if (aDoFill) { + if (isEmpty()) { + mFluid = aFluid.copy(); + mChangedFluids = true; + mAmount = Math.min(capacity(aFluid), aFluid.amount); + return mVoidExcess ? aFluid.amount : (int) mAmount; + } + if (!contains(aFluid)) return 0; + final long tCapacity = capacity(aFluid); + long tFilled = tCapacity - mAmount; + if (aFluid.amount < tFilled) { + mAmount += aFluid.amount; + tFilled = aFluid.amount; + } else mAmount = tCapacity; + return mVoidExcess ? aFluid.amount : (int) tFilled; + } + return saturatedCast( + isEmpty() ? mVoidExcess ? aFluid.amount : Math.min(capacity(aFluid), aFluid.amount) + : contains(aFluid) ? mVoidExcess ? aFluid.amount : Math.min(capacity(aFluid) - mAmount, aFluid.amount) + : 0); + } + + public boolean canFillAll(FluidStack aFluid) { + return aFluid == null || aFluid.amount <= 0 + || (isEmpty() ? mVoidExcess || aFluid.amount <= capacity(aFluid) + : contains(aFluid) && (mVoidExcess || mAmount + aFluid.amount <= capacity(aFluid))); + } + + public boolean canFillAll(long aAmount) { + return aAmount <= 0 || mVoidExcess || mAmount + aAmount <= capacity(); + } + + public boolean fillAll(FluidStack aFluid) { + if (aFluid == null || aFluid.amount <= 0) return true; + if (isEmpty()) { + final long tCapacity = capacity(aFluid); + if (aFluid.amount <= tCapacity || mVoidExcess) { + mFluid = aFluid.copy(); + mChangedFluids = true; + mAmount = aFluid.amount; + if (mAmount > tCapacity) mAmount = tCapacity; + return true; + } + return false; + } + if (contains(aFluid)) { + if (mAmount + aFluid.amount <= capacity()) { + mAmount += aFluid.amount; + return true; + } + if (mVoidExcess) { + mAmount = capacity(); + return true; + } + } + return false; + } + + public boolean fillAll(FluidStack aFluid, long aMultiplier) { + if (aMultiplier <= 0) return true; + if (aMultiplier == 1) return fillAll(aFluid); + if (aFluid == null || aFluid.amount <= 0) return true; + if (isEmpty()) { + final long tCapacity = capacity(aFluid); + if (aFluid.amount * aMultiplier <= tCapacity || mVoidExcess) { + mFluid = aFluid.copy(); + mChangedFluids = true; + mAmount = aFluid.amount * aMultiplier; + if (mAmount > tCapacity) mAmount = tCapacity; + return true; + } + return false; + } + if (contains(aFluid)) { + if (mAmount + aFluid.amount * aMultiplier <= capacity()) { + mAmount += aFluid.amount * aMultiplier; + return true; + } + if (mVoidExcess) { + mAmount = capacity(); + return true; + } + } + return false; + } + + /** Resets Tank Contents entirely */ + public GTFluidTank setEmpty() { + mFluid = null; + mChangedFluids = true; + mAmount = 0; + return this; + } + + /** Sets Fluid Content, taking Amount from the Fluid Parameter */ + public GTFluidTank setFluid(FluidStack aFluid) { + mFluid = aFluid; + mChangedFluids = true; + mAmount = (aFluid == null ? 0 : aFluid.amount); + return this; + } + + /** Sets Fluid Content and Amount */ + public GTFluidTank setFluid(FluidStack aFluid, long aAmount) { + mFluid = aFluid; + mChangedFluids = true; + mAmount = (aFluid == null ? 0 : aAmount); + return this; + } + + /** Sets Fluid Content, taking Amount from the Tank Parameter */ + public GTFluidTank setFluid(GTFluidTank aTank) { + mFluid = new FluidStack(aTank.mFluid, saturatedCast(aTank.mAmount)); + mChangedFluids = true; + mAmount = aTank.mAmount; + return this; + } + + /** Sets the Tank Index for easier Reverse Mapping. */ + public GTFluidTank setIndex(int aIndex) { + mIndex = aIndex; + return this; + } + + /** Sets the Capacity */ + public GTFluidTank setCapacity(long aCapacity) { + if (aCapacity >= 0) mCapacity = aCapacity; + return this; + } + + /** Sets the Capacity Multiplier */ + public GTFluidTank setCapacityMultiplier(long aCapacityMultiplier) { + if (aCapacityMultiplier >= 0) mAdjustableMultiplier = aCapacityMultiplier; + return this; + } + + /** Sets Tank capacity Map, should it be needed. */ + public GTFluidTank setCapacity(Map aMap, long aCapacityMultiplier) { + mAdjustableCapacity = aMap; + mAdjustableMultiplier = aCapacityMultiplier; + return this; + } + + /** Always keeps at least 0 Liters of Fluid instead of setting it to null */ + public GTFluidTank setPreventDraining() { + return setPreventDraining(true); + } + + /** Always keeps at least 0 Liters of Fluid instead of setting it to null */ + public GTFluidTank setPreventDraining(boolean aPrevent) { + mPreventDraining = aPrevent; + return this; + } + + /** Voids any Overlow */ + public GTFluidTank setVoidExcess() { + return setVoidExcess(true); + } + + /** Voids any Overlow */ + public GTFluidTank setVoidExcess(boolean aVoidExcess) { + mVoidExcess = aVoidExcess; + return this; + } + + public boolean isFull() { + return mFluid != null && mAmount >= capacity(); + } + + public long capacity() { + return capacity(mFluid); + } + + public long capacity(FluidStack aFluid) { + if (mAdjustableCapacity == null || aFluid == null) return mCapacity; + return capacity(aFluid.getFluid()); + } + + public long capacity(Fluid aFluid) { + if (mAdjustableCapacity == null || aFluid == null) return mCapacity; + return capacity(aFluid.getName()); + } + + public long capacity(String aFluid) { + if (mAdjustableCapacity == null || aFluid == null) return mCapacity; + + final Long tSize = mAdjustableCapacity.get(aFluid); + return tSize == null ? Math.max(mAmount, mCapacity) + : Math.max(tSize * mAdjustableMultiplier, Math.max(mAmount, mCapacity)); + } + + public boolean isHalf() { + return mFluid != null && mAmount * 2 >= capacity(); + } + + public boolean contains(Fluid aFluid) { + return mFluid != null && mFluid.getFluid() == aFluid; + } + + public boolean contains(FluidStack aFluid) { + return GTUtility.areFluidsEqual(mFluid, aFluid); + } + + public boolean has(long aAmount) { + return mAmount >= aAmount; + } + + public boolean has() { + return mAmount > 0; + } + + public boolean check() { + if (mChangedFluids) { + mChangedFluids = false; + return true; + } + return false; + } + + public boolean update() { + return mChangedFluids = true; + } + + public boolean changed() { + return mChangedFluids; + } + + public long amount() { + return isEmpty() ? 0 : mAmount; + } + + public boolean isEmpty() { + return mFluid == null; + } + + public long amount(long aMax) { + return isEmpty() || aMax <= 0 ? 0 : Math.min(mAmount, aMax); + } + + public String name() { + return mFluid == null ? null + : mFluid.getFluid() + .getName(); + } + + public FluidStack get() { + return mFluid; + } + + public FluidStack get(long aMax) { + return isEmpty() || aMax <= 0 ? null : new FluidStack(mFluid, saturatedCast(Math.min(mAmount, aMax))); + } + + @Override + public FluidStack getFluid() { + if (mFluid != null) mFluid.amount = saturatedCast(mAmount); + return mFluid; + } + + @Override + public int getFluidAmount() { + return saturatedCast(mAmount); + } + + @Override + public int getCapacity() { + return saturatedCast(capacity()); + } + + public long getCapacityMultiplier() { + return mAdjustableMultiplier; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(isEmpty() ? null : mFluid.copy(), saturatedCast(capacity())); + } + + public static FluidStack[] getFluidsFromTanks(GTFluidTank[] tanks) { + if (tanks == null) { + return null; + } + List fluidStacks = new ArrayList<>(); + for (GTFluidTank tank : tanks) { + if (tank.getFluid() != null) { + fluidStacks.add(tank.getFluid()); + } + } + return fluidStacks.toArray(new FluidStack[0]); + } + + @Override + public boolean isEmptyAndAcceptsAnyFluid() { + return getFluidAmount() == 0; + } + + @Override + public boolean canStoreFluid(@Nonnull FluidStack fluidStack) { + return GTUtility.areFluidsEqual(mFluid, fluidStack); + } +} diff --git a/src/main/java/gregtech/api/fluid/GT_FluidFactory.java b/src/main/java/gregtech/api/fluid/GT_FluidFactory.java deleted file mode 100644 index 7c65956c69..0000000000 --- a/src/main/java/gregtech/api/fluid/GT_FluidFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -package gregtech.api.fluid; - -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidContainerRegistry; -import net.minecraftforge.fluids.FluidRegistry; - -import gregtech.api.enums.FluidState; -import gregtech.api.enums.Materials; -import gregtech.api.interfaces.fluid.IGT_Fluid; -import gregtech.api.interfaces.fluid.IGT_FluidBuilder; -import gregtech.common.fluid.GT_FluidBuilder; - -/** - *

- * This class contains helpers factory methods to: - *

- *
    - *
  1. - *

    - * Build {@link IGT_Fluid} instances. - *

    - *
  2. - *
  3. - *

    - * Register the corresponding {@link Fluid}, built from an {@link IGT_Fluid}, to the {@link FluidRegistry}: - *

    - *
      - *
    • - *

      - * Register the optionally associated containers to the {@link FluidContainerRegistry}. - *

      - *
    • - *
    • - *

      - * Add the needed Fluid Canner recipes. - *

      - *
    • - *
    - *
  4. - *
- */ -@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope -public class GT_FluidFactory { - - /** - * Helper for quick fluid creation and registration - * - * @param fluidName The name key of the {@link Fluid} to register in the {@link FluidRegistry} - * @param localizedName The localized name of this {@link IGT_Fluid} - * @param material The {@link Materials} of this {@link IGT_Fluid} - * @param state The {@link FluidState} of this {@link IGT_Fluid} - * @param temperature The fluid temperature in Kelvin - * @return the registered {@link Fluid} - */ - public static Fluid of(final String fluidName, final String localizedName, final Materials material, - final FluidState state, final int temperature) { - return builder(fluidName).withLocalizedName(localizedName) - .withStateAndTemperature(state, temperature) - .buildAndRegister() - .configureMaterials(material) - .asFluid(); - } - - /** - * Helper for quick fluid creation and registration - * - * @param fluidName The name key of the {@link Fluid} to register in the {@link FluidRegistry} - * @param localizedName The localized name of this {@link IGT_Fluid} - * @param state The {@link FluidState} of this {@link IGT_Fluid} - * @param temperature The fluid temperature in Kelvin - * @return the registered {@link Fluid} - */ - public static Fluid of(final String fluidName, final String localizedName, final FluidState state, - final int temperature) { - return builder(fluidName).withLocalizedName(localizedName) - .withStateAndTemperature(state, temperature) - .buildAndRegister() - .asFluid(); - } - - /** - * Gets an {@link IGT_Fluid} builder instance - * - * @param fluidName The name key of the {@link Fluid} to register in the {@link FluidRegistry} - * @return the {@link IGT_FluidBuilder} instance - */ - public static IGT_FluidBuilder builder(final String fluidName) { - return new GT_FluidBuilder(fluidName); - } -} diff --git a/src/main/java/gregtech/api/graphs/GenerateNodeMap.java b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java index 7289f0faad..7eb8382e87 100644 --- a/src/main/java/gregtech/api/graphs/GenerateNodeMap.java +++ b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java @@ -1,6 +1,6 @@ package gregtech.api.graphs; -import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES; +import static gregtech.api.enums.GTValues.ALL_VALID_SIDES; import java.util.ArrayList; import java.util.HashSet; diff --git a/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java b/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java index 95f9aee32d..4203bbdc0a 100644 --- a/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java +++ b/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java @@ -7,7 +7,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import cofh.api.energy.IEnergyReceiver; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; import gregtech.api.graphs.consumers.ConsumerNode; import gregtech.api.graphs.consumers.EmptyPowerConsumer; import gregtech.api.graphs.consumers.NodeEnergyConnected; @@ -20,7 +20,7 @@ import gregtech.api.interfaces.tileentity.IEnergyConnected; import gregtech.api.metatileentity.BaseMetaPipeEntity; import gregtech.api.metatileentity.BaseMetaTileEntity; import gregtech.api.metatileentity.MetaPipeEntity; -import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; +import gregtech.api.metatileentity.implementations.MTECable; import ic2.api.energy.tile.IEnergySink; // node map generator for power distribution @@ -32,8 +32,7 @@ public class GenerateNodeMapPower extends GenerateNodeMap { @Override protected boolean isPipe(TileEntity aTileEntity) { - return super.isPipe(aTileEntity) - && ((BaseMetaPipeEntity) aTileEntity).getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable; + return super.isPipe(aTileEntity) && ((BaseMetaPipeEntity) aTileEntity).getMetaTileEntity() instanceof MTECable; } @Override @@ -74,7 +73,7 @@ public class GenerateNodeMapPower extends GenerateNodeMap { aConsumers.add(tConsumerNode); return true; } - } else if (GregTech_API.mOutputRF && aTileEntity instanceof IEnergyReceiver receiver) { + } else if (GregTechAPI.mOutputRF && aTileEntity instanceof IEnergyReceiver receiver) { ConsumerNode tConsumerNode = new NodeEnergyReceiver(aNodeValue, receiver, side, aConsumers); aConsumers.add(tConsumerNode); return true; diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java index 4f35922029..e9364f922b 100644 --- a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java +++ b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java @@ -8,13 +8,13 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import cofh.api.energy.IEnergyReceiver; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; import gregtech.api.enums.SoundResource; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import gregtech.api.util.WorldSpawnedEventBuilder; -import gregtech.common.GT_Pollution; +import gregtech.common.Pollution; // consumer for RF machines public class NodeEnergyReceiver extends ConsumerNode { @@ -29,7 +29,7 @@ public class NodeEnergyReceiver extends ConsumerNode { @Override public int injectEnergy(long aVoltage, long aMaxAmps) { ForgeDirection tDirection = mSide; - int rfOut = GT_Utility.safeInt(aVoltage * GregTech_API.mEUtoRF / 100); + int rfOut = GTUtility.safeInt(aVoltage * GregTechAPI.mEUtoRF / 100); int ampsUsed = 0; if (mRestRF < rfOut) { mRestRF += rfOut; @@ -40,7 +40,7 @@ public class NodeEnergyReceiver extends ConsumerNode { mRestRF -= consumed; return ampsUsed; } - if (GregTech_API.mRFExplosions && GregTech_API.sMachineExplosions + if (GregTechAPI.mRFExplosions && GregTechAPI.sMachineExplosions && ((IEnergyReceiver) mTileEntity).getMaxEnergyStored(tDirection) < rfOut * 600L) { explode(rfOut); } @@ -49,14 +49,14 @@ public class NodeEnergyReceiver extends ConsumerNode { // copied from IEnergyConnected private void explode(int aRfOut) { - if (aRfOut > 32L * GregTech_API.mEUtoRF / 100L) { - float tStrength = GT_Values.getExplosionPowerForVoltage(aRfOut); + if (aRfOut > 32L * GregTechAPI.mEUtoRF / 100L) { + float tStrength = GTValues.getExplosionPowerForVoltage(aRfOut); int tX = mTileEntity.xCoord, tY = mTileEntity.yCoord, tZ = mTileEntity.zCoord; World tWorld = mTileEntity.getWorldObj(); - GT_Utility.sendSoundToPlayers(tWorld, SoundResource.IC2_MACHINES_MACHINE_OVERLOAD, 1.0F, -1, tX, tY, tZ); + GTUtility.sendSoundToPlayers(tWorld, SoundResource.IC2_MACHINES_MACHINE_OVERLOAD, 1.0F, -1, tX, tY, tZ); tWorld.setBlock(tX, tY, tZ, Blocks.air); - if (GregTech_API.sMachineExplosions) if (GT_Mod.gregtechproxy.mPollution) GT_Pollution - .addPollution(tWorld.getChunkFromBlockCoords(tX, tZ), GT_Mod.gregtechproxy.mPollutionOnExplosion); + if (GregTechAPI.sMachineExplosions) if (GTMod.gregtechproxy.mPollution) Pollution + .addPollution(tWorld.getChunkFromBlockCoords(tX, tZ), GTMod.gregtechproxy.mPollutionOnExplosion); new WorldSpawnedEventBuilder.ExplosionEffectEventBuilder().setStrength(tStrength) .setSmoking(true) diff --git a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java index d09cf059e9..e9421056af 100644 --- a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java +++ b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java @@ -5,7 +5,7 @@ import net.minecraft.server.MinecraftServer; import gregtech.api.enums.TickTime; import gregtech.api.metatileentity.BaseMetaPipeEntity; import gregtech.api.metatileentity.MetaPipeEntity; -import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; +import gregtech.api.metatileentity.implementations.MTECable; import gregtech.api.util.AveragePerTickCounter; // path for cables @@ -49,7 +49,7 @@ public class PowerNodePath extends NodePath { if (aVoltage > mMaxVoltage) { lock.addTileEntity(null); for (MetaPipeEntity tCable : mPipes) { - if (((GT_MetaPipeEntity_Cable) tCable).mVoltage < this.mVoltage) { + if (((MTECable) tCable).mVoltage < this.mVoltage) { BaseMetaPipeEntity tBaseCable = (BaseMetaPipeEntity) tCable.getBaseMetaTileEntity(); if (tBaseCable != null) { tBaseCable.setToFire(); @@ -75,7 +75,7 @@ public class PowerNodePath extends NodePath { if (this.mAmps > mMaxAmps * 40) { lock.addTileEntity(null); for (MetaPipeEntity tCable : mPipes) { - if (((GT_MetaPipeEntity_Cable) tCable).mAmperage * 40 < this.mAmps) { + if (((MTECable) tCable).mAmperage * 40 < this.mAmps) { BaseMetaPipeEntity tBaseCable = (BaseMetaPipeEntity) tCable.getBaseMetaTileEntity(); if (tBaseCable != null) { tBaseCable.setToFire(); @@ -107,10 +107,10 @@ public class PowerNodePath extends NodePath { mMaxAmps = Integer.MAX_VALUE; mMaxVoltage = Integer.MAX_VALUE; for (MetaPipeEntity tCable : mPipes) { - if (tCable instanceof GT_MetaPipeEntity_Cable) { - mMaxAmps = Math.min(((GT_MetaPipeEntity_Cable) tCable).mAmperage, mMaxAmps); - mLoss += ((GT_MetaPipeEntity_Cable) tCable).mCableLossPerMeter; - mMaxVoltage = Math.min(((GT_MetaPipeEntity_Cable) tCable).mVoltage, mMaxVoltage); + if (tCable instanceof MTECable) { + mMaxAmps = Math.min(((MTECable) tCable).mAmperage, mMaxAmps); + mLoss += ((MTECable) tCable).mCableLossPerMeter; + mMaxVoltage = Math.min(((MTECable) tCable).mVoltage, mMaxVoltage); } } } diff --git a/src/main/java/gregtech/api/gui/GT_GUIColorOverride.java b/src/main/java/gregtech/api/gui/GT_GUIColorOverride.java deleted file mode 100644 index 6ade7b030d..0000000000 --- a/src/main/java/gregtech/api/gui/GT_GUIColorOverride.java +++ /dev/null @@ -1,93 +0,0 @@ -package gregtech.api.gui; - -import java.util.concurrent.ExecutionException; - -import javax.annotation.Nonnull; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IResource; -import net.minecraft.util.ResourceLocation; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.util.concurrent.UncheckedExecutionException; - -import cpw.mods.fml.relauncher.FMLLaunchHandler; -import cpw.mods.fml.relauncher.Side; -import gregtech.api.GregTech_API; -import gregtech.api.util.ColorsMetadataSection; - -@SuppressWarnings("UnstableApiUsage") -public class GT_GUIColorOverride { - - private static final Object NOT_FOUND = new Object(); - private static final LoadingCache cache = CacheBuilder.newBuilder() - .softValues() - .build(new CacheLoader<>() { - - @Override - public Object load(@Nonnull ResourceLocation key) throws Exception { - IResource ir = Minecraft.getMinecraft() - .getResourceManager() - .getResource(key); - if (ir.hasMetadata()) return ir.getMetadata("colors"); - // return a dummy - // object because - // LoadingCache - // doesn't like null - return NOT_FOUND; - } - }); - private static final GT_GUIColorOverride FALLBACK = new GT_GUIColorOverride(); - private ColorsMetadataSection cmSection; - - public static GT_GUIColorOverride get(String fullLocation) { - // see other get for more info - if (FMLLaunchHandler.side() != Side.CLIENT) return FALLBACK; - return new GT_GUIColorOverride(new ResourceLocation(fullLocation)); - } - - public static GT_GUIColorOverride get(ResourceLocation path) { - // use dummy fallback if there isn't such thing as a resource pack. - // #side() usually has two possible return value, but since this might be called by test code, it might - // also return null when in test env. Using #isClient will cause a NPE. A plain inequality test won't. - // FMLCommonHandler's #getSide() might trigger a NPE when in test env, so no. - if (FMLLaunchHandler.side() != Side.CLIENT) return FALLBACK; - return new GT_GUIColorOverride(path); - } - - private GT_GUIColorOverride() { - cmSection = null; - } - - private GT_GUIColorOverride(ResourceLocation resourceLocation) { - try { - Object metadata = cache.get(resourceLocation); - if (metadata != NOT_FOUND) cmSection = (ColorsMetadataSection) metadata; - } catch (ExecutionException | UncheckedExecutionException ignore) { - // make sure it doesn't cache a failing entry - cache.invalidate(resourceLocation); - } - } - - public int getTextColorOrDefault(String textType, int defaultColor) { - return sLoaded() ? cmSection.getTextColorOrDefault(textType, defaultColor) : defaultColor; - } - - public int getGuiTintOrDefault(String key, int defaultColor) { - return sLoaded() ? cmSection.getGuiTintOrDefault(key, defaultColor) : defaultColor; - } - - public boolean sGuiTintingEnabled() { - return sLoaded() ? cmSection.sGuiTintingEnabled() : GregTech_API.sColoredGUI; - } - - public boolean sLoaded() { - return cmSection != null; - } - - public static void onResourceManagerReload() { - cache.invalidateAll(); - } -} diff --git a/src/main/java/gregtech/api/gui/GUIColorOverride.java b/src/main/java/gregtech/api/gui/GUIColorOverride.java new file mode 100644 index 0000000000..aa796d2b63 --- /dev/null +++ b/src/main/java/gregtech/api/gui/GUIColorOverride.java @@ -0,0 +1,93 @@ +package gregtech.api.gui; + +import java.util.concurrent.ExecutionException; + +import javax.annotation.Nonnull; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResource; +import net.minecraft.util.ResourceLocation; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.util.concurrent.UncheckedExecutionException; + +import cpw.mods.fml.relauncher.FMLLaunchHandler; +import cpw.mods.fml.relauncher.Side; +import gregtech.api.GregTechAPI; +import gregtech.api.util.ColorsMetadataSection; + +@SuppressWarnings("UnstableApiUsage") +public class GUIColorOverride { + + private static final Object NOT_FOUND = new Object(); + private static final LoadingCache cache = CacheBuilder.newBuilder() + .softValues() + .build(new CacheLoader<>() { + + @Override + public Object load(@Nonnull ResourceLocation key) throws Exception { + IResource ir = Minecraft.getMinecraft() + .getResourceManager() + .getResource(key); + if (ir.hasMetadata()) return ir.getMetadata("colors"); + // return a dummy + // object because + // LoadingCache + // doesn't like null + return NOT_FOUND; + } + }); + private static final GUIColorOverride FALLBACK = new GUIColorOverride(); + private ColorsMetadataSection cmSection; + + public static GUIColorOverride get(String fullLocation) { + // see other get for more info + if (FMLLaunchHandler.side() != Side.CLIENT) return FALLBACK; + return new GUIColorOverride(new ResourceLocation(fullLocation)); + } + + public static GUIColorOverride get(ResourceLocation path) { + // use dummy fallback if there isn't such thing as a resource pack. + // #side() usually has two possible return value, but since this might be called by test code, it might + // also return null when in test env. Using #isClient will cause a NPE. A plain inequality test won't. + // FMLCommonHandler's #getSide() might trigger a NPE when in test env, so no. + if (FMLLaunchHandler.side() != Side.CLIENT) return FALLBACK; + return new GUIColorOverride(path); + } + + private GUIColorOverride() { + cmSection = null; + } + + private GUIColorOverride(ResourceLocation resourceLocation) { + try { + Object metadata = cache.get(resourceLocation); + if (metadata != NOT_FOUND) cmSection = (ColorsMetadataSection) metadata; + } catch (ExecutionException | UncheckedExecutionException ignore) { + // make sure it doesn't cache a failing entry + cache.invalidate(resourceLocation); + } + } + + public int getTextColorOrDefault(String textType, int defaultColor) { + return sLoaded() ? cmSection.getTextColorOrDefault(textType, defaultColor) : defaultColor; + } + + public int getGuiTintOrDefault(String key, int defaultColor) { + return sLoaded() ? cmSection.getGuiTintOrDefault(key, defaultColor) : defaultColor; + } + + public boolean sGuiTintingEnabled() { + return sLoaded() ? cmSection.sGuiTintingEnabled() : GregTechAPI.sColoredGUI; + } + + public boolean sLoaded() { + return cmSection != null; + } + + public static void onResourceManagerReload() { + cache.invalidateAll(); + } +} diff --git a/src/main/java/gregtech/api/gui/modularui/CoverUIBuildContext.java b/src/main/java/gregtech/api/gui/modularui/CoverUIBuildContext.java new file mode 100644 index 0000000000..2bf8795c5c --- /dev/null +++ b/src/main/java/gregtech/api/gui/modularui/CoverUIBuildContext.java @@ -0,0 +1,74 @@ +package gregtech.api.gui.modularui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; + +import gregtech.api.interfaces.tileentity.ICoverable; + +public class CoverUIBuildContext extends UIBuildContext { + + // cover data is not synced to client, while ID is + private final int coverID; + private final ForgeDirection side; + private final ICoverable tile; + private final boolean anotherWindow; + private final int guiColorization; + + /** + * @param player Player opened this UI + * @param coverID See {@link ICoverable#getCoverIDAtSide} + * @param side Side this cover is attached to + * @param tile Tile this cover is attached to + * @param anotherWindow If cover UI is shown on top of another window + * @param guiColorization The color used to render machine's GUI + */ + public CoverUIBuildContext(EntityPlayer player, int coverID, ForgeDirection side, ICoverable tile, + boolean anotherWindow, int guiColorization) { + super(player); + this.coverID = coverID; + this.side = side; + this.tile = tile; + this.anotherWindow = anotherWindow; + this.guiColorization = guiColorization; + } + + /** + * @param player Player opened this UI + * @param coverID See {@link ICoverable#getCoverIDAtSide} + * @param side Side this cover is attached to + * @param tile Tile this cover is attached to + * @param anotherWindow If cover GUI is shown in opened on top of another window + */ + public CoverUIBuildContext(EntityPlayer player, int coverID, ForgeDirection side, ICoverable tile, + boolean anotherWindow) { + this(player, coverID, side, tile, anotherWindow, tile.getGUIColorization()); + } + + public int getCoverID() { + return coverID; + } + + public ForgeDirection getCoverSide() { + return side; + } + + /** + * Note that this will return different object between client v.s. server side on SP. + */ + public ICoverable getTile() { + return tile; + } + + /** + * If cover GUI is shown in opened on top of another window. + */ + public boolean isAnotherWindow() { + return anotherWindow; + } + + public int getGuiColorization() { + return guiColorization; + } +} diff --git a/src/main/java/gregtech/api/gui/modularui/GTUIInfos.java b/src/main/java/gregtech/api/gui/modularui/GTUIInfos.java new file mode 100644 index 0000000000..ede4b54e08 --- /dev/null +++ b/src/main/java/gregtech/api/gui/modularui/GTUIInfos.java @@ -0,0 +1,188 @@ +package gregtech.api.gui.modularui; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.UIInfos; +import com.gtnewhorizons.modularui.api.screen.ITileWithModularUI; +import com.gtnewhorizons.modularui.api.screen.ModularUIContext; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.builder.UIBuilder; +import com.gtnewhorizons.modularui.common.builder.UIInfo; +import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils; +import com.gtnewhorizons.modularui.common.internal.wrapper.ModularGui; +import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.enums.GTValues; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords; +import gregtech.api.net.GTPacketSendCoverData; +import gregtech.api.util.CoverBehaviorBase; + +public class GTUIInfos { + + public static void init() {} + + /** + * Generator for {@link UIInfo} which is responsible for registering and opening UIs. Unlike + * {@link com.gtnewhorizons.modularui.api.UIInfos#TILE_MODULAR_UI}, this accepts custom constructors for UI.
+ * Do NOT run {@link UIBuilder#build} on-the-fly, otherwise MP client won't register UIs. Instead, store to static + * field, just like {@link #GTTileEntityDefaultUI}. Such mistake can be easily overlooked by testing only SP. + */ + public static final Function> GTTileEntityUIFactory = containerConstructor -> UIBuilder + .of() + .container((player, world, x, y, z) -> { + TileEntity te = world.getTileEntity(x, y, z); + if (te instanceof ITileWithModularUI mui) { + return createTileEntityContainer(player, mui::createWindow, te::markDirty, containerConstructor); + } + return null; + }) + .gui(((player, world, x, y, z) -> { + if (!world.isRemote) return null; + TileEntity te = world.getTileEntity(x, y, z); + if (te instanceof ITileWithModularUI mui) { + return createTileEntityGuiContainer(player, mui::createWindow, containerConstructor); + } + return null; + })) + .build(); + + private static final UIInfo GTTileEntityDefaultUI = GTTileEntityUIFactory.apply(ModularUIContainer::new); + + private static final Map> coverUI = new HashMap<>(); + + static { + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + coverUI.put( + side, + UIBuilder.of() + .container((player, world, x, y, z) -> { + final TileEntity te = world.getTileEntity(x, y, z); + if (!(te instanceof ICoverable gtTileEntity)) return null; + final CoverBehaviorBase cover = gtTileEntity.getCoverBehaviorAtSideNew(side); + return createCoverContainer( + player, + cover::createWindow, + te::markDirty, + gtTileEntity.getCoverIDAtSide(side), + side, + gtTileEntity); + }) + .gui((player, world, x, y, z) -> { + if (!world.isRemote) return null; + final TileEntity te = world.getTileEntity(x, y, z); + if (!(te instanceof ICoverable gtTileEntity)) return null; + final CoverBehaviorBase cover = gtTileEntity.getCoverBehaviorAtSideNew(side); + return createCoverGuiContainer( + player, + cover::createWindow, + gtTileEntity.getCoverIDAtSide(side), + side, + gtTileEntity); + }) + .build()); + } + } + + /** + * Opens TileEntity UI, created by {@link ITileWithModularUI#createWindow}. + */ + public static void openGTTileEntityUI(IHasWorldObjectAndCoords aTileEntity, EntityPlayer aPlayer) { + if (aTileEntity.isClientSide() || aPlayer instanceof FakePlayer) return; + GTTileEntityDefaultUI.open( + aPlayer, + aTileEntity.getWorld(), + aTileEntity.getXCoord(), + aTileEntity.getYCoord(), + aTileEntity.getZCoord()); + } + + /** + * Opens cover UI, created by {@link CoverBehaviorBase#createWindow}. + */ + public static void openCoverUI(ICoverable tileEntity, EntityPlayer player, ForgeDirection side) { + if (tileEntity.isClientSide()) return; + + GTValues.NW.sendToPlayer( + new GTPacketSendCoverData( + side, + tileEntity.getCoverIDAtSide(side), + tileEntity.getComplexCoverDataAtSide(side), + tileEntity), + (EntityPlayerMP) player); + + coverUI.get(side) + .open( + player, + tileEntity.getWorld(), + tileEntity.getXCoord(), + tileEntity.getYCoord(), + tileEntity.getZCoord()); + } + + /** + * Opens UI for player's item, created by + * {@link com.gtnewhorizons.modularui.api.screen.IItemWithModularUI#createWindow}. + */ + public static void openPlayerHeldItemUI(EntityPlayer player) { + if (NetworkUtils.isClient()) return; + UIInfos.PLAYER_HELD_ITEM_UI.open(player); + } + + private static ModularUIContainer createTileEntityContainer(EntityPlayer player, + Function windowCreator, Runnable onWidgetUpdate, + ContainerConstructor containerCreator) { + final UIBuildContext buildContext = new UIBuildContext(player); + final ModularWindow window = windowCreator.apply(buildContext); + if (window == null) return null; + return containerCreator.of(new ModularUIContext(buildContext, onWidgetUpdate), window); + } + + @SideOnly(Side.CLIENT) + private static ModularGui createTileEntityGuiContainer(EntityPlayer player, + Function windowCreator, ContainerConstructor containerConstructor) { + final ModularUIContainer container = createTileEntityContainer( + player, + windowCreator, + null, + containerConstructor); + if (container == null) return null; + return new ModularGui(container); + } + + private static ModularUIContainer createCoverContainer(EntityPlayer player, + Function windowCreator, Runnable onWidgetUpdate, int coverID, + ForgeDirection side, ICoverable tile) { + final CoverUIBuildContext buildContext = new CoverUIBuildContext(player, coverID, side, tile, false); + final ModularWindow window = windowCreator.apply(buildContext); + if (window == null) return null; + return new ModularUIContainer(new ModularUIContext(buildContext, onWidgetUpdate), window); + } + + @SideOnly(Side.CLIENT) + private static ModularGui createCoverGuiContainer(EntityPlayer player, + Function windowCreator, int coverID, ForgeDirection side, ICoverable tile) { + final ModularUIContainer container = createCoverContainer(player, windowCreator, null, coverID, side, tile); + if (container == null) { + return null; + } + return new ModularGui(container); + } + + @FunctionalInterface + public interface ContainerConstructor { + + ModularUIContainer of(ModularUIContext context, ModularWindow mainWindow); + } +} diff --git a/src/main/java/gregtech/api/gui/modularui/GTUITextures.java b/src/main/java/gregtech/api/gui/modularui/GTUITextures.java new file mode 100644 index 0000000000..125e1640b0 --- /dev/null +++ b/src/main/java/gregtech/api/gui/modularui/GTUITextures.java @@ -0,0 +1,542 @@ +package gregtech.api.gui.modularui; + +import static gregtech.api.enums.Mods.GregTech; + +import java.util.function.BiFunction; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import com.gtnewhorizons.modularui.api.drawable.AdaptableUITexture; +import com.gtnewhorizons.modularui.api.drawable.FallbackableUITexture; +import com.gtnewhorizons.modularui.api.drawable.UITexture; + +public class GTUITextures { + + public static final UITexture TRANSPARENT = UITexture.fullImage(GregTech.ID, "gui/picture/transparent"); + + public static final AdaptableUITexture BACKGROUND_SINGLEBLOCK_DEFAULT = AdaptableUITexture + .of(GregTech.ID, "gui/background/singleblock_default", 176, 166, 4); + public static final SteamTexture BACKGROUND_STEAM = SteamTexture + .adaptableTexture(GregTech.ID, "gui/background/%s", 176, 166, 4); + public static final UITexture BACKGROUND_FUSION_COMPUTER = UITexture + .fullImage(GregTech.ID, "gui/background/fusion_computer"); + public static final AdaptableUITexture BACKGROUND_TEXT_FIELD = AdaptableUITexture + .of(GregTech.ID, "gui/background/text_field", 142, 28, 1); + public static final AdaptableUITexture BACKGROUND_TEXT_FIELD_LIGHT_GRAY = AdaptableUITexture + .of(GregTech.ID, "gui/background/text_field_light_gray", 61, 12, 1); + public static final AdaptableUITexture BACKGROUND_NEI_SINGLE_RECIPE = AdaptableUITexture + .of(GregTech.ID, "gui/background/nei_single_recipe.png", 64, 64, 2); + public static final UITexture BACKGROUND_FLOCCULATION_RECIPE = UITexture + .fullImage(GregTech.ID, "gui/background/flocculation_recipe.png"); + public static final SteamTexture SLOT_ITEM_STEAM = SteamTexture.fullImage(GregTech.ID, "gui/slot/item_%s"); + public static final SteamTexture SLOT_FLUID_STEAM = SteamTexture.fullImage(GregTech.ID, "gui/slot/fluid_%s"); + public static final AdaptableUITexture SLOT_DARK_GRAY = AdaptableUITexture + .of(GregTech.ID, "gui/slot/dark_gray", 18, 18, 1); + public static final AdaptableUITexture SLOT_MAINTENANCE = AdaptableUITexture + .of(GregTech.ID, "gui/slot/maintenance", 20, 20, 1); + public static final AdaptableUITexture SLOT_UPLIFTED = AdaptableUITexture + .of(GregTech.ID, "gui/slot/uplifted", 18, 18, 1); + + public static final UITexture OVERLAY_SLOT_ARROW_ME = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/arrow_me"); + public static final UITexture OVERLAY_SLOT_PATTERN_ME = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/pattern_me"); + + public static final UITexture OVERLAY_SLOT_BEAKER_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/beaker_1"); + public static final UITexture OVERLAY_SLOT_BEAKER_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/beaker_2"); + public static final UITexture OVERLAY_SLOT_BEE_DRONE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/bee_drone"); + public static final UITexture OVERLAY_SLOT_BEE_QUEEN = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/bee_queen"); + public static final UITexture OVERLAY_SLOT_BENDER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/bender"); + public static final UITexture OVERLAY_SLOT_BOX = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/box"); + public static final UITexture OVERLAY_SLOT_BOXED = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/boxed"); + public static final UITexture OVERLAY_SLOT_CANISTER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/canister"); + public static final SteamTexture OVERLAY_SLOT_CANISTER_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/canister_%s"); + public static final UITexture OVERLAY_SLOT_CANNER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/canner"); + public static final UITexture OVERLAY_SLOT_CAULDRON = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/cauldron"); + public static final UITexture OVERLAY_SLOT_CENTRIFUGE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/centrifuge"); + public static final UITexture OVERLAY_SLOT_CENTRIFUGE_FLUID = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/centrifuge_fluid"); + public static final SteamTexture OVERLAY_SLOT_CENTRIFUGE_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/centrifuge_%s"); + public static final UITexture OVERLAY_SLOT_CHARGER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/charger"); + public static final UITexture OVERLAY_SLOT_CHARGER_FLUID = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/charger_fluid"); + public static final UITexture OVERLAY_SLOT_CIRCUIT = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/circuit"); + public static final SteamTexture OVERLAY_SLOT_COAL_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/coal_%s"); + public static final UITexture OVERLAY_SLOT_COMPRESSOR = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/compressor"); + public static final SteamTexture OVERLAY_SLOT_COMPRESSOR_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/compressor_%s"); + public static final UITexture OVERLAY_SLOT_CRUSHED_ORE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/crushed_ore"); + public static final SteamTexture OVERLAY_SLOT_CRUSHED_ORE_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/crushed_ore_%s"); + public static final UITexture OVERLAY_SLOT_CUTTER_SLICED = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/cutter_sliced"); + public static final UITexture OVERLAY_SLOT_DATA_ORB = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/data_orb"); + public static final UITexture OVERLAY_SLOT_DATA_STICK = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/data_stick"); + public static final UITexture OVERLAY_SLOT_DUST = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/dust"); + public static final SteamTexture OVERLAY_SLOT_DUST_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/dust_%s"); + public static final SteamTexture OVERLAY_SLOT_BLOCK_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/block_%s"); + public static final UITexture OVERLAY_SLOT_EXPLOSIVE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/explosive"); + public static final UITexture OVERLAY_SLOT_EXTRUDER_SHAPE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/extruder_shape"); + public static final UITexture OVERLAY_SLOT_FILTER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/filter"); + public static final UITexture OVERLAY_SLOT_FURNACE = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/furnace"); + public static final SteamTexture OVERLAY_SLOT_FURNACE_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/furnace_%s"); + public static final UITexture OVERLAY_SLOT_GEM = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/gem"); + public static final UITexture OVERLAY_SLOT_HAMMER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/hammer"); + public static final SteamTexture OVERLAY_SLOT_HAMMER_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/hammer_%s"); + public static final UITexture OVERLAY_SLOT_HEATER_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/heater_1"); + public static final UITexture OVERLAY_SLOT_HEATER_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/heater_2"); + public static final UITexture OVERLAY_SLOT_IMPLOSION = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/implosion"); + public static final UITexture OVERLAY_SLOT_IN = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/in"); + public static final SteamTexture OVERLAY_SLOT_IN_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/in_%s"); + public static final SteamTexture OVERLAY_SLOT_INGOT_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/ingot_%s"); + public static final UITexture OVERLAY_SLOT_INT_CIRCUIT = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/int_circuit"); + public static final UITexture OVERLAY_SLOT_LENS = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/lens"); + public static final UITexture OVERLAY_SLOT_MICROSCOPE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/microscope"); + public static final UITexture OVERLAY_SLOT_MINING_PIPE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/mining_pipe"); + public static final UITexture OVERLAY_SLOT_MOLD = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/mold"); + public static final UITexture OVERLAY_SLOT_MOLECULAR_1 = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/molecular_1"); + public static final UITexture OVERLAY_SLOT_MOLECULAR_2 = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/molecular_2"); + public static final UITexture OVERLAY_SLOT_MOLECULAR_3 = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/molecular_3"); + public static final UITexture OVERLAY_SLOT_OUT = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/out"); + public static final SteamTexture OVERLAY_SLOT_OUT_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/overlay_slot/out_%s"); + public static final UITexture OVERLAY_SLOT_PAGE_BLANK = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/page_blank"); + public static final UITexture OVERLAY_SLOT_PAGE_PRINTED = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/page_printed"); + public static final UITexture OVERLAY_SLOT_PRESS_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/press_1"); + public static final UITexture OVERLAY_SLOT_PRESS_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/press_2"); + public static final UITexture OVERLAY_SLOT_PRESS_3 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/press_3"); + public static final UITexture OVERLAY_SLOT_RECYCLE = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/recycle"); + public static final UITexture OVERLAY_SLOT_ROD_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/rod_1"); + public static final UITexture OVERLAY_SLOT_ROD_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/rod_2"); + public static final UITexture OVERLAY_SLOT_SLICE_SHAPE = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/slice_shape"); + public static final UITexture OVERLAY_SLOT_SLICER_SLICED = UITexture + .fullImage(GregTech.ID, "gui/overlay_slot/slicer_sliced"); + public static final UITexture OVERLAY_SLOT_SQUARE = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/square"); + public static final UITexture OVERLAY_SLOT_UUA = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/uua"); + public static final UITexture OVERLAY_SLOT_UUM = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/uum"); + public static final UITexture OVERLAY_SLOT_VIAL_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/vial_1"); + public static final UITexture OVERLAY_SLOT_VIAL_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/vial_2"); + public static final UITexture OVERLAY_SLOT_WIREMILL = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/wiremill"); + public static final UITexture OVERLAY_SLOT_WRENCH = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/wrench"); + public static final UITexture[] OVERLAY_SLOTS_NUMBER = IntStream.range(0, 12) + .mapToObj(i -> UITexture.fullImage(GregTech.ID, "gui/overlay_slot/number_" + i)) + .collect(Collectors.toList()) + .toArray(new UITexture[0]); + + public static final UITexture PROGRESSBAR_ARROW = UITexture.fullImage(GregTech.ID, "gui/progressbar/arrow"); + public static final SteamTexture PROGRESSBAR_ARROW_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/arrow_%s"); + public static final SteamTexture PROGRESSBAR_ARROW_2_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/arrow_2_%s"); + public static final UITexture PROGRESSBAR_ARROW_MULTIPLE = UITexture + .fullImage(GregTech.ID, "gui/progressbar/arrow_multiple"); + public static final UITexture PROGRESSBAR_ASSEMBLE = UITexture.fullImage(GregTech.ID, "gui/progressbar/assemble"); + public static final UITexture PROGRESSBAR_ASSEMBLY_LINE_1 = UITexture + .fullImage(GregTech.ID, "gui/progressbar/assemblyline_1"); + public static final UITexture PROGRESSBAR_ASSEMBLY_LINE_2 = UITexture + .fullImage(GregTech.ID, "gui/progressbar/assemblyline_2"); + public static final UITexture PROGRESSBAR_ASSEMBLY_LINE_3 = UITexture + .fullImage(GregTech.ID, "gui/progressbar/assemblyline_3"); + public static final UITexture PROGRESSBAR_BATH = UITexture.fullImage(GregTech.ID, "gui/progressbar/bath"); + public static final UITexture PROGRESSBAR_BENDING = UITexture.fullImage(GregTech.ID, "gui/progressbar/bending"); + public static final SteamTexture PROGRESSBAR_BOILER_EMPTY_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/boiler_empty_%s"); + public static final UITexture PROGRESSBAR_BOILER_HEAT = UITexture + .fullImage(GregTech.ID, "gui/progressbar/boiler_heat"); + public static final UITexture PROGRESSBAR_BOILER_STEAM = UITexture + .fullImage(GregTech.ID, "gui/progressbar/boiler_steam"); + public static final UITexture PROGRESSBAR_BOILER_WATER = UITexture + .fullImage(GregTech.ID, "gui/progressbar/boiler_water"); + public static final UITexture PROGRESSBAR_CANNER = UITexture.fullImage(GregTech.ID, "gui/progressbar/canner"); + public static final UITexture PROGRESSBAR_CIRCUIT_ASSEMBLER = UITexture + .fullImage(GregTech.ID, "gui/progressbar/circuit_assembler"); + public static final UITexture PROGRESSBAR_COMPRESS = UITexture.fullImage(GregTech.ID, "gui/progressbar/compress"); + public static final SteamTexture PROGRESSBAR_COMPRESS_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/compress_%s"); + public static final UITexture PROGRESSBAR_CUT = UITexture.fullImage(GregTech.ID, "gui/progressbar/cut"); + public static final UITexture PROGRESSBAR_EXTRACT = UITexture.fullImage(GregTech.ID, "gui/progressbar/extract"); + public static final SteamTexture PROGRESSBAR_EXTRACT_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/extract_%s"); + public static final UITexture PROGRESSBAR_EXTRUDE = UITexture.fullImage(GregTech.ID, "gui/progressbar/extrude"); + public static final SteamTexture PROGRESSBAR_FUEL_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/fuel_%s"); + public static final UITexture PROGRESSBAR_HAMMER = UITexture.fullImage(GregTech.ID, "gui/progressbar/hammer"); + public static final UITexture PROGRESSBAR_HAMMER_BASE = UITexture + .fullImage(GregTech.ID, "gui/progressbar/hammer_base"); + public static final SteamTexture PROGRESSBAR_HAMMER_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/hammer_%s"); + public static final SteamTexture PROGRESSBAR_HAMMER_BASE_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/hammer_base_%s"); + public static final UITexture PROGRESSBAR_LATHE = UITexture.fullImage(GregTech.ID, "gui/progressbar/lathe"); + public static final UITexture PROGRESSBAR_LATHE_BASE = UITexture + .fullImage(GregTech.ID, "gui/progressbar/lathe_base"); + public static final UITexture PROGRESSBAR_MACERATE = UITexture.fullImage(GregTech.ID, "gui/progressbar/macerate"); + public static final SteamTexture PROGRESSBAR_MACERATE_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/progressbar/macerate_%s"); + public static final UITexture PROGRESSBAR_MAGNET = UITexture.fullImage(GregTech.ID, "gui/progressbar/magnet"); + public static final UITexture PROGRESSBAR_MIXER = UITexture.fullImage(GregTech.ID, "gui/progressbar/mixer"); + public static final UITexture PROGRESSBAR_RECYCLE = UITexture.fullImage(GregTech.ID, "gui/progressbar/recycle"); + public static final UITexture PROGRESSBAR_SIFT = UITexture.fullImage(GregTech.ID, "gui/progressbar/sift"); + public static final UITexture PROGRESSBAR_SLICE = UITexture.fullImage(GregTech.ID, "gui/progressbar/slice"); + public static final UITexture PROGRESSBAR_STORED_EU = UITexture.fullImage(GregTech.ID, "gui/progressbar/stored_eu"); + public static final UITexture PROGRESSBAR_WIREMILL = UITexture.fullImage(GregTech.ID, "gui/progressbar/wiremill"); + public static final UITexture PROGRESSBAR_FLOCCULATION = UITexture + .fullImage(GregTech.ID, "gui/progressbar/flocculation"); + public static final UITexture PROGRESSBAR_CLARIFIER = UITexture.fullImage(GregTech.ID, "gui/progressbar/clarifier"); + public static final UITexture PROGRESSBAR_PH_NEUTRALIZATION = UITexture + .fullImage(GregTech.ID, "gui/progressbar/phneutralization"); + public static final UITexture PROGRESSBAR_OZONATION = UITexture.fullImage(GregTech.ID, "gui/progressbar/ozonation"); + public static final UITexture PROGRESSBAR_PLASMA_HEATER = UITexture + .fullImage(GregTech.ID, "gui/progressbar/water_plasma_heater"); + + public static FallbackableUITexture fallbackableProgressbar(String name, UITexture fallback) { + return new FallbackableUITexture(UITexture.fullImage(GregTech.ID, "gui/progressbar/" + name), fallback); + } + + public static final UITexture TAB_COVER_NORMAL = UITexture.fullImage(GregTech.ID, "gui/tab/cover_normal"); + public static final UITexture TAB_COVER_HIGHLIGHT = UITexture.fullImage(GregTech.ID, "gui/tab/cover_highlight"); + public static final UITexture TAB_COVER_DISABLED = UITexture.fullImage(GregTech.ID, "gui/tab/cover_disabled"); + public static final SteamTexture TAB_COVER_STEAM_NORMAL = SteamTexture + .fullImage(GregTech.ID, "gui/tab/cover_%s_normal"); + public static final SteamTexture TAB_COVER_STEAM_HIGHLIGHT = SteamTexture + .fullImage(GregTech.ID, "gui/tab/cover_%s_highlight"); + public static final SteamTexture TAB_COVER_STEAM_DISABLED = SteamTexture + .fullImage(GregTech.ID, "gui/tab/cover_%s_disabled"); + public static final AdaptableUITexture TAB_TITLE = AdaptableUITexture.of(GregTech.ID, "gui/tab/title", 28, 28, 4); + public static final AdaptableUITexture TAB_TITLE_DARK = AdaptableUITexture + .of(GregTech.ID, "gui/tab/title_dark", 28, 28, 4); + public static final SteamTexture TAB_TITLE_STEAM = SteamTexture + .adaptableTexture(GregTech.ID, "gui/tab/title_%s", 28, 28, 4); + public static final SteamTexture TAB_TITLE_DARK_STEAM = SteamTexture + .adaptableTexture(GregTech.ID, "gui/tab/title_dark_%s", 28, 28, 4); + public static final AdaptableUITexture TAB_TITLE_ANGULAR = AdaptableUITexture + .of(GregTech.ID, "gui/tab/title_angular", 28, 28, 4); + public static final SteamTexture TAB_TITLE_ANGULAR_STEAM = SteamTexture + .adaptableTexture(GregTech.ID, "gui/tab/title_angular_%s", 28, 28, 4); + + public static final UITexture BUTTON_STANDARD = AdaptableUITexture + .of(GregTech.ID, "gui/button/standard", 18, 18, 1); + public static final UITexture BUTTON_STANDARD_PRESSED = AdaptableUITexture + .of(GregTech.ID, "gui/button/standard_pressed", 18, 18, 1); + public static final UITexture BUTTON_STANDARD_DISABLED = AdaptableUITexture + .of(GregTech.ID, "gui/button/standard_disabled", 18, 18, 1); + public static final UITexture BUTTON_STANDARD_TOGGLE = AdaptableUITexture + .of(GregTech.ID, "gui/button/standard_toggle", 18, 18, 1); + public static final UITexture BUTTON_STANDARD_TOGGLE_DISABLED = AdaptableUITexture + .of(GregTech.ID, "gui/button/standard_toggle_disabled", 18, 18, 1); + public static final UITexture BUTTON_COVER_NORMAL = UITexture.fullImage(GregTech.ID, "gui/button/cover_normal"); + public static final UITexture BUTTON_COVER_NORMAL_HOVERED = UITexture + .fullImage(GregTech.ID, "gui/button/cover_normal_hovered"); + public static final UITexture BUTTON_COVER_NORMAL_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/button/cover_normal_disabled"); + + public static final UITexture OVERLAY_BUTTON_DISABLE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/disable"); + public static final UITexture OVERLAY_BUTTON_REDSTONE_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/redstone_off"); + public static final UITexture OVERLAY_BUTTON_REDSTONE_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/redstone_on"); + public static final UITexture OVERLAY_BUTTON_POWER_SWITCH_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/power_switch_on"); + public static final UITexture OVERLAY_BUTTON_POWER_SWITCH_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/power_switch_off"); + public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_NONE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/void_excess_none"); + public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_ITEM = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/void_excess_item"); + public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_FLUID = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/void_excess_fluid"); + public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_ALL = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/void_excess_all"); + public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/input_separation_on"); + public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_ON_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/input_separation_on_disabled"); + public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/input_separation_off"); + public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_OFF_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/input_separation_off_disabled"); + public static final UITexture OVERLAY_BUTTON_RECIPE_LOCKED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/recipe_locked"); + public static final UITexture OVERLAY_BUTTON_RECIPE_LOCKED_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/recipe_locked_disabled"); + public static final UITexture OVERLAY_BUTTON_RECIPE_UNLOCKED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/recipe_unlocked"); + public static final UITexture OVERLAY_BUTTON_RECIPE_UNLOCKED_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/recipe_unlocked_disabled"); + public static final UITexture OVERLAY_BUTTON_BATCH_MODE_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_on"); + public static final UITexture OVERLAY_BUTTON_BATCH_MODE_ON_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_on_disabled"); + public static final UITexture OVERLAY_BUTTON_BATCH_MODE_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_off"); + public static final UITexture OVERLAY_BUTTON_BATCH_MODE_OFF_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_off_disabled"); + public static final UITexture OVERLAY_BUTTON_STRUCTURE_UPDATE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/structure_update"); + public static final UITexture OVERLAY_BUTTON_FORBIDDEN = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/forbidden"); + public static final UITexture OVERLAY_BUTTON_LOCKED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/lock_small"); + public static final UITexture OVERLAY_BUTTON_DOWN_TIERING_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/down_tiering_on"); + public static final UITexture OVERLAY_BUTTON_DOWN_TIERING_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/down_tiering_off"); + public static final UITexture OVERLAY_BUTTON_CHECKMARK = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/checkmark"); + public static final UITexture OVERLAY_BUTTON_CROSS = UITexture.fullImage(GregTech.ID, "gui/overlay_button/cross"); + public static final UITexture OVERLAY_BUTTON_WHITELIST = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/whitelist"); + public static final UITexture OVERLAY_BUTTON_BLACKLIST = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/blacklist"); + public static final UITexture OVERLAY_BUTTON_PROGRESS = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/progress"); + public static final UITexture OVERLAY_BUTTON_EXPORT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/export"); + public static final UITexture OVERLAY_BUTTON_IMPORT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/import"); + public static final UITexture OVERLAY_BUTTON_AUTOOUTPUT_ITEM = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/autooutput_item"); + public static final UITexture OVERLAY_BUTTON_AUTOOUTPUT_FLUID = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/autooutput_fluid"); + public static final UITexture OVERLAY_BUTTON_ALLOW_INPUT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/allow_input"); + public static final UITexture OVERLAY_BUTTON_ALLOW_OUTPUT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/allow_output"); + public static final UITexture OVERLAY_BUTTON_AUTOPULL_ME = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/auto_pull_me"); + public static final UITexture OVERLAY_BUTTON_AUTOPULL_ME_DISABLED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/auto_pull_me_disabled"); + public static final UITexture OVERLAY_BUTTON_BLOCK_INPUT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/block_input"); + public static final UITexture OVERLAY_BUTTON_BLOCK_OUTPUT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/block_output"); + public static final UITexture OVERLAY_BUTTON_ARROW_GREEN_UP = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/arrow_green_up"); + public static final UITexture OVERLAY_BUTTON_ARROW_GREEN_DOWN = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/arrow_green_down"); + public static final UITexture OVERLAY_BUTTON_CYCLIC = UITexture.fullImage(GregTech.ID, "gui/overlay_button/cyclic"); + public static final UITexture OVERLAY_BUTTON_SHUFFLE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/shuffle"); + public static final UITexture OVERLAY_BUTTON_EMIT_ENERGY = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/emit_energy"); + public static final UITexture OVERLAY_BUTTON_EMIT_REDSTONE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/emit_redstone"); + public static final UITexture OVERLAY_BUTTON_INVERT_REDSTONE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/invert_redstone"); + public static final UITexture OVERLAY_BUTTON_STOCKING_MODE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/stocking_mode"); + public static final UITexture OVERLAY_BUTTON_INVERT_FILTER = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/invert_filter"); + public static final UITexture OVERLAY_BUTTON_NBT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/nbt"); + public static final UITexture OVERLAY_BUTTON_PRINT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/print"); + public static final UITexture OVERLAY_BUTTON_TRANSPOSE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/transpose"); + public static final UITexture OVERLAY_BUTTON_SORTING_MODE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/sorting_mode"); + public static final UITexture OVERLAY_BUTTON_ONE_STACK_LIMIT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/one_stack_limit"); + public static final UITexture OVERLAY_BUTTON_BOUNDING_BOX = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/bounding_box"); + public static final UITexture OVERLAY_BUTTON_MINUS_SMALL = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/minus_small"); + public static final UITexture OVERLAY_BUTTON_MINUS_LARGE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/minus_large"); + public static final UITexture OVERLAY_BUTTON_PLUS_SMALL = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/plus_small"); + public static final UITexture OVERLAY_BUTTON_PLUS_LARGE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/plus_large"); + public static final UITexture OVERLAY_BUTTON_GATE_AND = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/gate_and"); + public static final UITexture OVERLAY_BUTTON_GATE_NAND = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/gate_nand"); + public static final UITexture OVERLAY_BUTTON_GATE_OR = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/gate_or"); + public static final UITexture OVERLAY_BUTTON_GATE_NOR = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/gate_nor"); + public static final UITexture OVERLAY_BUTTON_ANALOG = UITexture.fullImage(GregTech.ID, "gui/overlay_button/analog"); + public static final UITexture OVERLAY_BUTTON_LOCK = UITexture.fullImage(GregTech.ID, "gui/overlay_button/lock"); + public static final UITexture OVERLAY_BUTTON_INPUT_FROM_OUTPUT_SIDE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/input_from_output_side"); + public static final UITexture OVERLAY_BUTTON_TANK_VOID_EXCESS = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/tank_void_excess"); + public static final UITexture OVERLAY_BUTTON_TANK_VOID_ALL = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/tank_void_all"); + public static final UITexture OVERLAY_BUTTON_NEI = UITexture.fullImage(GregTech.ID, "gui/overlay_button/nei"); + public static final UITexture OVERLAY_BUTTON_USE_PROCESSING_STATE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/use_processing_state.png"); + public static final UITexture OVERLAY_BUTTON_USE_INVERTED_PROCESSING_STATE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/use_inverted_processing_state.png"); + public static final UITexture OVERLAY_BUTTON_CHUNK_LOADING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/chunkloading"); + public static final UITexture OVERLAY_BUTTON_CHUNK_LOADING_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/chunkloading_off"); + public static final UITexture OVERLAY_BUTTON_WORK_AREA = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/work_area"); + public static final UITexture OVERLAY_BUTTON_REPLACE_COBBLE_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/replace_cobble_on"); + public static final UITexture OVERLAY_BUTTON_REPLACE_COBBLE_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/replace_cobble_off"); + public static final UITexture OVERLAY_BUTTON_RETRACT_PIPE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/retract_pipes"); + public static final UITexture OVERLAY_BUTTON_HOURGLASS = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/hourglass"); + + public static final UITexture OVERLAY_BUTTON_LIQUIDMODE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/LiquidMode"); + + public static final UITexture OVERLAY_BUTTON_LIQUIDMODE_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/LiquidMode_off"); + + // These icons are for mode switching machine modes + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_DEFAULT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_default"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_CHEMBATH = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_chembath"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_WASHPLANT = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_washplant"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SIMPLEWASHER = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_simplewasher"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_PACKAGER = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_packager"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_UNPACKAGER = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_unpackager"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SEPARATOR = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_separator"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_POLARIZER = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_polarizer"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_LPF_FLUID = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_lpf_fluid"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_LPF_METAL = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_lpf_metal"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_BENDING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_bending"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_FORMING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_forming"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SLICING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_slicing"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_CUTTING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_cutting"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_COMPRESSING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_compressing"); + public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SINGULARITY = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_singularity"); + + /** + * Can adjust size as needed. + */ + public static final AdaptableUITexture PICTURE_SCREEN_BLACK = AdaptableUITexture + .of(GregTech.ID, "gui/picture/screen_black", 16, 16, 2); + + public static final UITexture PICTURE_RADIATION_WARNING = UITexture + .fullImage(GregTech.ID, "gui/picture/radiation_warning"); + public static final UITexture PICTURE_GT_LOGO_17x17_TRANSPARENT = UITexture + .fullImage(GregTech.ID, "gui/picture/gt_logo_17x17_transparent"); + public static final UITexture PICTURE_GT_LOGO_17x17_TRANSPARENT_GRAY = UITexture + .fullImage(GregTech.ID, "gui/picture/gt_logo_17x17_transparent_gray"); + public static final SteamTexture PICTURE_GT_LOGO_17x17_TRANSPARENT_STEAM = SteamTexture + .fullImage(GregTech.ID, "gui/picture/gt_logo_17x17_transparent_%s"); + public static final UITexture PICTURE_GT_LOGO_18x18 = UITexture.fullImage(GregTech.ID, "gui/picture/gt_logo_18x18"); + public static final UITexture PICTURE_GT_LOGO_19x19 = UITexture.fullImage(GregTech.ID, "gui/picture/gt_logo_19x19"); + public static final UITexture PICTURE_INFORMATION = UITexture.fullImage(GregTech.ID, "gui/picture/information"); + public static final UITexture PICTURE_STALLED_ELECTRICITY = UITexture + .fullImage(GregTech.ID, "gui/picture/stalled_electricity"); + public static final UITexture PICTURE_STALLED_STEAM = UITexture.fullImage(GregTech.ID, "gui/picture/stalled_steam"); + public static final BiFunction PICTURE_ARROW_22_RED = (width, fromRight) -> UITexture + .partly( + GregTech.ID, + "gui/picture/arrow_22_red", + 87, + 22, + fromRight ? 87 - width : 0, + 0, + fromRight ? 87 : width, + 22); + public static final BiFunction PICTURE_ARROW_22_BLUE = (width, fromRight) -> UITexture + .partly( + GregTech.ID, + "gui/picture/arrow_22_blue", + 87, + 22, + fromRight ? 87 - width : 0, + 0, + fromRight ? 87 : width, + 22); + public static final BiFunction PICTURE_ARROW_22_WHITE = (width, fromRight) -> UITexture + .partly( + GregTech.ID, + "gui/picture/arrow_22_white", + 87, + 22, + fromRight ? 87 - width : 0, + 0, + fromRight ? 87 : width, + 22); + public static final BiFunction PICTURE_ARROW_24_RED = (width, fromRight) -> UITexture + .partly( + GregTech.ID, + "gui/picture/arrow_24_red", + 69, + 24, + fromRight ? 69 - width : 0, + 0, + fromRight ? 69 : width, + 24); + public static final BiFunction PICTURE_ARROW_24_BLUE = (width, fromRight) -> UITexture + .partly( + GregTech.ID, + "gui/picture/arrow_24_blue", + 69, + 24, + fromRight ? 69 - width : 0, + 0, + fromRight ? 69 : width, + 24); + public static final BiFunction PICTURE_ARROW_24_WHITE = (width, fromRight) -> UITexture + .partly( + GregTech.ID, + "gui/picture/arrow_24_white", + 69, + 24, + fromRight ? 69 - width : 0, + 0, + fromRight ? 69 : width, + 24); + public static final UITexture PICTURE_FLUID_WINDOW = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_window"); + public static final UITexture PICTURE_FLUID_TANK = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_tank"); + public static final UITexture PICTURE_SLOTS_HOLO_3BY3 = UITexture + .fullImage(GregTech.ID, "gui/picture/slots_holo_3by3"); + public static final UITexture PICTURE_ARROW_DOUBLE = UITexture.fullImage(GregTech.ID, "gui/picture/arrow_double"); + public static final UITexture PICTURE_SUPER_BUFFER = UITexture.fullImage(GregTech.ID, "gui/picture/super_buffer"); + public static final UITexture PICTURE_SQUARE_LIGHT_GRAY = UITexture + .fullImage(GregTech.ID, "gui/picture/square_light_gray"); + public static final UITexture PICTURE_GAUGE = UITexture.fullImage(GregTech.ID, "gui/picture/gauge"); + public static final UITexture PICTURE_ITEM_IN = UITexture.fullImage(GregTech.ID, "gui/picture/item_in"); + public static final UITexture PICTURE_ITEM_OUT = UITexture.fullImage(GregTech.ID, "gui/picture/item_out"); + public static final UITexture PICTURE_FLUID_IN = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_in"); + public static final UITexture PICTURE_FLUID_OUT = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_out"); +} diff --git a/src/main/java/gregtech/api/gui/modularui/GT_CoverUIBuildContext.java b/src/main/java/gregtech/api/gui/modularui/GT_CoverUIBuildContext.java deleted file mode 100644 index f98d6099fc..0000000000 --- a/src/main/java/gregtech/api/gui/modularui/GT_CoverUIBuildContext.java +++ /dev/null @@ -1,74 +0,0 @@ -package gregtech.api.gui.modularui; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; - -import gregtech.api.interfaces.tileentity.ICoverable; - -public class GT_CoverUIBuildContext extends UIBuildContext { - - // cover data is not synced to client, while ID is - private final int coverID; - private final ForgeDirection side; - private final ICoverable tile; - private final boolean anotherWindow; - private final int guiColorization; - - /** - * @param player Player opened this UI - * @param coverID See {@link ICoverable#getCoverIDAtSide} - * @param side Side this cover is attached to - * @param tile Tile this cover is attached to - * @param anotherWindow If cover UI is shown on top of another window - * @param guiColorization The color used to render machine's GUI - */ - public GT_CoverUIBuildContext(EntityPlayer player, int coverID, ForgeDirection side, ICoverable tile, - boolean anotherWindow, int guiColorization) { - super(player); - this.coverID = coverID; - this.side = side; - this.tile = tile; - this.anotherWindow = anotherWindow; - this.guiColorization = guiColorization; - } - - /** - * @param player Player opened this UI - * @param coverID See {@link ICoverable#getCoverIDAtSide} - * @param side Side this cover is attached to - * @param tile Tile this cover is attached to - * @param anotherWindow If cover GUI is shown in opened on top of another window - */ - public GT_CoverUIBuildContext(EntityPlayer player, int coverID, ForgeDirection side, ICoverable tile, - boolean anotherWindow) { - this(player, coverID, side, tile, anotherWindow, tile.getGUIColorization()); - } - - public int getCoverID() { - return coverID; - } - - public ForgeDirection getCoverSide() { - return side; - } - - /** - * Note that this will return different object between client v.s. server side on SP. - */ - public ICoverable getTile() { - return tile; - } - - /** - * If cover GUI is shown in opened on top of another window. - */ - public boolean isAnotherWindow() { - return anotherWindow; - } - - public int getGuiColorization() { - return guiColorization; - } -} diff --git a/src/main/java/gregtech/api/gui/modularui/GT_UIInfos.java b/src/main/java/gregtech/api/gui/modularui/GT_UIInfos.java deleted file mode 100644 index ea9a39bdf8..0000000000 --- a/src/main/java/gregtech/api/gui/modularui/GT_UIInfos.java +++ /dev/null @@ -1,189 +0,0 @@ -package gregtech.api.gui.modularui; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.UIInfos; -import com.gtnewhorizons.modularui.api.screen.ITileWithModularUI; -import com.gtnewhorizons.modularui.api.screen.ModularUIContext; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.builder.UIBuilder; -import com.gtnewhorizons.modularui.common.builder.UIInfo; -import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils; -import com.gtnewhorizons.modularui.common.internal.wrapper.ModularGui; -import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.enums.GT_Values; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords; -import gregtech.api.net.GT_Packet_SendCoverData; -import gregtech.api.util.GT_CoverBehaviorBase; - -public class GT_UIInfos { - - public static void init() {} - - /** - * Generator for {@link UIInfo} which is responsible for registering and opening UIs. Unlike - * {@link com.gtnewhorizons.modularui.api.UIInfos#TILE_MODULAR_UI}, this accepts custom constructors for UI.
- * Do NOT run {@link UIBuilder#build} on-the-fly, otherwise MP client won't register UIs. Instead, store to static - * field, just like {@link #GTTileEntityDefaultUI}. Such mistake can be easily overlooked by testing only SP. - */ - public static final Function> GTTileEntityUIFactory = containerConstructor -> UIBuilder - .of() - .container((player, world, x, y, z) -> { - TileEntity te = world.getTileEntity(x, y, z); - if (te instanceof ITileWithModularUI mui) { - return createTileEntityContainer(player, mui::createWindow, te::markDirty, containerConstructor); - } - return null; - }) - .gui(((player, world, x, y, z) -> { - if (!world.isRemote) return null; - TileEntity te = world.getTileEntity(x, y, z); - if (te instanceof ITileWithModularUI mui) { - return createTileEntityGuiContainer(player, mui::createWindow, containerConstructor); - } - return null; - })) - .build(); - - private static final UIInfo GTTileEntityDefaultUI = GTTileEntityUIFactory.apply(ModularUIContainer::new); - - private static final Map> coverUI = new HashMap<>(); - - static { - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - coverUI.put( - side, - UIBuilder.of() - .container((player, world, x, y, z) -> { - final TileEntity te = world.getTileEntity(x, y, z); - if (!(te instanceof ICoverable gtTileEntity)) return null; - final GT_CoverBehaviorBase cover = gtTileEntity.getCoverBehaviorAtSideNew(side); - return createCoverContainer( - player, - cover::createWindow, - te::markDirty, - gtTileEntity.getCoverIDAtSide(side), - side, - gtTileEntity); - }) - .gui((player, world, x, y, z) -> { - if (!world.isRemote) return null; - final TileEntity te = world.getTileEntity(x, y, z); - if (!(te instanceof ICoverable gtTileEntity)) return null; - final GT_CoverBehaviorBase cover = gtTileEntity.getCoverBehaviorAtSideNew(side); - return createCoverGuiContainer( - player, - cover::createWindow, - gtTileEntity.getCoverIDAtSide(side), - side, - gtTileEntity); - }) - .build()); - } - } - - /** - * Opens TileEntity UI, created by {@link ITileWithModularUI#createWindow}. - */ - public static void openGTTileEntityUI(IHasWorldObjectAndCoords aTileEntity, EntityPlayer aPlayer) { - if (aTileEntity.isClientSide() || aPlayer instanceof FakePlayer) return; - GTTileEntityDefaultUI.open( - aPlayer, - aTileEntity.getWorld(), - aTileEntity.getXCoord(), - aTileEntity.getYCoord(), - aTileEntity.getZCoord()); - } - - /** - * Opens cover UI, created by {@link GT_CoverBehaviorBase#createWindow}. - */ - public static void openCoverUI(ICoverable tileEntity, EntityPlayer player, ForgeDirection side) { - if (tileEntity.isClientSide()) return; - - GT_Values.NW.sendToPlayer( - new GT_Packet_SendCoverData( - side, - tileEntity.getCoverIDAtSide(side), - tileEntity.getComplexCoverDataAtSide(side), - tileEntity), - (EntityPlayerMP) player); - - coverUI.get(side) - .open( - player, - tileEntity.getWorld(), - tileEntity.getXCoord(), - tileEntity.getYCoord(), - tileEntity.getZCoord()); - } - - /** - * Opens UI for player's item, created by - * {@link com.gtnewhorizons.modularui.api.screen.IItemWithModularUI#createWindow}. - */ - public static void openPlayerHeldItemUI(EntityPlayer player) { - if (NetworkUtils.isClient()) return; - UIInfos.PLAYER_HELD_ITEM_UI.open(player); - } - - private static ModularUIContainer createTileEntityContainer(EntityPlayer player, - Function windowCreator, Runnable onWidgetUpdate, - ContainerConstructor containerCreator) { - final UIBuildContext buildContext = new UIBuildContext(player); - final ModularWindow window = windowCreator.apply(buildContext); - if (window == null) return null; - return containerCreator.of(new ModularUIContext(buildContext, onWidgetUpdate), window); - } - - @SideOnly(Side.CLIENT) - private static ModularGui createTileEntityGuiContainer(EntityPlayer player, - Function windowCreator, ContainerConstructor containerConstructor) { - final ModularUIContainer container = createTileEntityContainer( - player, - windowCreator, - null, - containerConstructor); - if (container == null) return null; - return new ModularGui(container); - } - - private static ModularUIContainer createCoverContainer(EntityPlayer player, - Function windowCreator, Runnable onWidgetUpdate, int coverID, - ForgeDirection side, ICoverable tile) { - final GT_CoverUIBuildContext buildContext = new GT_CoverUIBuildContext(player, coverID, side, tile, false); - final ModularWindow window = windowCreator.apply(buildContext); - if (window == null) return null; - return new ModularUIContainer(new ModularUIContext(buildContext, onWidgetUpdate), window); - } - - @SideOnly(Side.CLIENT) - private static ModularGui createCoverGuiContainer(EntityPlayer player, - Function windowCreator, int coverID, ForgeDirection side, - ICoverable tile) { - final ModularUIContainer container = createCoverContainer(player, windowCreator, null, coverID, side, tile); - if (container == null) { - return null; - } - return new ModularGui(container); - } - - @FunctionalInterface - public interface ContainerConstructor { - - ModularUIContainer of(ModularUIContext context, ModularWindow mainWindow); - } -} diff --git a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java deleted file mode 100644 index 6031399c06..0000000000 --- a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java +++ /dev/null @@ -1,542 +0,0 @@ -package gregtech.api.gui.modularui; - -import static gregtech.api.enums.Mods.GregTech; - -import java.util.function.BiFunction; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import com.gtnewhorizons.modularui.api.drawable.AdaptableUITexture; -import com.gtnewhorizons.modularui.api.drawable.FallbackableUITexture; -import com.gtnewhorizons.modularui.api.drawable.UITexture; - -public class GT_UITextures { - - public static final UITexture TRANSPARENT = UITexture.fullImage(GregTech.ID, "gui/picture/transparent"); - - public static final AdaptableUITexture BACKGROUND_SINGLEBLOCK_DEFAULT = AdaptableUITexture - .of(GregTech.ID, "gui/background/singleblock_default", 176, 166, 4); - public static final SteamTexture BACKGROUND_STEAM = SteamTexture - .adaptableTexture(GregTech.ID, "gui/background/%s", 176, 166, 4); - public static final UITexture BACKGROUND_FUSION_COMPUTER = UITexture - .fullImage(GregTech.ID, "gui/background/fusion_computer"); - public static final AdaptableUITexture BACKGROUND_TEXT_FIELD = AdaptableUITexture - .of(GregTech.ID, "gui/background/text_field", 142, 28, 1); - public static final AdaptableUITexture BACKGROUND_TEXT_FIELD_LIGHT_GRAY = AdaptableUITexture - .of(GregTech.ID, "gui/background/text_field_light_gray", 61, 12, 1); - public static final AdaptableUITexture BACKGROUND_NEI_SINGLE_RECIPE = AdaptableUITexture - .of(GregTech.ID, "gui/background/nei_single_recipe.png", 64, 64, 2); - public static final UITexture BACKGROUND_FLOCCULATION_RECIPE = UITexture - .fullImage(GregTech.ID, "gui/background/flocculation_recipe.png"); - public static final SteamTexture SLOT_ITEM_STEAM = SteamTexture.fullImage(GregTech.ID, "gui/slot/item_%s"); - public static final SteamTexture SLOT_FLUID_STEAM = SteamTexture.fullImage(GregTech.ID, "gui/slot/fluid_%s"); - public static final AdaptableUITexture SLOT_DARK_GRAY = AdaptableUITexture - .of(GregTech.ID, "gui/slot/dark_gray", 18, 18, 1); - public static final AdaptableUITexture SLOT_MAINTENANCE = AdaptableUITexture - .of(GregTech.ID, "gui/slot/maintenance", 20, 20, 1); - public static final AdaptableUITexture SLOT_UPLIFTED = AdaptableUITexture - .of(GregTech.ID, "gui/slot/uplifted", 18, 18, 1); - - public static final UITexture OVERLAY_SLOT_ARROW_ME = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/arrow_me"); - public static final UITexture OVERLAY_SLOT_PATTERN_ME = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/pattern_me"); - - public static final UITexture OVERLAY_SLOT_BEAKER_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/beaker_1"); - public static final UITexture OVERLAY_SLOT_BEAKER_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/beaker_2"); - public static final UITexture OVERLAY_SLOT_BEE_DRONE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/bee_drone"); - public static final UITexture OVERLAY_SLOT_BEE_QUEEN = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/bee_queen"); - public static final UITexture OVERLAY_SLOT_BENDER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/bender"); - public static final UITexture OVERLAY_SLOT_BOX = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/box"); - public static final UITexture OVERLAY_SLOT_BOXED = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/boxed"); - public static final UITexture OVERLAY_SLOT_CANISTER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/canister"); - public static final SteamTexture OVERLAY_SLOT_CANISTER_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/canister_%s"); - public static final UITexture OVERLAY_SLOT_CANNER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/canner"); - public static final UITexture OVERLAY_SLOT_CAULDRON = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/cauldron"); - public static final UITexture OVERLAY_SLOT_CENTRIFUGE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/centrifuge"); - public static final UITexture OVERLAY_SLOT_CENTRIFUGE_FLUID = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/centrifuge_fluid"); - public static final SteamTexture OVERLAY_SLOT_CENTRIFUGE_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/centrifuge_%s"); - public static final UITexture OVERLAY_SLOT_CHARGER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/charger"); - public static final UITexture OVERLAY_SLOT_CHARGER_FLUID = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/charger_fluid"); - public static final UITexture OVERLAY_SLOT_CIRCUIT = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/circuit"); - public static final SteamTexture OVERLAY_SLOT_COAL_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/coal_%s"); - public static final UITexture OVERLAY_SLOT_COMPRESSOR = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/compressor"); - public static final SteamTexture OVERLAY_SLOT_COMPRESSOR_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/compressor_%s"); - public static final UITexture OVERLAY_SLOT_CRUSHED_ORE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/crushed_ore"); - public static final SteamTexture OVERLAY_SLOT_CRUSHED_ORE_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/crushed_ore_%s"); - public static final UITexture OVERLAY_SLOT_CUTTER_SLICED = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/cutter_sliced"); - public static final UITexture OVERLAY_SLOT_DATA_ORB = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/data_orb"); - public static final UITexture OVERLAY_SLOT_DATA_STICK = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/data_stick"); - public static final UITexture OVERLAY_SLOT_DUST = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/dust"); - public static final SteamTexture OVERLAY_SLOT_DUST_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/dust_%s"); - public static final SteamTexture OVERLAY_SLOT_BLOCK_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/block_%s"); - public static final UITexture OVERLAY_SLOT_EXPLOSIVE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/explosive"); - public static final UITexture OVERLAY_SLOT_EXTRUDER_SHAPE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/extruder_shape"); - public static final UITexture OVERLAY_SLOT_FILTER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/filter"); - public static final UITexture OVERLAY_SLOT_FURNACE = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/furnace"); - public static final SteamTexture OVERLAY_SLOT_FURNACE_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/furnace_%s"); - public static final UITexture OVERLAY_SLOT_GEM = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/gem"); - public static final UITexture OVERLAY_SLOT_HAMMER = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/hammer"); - public static final SteamTexture OVERLAY_SLOT_HAMMER_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/hammer_%s"); - public static final UITexture OVERLAY_SLOT_HEATER_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/heater_1"); - public static final UITexture OVERLAY_SLOT_HEATER_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/heater_2"); - public static final UITexture OVERLAY_SLOT_IMPLOSION = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/implosion"); - public static final UITexture OVERLAY_SLOT_IN = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/in"); - public static final SteamTexture OVERLAY_SLOT_IN_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/in_%s"); - public static final SteamTexture OVERLAY_SLOT_INGOT_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/ingot_%s"); - public static final UITexture OVERLAY_SLOT_INT_CIRCUIT = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/int_circuit"); - public static final UITexture OVERLAY_SLOT_LENS = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/lens"); - public static final UITexture OVERLAY_SLOT_MICROSCOPE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/microscope"); - public static final UITexture OVERLAY_SLOT_MINING_PIPE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/mining_pipe"); - public static final UITexture OVERLAY_SLOT_MOLD = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/mold"); - public static final UITexture OVERLAY_SLOT_MOLECULAR_1 = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/molecular_1"); - public static final UITexture OVERLAY_SLOT_MOLECULAR_2 = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/molecular_2"); - public static final UITexture OVERLAY_SLOT_MOLECULAR_3 = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/molecular_3"); - public static final UITexture OVERLAY_SLOT_OUT = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/out"); - public static final SteamTexture OVERLAY_SLOT_OUT_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/overlay_slot/out_%s"); - public static final UITexture OVERLAY_SLOT_PAGE_BLANK = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/page_blank"); - public static final UITexture OVERLAY_SLOT_PAGE_PRINTED = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/page_printed"); - public static final UITexture OVERLAY_SLOT_PRESS_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/press_1"); - public static final UITexture OVERLAY_SLOT_PRESS_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/press_2"); - public static final UITexture OVERLAY_SLOT_PRESS_3 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/press_3"); - public static final UITexture OVERLAY_SLOT_RECYCLE = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/recycle"); - public static final UITexture OVERLAY_SLOT_ROD_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/rod_1"); - public static final UITexture OVERLAY_SLOT_ROD_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/rod_2"); - public static final UITexture OVERLAY_SLOT_SLICE_SHAPE = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/slice_shape"); - public static final UITexture OVERLAY_SLOT_SLICER_SLICED = UITexture - .fullImage(GregTech.ID, "gui/overlay_slot/slicer_sliced"); - public static final UITexture OVERLAY_SLOT_SQUARE = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/square"); - public static final UITexture OVERLAY_SLOT_UUA = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/uua"); - public static final UITexture OVERLAY_SLOT_UUM = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/uum"); - public static final UITexture OVERLAY_SLOT_VIAL_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/vial_1"); - public static final UITexture OVERLAY_SLOT_VIAL_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/vial_2"); - public static final UITexture OVERLAY_SLOT_WIREMILL = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/wiremill"); - public static final UITexture OVERLAY_SLOT_WRENCH = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/wrench"); - public static final UITexture[] OVERLAY_SLOTS_NUMBER = IntStream.range(0, 12) - .mapToObj(i -> UITexture.fullImage(GregTech.ID, "gui/overlay_slot/number_" + i)) - .collect(Collectors.toList()) - .toArray(new UITexture[0]); - - public static final UITexture PROGRESSBAR_ARROW = UITexture.fullImage(GregTech.ID, "gui/progressbar/arrow"); - public static final SteamTexture PROGRESSBAR_ARROW_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/arrow_%s"); - public static final SteamTexture PROGRESSBAR_ARROW_2_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/arrow_2_%s"); - public static final UITexture PROGRESSBAR_ARROW_MULTIPLE = UITexture - .fullImage(GregTech.ID, "gui/progressbar/arrow_multiple"); - public static final UITexture PROGRESSBAR_ASSEMBLE = UITexture.fullImage(GregTech.ID, "gui/progressbar/assemble"); - public static final UITexture PROGRESSBAR_ASSEMBLY_LINE_1 = UITexture - .fullImage(GregTech.ID, "gui/progressbar/assemblyline_1"); - public static final UITexture PROGRESSBAR_ASSEMBLY_LINE_2 = UITexture - .fullImage(GregTech.ID, "gui/progressbar/assemblyline_2"); - public static final UITexture PROGRESSBAR_ASSEMBLY_LINE_3 = UITexture - .fullImage(GregTech.ID, "gui/progressbar/assemblyline_3"); - public static final UITexture PROGRESSBAR_BATH = UITexture.fullImage(GregTech.ID, "gui/progressbar/bath"); - public static final UITexture PROGRESSBAR_BENDING = UITexture.fullImage(GregTech.ID, "gui/progressbar/bending"); - public static final SteamTexture PROGRESSBAR_BOILER_EMPTY_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/boiler_empty_%s"); - public static final UITexture PROGRESSBAR_BOILER_HEAT = UITexture - .fullImage(GregTech.ID, "gui/progressbar/boiler_heat"); - public static final UITexture PROGRESSBAR_BOILER_STEAM = UITexture - .fullImage(GregTech.ID, "gui/progressbar/boiler_steam"); - public static final UITexture PROGRESSBAR_BOILER_WATER = UITexture - .fullImage(GregTech.ID, "gui/progressbar/boiler_water"); - public static final UITexture PROGRESSBAR_CANNER = UITexture.fullImage(GregTech.ID, "gui/progressbar/canner"); - public static final UITexture PROGRESSBAR_CIRCUIT_ASSEMBLER = UITexture - .fullImage(GregTech.ID, "gui/progressbar/circuit_assembler"); - public static final UITexture PROGRESSBAR_COMPRESS = UITexture.fullImage(GregTech.ID, "gui/progressbar/compress"); - public static final SteamTexture PROGRESSBAR_COMPRESS_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/compress_%s"); - public static final UITexture PROGRESSBAR_CUT = UITexture.fullImage(GregTech.ID, "gui/progressbar/cut"); - public static final UITexture PROGRESSBAR_EXTRACT = UITexture.fullImage(GregTech.ID, "gui/progressbar/extract"); - public static final SteamTexture PROGRESSBAR_EXTRACT_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/extract_%s"); - public static final UITexture PROGRESSBAR_EXTRUDE = UITexture.fullImage(GregTech.ID, "gui/progressbar/extrude"); - public static final SteamTexture PROGRESSBAR_FUEL_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/fuel_%s"); - public static final UITexture PROGRESSBAR_HAMMER = UITexture.fullImage(GregTech.ID, "gui/progressbar/hammer"); - public static final UITexture PROGRESSBAR_HAMMER_BASE = UITexture - .fullImage(GregTech.ID, "gui/progressbar/hammer_base"); - public static final SteamTexture PROGRESSBAR_HAMMER_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/hammer_%s"); - public static final SteamTexture PROGRESSBAR_HAMMER_BASE_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/hammer_base_%s"); - public static final UITexture PROGRESSBAR_LATHE = UITexture.fullImage(GregTech.ID, "gui/progressbar/lathe"); - public static final UITexture PROGRESSBAR_LATHE_BASE = UITexture - .fullImage(GregTech.ID, "gui/progressbar/lathe_base"); - public static final UITexture PROGRESSBAR_MACERATE = UITexture.fullImage(GregTech.ID, "gui/progressbar/macerate"); - public static final SteamTexture PROGRESSBAR_MACERATE_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/progressbar/macerate_%s"); - public static final UITexture PROGRESSBAR_MAGNET = UITexture.fullImage(GregTech.ID, "gui/progressbar/magnet"); - public static final UITexture PROGRESSBAR_MIXER = UITexture.fullImage(GregTech.ID, "gui/progressbar/mixer"); - public static final UITexture PROGRESSBAR_RECYCLE = UITexture.fullImage(GregTech.ID, "gui/progressbar/recycle"); - public static final UITexture PROGRESSBAR_SIFT = UITexture.fullImage(GregTech.ID, "gui/progressbar/sift"); - public static final UITexture PROGRESSBAR_SLICE = UITexture.fullImage(GregTech.ID, "gui/progressbar/slice"); - public static final UITexture PROGRESSBAR_STORED_EU = UITexture.fullImage(GregTech.ID, "gui/progressbar/stored_eu"); - public static final UITexture PROGRESSBAR_WIREMILL = UITexture.fullImage(GregTech.ID, "gui/progressbar/wiremill"); - public static final UITexture PROGRESSBAR_FLOCCULATION = UITexture - .fullImage(GregTech.ID, "gui/progressbar/flocculation"); - public static final UITexture PROGRESSBAR_CLARIFIER = UITexture.fullImage(GregTech.ID, "gui/progressbar/clarifier"); - public static final UITexture PROGRESSBAR_PH_NEUTRALIZATION = UITexture - .fullImage(GregTech.ID, "gui/progressbar/phneutralization"); - public static final UITexture PROGRESSBAR_OZONATION = UITexture.fullImage(GregTech.ID, "gui/progressbar/ozonation"); - public static final UITexture PROGRESSBAR_PLASMA_HEATER = UITexture - .fullImage(GregTech.ID, "gui/progressbar/water_plasma_heater"); - - public static FallbackableUITexture fallbackableProgressbar(String name, UITexture fallback) { - return new FallbackableUITexture(UITexture.fullImage(GregTech.ID, "gui/progressbar/" + name), fallback); - } - - public static final UITexture TAB_COVER_NORMAL = UITexture.fullImage(GregTech.ID, "gui/tab/cover_normal"); - public static final UITexture TAB_COVER_HIGHLIGHT = UITexture.fullImage(GregTech.ID, "gui/tab/cover_highlight"); - public static final UITexture TAB_COVER_DISABLED = UITexture.fullImage(GregTech.ID, "gui/tab/cover_disabled"); - public static final SteamTexture TAB_COVER_STEAM_NORMAL = SteamTexture - .fullImage(GregTech.ID, "gui/tab/cover_%s_normal"); - public static final SteamTexture TAB_COVER_STEAM_HIGHLIGHT = SteamTexture - .fullImage(GregTech.ID, "gui/tab/cover_%s_highlight"); - public static final SteamTexture TAB_COVER_STEAM_DISABLED = SteamTexture - .fullImage(GregTech.ID, "gui/tab/cover_%s_disabled"); - public static final AdaptableUITexture TAB_TITLE = AdaptableUITexture.of(GregTech.ID, "gui/tab/title", 28, 28, 4); - public static final AdaptableUITexture TAB_TITLE_DARK = AdaptableUITexture - .of(GregTech.ID, "gui/tab/title_dark", 28, 28, 4); - public static final SteamTexture TAB_TITLE_STEAM = SteamTexture - .adaptableTexture(GregTech.ID, "gui/tab/title_%s", 28, 28, 4); - public static final SteamTexture TAB_TITLE_DARK_STEAM = SteamTexture - .adaptableTexture(GregTech.ID, "gui/tab/title_dark_%s", 28, 28, 4); - public static final AdaptableUITexture TAB_TITLE_ANGULAR = AdaptableUITexture - .of(GregTech.ID, "gui/tab/title_angular", 28, 28, 4); - public static final SteamTexture TAB_TITLE_ANGULAR_STEAM = SteamTexture - .adaptableTexture(GregTech.ID, "gui/tab/title_angular_%s", 28, 28, 4); - - public static final UITexture BUTTON_STANDARD = AdaptableUITexture - .of(GregTech.ID, "gui/button/standard", 18, 18, 1); - public static final UITexture BUTTON_STANDARD_PRESSED = AdaptableUITexture - .of(GregTech.ID, "gui/button/standard_pressed", 18, 18, 1); - public static final UITexture BUTTON_STANDARD_DISABLED = AdaptableUITexture - .of(GregTech.ID, "gui/button/standard_disabled", 18, 18, 1); - public static final UITexture BUTTON_STANDARD_TOGGLE = AdaptableUITexture - .of(GregTech.ID, "gui/button/standard_toggle", 18, 18, 1); - public static final UITexture BUTTON_STANDARD_TOGGLE_DISABLED = AdaptableUITexture - .of(GregTech.ID, "gui/button/standard_toggle_disabled", 18, 18, 1); - public static final UITexture BUTTON_COVER_NORMAL = UITexture.fullImage(GregTech.ID, "gui/button/cover_normal"); - public static final UITexture BUTTON_COVER_NORMAL_HOVERED = UITexture - .fullImage(GregTech.ID, "gui/button/cover_normal_hovered"); - public static final UITexture BUTTON_COVER_NORMAL_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/button/cover_normal_disabled"); - - public static final UITexture OVERLAY_BUTTON_DISABLE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/disable"); - public static final UITexture OVERLAY_BUTTON_REDSTONE_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/redstone_off"); - public static final UITexture OVERLAY_BUTTON_REDSTONE_ON = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/redstone_on"); - public static final UITexture OVERLAY_BUTTON_POWER_SWITCH_ON = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/power_switch_on"); - public static final UITexture OVERLAY_BUTTON_POWER_SWITCH_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/power_switch_off"); - public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_NONE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/void_excess_none"); - public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_ITEM = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/void_excess_item"); - public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_FLUID = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/void_excess_fluid"); - public static final UITexture OVERLAY_BUTTON_VOID_EXCESS_ALL = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/void_excess_all"); - public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_ON = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/input_separation_on"); - public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_ON_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/input_separation_on_disabled"); - public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/input_separation_off"); - public static final UITexture OVERLAY_BUTTON_INPUT_SEPARATION_OFF_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/input_separation_off_disabled"); - public static final UITexture OVERLAY_BUTTON_RECIPE_LOCKED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/recipe_locked"); - public static final UITexture OVERLAY_BUTTON_RECIPE_LOCKED_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/recipe_locked_disabled"); - public static final UITexture OVERLAY_BUTTON_RECIPE_UNLOCKED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/recipe_unlocked"); - public static final UITexture OVERLAY_BUTTON_RECIPE_UNLOCKED_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/recipe_unlocked_disabled"); - public static final UITexture OVERLAY_BUTTON_BATCH_MODE_ON = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_on"); - public static final UITexture OVERLAY_BUTTON_BATCH_MODE_ON_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_on_disabled"); - public static final UITexture OVERLAY_BUTTON_BATCH_MODE_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_off"); - public static final UITexture OVERLAY_BUTTON_BATCH_MODE_OFF_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_off_disabled"); - public static final UITexture OVERLAY_BUTTON_STRUCTURE_UPDATE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/structure_update"); - public static final UITexture OVERLAY_BUTTON_FORBIDDEN = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/forbidden"); - public static final UITexture OVERLAY_BUTTON_LOCKED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/lock_small"); - public static final UITexture OVERLAY_BUTTON_DOWN_TIERING_ON = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/down_tiering_on"); - public static final UITexture OVERLAY_BUTTON_DOWN_TIERING_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/down_tiering_off"); - public static final UITexture OVERLAY_BUTTON_CHECKMARK = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/checkmark"); - public static final UITexture OVERLAY_BUTTON_CROSS = UITexture.fullImage(GregTech.ID, "gui/overlay_button/cross"); - public static final UITexture OVERLAY_BUTTON_WHITELIST = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/whitelist"); - public static final UITexture OVERLAY_BUTTON_BLACKLIST = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/blacklist"); - public static final UITexture OVERLAY_BUTTON_PROGRESS = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/progress"); - public static final UITexture OVERLAY_BUTTON_EXPORT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/export"); - public static final UITexture OVERLAY_BUTTON_IMPORT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/import"); - public static final UITexture OVERLAY_BUTTON_AUTOOUTPUT_ITEM = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/autooutput_item"); - public static final UITexture OVERLAY_BUTTON_AUTOOUTPUT_FLUID = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/autooutput_fluid"); - public static final UITexture OVERLAY_BUTTON_ALLOW_INPUT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/allow_input"); - public static final UITexture OVERLAY_BUTTON_ALLOW_OUTPUT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/allow_output"); - public static final UITexture OVERLAY_BUTTON_AUTOPULL_ME = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/auto_pull_me"); - public static final UITexture OVERLAY_BUTTON_AUTOPULL_ME_DISABLED = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/auto_pull_me_disabled"); - public static final UITexture OVERLAY_BUTTON_BLOCK_INPUT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/block_input"); - public static final UITexture OVERLAY_BUTTON_BLOCK_OUTPUT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/block_output"); - public static final UITexture OVERLAY_BUTTON_ARROW_GREEN_UP = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/arrow_green_up"); - public static final UITexture OVERLAY_BUTTON_ARROW_GREEN_DOWN = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/arrow_green_down"); - public static final UITexture OVERLAY_BUTTON_CYCLIC = UITexture.fullImage(GregTech.ID, "gui/overlay_button/cyclic"); - public static final UITexture OVERLAY_BUTTON_SHUFFLE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/shuffle"); - public static final UITexture OVERLAY_BUTTON_EMIT_ENERGY = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/emit_energy"); - public static final UITexture OVERLAY_BUTTON_EMIT_REDSTONE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/emit_redstone"); - public static final UITexture OVERLAY_BUTTON_INVERT_REDSTONE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/invert_redstone"); - public static final UITexture OVERLAY_BUTTON_STOCKING_MODE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/stocking_mode"); - public static final UITexture OVERLAY_BUTTON_INVERT_FILTER = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/invert_filter"); - public static final UITexture OVERLAY_BUTTON_NBT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/nbt"); - public static final UITexture OVERLAY_BUTTON_PRINT = UITexture.fullImage(GregTech.ID, "gui/overlay_button/print"); - public static final UITexture OVERLAY_BUTTON_TRANSPOSE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/transpose"); - public static final UITexture OVERLAY_BUTTON_SORTING_MODE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/sorting_mode"); - public static final UITexture OVERLAY_BUTTON_ONE_STACK_LIMIT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/one_stack_limit"); - public static final UITexture OVERLAY_BUTTON_BOUNDING_BOX = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/bounding_box"); - public static final UITexture OVERLAY_BUTTON_MINUS_SMALL = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/minus_small"); - public static final UITexture OVERLAY_BUTTON_MINUS_LARGE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/minus_large"); - public static final UITexture OVERLAY_BUTTON_PLUS_SMALL = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/plus_small"); - public static final UITexture OVERLAY_BUTTON_PLUS_LARGE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/plus_large"); - public static final UITexture OVERLAY_BUTTON_GATE_AND = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/gate_and"); - public static final UITexture OVERLAY_BUTTON_GATE_NAND = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/gate_nand"); - public static final UITexture OVERLAY_BUTTON_GATE_OR = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/gate_or"); - public static final UITexture OVERLAY_BUTTON_GATE_NOR = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/gate_nor"); - public static final UITexture OVERLAY_BUTTON_ANALOG = UITexture.fullImage(GregTech.ID, "gui/overlay_button/analog"); - public static final UITexture OVERLAY_BUTTON_LOCK = UITexture.fullImage(GregTech.ID, "gui/overlay_button/lock"); - public static final UITexture OVERLAY_BUTTON_INPUT_FROM_OUTPUT_SIDE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/input_from_output_side"); - public static final UITexture OVERLAY_BUTTON_TANK_VOID_EXCESS = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/tank_void_excess"); - public static final UITexture OVERLAY_BUTTON_TANK_VOID_ALL = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/tank_void_all"); - public static final UITexture OVERLAY_BUTTON_NEI = UITexture.fullImage(GregTech.ID, "gui/overlay_button/nei"); - public static final UITexture OVERLAY_BUTTON_USE_PROCESSING_STATE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/use_processing_state.png"); - public static final UITexture OVERLAY_BUTTON_USE_INVERTED_PROCESSING_STATE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/use_inverted_processing_state.png"); - public static final UITexture OVERLAY_BUTTON_CHUNK_LOADING = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/chunkloading"); - public static final UITexture OVERLAY_BUTTON_CHUNK_LOADING_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/chunkloading_off"); - public static final UITexture OVERLAY_BUTTON_WORK_AREA = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/work_area"); - public static final UITexture OVERLAY_BUTTON_REPLACE_COBBLE_ON = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/replace_cobble_on"); - public static final UITexture OVERLAY_BUTTON_REPLACE_COBBLE_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/replace_cobble_off"); - public static final UITexture OVERLAY_BUTTON_RETRACT_PIPE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/retract_pipes"); - public static final UITexture OVERLAY_BUTTON_HOURGLASS = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/hourglass"); - - public static final UITexture OVERLAY_BUTTON_LIQUIDMODE = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/LiquidMode"); - - public static final UITexture OVERLAY_BUTTON_LIQUIDMODE_OFF = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/LiquidMode_off"); - - // These icons are for mode switching machine modes - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_DEFAULT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_default"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_CHEMBATH = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_chembath"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_WASHPLANT = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_washplant"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SIMPLEWASHER = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_simplewasher"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_PACKAGER = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_packager"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_UNPACKAGER = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_unpackager"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SEPARATOR = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_separator"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_POLARIZER = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_polarizer"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_LPF_FLUID = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_lpf_fluid"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_LPF_METAL = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_lpf_metal"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_BENDING = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_bending"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_FORMING = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_forming"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SLICING = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_slicing"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_CUTTING = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_cutting"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_COMPRESSING = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_compressing"); - public static final UITexture OVERLAY_BUTTON_MACHINEMODE_SINGULARITY = UITexture - .fullImage(GregTech.ID, "gui/overlay_button/machine_mode_singularity"); - - /** - * Can adjust size as needed. - */ - public static final AdaptableUITexture PICTURE_SCREEN_BLACK = AdaptableUITexture - .of(GregTech.ID, "gui/picture/screen_black", 16, 16, 2); - - public static final UITexture PICTURE_RADIATION_WARNING = UITexture - .fullImage(GregTech.ID, "gui/picture/radiation_warning"); - public static final UITexture PICTURE_GT_LOGO_17x17_TRANSPARENT = UITexture - .fullImage(GregTech.ID, "gui/picture/gt_logo_17x17_transparent"); - public static final UITexture PICTURE_GT_LOGO_17x17_TRANSPARENT_GRAY = UITexture - .fullImage(GregTech.ID, "gui/picture/gt_logo_17x17_transparent_gray"); - public static final SteamTexture PICTURE_GT_LOGO_17x17_TRANSPARENT_STEAM = SteamTexture - .fullImage(GregTech.ID, "gui/picture/gt_logo_17x17_transparent_%s"); - public static final UITexture PICTURE_GT_LOGO_18x18 = UITexture.fullImage(GregTech.ID, "gui/picture/gt_logo_18x18"); - public static final UITexture PICTURE_GT_LOGO_19x19 = UITexture.fullImage(GregTech.ID, "gui/picture/gt_logo_19x19"); - public static final UITexture PICTURE_INFORMATION = UITexture.fullImage(GregTech.ID, "gui/picture/information"); - public static final UITexture PICTURE_STALLED_ELECTRICITY = UITexture - .fullImage(GregTech.ID, "gui/picture/stalled_electricity"); - public static final UITexture PICTURE_STALLED_STEAM = UITexture.fullImage(GregTech.ID, "gui/picture/stalled_steam"); - public static final BiFunction PICTURE_ARROW_22_RED = (width, fromRight) -> UITexture - .partly( - GregTech.ID, - "gui/picture/arrow_22_red", - 87, - 22, - fromRight ? 87 - width : 0, - 0, - fromRight ? 87 : width, - 22); - public static final BiFunction PICTURE_ARROW_22_BLUE = (width, fromRight) -> UITexture - .partly( - GregTech.ID, - "gui/picture/arrow_22_blue", - 87, - 22, - fromRight ? 87 - width : 0, - 0, - fromRight ? 87 : width, - 22); - public static final BiFunction PICTURE_ARROW_22_WHITE = (width, fromRight) -> UITexture - .partly( - GregTech.ID, - "gui/picture/arrow_22_white", - 87, - 22, - fromRight ? 87 - width : 0, - 0, - fromRight ? 87 : width, - 22); - public static final BiFunction PICTURE_ARROW_24_RED = (width, fromRight) -> UITexture - .partly( - GregTech.ID, - "gui/picture/arrow_24_red", - 69, - 24, - fromRight ? 69 - width : 0, - 0, - fromRight ? 69 : width, - 24); - public static final BiFunction PICTURE_ARROW_24_BLUE = (width, fromRight) -> UITexture - .partly( - GregTech.ID, - "gui/picture/arrow_24_blue", - 69, - 24, - fromRight ? 69 - width : 0, - 0, - fromRight ? 69 : width, - 24); - public static final BiFunction PICTURE_ARROW_24_WHITE = (width, fromRight) -> UITexture - .partly( - GregTech.ID, - "gui/picture/arrow_24_white", - 69, - 24, - fromRight ? 69 - width : 0, - 0, - fromRight ? 69 : width, - 24); - public static final UITexture PICTURE_FLUID_WINDOW = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_window"); - public static final UITexture PICTURE_FLUID_TANK = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_tank"); - public static final UITexture PICTURE_SLOTS_HOLO_3BY3 = UITexture - .fullImage(GregTech.ID, "gui/picture/slots_holo_3by3"); - public static final UITexture PICTURE_ARROW_DOUBLE = UITexture.fullImage(GregTech.ID, "gui/picture/arrow_double"); - public static final UITexture PICTURE_SUPER_BUFFER = UITexture.fullImage(GregTech.ID, "gui/picture/super_buffer"); - public static final UITexture PICTURE_SQUARE_LIGHT_GRAY = UITexture - .fullImage(GregTech.ID, "gui/picture/square_light_gray"); - public static final UITexture PICTURE_GAUGE = UITexture.fullImage(GregTech.ID, "gui/picture/gauge"); - public static final UITexture PICTURE_ITEM_IN = UITexture.fullImage(GregTech.ID, "gui/picture/item_in"); - public static final UITexture PICTURE_ITEM_OUT = UITexture.fullImage(GregTech.ID, "gui/picture/item_out"); - public static final UITexture PICTURE_FLUID_IN = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_in"); - public static final UITexture PICTURE_FLUID_OUT = UITexture.fullImage(GregTech.ID, "gui/picture/fluid_out"); -} diff --git a/src/main/java/gregtech/api/gui/modularui/GUITextureSet.java b/src/main/java/gregtech/api/gui/modularui/GUITextureSet.java index 18d7741421..0063d59346 100644 --- a/src/main/java/gregtech/api/gui/modularui/GUITextureSet.java +++ b/src/main/java/gregtech/api/gui/modularui/GUITextureSet.java @@ -30,29 +30,26 @@ public class GUITextureSet { private UITexture gregtechLogo; public static final GUITextureSet DEFAULT = new GUITextureSet() - .setMainBackground(GT_UITextures.BACKGROUND_SINGLEBLOCK_DEFAULT) + .setMainBackground(GTUITextures.BACKGROUND_SINGLEBLOCK_DEFAULT) .setItemSlot(ModularUITextures.ITEM_SLOT) .setFluidSlot(ModularUITextures.FLUID_SLOT) - .setCoverTab( - GT_UITextures.TAB_COVER_NORMAL, - GT_UITextures.TAB_COVER_HIGHLIGHT, - GT_UITextures.TAB_COVER_DISABLED) - .setTitleTab(GT_UITextures.TAB_TITLE, GT_UITextures.TAB_TITLE_DARK, GT_UITextures.TAB_TITLE_ANGULAR) - .setGregTechLogo(GT_UITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT); + .setCoverTab(GTUITextures.TAB_COVER_NORMAL, GTUITextures.TAB_COVER_HIGHLIGHT, GTUITextures.TAB_COVER_DISABLED) + .setTitleTab(GTUITextures.TAB_TITLE, GTUITextures.TAB_TITLE_DARK, GTUITextures.TAB_TITLE_ANGULAR) + .setGregTechLogo(GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT); public static final Function STEAM = steamVariant -> new GUITextureSet() - .setMainBackground(GT_UITextures.BACKGROUND_STEAM.get(steamVariant)) - .setItemSlot(GT_UITextures.SLOT_ITEM_STEAM.get(steamVariant)) - .setFluidSlot(GT_UITextures.SLOT_FLUID_STEAM.get(steamVariant)) + .setMainBackground(GTUITextures.BACKGROUND_STEAM.get(steamVariant)) + .setItemSlot(GTUITextures.SLOT_ITEM_STEAM.get(steamVariant)) + .setFluidSlot(GTUITextures.SLOT_FLUID_STEAM.get(steamVariant)) .setCoverTab( - GT_UITextures.TAB_COVER_STEAM_NORMAL.get(steamVariant), - GT_UITextures.TAB_COVER_STEAM_HIGHLIGHT.get(steamVariant), - GT_UITextures.TAB_COVER_STEAM_DISABLED.get(steamVariant)) + GTUITextures.TAB_COVER_STEAM_NORMAL.get(steamVariant), + GTUITextures.TAB_COVER_STEAM_HIGHLIGHT.get(steamVariant), + GTUITextures.TAB_COVER_STEAM_DISABLED.get(steamVariant)) .setTitleTab( - GT_UITextures.TAB_TITLE_STEAM.getAdaptable(steamVariant), - GT_UITextures.TAB_TITLE_DARK_STEAM.getAdaptable(steamVariant), - GT_UITextures.TAB_TITLE_ANGULAR_STEAM.getAdaptable(steamVariant)) - .setGregTechLogo(GT_UITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT_STEAM.get(steamVariant)); + GTUITextures.TAB_TITLE_STEAM.getAdaptable(steamVariant), + GTUITextures.TAB_TITLE_DARK_STEAM.getAdaptable(steamVariant), + GTUITextures.TAB_TITLE_ANGULAR_STEAM.getAdaptable(steamVariant)) + .setGregTechLogo(GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT_STEAM.get(steamVariant)); public GUITextureSet() {} diff --git a/src/main/java/gregtech/api/gui/widgets/CoverTickRateButton.java b/src/main/java/gregtech/api/gui/widgets/CoverTickRateButton.java new file mode 100644 index 0000000000..ab05a98925 --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/CoverTickRateButton.java @@ -0,0 +1,82 @@ +package gregtech.api.gui.widgets; + +import static gregtech.api.gui.modularui.GTUITextures.OVERLAY_BUTTON_HOURGLASS; +import static gregtech.common.covers.CoverInfo.MAX_TICK_RATE_ADDITION; + +import java.util.List; + +import net.minecraft.util.StatCollector; + +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; + +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.common.covers.CoverInfo; + +public class CoverTickRateButton extends ButtonWidget { + + private static final UITexture BACKGROUND = GTUITextures.BUTTON_COVER_NORMAL.getSubArea(0, 0, 1, 0.5f); + + private final CoverInfo coverInfo; + private int clientTickRate; + private int tickRateAddition; + + public CoverTickRateButton(@NotNull CoverInfo coverInfo, @NotNull IWidgetBuilder builder) { + this.coverInfo = coverInfo; + this.clientTickRate = coverInfo.getTickRate(); + this.tickRateAddition = coverInfo.getTickRateAddition(); + + super.setBackground(BACKGROUND, OVERLAY_BUTTON_HOURGLASS); + super.setOnClick(this::onClick); + super.dynamicTooltip(this::dynamicTooltip); + super.attachSyncer( + new FakeSyncWidget.IntegerSyncer(this.coverInfo::getTickRate, integer -> clientTickRate = integer), + builder, + (widget, aInt) -> notifyTooltipChange()) + .attachSyncer( + new FakeSyncWidget.IntegerSyncer( + this.coverInfo::getTickRateAddition, + integer -> tickRateAddition = integer), + builder); + + } + + private void onClick(@NotNull ClickData clickData, @NotNull Widget widget) { + final int iterations = clickData.ctrl ? 5 : 1; + final boolean isDecreasing = clickData.mouseButton == 1; + + // Do five operations at once if Ctrl is held down. Since the actual increase granted by each invocation can be + // different on each call, just call the method several times rather than trying to do a bunch of weird math. + for (int i = 0; i < iterations; i++) { + coverInfo.adjustTickRateMultiplier(isDecreasing); + } + } + + private List dynamicTooltip() { + final String boundsNotification; + + if (tickRateAddition == 0) { + boundsNotification = StatCollector.translateToLocal("gt.cover.info.button.bounds_notification.minimum"); + } else if (tickRateAddition >= MAX_TICK_RATE_ADDITION - 1) { + // Clamping can make tickRateAddition approach but never actually equal MAX_ADDITION, so we need this + // adjustment. + boundsNotification = StatCollector.translateToLocal("gt.cover.info.button.bounds_notification.maximum"); + } else { + boundsNotification = ""; + } + + return ImmutableList.of( + StatCollector.translateToLocalFormatted( + "gt.cover.info.button.tick_rate.1", + new CoverInfo.ClientTickRateFormatter(clientTickRate), + boundsNotification), + StatCollector.translateToLocal("gt.cover.info.button.tick_rate.2"), + StatCollector.translateToLocal("gt.cover.info.button.tick_rate.3")); + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java b/src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java deleted file mode 100644 index 883ffb4079..0000000000 --- a/src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java +++ /dev/null @@ -1,82 +0,0 @@ -package gregtech.api.gui.widgets; - -import static gregtech.api.gui.modularui.GT_UITextures.OVERLAY_BUTTON_HOURGLASS; -import static gregtech.common.covers.CoverInfo.MAX_TICK_RATE_ADDITION; - -import java.util.List; - -import net.minecraft.util.StatCollector; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizons.modularui.api.drawable.UITexture; -import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.widget.ButtonWidget; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; - -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.common.covers.CoverInfo; - -public class GT_CoverTickRateButton extends ButtonWidget { - - private static final UITexture BACKGROUND = GT_UITextures.BUTTON_COVER_NORMAL.getSubArea(0, 0, 1, 0.5f); - - private final CoverInfo coverInfo; - private int clientTickRate; - private int tickRateAddition; - - public GT_CoverTickRateButton(@NotNull CoverInfo coverInfo, @NotNull IWidgetBuilder builder) { - this.coverInfo = coverInfo; - this.clientTickRate = coverInfo.getTickRate(); - this.tickRateAddition = coverInfo.getTickRateAddition(); - - super.setBackground(BACKGROUND, OVERLAY_BUTTON_HOURGLASS); - super.setOnClick(this::onClick); - super.dynamicTooltip(this::dynamicTooltip); - super.attachSyncer( - new FakeSyncWidget.IntegerSyncer(this.coverInfo::getTickRate, integer -> clientTickRate = integer), - builder, - (widget, aInt) -> notifyTooltipChange()) - .attachSyncer( - new FakeSyncWidget.IntegerSyncer( - this.coverInfo::getTickRateAddition, - integer -> tickRateAddition = integer), - builder); - - } - - private void onClick(@NotNull ClickData clickData, @NotNull Widget widget) { - final int iterations = clickData.ctrl ? 5 : 1; - final boolean isDecreasing = clickData.mouseButton == 1; - - // Do five operations at once if Ctrl is held down. Since the actual increase granted by each invocation can be - // different on each call, just call the method several times rather than trying to do a bunch of weird math. - for (int i = 0; i < iterations; i++) { - coverInfo.adjustTickRateMultiplier(isDecreasing); - } - } - - private List dynamicTooltip() { - final String boundsNotification; - - if (tickRateAddition == 0) { - boundsNotification = StatCollector.translateToLocal("gt.cover.info.button.bounds_notification.minimum"); - } else if (tickRateAddition >= MAX_TICK_RATE_ADDITION - 1) { - // Clamping can make tickRateAddition approach but never actually equal MAX_ADDITION, so we need this - // adjustment. - boundsNotification = StatCollector.translateToLocal("gt.cover.info.button.bounds_notification.maximum"); - } else { - boundsNotification = ""; - } - - return ImmutableList.of( - StatCollector.translateToLocalFormatted( - "gt.cover.info.button.tick_rate.1", - new CoverInfo.ClientTickRateFormatter(clientTickRate), - boundsNotification), - StatCollector.translateToLocal("gt.cover.info.button.tick_rate.2"), - StatCollector.translateToLocal("gt.cover.info.button.tick_rate.3")); - } -} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_LockedWhileActiveButton.java b/src/main/java/gregtech/api/gui/widgets/GT_LockedWhileActiveButton.java deleted file mode 100644 index 9a93a8fadf..0000000000 --- a/src/main/java/gregtech/api/gui/widgets/GT_LockedWhileActiveButton.java +++ /dev/null @@ -1,90 +0,0 @@ -package gregtech.api.gui.widgets; - -import java.util.Arrays; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.Supplier; - -import net.minecraft.util.StatCollector; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizons.modularui.api.drawable.IDrawable; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.widget.ButtonWidget; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; - -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.tileentity.IMachineProgress; - -public class GT_LockedWhileActiveButton extends ButtonWidget { - - @NotNull - private final IMachineProgress machine; - - public GT_LockedWhileActiveButton(@NotNull IMachineProgress machine, @NotNull ModularWindow.Builder builder) { - super(); - this.machine = machine; - - super.attachSyncer( - new FakeSyncWidget.BooleanSyncer(machine::isActive, a -> {}), - builder, - (widget, aBoolean) -> widget.notifyTooltipChange()); - - super.dynamicTooltip(this::generateTooltip); - } - - @NotNull - @Override - public ButtonWidget setOnClick(@NotNull BiConsumer clickAction) { - return super.setOnClick((clickData, widget) -> { - if (!machine.isActive()) { - clickAction.accept(clickData, widget); - } - }); - } - - @NotNull - @Override - public Widget setBackground(@NotNull IDrawable... drawables) { - return super.setBackground(() -> appendLockedOverlay(drawables)); - } - - @NotNull - @Override - public Widget setBackground(@NotNull Supplier drawablesSupplier) { - return super.setBackground(() -> appendLockedOverlay(drawablesSupplier.get())); - } - - @NotNull - @Override - public Widget dynamicTooltip(@NotNull Supplier> dynamicTooltip) { - return super.dynamicTooltip(() -> { - ImmutableList.Builder tooltips = ImmutableList.builder() - .addAll(dynamicTooltip.get()); - tooltips.addAll(generateTooltip()); - - return tooltips.build(); - }); - } - - @NotNull - private IDrawable[] appendLockedOverlay(@NotNull IDrawable[] drawables) { - if (machine.isActive()) { - final IDrawable[] copy = Arrays.copyOf(drawables, drawables.length + 1); - copy[drawables.length] = GT_UITextures.OVERLAY_BUTTON_LOCKED; - return copy; - } - return drawables; - } - - @NotNull - private List generateTooltip() { - if (machine.isActive()) { - return ImmutableList.of(StatCollector.translateToLocal("GT5U.gui.button.forbidden_while_running")); - } - return ImmutableList.of(); - } -} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_PhantomItemButton.java b/src/main/java/gregtech/api/gui/widgets/GT_PhantomItemButton.java deleted file mode 100644 index 4e2d144aa7..0000000000 --- a/src/main/java/gregtech/api/gui/widgets/GT_PhantomItemButton.java +++ /dev/null @@ -1,92 +0,0 @@ -package gregtech.api.gui.widgets; - -import java.util.List; - -import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; - -import org.apache.commons.lang3.NotImplementedException; -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizons.modularui.api.ModularUITextures; -import com.gtnewhorizons.modularui.api.drawable.IDrawable; -import com.gtnewhorizons.modularui.api.drawable.Text; -import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; -import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; - -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.metatileentity.IItemLockable; - -/** - * Creates a phantom item in a GUI. Useful for filtering. - */ -public class GT_PhantomItemButton extends SlotWidget { - - public static final IDrawable[] FILTER_BACKGROUND = { ModularUITextures.ITEM_SLOT, - GT_UITextures.OVERLAY_SLOT_FILTER }; - - public GT_PhantomItemButton(final IItemLockable delegate) { - super(BaseSlot.phantom(new PhantomItemDelegate(delegate), 0)); - controlsAmount = false; - } - - @Override - public List getTooltip() { - return ImmutableList.of(new Text(StatCollector.translateToLocal("GT5U.bus.filterTooltip.empty"))); - } - - @Override - public List getExtraTooltip() { - return ImmutableList.of(StatCollector.translateToLocal("GT5U.bus.filterTooltip.full")); - } - - @Override - public boolean onMouseScroll(int direction) { - return false; - } - - @SuppressWarnings("ClassCanBeRecord") - private static class PhantomItemDelegate implements IItemHandlerModifiable { - - private final IItemLockable delegate; - - public PhantomItemDelegate(final IItemLockable delegate) { - this.delegate = delegate; - } - - @Override - public void setStackInSlot(int slot, ItemStack itemStack) { - delegate.setLockedItem(itemStack); - } - - @Override - public int getSlots() { - return 1; - } - - @Override - public ItemStack getStackInSlot(int slot) { - return delegate.getLockedItem(); - } - - @Nullable - @Override - public ItemStack insertItem(int slot, ItemStack itemStack, boolean simulate) { - delegate.setLockedItem(itemStack); - return null; - } - - @Nullable - @Override - public ItemStack extractItem(int var1, int var2, boolean var3) { - throw new NotImplementedException("Extract item is disabled for GhostItemButtons."); - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - } -} diff --git a/src/main/java/gregtech/api/gui/widgets/LockedWhileActiveButton.java b/src/main/java/gregtech/api/gui/widgets/LockedWhileActiveButton.java new file mode 100644 index 0000000000..0e793372c5 --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/LockedWhileActiveButton.java @@ -0,0 +1,90 @@ +package gregtech.api.gui.widgets; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + +import net.minecraft.util.StatCollector; + +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; + +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.tileentity.IMachineProgress; + +public class LockedWhileActiveButton extends ButtonWidget { + + @NotNull + private final IMachineProgress machine; + + public LockedWhileActiveButton(@NotNull IMachineProgress machine, @NotNull ModularWindow.Builder builder) { + super(); + this.machine = machine; + + super.attachSyncer( + new FakeSyncWidget.BooleanSyncer(machine::isActive, a -> {}), + builder, + (widget, aBoolean) -> widget.notifyTooltipChange()); + + super.dynamicTooltip(this::generateTooltip); + } + + @NotNull + @Override + public ButtonWidget setOnClick(@NotNull BiConsumer clickAction) { + return super.setOnClick((clickData, widget) -> { + if (!machine.isActive()) { + clickAction.accept(clickData, widget); + } + }); + } + + @NotNull + @Override + public Widget setBackground(@NotNull IDrawable... drawables) { + return super.setBackground(() -> appendLockedOverlay(drawables)); + } + + @NotNull + @Override + public Widget setBackground(@NotNull Supplier drawablesSupplier) { + return super.setBackground(() -> appendLockedOverlay(drawablesSupplier.get())); + } + + @NotNull + @Override + public Widget dynamicTooltip(@NotNull Supplier> dynamicTooltip) { + return super.dynamicTooltip(() -> { + ImmutableList.Builder tooltips = ImmutableList.builder() + .addAll(dynamicTooltip.get()); + tooltips.addAll(generateTooltip()); + + return tooltips.build(); + }); + } + + @NotNull + private IDrawable[] appendLockedOverlay(@NotNull IDrawable[] drawables) { + if (machine.isActive()) { + final IDrawable[] copy = Arrays.copyOf(drawables, drawables.length + 1); + copy[drawables.length] = GTUITextures.OVERLAY_BUTTON_LOCKED; + return copy; + } + return drawables; + } + + @NotNull + private List generateTooltip() { + if (machine.isActive()) { + return ImmutableList.of(StatCollector.translateToLocal("GT5U.gui.button.forbidden_while_running")); + } + return ImmutableList.of(); + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/PhantomItemButton.java b/src/main/java/gregtech/api/gui/widgets/PhantomItemButton.java new file mode 100644 index 0000000000..e13266b33f --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/PhantomItemButton.java @@ -0,0 +1,92 @@ +package gregtech.api.gui.widgets; + +import java.util.List; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import org.apache.commons.lang3.NotImplementedException; +import org.jetbrains.annotations.Nullable; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.ModularUITextures; +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.drawable.Text; +import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; +import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; + +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.metatileentity.IItemLockable; + +/** + * Creates a phantom item in a GUI. Useful for filtering. + */ +public class PhantomItemButton extends SlotWidget { + + public static final IDrawable[] FILTER_BACKGROUND = { ModularUITextures.ITEM_SLOT, + GTUITextures.OVERLAY_SLOT_FILTER }; + + public PhantomItemButton(final IItemLockable delegate) { + super(BaseSlot.phantom(new PhantomItemDelegate(delegate), 0)); + controlsAmount = false; + } + + @Override + public List getTooltip() { + return ImmutableList.of(new Text(StatCollector.translateToLocal("GT5U.bus.filterTooltip.empty"))); + } + + @Override + public List getExtraTooltip() { + return ImmutableList.of(StatCollector.translateToLocal("GT5U.bus.filterTooltip.full")); + } + + @Override + public boolean onMouseScroll(int direction) { + return false; + } + + @SuppressWarnings("ClassCanBeRecord") + private static class PhantomItemDelegate implements IItemHandlerModifiable { + + private final IItemLockable delegate; + + public PhantomItemDelegate(final IItemLockable delegate) { + this.delegate = delegate; + } + + @Override + public void setStackInSlot(int slot, ItemStack itemStack) { + delegate.setLockedItem(itemStack); + } + + @Override + public int getSlots() { + return 1; + } + + @Override + public ItemStack getStackInSlot(int slot) { + return delegate.getLockedItem(); + } + + @Nullable + @Override + public ItemStack insertItem(int slot, ItemStack itemStack, boolean simulate) { + delegate.setLockedItem(itemStack); + return null; + } + + @Nullable + @Override + public ItemStack extractItem(int var1, int var2, boolean var3) { + throw new NotImplementedException("Extract item is disabled for GhostItemButtons."); + } + + @Override + public int getSlotLimit(int slot) { + return 1; + } + } +} diff --git a/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java b/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java index b0d42f9aec..b26c7035c7 100644 --- a/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java +++ b/src/main/java/gregtech/api/interfaces/ICleanroomReceiver.java @@ -4,9 +4,11 @@ import javax.annotation.Nullable; import net.minecraft.tileentity.TileEntity; +import gregtech.common.Pollution; + /** * Implement this interface for TileEntities that can have association to cleanroom. - * Calling {@link gregtech.common.GT_Pollution#addPollution(TileEntity, int)} from this machine + * Calling {@link Pollution#addPollution(TileEntity, int)} from this machine * will pollute associated cleanroom. */ public interface ICleanroomReceiver { diff --git a/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java b/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java index 8dde8163c8..5f225b0b4f 100644 --- a/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java +++ b/src/main/java/gregtech/api/interfaces/IConfigurationCircuitSupport.java @@ -4,7 +4,7 @@ import java.util.List; import net.minecraft.item.ItemStack; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; /** * Implement this interface if your tileentity (or metatileentity) supports configuration circuits to resolve recipe @@ -24,7 +24,7 @@ public interface IConfigurationCircuitSupport { * This list is unmodifiable. Its elements are not supposed to be modified in any way! */ default List getConfigurationCircuits() { - return GregTech_API.getConfigurationCircuitList(100); + return GregTechAPI.getConfigurationCircuitList(100); } /** diff --git a/src/main/java/gregtech/api/interfaces/IFoodStat.java b/src/main/java/gregtech/api/interfaces/IFoodStat.java index c768c5ca1c..4b1bd121e9 100644 --- a/src/main/java/gregtech/api/interfaces/IFoodStat.java +++ b/src/main/java/gregtech/api/interfaces/IFoodStat.java @@ -4,34 +4,34 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import gregtech.api.items.GT_MetaBase_Item; +import gregtech.api.items.MetaBaseItem; public interface IFoodStat { /** * Warning the "aPlayer" Parameter may be null! */ - int getFoodLevel(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer); + int getFoodLevel(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer); /** * Warning the "aPlayer" Parameter may be null! */ - float getSaturation(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer); + float getSaturation(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer); /** * Warning the "aPlayer" Parameter may be null! */ - boolean alwaysEdible(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer); + boolean alwaysEdible(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer); /** * Warning the "aPlayer" Parameter may be null! */ - boolean isRotten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer); + boolean isRotten(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer); /** * Warning the "aPlayer" Parameter may be null! */ - EnumAction getFoodAction(GT_MetaBase_Item aItem, ItemStack aStack); + EnumAction getFoodAction(MetaBaseItem aItem, ItemStack aStack); - void onEaten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer); + void onEaten(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer); } diff --git a/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java b/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java index 4bf0311544..1dc460f3de 100644 --- a/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java +++ b/src/main/java/gregtech/api/interfaces/IGT_ItemWithMaterialRenderer.java @@ -6,22 +6,24 @@ import net.minecraft.util.IIcon; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import gregtech.common.render.items.GT_GeneratedMaterial_Renderer; +import gregtech.common.render.items.GeneratedItemRenderer; +import gregtech.common.render.items.GeneratedMaterialRenderer; +import gregtech.common.render.items.MetaGeneratedItemRenderer; public interface IGT_ItemWithMaterialRenderer { /** - * @return If allow using {@link gregtech.common.render.items.GT_MetaGenerated_Item_Renderer} to render item + * @return If allow using {@link MetaGeneratedItemRenderer} to render item */ boolean shouldUseCustomRenderer(int aMetaData); /** * @return Custom renderer of the Material with offset < 32000 */ - GT_GeneratedMaterial_Renderer getMaterialRenderer(int aMetaData); + GeneratedMaterialRenderer getMaterialRenderer(int aMetaData); /** - * If this returns false, renderer falls back to {@link gregtech.common.render.items.GT_GeneratedItem_Renderer} + * If this returns false, renderer falls back to {@link GeneratedItemRenderer} */ boolean allowMaterialRenderer(int aMetaData); diff --git a/src/main/java/gregtech/api/interfaces/IHatchElement.java b/src/main/java/gregtech/api/interfaces/IHatchElement.java index 482b7899ab..9618c1ee1b 100644 --- a/src/main/java/gregtech/api/interfaces/IHatchElement.java +++ b/src/main/java/gregtech/api/interfaces/IHatchElement.java @@ -11,18 +11,17 @@ import net.minecraftforge.common.util.ForgeDirection; import com.google.common.collect.ImmutableList; import com.gtnewhorizon.structurelib.structure.IStructureElement; -import com.gtnewhorizon.structurelib.structure.StructureUtility; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_StructureUtility; -import gregtech.api.util.IGT_HatchAdder; +import gregtech.api.util.GTStructureUtility; +import gregtech.api.util.IGTHatchAdder; public interface IHatchElement { List> mteClasses(); - IGT_HatchAdder adder(); + IGTHatchAdder adder(); String name(); @@ -44,7 +43,7 @@ public interface IHatchElement { return new HatchElement<>(aClasses, null, null, null, this); } - default IHatchElement withAdder(IGT_HatchAdder aAdder) { + default IHatchElement withAdder(IGTHatchAdder aAdder) { if (aAdder == null) throw new IllegalArgumentException(); return new HatchElement<>(null, aAdder, null, null, this); } @@ -61,7 +60,7 @@ public interface IHatchElement { default IStructureElement newAny(int aCasingIndex, int aDot) { if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException(); - return GT_StructureUtility.buildHatchAdder() + return GTStructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) @@ -73,17 +72,17 @@ public interface IHatchElement { default IStructureElement newAnyOrCasing(int aCasingIndex, int aDot, Block casingBlock, int casingMeta) { if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException(); - return GT_StructureUtility.buildHatchAdder() + return GTStructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) .continueIfSuccess() - .buildAndChain(StructureUtility.ofBlock(casingBlock, casingMeta)); + .buildAndChain(com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock(casingBlock, casingMeta)); } default IStructureElement newAny(int aCasingIndex, int aDot, ForgeDirection... allowedFacings) { if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException(); - return GT_StructureUtility.buildHatchAdder() + return GTStructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) @@ -96,7 +95,7 @@ public interface IHatchElement { default IStructureElement newAny(int aCasingIndex, int aDot, BiPredicate aShouldSkip) { if (aCasingIndex < 0 || aDot < 0 || aShouldSkip == null) throw new IllegalArgumentException(); - return GT_StructureUtility.buildHatchAdder() + return GTStructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) @@ -131,7 +130,7 @@ class HatchElementEither implements IHatchElement { } @Override - public IGT_HatchAdder adder() { + public IGTHatchAdder adder() { return ((t, te, i) -> first.adder() .apply(t, te, i) || second.adder() @@ -153,12 +152,12 @@ class HatchElementEither implements IHatchElement { class HatchElement implements IHatchElement { private final List> mClasses; - private final IGT_HatchAdder mAdder; + private final IGTHatchAdder mAdder; private final String mName; private final IHatchElement mBacking; private final ToLongFunction mCount; - public HatchElement(List> aMteClasses, IGT_HatchAdder aAdder, + public HatchElement(List> aMteClasses, IGTHatchAdder aAdder, String aName, ToLongFunction aCount, IHatchElement aBacking) { this.mClasses = aMteClasses; this.mAdder = aAdder; @@ -173,7 +172,7 @@ class HatchElement implements IHatchElement { } @Override - public IGT_HatchAdder adder() { + public IGTHatchAdder adder() { return mAdder == null ? mBacking.adder() : mAdder; } @@ -194,7 +193,7 @@ class HatchElement implements IHatchElement { } @Override - public IHatchElement withAdder(IGT_HatchAdder aAdder) { + public IHatchElement withAdder(IGTHatchAdder aAdder) { if (aAdder == null) throw new IllegalArgumentException(); return new HatchElement<>(mClasses, aAdder, mName, mCount, mBacking); } diff --git a/src/main/java/gregtech/api/interfaces/IIconContainer.java b/src/main/java/gregtech/api/interfaces/IIconContainer.java index 525721bb5c..319615b58d 100644 --- a/src/main/java/gregtech/api/interfaces/IIconContainer.java +++ b/src/main/java/gregtech/api/interfaces/IIconContainer.java @@ -1,6 +1,6 @@ package gregtech.api.interfaces; -import static gregtech.api.enums.GT_Values.UNCOLORED_RGBA; +import static gregtech.api.enums.GTValues.UNCOLORED_RGBA; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; diff --git a/src/main/java/gregtech/api/interfaces/IItemBehaviour.java b/src/main/java/gregtech/api/interfaces/IItemBehaviour.java index 67bb505c6b..d9f8706824 100644 --- a/src/main/java/gregtech/api/interfaces/IItemBehaviour.java +++ b/src/main/java/gregtech/api/interfaces/IItemBehaviour.java @@ -13,7 +13,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import gregtech.api.enums.SubTag; -import gregtech.api.items.GT_MetaBase_Item; +import gregtech.api.items.MetaBaseItem; public interface IItemBehaviour { @@ -37,7 +37,7 @@ public interface IItemBehaviour { ItemStack onDispense(E aItem, IBlockSource aSource, ItemStack aStack); - boolean hasProjectile(GT_MetaBase_Item aItem, SubTag aProjectileType, ItemStack aStack); + boolean hasProjectile(MetaBaseItem aItem, SubTag aProjectileType, ItemStack aStack); EntityArrow getProjectile(E aItem, SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY, double aZ); diff --git a/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java b/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java index 1dd36d9998..4af8ec232c 100644 --- a/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java +++ b/src/main/java/gregtech/api/interfaces/INetworkUpdatableItem.java @@ -4,8 +4,10 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import gregtech.api.net.GTPacketUpdateItem; + /** - * Together with {@link gregtech.api.net.GT_Packet_UpdateItem} you can request server side to update item in hand with a + * Together with {@link GTPacketUpdateItem} you can request server side to update item in hand with a * NBT tag. *

* Usual NBT tag size limit applies. diff --git a/src/main/java/gregtech/api/interfaces/IRecipeMap.java b/src/main/java/gregtech/api/interfaces/IRecipeMap.java index ce48b29927..c6184bee34 100644 --- a/src/main/java/gregtech/api/interfaces/IRecipeMap.java +++ b/src/main/java/gregtech/api/interfaces/IRecipeMap.java @@ -7,9 +7,9 @@ import java.util.function.Function; import javax.annotation.Nonnull; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; +import gregtech.api.util.GTUtility; /** * Represents the target of a recipe adding action, usually, but not necessarily, is a recipe map itself. @@ -33,7 +33,7 @@ public interface IRecipeMap { * Actually add the recipe represented by the builder. CAN modify the builder's internal states!!! */ @Nonnull - Collection doAdd(GT_RecipeBuilder builder); + Collection doAdd(GTRecipeBuilder builder); /** * Return a variant of this recipe map that will perform a deep copy on input recipe builder before doing anything @@ -45,7 +45,7 @@ public interface IRecipeMap { return newRecipeMap(b -> doAdd(b.copy())); } - static IRecipeMap newRecipeMap(Function> func) { + static IRecipeMap newRecipeMap(Function> func) { return new IRecipeMap() { private final Collection downstreams = new ArrayList<>(); @@ -57,9 +57,9 @@ public interface IRecipeMap { @Nonnull @Override - public Collection doAdd(GT_RecipeBuilder builder) { - List> ret = new ArrayList<>(); - Collection out = func.apply(builder); + public Collection doAdd(GTRecipeBuilder builder) { + List> ret = new ArrayList<>(); + Collection out = func.apply(builder); ret.add(out); builder.clearInvalid(); if (!out.isEmpty()) { @@ -67,7 +67,7 @@ public interface IRecipeMap { ret.add(downstream.doAdd(builder)); } } - return GT_Utility.concat(ret); + return GTUtility.concat(ret); } }; } diff --git a/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java b/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java index 0eea6ca3a4..a0a362c4e5 100644 --- a/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java +++ b/src/main/java/gregtech/api/interfaces/IRedstoneCircuitBlock.java @@ -5,7 +5,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.util.GT_CoverBehavior; +import gregtech.api.util.CoverBehavior; /** * Implemented by the MetaTileEntity of the Redstone Circuit Block @@ -36,7 +36,7 @@ public interface IRedstoneCircuitBlock { /** * If this Side is Covered up and therefor not doing any Redstone */ - GT_CoverBehavior getCover(ForgeDirection side); + CoverBehavior getCover(ForgeDirection side); int getCoverID(ForgeDirection side); diff --git a/src/main/java/gregtech/api/interfaces/IToolStats.java b/src/main/java/gregtech/api/interfaces/IToolStats.java index 9d8da63b6c..6f506a6ee1 100644 --- a/src/main/java/gregtech/api/interfaces/IToolStats.java +++ b/src/main/java/gregtech/api/interfaces/IToolStats.java @@ -16,7 +16,7 @@ import net.minecraft.util.DamageSource; import net.minecraft.world.World; import net.minecraftforge.event.world.BlockEvent; -import gregtech.api.items.GT_MetaGenerated_Tool; +import gregtech.api.items.MetaGeneratedTool; /** * The Stats for GT Tools. Not including any Material Modifiers. @@ -33,7 +33,7 @@ public interface IToolStats { /** * Called when this gets added to a Tool Item */ - void onStatsAddedToTool(GT_MetaGenerated_Tool aItem, int aID); + void onStatsAddedToTool(MetaGeneratedTool aItem, int aID); /** * @implNote if you are only modifying drops, override diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGTFluid.java b/src/main/java/gregtech/api/interfaces/fluid/IGTFluid.java new file mode 100644 index 0000000000..b3765d37db --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/fluid/IGTFluid.java @@ -0,0 +1,14 @@ +package gregtech.api.interfaces.fluid; + +import net.minecraftforge.fluids.FluidRegistry; + +@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope +public interface IGTFluid { + + /** + * Adds this {@link IGTFluid} to the {@link FluidRegistry} and internally-implemented registrations + * + * @return {@link IGTRegisteredFluid} The GregTech registered fluid + */ + IGTRegisteredFluid addFluid(); +} diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGTFluidBuilder.java b/src/main/java/gregtech/api/interfaces/fluid/IGTFluidBuilder.java new file mode 100644 index 0000000000..2902824873 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/fluid/IGTFluidBuilder.java @@ -0,0 +1,96 @@ +package gregtech.api.interfaces.fluid; + +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +import gregtech.api.enums.FluidState; + +@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope +public interface IGTFluidBuilder { + + /** + * @param colorRGBA The {@code short[]} RGBA color of the {@link Fluid} or {@code null} for no defined RGBA color + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withColorRGBA(final short[] colorRGBA); + + /** + * @param localizedName The localized name of this {@link IGTFluidBuilder} + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withLocalizedName(final String localizedName); + + /** + * @param fluidState The {@link FluidState} of this {@link IGTFluidBuilder} + * @param temperature The Kelvin temperature of this {@link IGTFluidBuilder} + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withStateAndTemperature(final FluidState fluidState, final int temperature); + + /** + * @param stillIconResourceLocation the {@link ResourceLocation} of the still fluid icon + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withStillIconResourceLocation(final ResourceLocation stillIconResourceLocation); + + /** + * @param flowingIconResourceLocation the {@link ResourceLocation} of the flowing fluid icon + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withFlowingIconResourceLocation(final ResourceLocation flowingIconResourceLocation); + + /** + * @param textureName The name of the GregTech mod texture of this {@link IGTFluidBuilder} + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withTextureName(final String textureName); + + /** + * @param fluidBlock the {@link Block} implementation of the {@link IGTFluid} + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withFluidBlock(final Block fluidBlock); + + /** + * @param fromFluid the {@link Fluid} to copy the icons from + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withIconsFrom(@Nonnull final Fluid fromFluid); + + /** + * @param stillIconResourceLocation The {@link ResourceLocation} of the still fluid texture + * @param flowingIconResourceLocation The {@link ResourceLocation} of the flowing fluid texture + * @return {@link IGTFluidBuilder} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTFluidBuilder withTextures(final ResourceLocation stillIconResourceLocation, + final ResourceLocation flowingIconResourceLocation); + + /** + * Builds the {@link IGTFluid} + * + * @return the built {@link IGTFluid} + */ + IGTFluid build(); + + /** + * Builds, then adds the {@link IGTFluid} to the {@link FluidRegistry} + * + * @return the {@link IGTFluid} + * @see #build() + * @see IGTFluid#addFluid() + */ + IGTRegisteredFluid buildAndRegister(); +} diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGTRegisteredFluid.java b/src/main/java/gregtech/api/interfaces/fluid/IGTRegisteredFluid.java new file mode 100644 index 0000000000..b2796ed3f7 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/fluid/IGTRegisteredFluid.java @@ -0,0 +1,60 @@ +package gregtech.api.interfaces.fluid; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; + +import gregtech.api.enums.FluidState; +import gregtech.api.enums.Materials; + +public interface IGTRegisteredFluid { + + /** + * Registers the containers in the {@link FluidContainerRegistry} for this {@link IGTRegisteredFluid} + * + * @param fullContainer The full fluid container + * @param emptyContainer The empty fluid container + * @param containerSize The size of the container + * @return The {@link IGTRegisteredFluid} for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTRegisteredFluid registerContainers(final ItemStack fullContainer, final ItemStack emptyContainer, + final int containerSize); + + /** + * Registers the bucket-sized 1000L containers in the {@link FluidContainerRegistry} for this + * {@link IGTRegisteredFluid} + * + * @param fullContainer The full container to associate with this {@link IGTRegisteredFluid} + * @param emptyContainer The empty container associate with this {@link IGTRegisteredFluid} + * @return {@link IGTRegisteredFluid} for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTRegisteredFluid registerBContainers(final ItemStack fullContainer, final ItemStack emptyContainer); + + /** + * Registers the potion-sized 250L containers in the {@link FluidContainerRegistry} for this + * {@link IGTRegisteredFluid} + * + * @param fullContainer The full container to associate with this {@link IGTRegisteredFluid} + * @param emptyContainer The empty container associate with this {@link IGTRegisteredFluid} + * @return {@link IGTRegisteredFluid} self for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTRegisteredFluid registerPContainers(final ItemStack fullContainer, final ItemStack emptyContainer); + + /** + * Updates the {@link Materials}'s fluids from this {@link IGTRegisteredFluid}'s state + * + * @param material the {@link Materials} to configure based on this {@link IGTRegisteredFluid} and + * {@link FluidState} + * @return The {@link IGTRegisteredFluid} for call chaining + */ + @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value + IGTRegisteredFluid configureMaterials(final Materials material); + + /** + * @return this {@link IGTRegisteredFluid} cast to {@link Fluid} + */ + Fluid asFluid(); +} diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java b/src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java deleted file mode 100644 index 7c8b2b3f11..0000000000 --- a/src/main/java/gregtech/api/interfaces/fluid/IGT_Fluid.java +++ /dev/null @@ -1,14 +0,0 @@ -package gregtech.api.interfaces.fluid; - -import net.minecraftforge.fluids.FluidRegistry; - -@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope -public interface IGT_Fluid { - - /** - * Adds this {@link IGT_Fluid} to the {@link FluidRegistry} and internally-implemented registrations - * - * @return {@link IGT_RegisteredFluid} The GregTech registered fluid - */ - IGT_RegisteredFluid addFluid(); -} diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java b/src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java deleted file mode 100644 index f15b148fcb..0000000000 --- a/src/main/java/gregtech/api/interfaces/fluid/IGT_FluidBuilder.java +++ /dev/null @@ -1,96 +0,0 @@ -package gregtech.api.interfaces.fluid; - -import javax.annotation.Nonnull; - -import net.minecraft.block.Block; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; - -import gregtech.api.enums.FluidState; - -@SuppressWarnings("unused") // API might legitimately expose unused methods within this local project's scope -public interface IGT_FluidBuilder { - - /** - * @param colorRGBA The {@code short[]} RGBA color of the {@link Fluid} or {@code null} for no defined RGBA color - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withColorRGBA(final short[] colorRGBA); - - /** - * @param localizedName The localized name of this {@link IGT_FluidBuilder} - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withLocalizedName(final String localizedName); - - /** - * @param fluidState The {@link FluidState} of this {@link IGT_FluidBuilder} - * @param temperature The Kelvin temperature of this {@link IGT_FluidBuilder} - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withStateAndTemperature(final FluidState fluidState, final int temperature); - - /** - * @param stillIconResourceLocation the {@link ResourceLocation} of the still fluid icon - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withStillIconResourceLocation(final ResourceLocation stillIconResourceLocation); - - /** - * @param flowingIconResourceLocation the {@link ResourceLocation} of the flowing fluid icon - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withFlowingIconResourceLocation(final ResourceLocation flowingIconResourceLocation); - - /** - * @param textureName The name of the GregTech mod texture of this {@link IGT_FluidBuilder} - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withTextureName(final String textureName); - - /** - * @param fluidBlock the {@link Block} implementation of the {@link IGT_Fluid} - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withFluidBlock(final Block fluidBlock); - - /** - * @param fromFluid the {@link Fluid} to copy the icons from - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withIconsFrom(@Nonnull final Fluid fromFluid); - - /** - * @param stillIconResourceLocation The {@link ResourceLocation} of the still fluid texture - * @param flowingIconResourceLocation The {@link ResourceLocation} of the flowing fluid texture - * @return {@link IGT_FluidBuilder} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_FluidBuilder withTextures(final ResourceLocation stillIconResourceLocation, - final ResourceLocation flowingIconResourceLocation); - - /** - * Builds the {@link IGT_Fluid} - * - * @return the built {@link IGT_Fluid} - */ - IGT_Fluid build(); - - /** - * Builds, then adds the {@link IGT_Fluid} to the {@link FluidRegistry} - * - * @return the {@link IGT_Fluid} - * @see #build() - * @see IGT_Fluid#addFluid() - */ - IGT_RegisteredFluid buildAndRegister(); -} diff --git a/src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java b/src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java deleted file mode 100644 index 181824874c..0000000000 --- a/src/main/java/gregtech/api/interfaces/fluid/IGT_RegisteredFluid.java +++ /dev/null @@ -1,60 +0,0 @@ -package gregtech.api.interfaces.fluid; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidContainerRegistry; - -import gregtech.api.enums.FluidState; -import gregtech.api.enums.Materials; - -public interface IGT_RegisteredFluid { - - /** - * Registers the containers in the {@link FluidContainerRegistry} for this {@link IGT_RegisteredFluid} - * - * @param fullContainer The full fluid container - * @param emptyContainer The empty fluid container - * @param containerSize The size of the container - * @return The {@link IGT_RegisteredFluid} for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_RegisteredFluid registerContainers(final ItemStack fullContainer, final ItemStack emptyContainer, - final int containerSize); - - /** - * Registers the bucket-sized 1000L containers in the {@link FluidContainerRegistry} for this - * {@link IGT_RegisteredFluid} - * - * @param fullContainer The full container to associate with this {@link IGT_RegisteredFluid} - * @param emptyContainer The empty container associate with this {@link IGT_RegisteredFluid} - * @return {@link IGT_RegisteredFluid} for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_RegisteredFluid registerBContainers(final ItemStack fullContainer, final ItemStack emptyContainer); - - /** - * Registers the potion-sized 250L containers in the {@link FluidContainerRegistry} for this - * {@link IGT_RegisteredFluid} - * - * @param fullContainer The full container to associate with this {@link IGT_RegisteredFluid} - * @param emptyContainer The empty container associate with this {@link IGT_RegisteredFluid} - * @return {@link IGT_RegisteredFluid} self for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_RegisteredFluid registerPContainers(final ItemStack fullContainer, final ItemStack emptyContainer); - - /** - * Updates the {@link Materials}'s fluids from this {@link IGT_RegisteredFluid}'s state - * - * @param material the {@link Materials} to configure based on this {@link IGT_RegisteredFluid} and - * {@link FluidState} - * @return The {@link IGT_RegisteredFluid} for call chaining - */ - @SuppressWarnings("UnusedReturnValue") // Last call in chain, may not use this returned value - IGT_RegisteredFluid configureMaterials(final Materials material); - - /** - * @return this {@link IGT_RegisteredFluid} cast to {@link Fluid} - */ - Fluid asFluid(); -} diff --git a/src/main/java/gregtech/api/interfaces/internal/IGTCraftingRecipe.java b/src/main/java/gregtech/api/interfaces/internal/IGTCraftingRecipe.java new file mode 100644 index 0000000000..beacd71f95 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/internal/IGTCraftingRecipe.java @@ -0,0 +1,8 @@ +package gregtech.api.interfaces.internal; + +import net.minecraft.item.crafting.IRecipe; + +public interface IGTCraftingRecipe extends IRecipe { + + boolean isRemovable(); +} diff --git a/src/main/java/gregtech/api/interfaces/internal/IGTMod.java b/src/main/java/gregtech/api/interfaces/internal/IGTMod.java new file mode 100644 index 0000000000..f47a7ef645 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/internal/IGTMod.java @@ -0,0 +1,50 @@ +package gregtech.api.interfaces.internal; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +/** + * Interface used by the Mods Main Class to reference to internals. + *

+ * Don't even think about including this File in your Mod. + */ +public interface IGTMod { + + /** + * This means that Server specific Basefiles are definitely existing! Not if the World is actually server side or + * not! + */ + boolean isServerSide(); + + /** + * This means that Client specific Basefiles are definitely existing! Not if the World is actually client side or + * not! + */ + boolean isClientSide(); + + /** + * This means that Bukkit specific Basefiles are definitely existing! Not if the World is actually bukkit server or + * not! + */ + boolean isBukkitSide(); + + /** + * works only ClientSide otherwise returns null + */ + EntityPlayer getThePlayer(); + + // ---------- Internal Usage Only ---------- + + /** + * works only ClientSide otherwise returns 0 + * + * @return the Index of the added Armor + */ + int addArmor(String aArmorPrefix); + + /** + * Plays the Sonictron Sound for the ItemStack on the Client Side + */ + void doSonictronSound(ItemStack aStack, World aWorld, double aX, double aY, double aZ); +} diff --git a/src/main/java/gregtech/api/interfaces/internal/IGTRecipeAdder.java b/src/main/java/gregtech/api/interfaces/internal/IGTRecipeAdder.java new file mode 100644 index 0000000000..a4d554428e --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/internal/IGTRecipeAdder.java @@ -0,0 +1,8 @@ +package gregtech.api.interfaces.internal; + +import gregtech.api.util.GTRecipeBuilder; + +public interface IGTRecipeAdder { + + GTRecipeBuilder stdBuilder(); +} diff --git a/src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java b/src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java deleted file mode 100644 index 3f29736470..0000000000 --- a/src/main/java/gregtech/api/interfaces/internal/IGT_CraftingRecipe.java +++ /dev/null @@ -1,8 +0,0 @@ -package gregtech.api.interfaces.internal; - -import net.minecraft.item.crafting.IRecipe; - -public interface IGT_CraftingRecipe extends IRecipe { - - boolean isRemovable(); -} diff --git a/src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java b/src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java deleted file mode 100644 index dbf888ef96..0000000000 --- a/src/main/java/gregtech/api/interfaces/internal/IGT_Mod.java +++ /dev/null @@ -1,50 +0,0 @@ -package gregtech.api.interfaces.internal; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; - -/** - * Interface used by the Mods Main Class to reference to internals. - *

- * Don't even think about including this File in your Mod. - */ -public interface IGT_Mod { - - /** - * This means that Server specific Basefiles are definitely existing! Not if the World is actually server side or - * not! - */ - boolean isServerSide(); - - /** - * This means that Client specific Basefiles are definitely existing! Not if the World is actually client side or - * not! - */ - boolean isClientSide(); - - /** - * This means that Bukkit specific Basefiles are definitely existing! Not if the World is actually bukkit server or - * not! - */ - boolean isBukkitSide(); - - /** - * works only ClientSide otherwise returns null - */ - EntityPlayer getThePlayer(); - - // ---------- Internal Usage Only ---------- - - /** - * works only ClientSide otherwise returns 0 - * - * @return the Index of the added Armor - */ - int addArmor(String aArmorPrefix); - - /** - * Plays the Sonictron Sound for the ItemStack on the Client Side - */ - void doSonictronSound(ItemStack aStack, World aWorld, double aX, double aY, double aZ); -} diff --git a/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java b/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java deleted file mode 100644 index e3c3a8cbaa..0000000000 --- a/src/main/java/gregtech/api/interfaces/internal/IGT_RecipeAdder.java +++ /dev/null @@ -1,8 +0,0 @@ -package gregtech.api.interfaces.internal; - -import gregtech.api.util.GT_RecipeBuilder; - -public interface IGT_RecipeAdder { - - GT_RecipeBuilder stdBuilder(); -} diff --git a/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java b/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java index 5d99f83689..2cb2e6fd84 100644 --- a/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java +++ b/src/main/java/gregtech/api/interfaces/internal/IThaumcraftCompat.java @@ -6,8 +6,8 @@ import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; import net.minecraft.item.ItemStack; -import gregtech.api.enums.TC_Aspects; -import gregtech.api.enums.TC_Aspects.TC_AspectStack; +import gregtech.api.enums.TCAspects; +import gregtech.api.enums.TCAspects.TC_AspectStack; public interface IThaumcraftCompat { @@ -35,10 +35,10 @@ public interface IThaumcraftCompat { Object addCrucibleRecipe(String aResearch, Object aInput, ItemStack aOutput, List aAspects); Object addInfusionRecipe(String aResearch, ItemStack aMainInput, ItemStack[] aSideInputs, ItemStack aOutput, - int aInstability, List aAspects); + int aInstability, List aAspects); Object addInfusionEnchantmentRecipe(String aResearch, Enchantment aEnchantment, int aInstability, - List aAspects, ItemStack[] aSideInputs); + List aAspects, ItemStack[] aSideInputs); Object addResearch(String aResearch, String aName, String aText, String[] aParentResearches, String aCategory, ItemStack aIcon, int aComplexity, int aType, int aX, int aY, List aAspects, diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java index 4959f8b060..824925f928 100644 --- a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java +++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java @@ -34,8 +34,8 @@ import gregtech.api.interfaces.tileentity.IGearEnergyTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IGregtechWailaProvider; import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_Util; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.GTUtil; /** * Warning, this Interface has just been made to be able to add multiple kinds of MetaTileEntities (Cables, Pipes, @@ -127,7 +127,7 @@ public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHand * If a Cover of that Type can be placed on this Side. Also Called when the Facing of the Block Changes and a Cover * is on said Side. */ - boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aStack); + boolean allowCoverOnSide(ForgeDirection side, GTItemStack aStack); /** * When a Player right-clicks the Facing with a Screwdriver. @@ -400,7 +400,7 @@ public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHand if (getBaseMetaTileEntity() != null) { return getBaseMetaTileEntity().getGUIColorization(); } else { - return GT_Util.getRGBInt(Dyes.MACHINE_METAL.getRGBA()); + return GTUtil.getRGBInt(Dyes.MACHINE_METAL.getRGBA()); } } diff --git a/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java b/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java deleted file mode 100644 index 8574de7007..0000000000 --- a/src/main/java/gregtech/api/interfaces/modularui/ControllerWithOptionalFeatures.java +++ /dev/null @@ -1,393 +0,0 @@ -package gregtech.api.interfaces.modularui; - -import static gregtech.api.metatileentity.BaseTileEntity.BUTTON_FORBIDDEN_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import net.minecraft.util.StatCollector; - -import com.gtnewhorizons.modularui.api.drawable.IDrawable; -import com.gtnewhorizons.modularui.api.drawable.UITexture; -import com.gtnewhorizons.modularui.api.math.Pos2d; -import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.widget.ButtonWidget; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; - -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.VoidingMode; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.tileentity.IRecipeLockable; -import gregtech.api.interfaces.tileentity.IVoidable; - -/** - * Machines implementing this interface can have logic and GUI buttons - * to configure various behaviors regarding multiblock. - *

    - *
  • Power switch
  • - *
  • Void protection
  • - *
  • Separated input buses
  • - *
  • Batch mode
  • - *
  • Recipe locking
  • - *
  • Multiple machine modes
  • - *
- */ -public interface ControllerWithOptionalFeatures extends IVoidable, IRecipeLockable { - - boolean isAllowedToWork(); - - void disableWorking(); - - void enableWorking(); - - Pos2d getPowerSwitchButtonPos(); - - default ButtonWidget createPowerSwitchButton(IWidgetBuilder builder) { - Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { - if (isAllowedToWork()) { - disableWorking(); - } else { - enableWorking(); - } - }) - .setPlayClickSoundResource( - () -> isAllowedToWork() ? SoundResource.GUI_BUTTON_UP.resourceLocation - : SoundResource.GUI_BUTTON_DOWN.resourceLocation) - .setBackground(() -> { - if (isAllowedToWork()) { - return new IDrawable[] { GT_UITextures.BUTTON_STANDARD_PRESSED, - GT_UITextures.OVERLAY_BUTTON_POWER_SWITCH_ON }; - } else { - return new IDrawable[] { GT_UITextures.BUTTON_STANDARD, - GT_UITextures.OVERLAY_BUTTON_POWER_SWITCH_OFF }; - } - }) - .attachSyncer(new FakeSyncWidget.BooleanSyncer(this::isAllowedToWork, val -> { - if (val) enableWorking(); - else disableWorking(); - }), builder) - .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.power_switch")) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getPowerSwitchButtonPos()) - .setSize(16, 16); - return (ButtonWidget) button; - } - - Pos2d getVoidingModeButtonPos(); - - default ButtonWidget createVoidExcessButton(IWidgetBuilder builder) { - Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { - if (supportsVoidProtection()) { - Set allowed = getAllowedVoidingModes(); - switch (clickData.mouseButton) { - case 0 -> setVoidingMode(getVoidingMode().nextInCollection(allowed)); - case 1 -> setVoidingMode(getVoidingMode().previousInCollection(allowed)); - } - widget.notifyTooltipChange(); - } - }) - .setPlayClickSound(supportsVoidProtection()) - .setBackground(() -> { - List ret = new ArrayList<>(); - ret.add(getVoidingMode().buttonTexture); - ret.add(getVoidingMode().buttonOverlay); - if (!supportsVoidProtection()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN); - } - return ret.toArray(new IDrawable[0]); - }) - .attachSyncer( - new FakeSyncWidget.IntegerSyncer( - () -> getVoidingMode().ordinal(), - val -> setVoidingMode(VoidingMode.fromOrdinal(val))), - builder) - .dynamicTooltip( - () -> Arrays.asList( - StatCollector.translateToLocal("GT5U.gui.button.voiding_mode"), - StatCollector.translateToLocal(getVoidingMode().getTransKey()))) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getVoidingModeButtonPos()) - .setSize(16, 16); - if (!supportsVoidProtection()) { - button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); - } - return (ButtonWidget) button; - } - - /** - * @return if the multi has more than 1 mode - */ - default boolean supportsMachineModeSwitch() { - return false; - } - - /** - * @return the current mode number. This is a getter is used for displaying the icon in the GUI - */ - default int getMachineMode() { - return 0; - } - - /** - * @return name for the current machine mode on this machine. Defaults "Unknown Mode" - */ - default String getMachineModeName() { - return "Unknown Mode"; - } - - /** - * @param index Index of machineModeIcons to pull from - * @return UITexture associated with that machineMode - */ - default UITexture getMachineModeIcon(int index) { - return null; - } - - /** - * @param index Number to set machineMode to - */ - default void setMachineMode(int index) {} - - /** - * @return Returns the next machineMode number in the sequence - */ - default int nextMachineMode() { - return 0; - } - - /** - * @return Returns whether machine supports mode switch by default - */ - default boolean getDefaultModeSwitch() { - return supportsMachineModeSwitch(); - } - - Pos2d getMachineModeSwitchButtonPos(); - - /** - * Called when the mode switch button is clicked - */ - default void onMachineModeSwitchClick() {} - - default ButtonWidget createModeSwitchButton(IWidgetBuilder builder) { - if (!supportsMachineModeSwitch()) return null; - Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { - if (supportsMachineModeSwitch()) { - onMachineModeSwitchClick(); - setMachineMode(nextMachineMode()); - } - }) - .setPlayClickSound(supportsMachineModeSwitch()) - .setBackground(() -> { - List ret = new ArrayList<>(); - if (supportsMachineModeSwitch()) { - ret.add(GT_UITextures.BUTTON_STANDARD); - ret.add(getMachineModeIcon(getMachineMode())); - } else return null; - return ret.toArray(new IDrawable[0]); - }) - .attachSyncer(new FakeSyncWidget.IntegerSyncer(this::getMachineMode, this::setMachineMode), builder) - .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.mode_switch")) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getMachineModeSwitchButtonPos()) - .setSize(16, 16); - return (ButtonWidget) button; - } - - /** - * @return if the multi supports input separation. - */ - boolean supportsInputSeparation(); - - /** - * @return true if input separation is enabled, else false. This is getter is used for displaying the icon in the - * GUI - */ - boolean isInputSeparationEnabled(); - - void setInputSeparation(boolean enabled); - - default boolean getDefaultInputSeparationMode() { - return supportsInputSeparation(); - } - - Pos2d getInputSeparationButtonPos(); - - default ButtonWidget createInputSeparationButton(IWidgetBuilder builder) { - Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { - if (supportsInputSeparation()) { - setInputSeparation(!isInputSeparationEnabled()); - } - }) - .setPlayClickSound(supportsInputSeparation()) - .setBackground(() -> { - List ret = new ArrayList<>(); - if (isInputSeparationEnabled()) { - ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED); - if (supportsInputSeparation()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON); - } else { - ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON_DISABLED); - } - } else { - ret.add(GT_UITextures.BUTTON_STANDARD); - if (supportsInputSeparation()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF); - } else { - ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF_DISABLED); - } - } - if (!supportsInputSeparation()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN); - } - return ret.toArray(new IDrawable[0]); - }) - .attachSyncer( - new FakeSyncWidget.BooleanSyncer(this::isInputSeparationEnabled, this::setInputSeparation), - builder) - .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.input_separation")) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getInputSeparationButtonPos()) - .setSize(16, 16); - if (!supportsInputSeparation()) { - button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); - } - return (ButtonWidget) button; - } - - /** - * @return if the multi supports batch mode. - */ - boolean supportsBatchMode(); - - /** - * @return true if batch mode is enabled, else false. This is getter is used for displaying the icon in the GUI - */ - boolean isBatchModeEnabled(); - - void setBatchMode(boolean enabled); - - default boolean getDefaultBatchMode() { - return false; - } - - Pos2d getBatchModeButtonPos(); - - default ButtonWidget createBatchModeButton(IWidgetBuilder builder) { - Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { - if (supportsBatchMode()) { - setBatchMode(!isBatchModeEnabled()); - } - }) - .setPlayClickSound(supportsBatchMode()) - .setBackground(() -> { - List ret = new ArrayList<>(); - if (isBatchModeEnabled()) { - ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED); - if (supportsBatchMode()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_ON); - } else { - ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_ON_DISABLED); - } - } else { - ret.add(GT_UITextures.BUTTON_STANDARD); - if (supportsBatchMode()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_OFF); - } else { - ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_OFF_DISABLED); - } - } - if (!supportsBatchMode()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN); - } - return ret.toArray(new IDrawable[0]); - }) - .attachSyncer(new FakeSyncWidget.BooleanSyncer(this::isBatchModeEnabled, this::setBatchMode), builder) - .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.batch_mode")) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getBatchModeButtonPos()) - .setSize(16, 16); - if (!supportsBatchMode()) { - button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); - } - return (ButtonWidget) button; - } - - Pos2d getRecipeLockingButtonPos(); - - default ButtonWidget createLockToSingleRecipeButton(IWidgetBuilder builder) { - Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { - if (supportsSingleRecipeLocking()) { - setRecipeLocking(!isRecipeLockingEnabled()); - } - }) - .setPlayClickSound(supportsSingleRecipeLocking()) - .setBackground(() -> { - List ret = new ArrayList<>(); - if (isRecipeLockingEnabled()) { - ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED); - if (supportsSingleRecipeLocking()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_LOCKED); - } else { - ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_LOCKED_DISABLED); - } - } else { - ret.add(GT_UITextures.BUTTON_STANDARD); - if (supportsSingleRecipeLocking()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED); - } else { - ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED_DISABLED); - } - } - if (!supportsSingleRecipeLocking()) { - ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN); - } - return ret.toArray(new IDrawable[0]); - }) - .attachSyncer( - new FakeSyncWidget.BooleanSyncer(this::isRecipeLockingEnabled, this::setRecipeLocking), - builder) - .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.lock_recipe")) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getRecipeLockingButtonPos()) - .setSize(16, 16); - if (!supportsSingleRecipeLocking()) { - button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); - } - return (ButtonWidget) button; - } - - Pos2d getStructureUpdateButtonPos(); - - int getStructureUpdateTime(); - - void setStructureUpdateTime(int time); - - default ButtonWidget createStructureUpdateButton(IWidgetBuilder builder) { - Widget button = new ButtonWidget() - .setOnClick((clickData, widget) -> { if (getStructureUpdateTime() <= -20) setStructureUpdateTime(1); }) - .setPlayClickSound(true) - .setBackground(() -> { - List ret = new ArrayList<>(); - if (getStructureUpdateTime() > -20) { - ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED); - } else { - ret.add(GT_UITextures.BUTTON_STANDARD); - } - ret.add(GT_UITextures.OVERLAY_BUTTON_STRUCTURE_UPDATE); - return ret.toArray(new IDrawable[0]); - }) - .attachSyncer( - new FakeSyncWidget.IntegerSyncer(this::getStructureUpdateTime, this::setStructureUpdateTime), - builder) - .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.structure_update")) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(getStructureUpdateButtonPos()) - .setSize(16, 16); - return (ButtonWidget) button; - } -} diff --git a/src/main/java/gregtech/api/interfaces/modularui/IControllerWithOptionalFeatures.java b/src/main/java/gregtech/api/interfaces/modularui/IControllerWithOptionalFeatures.java new file mode 100644 index 0000000000..d203d9fc87 --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/modularui/IControllerWithOptionalFeatures.java @@ -0,0 +1,393 @@ +package gregtech.api.interfaces.modularui; + +import static gregtech.api.metatileentity.BaseTileEntity.BUTTON_FORBIDDEN_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import net.minecraft.util.StatCollector; + +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; + +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.VoidingMode; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.tileentity.IRecipeLockable; +import gregtech.api.interfaces.tileentity.IVoidable; + +/** + * Machines implementing this interface can have logic and GUI buttons + * to configure various behaviors regarding multiblock. + *
    + *
  • Power switch
  • + *
  • Void protection
  • + *
  • Separated input buses
  • + *
  • Batch mode
  • + *
  • Recipe locking
  • + *
  • Multiple machine modes
  • + *
+ */ +public interface IControllerWithOptionalFeatures extends IVoidable, IRecipeLockable { + + boolean isAllowedToWork(); + + void disableWorking(); + + void enableWorking(); + + Pos2d getPowerSwitchButtonPos(); + + default ButtonWidget createPowerSwitchButton(IWidgetBuilder builder) { + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (isAllowedToWork()) { + disableWorking(); + } else { + enableWorking(); + } + }) + .setPlayClickSoundResource( + () -> isAllowedToWork() ? SoundResource.GUI_BUTTON_UP.resourceLocation + : SoundResource.GUI_BUTTON_DOWN.resourceLocation) + .setBackground(() -> { + if (isAllowedToWork()) { + return new IDrawable[] { GTUITextures.BUTTON_STANDARD_PRESSED, + GTUITextures.OVERLAY_BUTTON_POWER_SWITCH_ON }; + } else { + return new IDrawable[] { GTUITextures.BUTTON_STANDARD, + GTUITextures.OVERLAY_BUTTON_POWER_SWITCH_OFF }; + } + }) + .attachSyncer(new FakeSyncWidget.BooleanSyncer(this::isAllowedToWork, val -> { + if (val) enableWorking(); + else disableWorking(); + }), builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.power_switch")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getPowerSwitchButtonPos()) + .setSize(16, 16); + return (ButtonWidget) button; + } + + Pos2d getVoidingModeButtonPos(); + + default ButtonWidget createVoidExcessButton(IWidgetBuilder builder) { + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (supportsVoidProtection()) { + Set allowed = getAllowedVoidingModes(); + switch (clickData.mouseButton) { + case 0 -> setVoidingMode(getVoidingMode().nextInCollection(allowed)); + case 1 -> setVoidingMode(getVoidingMode().previousInCollection(allowed)); + } + widget.notifyTooltipChange(); + } + }) + .setPlayClickSound(supportsVoidProtection()) + .setBackground(() -> { + List ret = new ArrayList<>(); + ret.add(getVoidingMode().buttonTexture); + ret.add(getVoidingMode().buttonOverlay); + if (!supportsVoidProtection()) { + ret.add(GTUITextures.OVERLAY_BUTTON_FORBIDDEN); + } + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer( + new FakeSyncWidget.IntegerSyncer( + () -> getVoidingMode().ordinal(), + val -> setVoidingMode(VoidingMode.fromOrdinal(val))), + builder) + .dynamicTooltip( + () -> Arrays.asList( + StatCollector.translateToLocal("GT5U.gui.button.voiding_mode"), + StatCollector.translateToLocal(getVoidingMode().getTransKey()))) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getVoidingModeButtonPos()) + .setSize(16, 16); + if (!supportsVoidProtection()) { + button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); + } + return (ButtonWidget) button; + } + + /** + * @return if the multi has more than 1 mode + */ + default boolean supportsMachineModeSwitch() { + return false; + } + + /** + * @return the current mode number. This is a getter is used for displaying the icon in the GUI + */ + default int getMachineMode() { + return 0; + } + + /** + * @return name for the current machine mode on this machine. Defaults "Unknown Mode" + */ + default String getMachineModeName() { + return "Unknown Mode"; + } + + /** + * @param index Index of machineModeIcons to pull from + * @return UITexture associated with that machineMode + */ + default UITexture getMachineModeIcon(int index) { + return null; + } + + /** + * @param index Number to set machineMode to + */ + default void setMachineMode(int index) {} + + /** + * @return Returns the next machineMode number in the sequence + */ + default int nextMachineMode() { + return 0; + } + + /** + * @return Returns whether machine supports mode switch by default + */ + default boolean getDefaultModeSwitch() { + return supportsMachineModeSwitch(); + } + + Pos2d getMachineModeSwitchButtonPos(); + + /** + * Called when the mode switch button is clicked + */ + default void onMachineModeSwitchClick() {} + + default ButtonWidget createModeSwitchButton(IWidgetBuilder builder) { + if (!supportsMachineModeSwitch()) return null; + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (supportsMachineModeSwitch()) { + onMachineModeSwitchClick(); + setMachineMode(nextMachineMode()); + } + }) + .setPlayClickSound(supportsMachineModeSwitch()) + .setBackground(() -> { + List ret = new ArrayList<>(); + if (supportsMachineModeSwitch()) { + ret.add(GTUITextures.BUTTON_STANDARD); + ret.add(getMachineModeIcon(getMachineMode())); + } else return null; + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer(new FakeSyncWidget.IntegerSyncer(this::getMachineMode, this::setMachineMode), builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.mode_switch")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getMachineModeSwitchButtonPos()) + .setSize(16, 16); + return (ButtonWidget) button; + } + + /** + * @return if the multi supports input separation. + */ + boolean supportsInputSeparation(); + + /** + * @return true if input separation is enabled, else false. This is getter is used for displaying the icon in the + * GUI + */ + boolean isInputSeparationEnabled(); + + void setInputSeparation(boolean enabled); + + default boolean getDefaultInputSeparationMode() { + return supportsInputSeparation(); + } + + Pos2d getInputSeparationButtonPos(); + + default ButtonWidget createInputSeparationButton(IWidgetBuilder builder) { + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (supportsInputSeparation()) { + setInputSeparation(!isInputSeparationEnabled()); + } + }) + .setPlayClickSound(supportsInputSeparation()) + .setBackground(() -> { + List ret = new ArrayList<>(); + if (isInputSeparationEnabled()) { + ret.add(GTUITextures.BUTTON_STANDARD_PRESSED); + if (supportsInputSeparation()) { + ret.add(GTUITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON); + } else { + ret.add(GTUITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON_DISABLED); + } + } else { + ret.add(GTUITextures.BUTTON_STANDARD); + if (supportsInputSeparation()) { + ret.add(GTUITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF); + } else { + ret.add(GTUITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF_DISABLED); + } + } + if (!supportsInputSeparation()) { + ret.add(GTUITextures.OVERLAY_BUTTON_FORBIDDEN); + } + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer( + new FakeSyncWidget.BooleanSyncer(this::isInputSeparationEnabled, this::setInputSeparation), + builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.input_separation")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getInputSeparationButtonPos()) + .setSize(16, 16); + if (!supportsInputSeparation()) { + button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); + } + return (ButtonWidget) button; + } + + /** + * @return if the multi supports batch mode. + */ + boolean supportsBatchMode(); + + /** + * @return true if batch mode is enabled, else false. This is getter is used for displaying the icon in the GUI + */ + boolean isBatchModeEnabled(); + + void setBatchMode(boolean enabled); + + default boolean getDefaultBatchMode() { + return false; + } + + Pos2d getBatchModeButtonPos(); + + default ButtonWidget createBatchModeButton(IWidgetBuilder builder) { + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (supportsBatchMode()) { + setBatchMode(!isBatchModeEnabled()); + } + }) + .setPlayClickSound(supportsBatchMode()) + .setBackground(() -> { + List ret = new ArrayList<>(); + if (isBatchModeEnabled()) { + ret.add(GTUITextures.BUTTON_STANDARD_PRESSED); + if (supportsBatchMode()) { + ret.add(GTUITextures.OVERLAY_BUTTON_BATCH_MODE_ON); + } else { + ret.add(GTUITextures.OVERLAY_BUTTON_BATCH_MODE_ON_DISABLED); + } + } else { + ret.add(GTUITextures.BUTTON_STANDARD); + if (supportsBatchMode()) { + ret.add(GTUITextures.OVERLAY_BUTTON_BATCH_MODE_OFF); + } else { + ret.add(GTUITextures.OVERLAY_BUTTON_BATCH_MODE_OFF_DISABLED); + } + } + if (!supportsBatchMode()) { + ret.add(GTUITextures.OVERLAY_BUTTON_FORBIDDEN); + } + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer(new FakeSyncWidget.BooleanSyncer(this::isBatchModeEnabled, this::setBatchMode), builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.batch_mode")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getBatchModeButtonPos()) + .setSize(16, 16); + if (!supportsBatchMode()) { + button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); + } + return (ButtonWidget) button; + } + + Pos2d getRecipeLockingButtonPos(); + + default ButtonWidget createLockToSingleRecipeButton(IWidgetBuilder builder) { + Widget button = new ButtonWidget().setOnClick((clickData, widget) -> { + if (supportsSingleRecipeLocking()) { + setRecipeLocking(!isRecipeLockingEnabled()); + } + }) + .setPlayClickSound(supportsSingleRecipeLocking()) + .setBackground(() -> { + List ret = new ArrayList<>(); + if (isRecipeLockingEnabled()) { + ret.add(GTUITextures.BUTTON_STANDARD_PRESSED); + if (supportsSingleRecipeLocking()) { + ret.add(GTUITextures.OVERLAY_BUTTON_RECIPE_LOCKED); + } else { + ret.add(GTUITextures.OVERLAY_BUTTON_RECIPE_LOCKED_DISABLED); + } + } else { + ret.add(GTUITextures.BUTTON_STANDARD); + if (supportsSingleRecipeLocking()) { + ret.add(GTUITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED); + } else { + ret.add(GTUITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED_DISABLED); + } + } + if (!supportsSingleRecipeLocking()) { + ret.add(GTUITextures.OVERLAY_BUTTON_FORBIDDEN); + } + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer( + new FakeSyncWidget.BooleanSyncer(this::isRecipeLockingEnabled, this::setRecipeLocking), + builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.lock_recipe")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getRecipeLockingButtonPos()) + .setSize(16, 16); + if (!supportsSingleRecipeLocking()) { + button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP)); + } + return (ButtonWidget) button; + } + + Pos2d getStructureUpdateButtonPos(); + + int getStructureUpdateTime(); + + void setStructureUpdateTime(int time); + + default ButtonWidget createStructureUpdateButton(IWidgetBuilder builder) { + Widget button = new ButtonWidget() + .setOnClick((clickData, widget) -> { if (getStructureUpdateTime() <= -20) setStructureUpdateTime(1); }) + .setPlayClickSound(true) + .setBackground(() -> { + List ret = new ArrayList<>(); + if (getStructureUpdateTime() > -20) { + ret.add(GTUITextures.BUTTON_STANDARD_PRESSED); + } else { + ret.add(GTUITextures.BUTTON_STANDARD); + } + ret.add(GTUITextures.OVERLAY_BUTTON_STRUCTURE_UPDATE); + return ret.toArray(new IDrawable[0]); + }) + .attachSyncer( + new FakeSyncWidget.IntegerSyncer(this::getStructureUpdateTime, this::setStructureUpdateTime), + builder) + .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.structure_update")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(getStructureUpdateButtonPos()) + .setSize(16, 16); + return (ButtonWidget) button; + } +} diff --git a/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java b/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java index 76d94ee299..442ad05efd 100644 --- a/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java +++ b/src/main/java/gregtech/api/interfaces/modularui/IGetTitleColor.java @@ -1,11 +1,11 @@ package gregtech.api.interfaces.modularui; import gregtech.api.enums.Dyes; -import gregtech.api.util.GT_Util; +import gregtech.api.util.GTUtil; public interface IGetTitleColor { default int getTitleColor() { - return GT_Util.getRGBaInt(Dyes.dyeWhite.getRGBA()); + return GTUtil.getRGBaInt(Dyes.dyeWhite.getRGBA()); } } diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java index ec760dd346..852817add2 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/IColoredTileEntity.java @@ -1,7 +1,7 @@ package gregtech.api.interfaces.tileentity; import gregtech.api.enums.Dyes; -import gregtech.api.util.GT_Util; +import gregtech.api.util.GTUtil; public interface IColoredTileEntity { @@ -21,7 +21,6 @@ public interface IColoredTileEntity { * @return Actual color shown on GUI */ default int getGUIColorization() { - return GT_Util - .getRGBInt((getColorization() != -1 ? Dyes.get(getColorization()) : Dyes.MACHINE_METAL).getRGBA()); + return GTUtil.getRGBInt((getColorization() != -1 ? Dyes.get(getColorization()) : Dyes.MACHINE_METAL).getRGBA()); } } diff --git a/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java b/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java index 8834678984..00ae2db9bd 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/ICoverable.java @@ -4,8 +4,8 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.ForgeDirection; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; import gregtech.api.util.ISerializableObject; import gregtech.common.covers.CoverInfo; @@ -49,9 +49,9 @@ public interface ICoverable extends IRedstoneTileEntity, IHasInventory, IBasicEn ItemStack getCoverItemAtSide(ForgeDirection side); @Deprecated - GT_CoverBehavior getCoverBehaviorAtSide(ForgeDirection side); + CoverBehavior getCoverBehaviorAtSide(ForgeDirection side); - default GT_CoverBehaviorBase getCoverBehaviorAtSideNew(ForgeDirection side) { + default CoverBehaviorBase getCoverBehaviorAtSideNew(ForgeDirection side) { return getCoverBehaviorAtSide(side); } diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java index 91a9759e47..6dbc6bd5b8 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java @@ -8,10 +8,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import cofh.api.energy.IEnergyReceiver; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; import gregtech.api.logic.PowerLogic; import gregtech.api.logic.interfaces.PowerLogicHost; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import ic2.api.energy.tile.IEnergySink; /** @@ -97,8 +97,8 @@ public interface IEnergyConnected extends IColoredTileEntity { while (amperage > usedAmperes && sink.getDemandedEnergy() > 0 && sink.injectEnergy(oppositeSide, voltage, voltage) < voltage) usedAmperes++; } - } else if (GregTech_API.mOutputRF && tTileEntity instanceof IEnergyReceiver receiver) { - final int rfOut = GT_Utility.safeInt(voltage * GregTech_API.mEUtoRF / 100); + } else if (GregTechAPI.mOutputRF && tTileEntity instanceof IEnergyReceiver receiver) { + final int rfOut = GTUtility.safeInt(voltage * GregTechAPI.mEUtoRF / 100); if (receiver.receiveEnergy(oppositeSide, rfOut, true) == rfOut) { receiver.receiveEnergy(oppositeSide, rfOut, false); usedAmperes++; @@ -152,7 +152,7 @@ public interface IEnergyConnected extends IColoredTileEntity { emitterLogic.removeEnergyUnsafe(usedAmperes * voltage); return; } - + if (tileEntity instanceof IEnergySink sink) { if (sink.acceptsEnergyFrom((TileEntity) emitter, oppositeSide)) { while (amperage > usedAmperes && sink.getDemandedEnergy() > 0 @@ -164,8 +164,8 @@ public interface IEnergyConnected extends IColoredTileEntity { } } - if (GregTech_API.mOutputRF && tileEntity instanceof IEnergyReceiver receiver) { - final int rfOut = GT_Utility.safeInt(voltage * GregTech_API.mEUtoRF / 100); + if (GregTechAPI.mOutputRF && tileEntity instanceof IEnergyReceiver receiver) { + final int rfOut = GTUtility.safeInt(voltage * GregTechAPI.mEUtoRF / 100); if (receiver.receiveEnergy(oppositeSide, rfOut, true) == rfOut) { receiver.receiveEnergy(oppositeSide, rfOut, false); usedAmperes++; diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java index d8231ee544..9e6b4c57c0 100644 --- a/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java +++ b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java @@ -22,7 +22,7 @@ import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.modularui.IAddInventorySlots; import gregtech.api.interfaces.modularui.IGetGUITextureSet; import gregtech.api.util.shutdown.ShutDownReason; -import gregtech.common.blocks.GT_Block_Machines; +import gregtech.common.blocks.BlockMachines; /** * A simple compound Interface for all my TileEntities. @@ -186,7 +186,7 @@ public interface IGregTechTileEntity extends ITexturedTileEntity, IGearEnergyTil /** * A randomly called display update to be able to add particles or other items for display The event is proxied by - * the {@link GT_Block_Machines#randomDisplayTick} + * the {@link BlockMachines#randomDisplayTick} */ @SideOnly(Side.CLIENT) default void onRandomDisplayTick() { diff --git a/src/main/java/gregtech/api/items/BlockLongDistancePipe.java b/src/main/java/gregtech/api/items/BlockLongDistancePipe.java new file mode 100644 index 0000000000..3de95981f5 --- /dev/null +++ b/src/main/java/gregtech/api/items/BlockLongDistancePipe.java @@ -0,0 +1,125 @@ +package gregtech.api.items; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.StatCollector; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.util.GTLanguageManager; +import gregtech.common.blocks.ItemLongDistancePipe; +import gregtech.common.blocks.MaterialMachines; + +public class BlockLongDistancePipe extends GTGenericBlock { + + public IIconContainer[] mIcons; + + public BlockLongDistancePipe() { + super(ItemLongDistancePipe.class, "gt.block.longdistancepipe", new MaterialMachines()); + setStepSound(soundTypeMetal); + setCreativeTab(GregTechAPI.TAB_GREGTECH); + GregTechAPI.registerMachineBlock(this, -1); + + GTLanguageManager.addStringLocalization(getUnlocalizedName() + ".0.name", "Long Distance Fluid Pipeline Pipe"); + GTLanguageManager.addStringLocalization(getUnlocalizedName() + ".1.name", "Long Distance Item Pipeline Pipe"); + GTLanguageManager.addStringLocalization(getUnlocalizedName() + "." + 32767 + ".name", "Any Sub Block of this"); + + ItemList.Long_Distance_Pipeline_Fluid_Pipe.set(new ItemStack(this, 1, 0)); + ItemList.Long_Distance_Pipeline_Item_Pipe.set(new ItemStack(this, 1, 1)); + mIcons = new IIconContainer[] { Textures.BlockIcons.LONG_DISTANCE_PIPE_FLUID, + Textures.BlockIcons.LONG_DISTANCE_PIPE_ITEM }; + } + + @Override + public void onBlockAdded(World aWorld, int aX, int aY, int aZ) { + super.onBlockAdded(aWorld, aX, aY, aZ); + if (GregTechAPI.isMachineBlock(this, aWorld.getBlockMetadata(aX, aY, aZ))) { + GregTechAPI.causeMachineUpdate(aWorld, aX, aY, aZ); + } + } + + @Override + public void breakBlock(World aWorld, int aX, int aY, int aZ, Block aBlock, int aMetaData) { + GregTechAPI.causeMachineUpdate(aWorld, aX, aY, aZ); + super.breakBlock(aWorld, aX, aY, aZ, aBlock, aMetaData); + } + + @Override + public String getHarvestTool(int aMeta) { + return "wrench"; + } + + @Override + public int getHarvestLevel(int aMeta) { + return 2; + } + + @Override + public float getBlockHardness(World aWorld, int aX, int aY, int aZ) { + return Blocks.stone.getBlockHardness(aWorld, aX, aY, aZ); + } + + @Override + public float getExplosionResistance(Entity aTNT) { + return Blocks.iron_block.getExplosionResistance(aTNT); + } + + @Override + public String getUnlocalizedName() { + return this.mUnlocalizedName; + } + + @Override + public String getLocalizedName() { + return StatCollector.translateToLocal(this.mUnlocalizedName + ".name"); + } + + @Override + public IIcon getIcon(int ordinalSide, int aMeta) { + return mIcons[aMeta % mIcons.length].getIcon(); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister aIconRegister) {} + + @Override + public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z) { + return false; + } + + @Override + public int damageDropped(int metadata) { + return metadata; + } + + @Override + public int getDamageValue(World aWorld, int aX, int aY, int aZ) { + return aWorld.getBlockMetadata(aX, aY, aZ); + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item aItem, CreativeTabs aCreativeTab, List aList) { + for (int i = 0; i < 3; i++) { + ItemStack aStack = new ItemStack(aItem, 1, i); + if (!aStack.getDisplayName() + .contains(".name")) aList.add(aStack); + } + } +} diff --git a/src/main/java/gregtech/api/items/GTGenericBlock.java b/src/main/java/gregtech/api/items/GTGenericBlock.java new file mode 100644 index 0000000000..314849e8cf --- /dev/null +++ b/src/main/java/gregtech/api/items/GTGenericBlock.java @@ -0,0 +1,22 @@ +package gregtech.api.items; + +import static gregtech.api.enums.GTValues.W; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.item.ItemBlock; + +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.util.GTLanguageManager; + +public class GTGenericBlock extends Block { + + protected final String mUnlocalizedName; + + protected GTGenericBlock(Class aItemClass, String aName, Material aMaterial) { + super(aMaterial); + setBlockName(mUnlocalizedName = aName); + GameRegistry.registerBlock(this, aItemClass, getUnlocalizedName()); + GTLanguageManager.addStringLocalization(getUnlocalizedName() + "." + W + ".name", "Any Sub Block of this one"); + } +} diff --git a/src/main/java/gregtech/api/items/GTGenericItem.java b/src/main/java/gregtech/api/items/GTGenericItem.java new file mode 100644 index 0000000000..4f0994bb12 --- /dev/null +++ b/src/main/java/gregtech/api/items/GTGenericItem.java @@ -0,0 +1,162 @@ +package gregtech.api.items; + +import static gregtech.api.enums.Mods.GregTech; + +import java.util.List; + +import net.minecraft.block.BlockDispenser; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.dispenser.BehaviorDefaultDispenseItem; +import net.minecraft.dispenser.BehaviorProjectileDispense; +import net.minecraft.dispenser.IBlockSource; +import net.minecraft.dispenser.IPosition; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IProjectile; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.SubTag; +import gregtech.api.interfaces.IProjectileItem; +import gregtech.api.util.GTConfig; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; + +/** + * Extended by most Items, also used as a fallback Item, to prevent the accidental deletion when Errors occur. + */ +public class GTGenericItem extends Item implements IProjectileItem { + + private final String mName, mTooltip; + protected IIcon mIcon; + + public GTGenericItem(String aUnlocalized, String aEnglish, String aEnglishTooltip) { + super(); + mName = "gt." + aUnlocalized; + GTLanguageManager.addStringLocalization(mName + ".name", aEnglish); + if (GTUtility.isStringValid(aEnglishTooltip)) + GTLanguageManager.addStringLocalization(mTooltip = mName + ".tooltip_main", aEnglishTooltip); + else mTooltip = null; + setCreativeTab(GregTechAPI.TAB_GREGTECH); + GameRegistry.registerItem(this, mName, GregTech.ID); + BlockDispenser.dispenseBehaviorRegistry.putObject(this, new GT_Item_Dispense()); + } + + @Override + public final Item setUnlocalizedName(String aName) { + return this; + } + + @Override + public final String getUnlocalizedName() { + return mName; + } + + @Override + public String getUnlocalizedName(ItemStack aStack) { + return getHasSubtypes() ? mName + "." + getDamage(aStack) : mName; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister aIconRegister) { + mIcon = aIconRegister.registerIcon(GregTech.getResourcePath(GTConfig.troll ? "troll" : mName)); + } + + @Override + public boolean doesSneakBypassUse(World aWorld, int aX, int aY, int aZ, EntityPlayer aPlayer) { + return true; + } + + @Override + public IIcon getIconFromDamage(int aMetaData) { + return mIcon; + } + + public int getTier(ItemStack aStack) { + return 0; + } + + @Override + public void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { + if (getMaxDamage() > 0 && !getHasSubtypes()) + aList.add((aStack.getMaxDamage() - getDamage(aStack)) + " / " + aStack.getMaxDamage()); + if (mTooltip != null) aList.add(GTLanguageManager.getTranslation(mTooltip)); + if (GTModHandler.isElectricItem(aStack)) aList.add("Tier: " + getTier(aStack)); + addAdditionalToolTips(aList, aStack, aPlayer); + } + + protected void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { + // + } + + @Override + public void onCreated(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + isItemStackUsable(aStack); + } + + public boolean isItemStackUsable(ItemStack aStack) { + return true; + } + + public ItemStack onDispense(IBlockSource aSource, ItemStack aStack) { + EnumFacing enumfacing = BlockDispenser.func_149937_b(aSource.getBlockMetadata()); + IPosition iposition = BlockDispenser.func_149939_a(aSource); + ItemStack itemstack1 = aStack.splitStack(1); + BehaviorDefaultDispenseItem.doDispense(aSource.getWorld(), itemstack1, 6, enumfacing, iposition); + return aStack; + } + + @Override + public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY, + double aZ) { + return null; + } + + @Override + public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, EntityLivingBase aEntity, + float aSpeed) { + return null; + } + + @Override + public boolean hasProjectile(SubTag aProjectileType, ItemStack aStack) { + return false; + } + + @Override + public ItemStack getContainerItem(ItemStack aStack) { + return null; + } + + @Override + public boolean hasContainerItem(ItemStack aStack) { + return getContainerItem(aStack) != null; + } + + public String transItem(String aKey, String aEnglish) { + return GTLanguageManager.addStringLocalization("Item_DESCRIPTION_Index_" + aKey, aEnglish); + } + + public static class GT_Item_Dispense extends BehaviorProjectileDispense { + + @Override + public ItemStack dispenseStack(IBlockSource aSource, ItemStack aStack) { + return ((GTGenericItem) aStack.getItem()).onDispense(aSource, aStack); + } + + @Override + protected IProjectile getProjectileEntity(World aWorld, IPosition aPosition) { + return null; + } + } +} diff --git a/src/main/java/gregtech/api/items/GT_Block_LongDistancePipe.java b/src/main/java/gregtech/api/items/GT_Block_LongDistancePipe.java deleted file mode 100644 index 31a44f3dbc..0000000000 --- a/src/main/java/gregtech/api/items/GT_Block_LongDistancePipe.java +++ /dev/null @@ -1,125 +0,0 @@ -package gregtech.api.items; - -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.StatCollector; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.util.GT_LanguageManager; -import gregtech.common.blocks.GT_Item_LongDistancePipe; -import gregtech.common.blocks.GT_Material_Machines; - -public class GT_Block_LongDistancePipe extends GT_Generic_Block { - - public IIconContainer[] mIcons; - - public GT_Block_LongDistancePipe() { - super(GT_Item_LongDistancePipe.class, "gt.block.longdistancepipe", new GT_Material_Machines()); - setStepSound(soundTypeMetal); - setCreativeTab(GregTech_API.TAB_GREGTECH); - GregTech_API.registerMachineBlock(this, -1); - - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + ".0.name", "Long Distance Fluid Pipeline Pipe"); - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + ".1.name", "Long Distance Item Pipeline Pipe"); - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + "." + 32767 + ".name", "Any Sub Block of this"); - - ItemList.Long_Distance_Pipeline_Fluid_Pipe.set(new ItemStack(this, 1, 0)); - ItemList.Long_Distance_Pipeline_Item_Pipe.set(new ItemStack(this, 1, 1)); - mIcons = new IIconContainer[] { Textures.BlockIcons.LONG_DISTANCE_PIPE_FLUID, - Textures.BlockIcons.LONG_DISTANCE_PIPE_ITEM }; - } - - @Override - public void onBlockAdded(World aWorld, int aX, int aY, int aZ) { - super.onBlockAdded(aWorld, aX, aY, aZ); - if (GregTech_API.isMachineBlock(this, aWorld.getBlockMetadata(aX, aY, aZ))) { - GregTech_API.causeMachineUpdate(aWorld, aX, aY, aZ); - } - } - - @Override - public void breakBlock(World aWorld, int aX, int aY, int aZ, Block aBlock, int aMetaData) { - GregTech_API.causeMachineUpdate(aWorld, aX, aY, aZ); - super.breakBlock(aWorld, aX, aY, aZ, aBlock, aMetaData); - } - - @Override - public String getHarvestTool(int aMeta) { - return "wrench"; - } - - @Override - public int getHarvestLevel(int aMeta) { - return 2; - } - - @Override - public float getBlockHardness(World aWorld, int aX, int aY, int aZ) { - return Blocks.stone.getBlockHardness(aWorld, aX, aY, aZ); - } - - @Override - public float getExplosionResistance(Entity aTNT) { - return Blocks.iron_block.getExplosionResistance(aTNT); - } - - @Override - public String getUnlocalizedName() { - return this.mUnlocalizedName; - } - - @Override - public String getLocalizedName() { - return StatCollector.translateToLocal(this.mUnlocalizedName + ".name"); - } - - @Override - public IIcon getIcon(int ordinalSide, int aMeta) { - return mIcons[aMeta % mIcons.length].getIcon(); - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister aIconRegister) {} - - @Override - public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z) { - return false; - } - - @Override - public int damageDropped(int metadata) { - return metadata; - } - - @Override - public int getDamageValue(World aWorld, int aX, int aY, int aZ) { - return aWorld.getBlockMetadata(aX, aY, aZ); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubBlocks(Item aItem, CreativeTabs aCreativeTab, List aList) { - for (int i = 0; i < 3; i++) { - ItemStack aStack = new ItemStack(aItem, 1, i); - if (!aStack.getDisplayName() - .contains(".name")) aList.add(aStack); - } - } -} diff --git a/src/main/java/gregtech/api/items/GT_BreederCell_Item.java b/src/main/java/gregtech/api/items/GT_BreederCell_Item.java deleted file mode 100644 index 438b0f467e..0000000000 --- a/src/main/java/gregtech/api/items/GT_BreederCell_Item.java +++ /dev/null @@ -1,153 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.util.GT_Utility.formatNumbers; - -import java.util.List; -import java.util.function.Supplier; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.world.World; - -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; -import gregtech.api.recipe.RecipeMaps; -import gregtech.api.util.GT_Utility; -import ic2.api.reactor.IReactor; -import ic2.api.reactor.IReactorComponent; -import ic2.core.IC2Potion; - -/** - * A {@link ic2.core.item.reactor.ItemReactorLithiumCell}, but can be used to produce anything! - * - * @author glee8e - */ -public class GT_BreederCell_Item extends GT_Generic_Item implements IReactorComponent { - - protected final int mHeatBonusStep; - protected final int mHeatBonusMultiplier; - protected ItemStack mProduct; - protected boolean deflector = false; - protected boolean hidden = false; - protected boolean neiAdded = false; - - public GT_BreederCell_Item(String aUnlocalized, String aEnglish, String aEnglishTooltip, int aHeatBonusStep, - int aHeatBonusMultiplier, int aRequiredPulse, Supplier aProduct) { - super(aUnlocalized, aEnglish, aEnglishTooltip); - this.mHeatBonusStep = aHeatBonusStep; - this.mHeatBonusMultiplier = aHeatBonusMultiplier; - this.setMaxDamage(aRequiredPulse); - setNoRepair(); - GregTech_API.sAfterGTPostload.add(() -> { - mProduct = aProduct.get(); - if (!hidden && !neiAdded) { - GT_Values.RA.stdBuilder() - .itemInputs(new ItemStack(this)) - .itemOutputs(mProduct) - .setNEIDesc( - deflector ? "Neutron reflecting Breeder" : "Heat neutral Breeder", - String.format("Every %d reactor hull heat", mHeatBonusStep), - String.format("increase speed by %d00%%", mHeatBonusMultiplier), - String.format("Required pulses: %d", getMaxDamage())) - .duration(0) - .eut(0) - .addTo(RecipeMaps.ic2NuclearFakeRecipes); - - neiAdded = true; - } - }); - } - - public GT_BreederCell_Item setDeflector() { - deflector = true; - return this; - } - - public GT_BreederCell_Item setHidden() { - hidden = true; - return this; - } - - @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slotIndex, boolean isCurrentItem) { - if ((entity instanceof EntityLivingBase entityLiving)) { - if (!GT_Utility.isWearingFullRadioHazmat(entityLiving)) { - IC2Potion.radiation.applyTo(entityLiving, 20, 1); - } - } - } - - @Override - public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { - aList.add(transItem("019", "Bath with neutron in a hot reactor")); - int rDmg = aStack.getItemDamage() * 4 / getMaxDamage(); - EnumChatFormatting color2 = switch (rDmg) { - case 0 -> EnumChatFormatting.DARK_GRAY; - case 1, 2 -> EnumChatFormatting.GRAY; - default -> EnumChatFormatting.WHITE; - }; - aList.add( - String.format( - transItem("020", "Progress: %s/%s"), - "" + color2 + formatNumbers(aStack.getItemDamage()) + EnumChatFormatting.RESET, - "" + formatNumbers(getMaxDamage()))); - if (aStack.getItemDamage() > 0) aList.add(EnumChatFormatting.RED + transItem("021", "Radiation Hazard")); - } - - @Override - public int getItemStackLimit(ItemStack stack) { - return stack.getItemDamage() == 0 ? maxStackSize : 1; - } - - @Override - public void processChamber(IReactor reactor, ItemStack yourStack, int x, int y, boolean heatrun) {} - - @Override - public boolean acceptUraniumPulse(IReactor reactor, ItemStack yourStack, ItemStack pulsingStack, int youX, int youY, - int pulseX, int pulseY, boolean heatrun) { - if (heatrun) { - int myLevel = getNewDamage(reactor, yourStack); - if (myLevel >= getMaxDamage()) reactor.setItemAt(youX, youY, mProduct.copy()); - else yourStack.setItemDamage(myLevel); - } - - return deflector; - } - - protected int getNewDamage(IReactor reactor, ItemStack stack) { - return stack.getItemDamage() + 1 + reactor.getHeat() / mHeatBonusStep * mHeatBonusMultiplier; - } - - @Override - public boolean canStoreHeat(IReactor reactor, ItemStack yourStack, int x, int y) { - return false; - } - - @Override - public int getMaxHeat(IReactor reactor, ItemStack yourStack, int x, int y) { - return 0; - } - - @Override - public int getCurrentHeat(IReactor reactor, ItemStack yourStack, int x, int y) { - return 0; - } - - @Override - public int alterHeat(IReactor reactor, ItemStack yourStack, int x, int y, int heat) { - return heat; - } - - @Override - public float influenceExplosion(IReactor reactor, ItemStack yourStack) { - return 0.0F; - } - - @Override - public double getDurabilityForDisplay(ItemStack stack) { - return 1.0D - (double) stack.getItemDamageForDisplay() / (double) stack.getMaxDamage(); - } -} diff --git a/src/main/java/gregtech/api/items/GT_CoolantCellIC_Item.java b/src/main/java/gregtech/api/items/GT_CoolantCellIC_Item.java deleted file mode 100644 index eb3c6276cf..0000000000 --- a/src/main/java/gregtech/api/items/GT_CoolantCellIC_Item.java +++ /dev/null @@ -1,67 +0,0 @@ -package gregtech.api.items; - -import net.minecraft.item.ItemStack; - -import ic2.api.reactor.IReactor; -import ic2.api.reactor.IReactorComponent; - -public class GT_CoolantCellIC_Item extends GT_CoolantCell_Item implements IReactorComponent { - - public GT_CoolantCellIC_Item(String aUnlocalized, String aEnglish, int aMaxStore) { - super(aUnlocalized, aEnglish, aMaxStore); - } - - @Override - public void processChamber(IReactor aReactor, ItemStack aStack, int x, int y, boolean aHeatRun) {} - - @Override - public boolean acceptUraniumPulse(IReactor aReactor, ItemStack aStack, ItemStack pulsingStack, int youX, int youY, - int pulseX, int pulseY, boolean aHeatRun) { - return false; - } - - @Override - public boolean canStoreHeat(IReactor aReactor, ItemStack aStack, int x, int y) { - return !aReactor.isFluidCooled() || getControlTagOfStack(aStack) == 0; - } - - @Override - public int getMaxHeat(IReactor aReactor, ItemStack aStack, int x, int y) { - return this.heatStorage; - } - - @Override - public int getCurrentHeat(IReactor aReactor, ItemStack aStack, int x, int y) { - return getHeatOfStack(aStack); - } - - @Override - public float influenceExplosion(IReactor aReactor, ItemStack aStack) { - return 1.0F + this.heatStorage / 30000.0F; - } - - @Override - public int alterHeat(IReactor aReactor, ItemStack aStack, int x, int y, int aHeat) { - int tHeat = getHeatOfStack(aStack); - if ((tHeat == 0) && (getControlTagOfStack(aStack) != 0)) { - setControlTagOfStack(aStack, 0); - } - tHeat += aHeat; - if (tHeat > this.heatStorage) { - aReactor.setItemAt(x, y, null); - aHeat = this.heatStorage - tHeat + 1; - } else { - if (tHeat < 0) { - aHeat = tHeat; - tHeat = 0; - } else { - aHeat = 0; - } - if ((tHeat > 0) && (getControlTagOfStack(aStack) == 0) && (!aReactor.isFluidCooled())) { - setControlTagOfStack(aStack, 1); - } - setHeatForStack(aStack, tHeat); - } - return aHeat; - } -} diff --git a/src/main/java/gregtech/api/items/GT_CoolantCell_Item.java b/src/main/java/gregtech/api/items/GT_CoolantCell_Item.java deleted file mode 100644 index 6ed7dae3b0..0000000000 --- a/src/main/java/gregtech/api/items/GT_CoolantCell_Item.java +++ /dev/null @@ -1,82 +0,0 @@ -package gregtech.api.items; - -import java.util.List; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; - -import gregtech.api.GregTech_API; -import ic2.core.util.StackUtil; - -public class GT_CoolantCell_Item extends GT_Generic_Item { - - protected final int heatStorage; - - public GT_CoolantCell_Item(String aUnlocalized, String aEnglish, int aMaxStore) { - super(aUnlocalized, aEnglish, null); - this.setMaxStackSize(1); - this.setMaxDamage(100); - setNoRepair(); - this.heatStorage = aMaxStore; - this.setCreativeTab(GregTech_API.TAB_GREGTECH); - } - - protected static int getHeatOfStack(ItemStack aStack) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - aStack.setTagCompound(tNBT); - } - return tNBT.getInteger("heat"); - } - - protected void setHeatForStack(ItemStack aStack, int aHeat) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - aStack.setTagCompound(tNBT); - } - tNBT.setInteger("heat", aHeat); - if (this.heatStorage > 0) { - double heatRatio = (double) aHeat / (double) this.heatStorage; - int damage = (int) (aStack.getMaxDamage() * heatRatio); - if (damage >= aStack.getMaxDamage()) { - damage = aStack.getMaxDamage() - 1; - } - aStack.setItemDamage(damage); - } - } - - @Override - public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { - super.addAdditionalToolTips(aList, aStack, aPlayer); - int rHeat = getHeatOfStack(aStack) * 10 / this.heatStorage; - EnumChatFormatting color = switch (rHeat) { - case 0 -> EnumChatFormatting.BLUE; - case 1, 2 -> EnumChatFormatting.GREEN; - case 3, 4, 5, 6 -> EnumChatFormatting.YELLOW; - case 7, 8 -> EnumChatFormatting.RED; - default -> EnumChatFormatting.DARK_RED; - }; - aList.add( - EnumChatFormatting.WHITE - + String.format(transItem("000", "Stored Heat: %s"), "" + color + getHeatOfStack(aStack))); - if (getControlTagOfStack(aStack) == 1) { - aList.add(StatCollector.translateToLocal("ic2.reactoritem.heatwarning.line1")); - aList.add(StatCollector.translateToLocal("ic2.reactoritem.heatwarning.line2")); - } - } - - public int getControlTagOfStack(ItemStack stack) { - NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); - return nbtData.getInteger("tag"); - } - - public void setControlTagOfStack(ItemStack stack, int tag) { - NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); - nbtData.setInteger("tag", tag); - } -} diff --git a/src/main/java/gregtech/api/items/GT_EnergyArmor_Item.java b/src/main/java/gregtech/api/items/GT_EnergyArmor_Item.java deleted file mode 100644 index df820f928a..0000000000 --- a/src/main/java/gregtech/api/items/GT_EnergyArmor_Item.java +++ /dev/null @@ -1,332 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.Mods.GregTech; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemArmor; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; -import net.minecraftforge.common.ISpecialArmor; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.living.LivingFallEvent; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; - -public class GT_EnergyArmor_Item extends ItemArmor implements ISpecialArmor { - - public static Map jumpChargeMap = new ConcurrentHashMap<>(); - public int mCharge, mTransfer, mTier, mDamageEnergyCost, mSpecials; - public boolean mChargeProvider; - public double mArmorAbsorbtionPercentage; - - public GT_EnergyArmor_Item(int aID, String aUnlocalized, String aEnglish, int aCharge, int aTransfer, int aTier, - int aDamageEnergyCost, int aSpecials, double aArmorAbsorbtionPercentage, boolean aChargeProvider, int aType, - int aArmorIndex) { - super(ArmorMaterial.DIAMOND, aArmorIndex, aType); - setMaxStackSize(1); - setMaxDamage(100); - setNoRepair(); - setUnlocalizedName(aUnlocalized); - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + ".name", aEnglish); - mCharge = Math.max(1, aCharge); - mTransfer = Math.max(1, aTransfer); - mTier = Math.max(1, aTier); - mSpecials = aSpecials; - mChargeProvider = aChargeProvider; - mDamageEnergyCost = Math.max(0, aDamageEnergyCost); - mArmorAbsorbtionPercentage = aArmorAbsorbtionPercentage; - - setCreativeTab(GregTech_API.TAB_GREGTECH); - - MinecraftForge.EVENT_BUS.register(this); - } - - private static void setCharge(ItemStack aStack) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) tNBT = new NBTTagCompound(); - tNBT.setInteger("charge", 1000000000); - aStack.setTagCompound(tNBT); - } - - @Override - public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - ItemStack tStack = aPlayer.inventory.armorInventory[3 - armorType]; - if (tStack != null) { - for (int i = 0; i < 9; i++) { - if (aPlayer.inventory.mainInventory[i] == aStack) { - aPlayer.inventory.armorInventory[3 - armorType] = aPlayer.inventory.mainInventory[i]; - aPlayer.inventory.mainInventory[i] = tStack; - return tStack; - } - } - } - return super.onItemRightClick(aStack, aWorld, aPlayer); - } - - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister aIconRegister) { - this.itemIcon = aIconRegister.registerIcon(GregTech.getResourcePath(getUnlocalizedName())); - } - - @Override - public void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { - aList.add("Tier: " + mTier); - if ((mSpecials & 1) != 0) aList.add("Rebreather"); - if ((mSpecials & 2) != 0) aList.add("Inertia Damper"); - if ((mSpecials & 4) != 0) aList.add("Food Replicator"); - if ((mSpecials & 8) != 0) aList.add("Medicine Module"); - if ((mSpecials & 16) != 0) aList.add("Lamp"); - if ((mSpecials & 32) != 0) aList.add("Solarpanel"); - if ((mSpecials & 64) != 0) aList.add("Extinguisher Module"); - if ((mSpecials & 128) != 0) aList.add("Jump Booster"); - if ((mSpecials & 256) != 0) aList.add("Speed Booster"); - if ((mSpecials & 512) != 0) aList.add("Invisibility Field"); - if ((mSpecials & 1024) != 0) aList.add("Infinite Charge"); - } - - @Override - public void onArmorTick(World aWorld, EntityPlayer aPlayer, ItemStack aStack) { - if (mSpecials == 0) return; - - if (!aPlayer.worldObj.isRemote && (mSpecials & 1) != 0) { - int airSupply = aPlayer.getAir(); - if (GT_ModHandler.canUseElectricItem(aStack, 1000) && airSupply < 50) { - aPlayer.setAir(airSupply + 250); - GT_ModHandler.useElectricItem(aStack, 1000, aPlayer); - } - } - - if (!aPlayer.worldObj.isRemote && (mSpecials & 4) != 0) { - if (GT_ModHandler.canUseElectricItem(aStack, 50000) && aPlayer.getFoodStats() - .needFood()) { - aPlayer.getFoodStats() - .addStats(1, 0.0F); - GT_ModHandler.useElectricItem(aStack, 50000, aPlayer); - } - } - - if ((mSpecials & 8) != 0) { - if (GT_ModHandler.canUseElectricItem(aStack, 10000) && aPlayer.isPotionActive(Potion.poison)) { - GT_Utility.removePotion(aPlayer, Potion.poison.id); - GT_ModHandler.useElectricItem(aStack, 10000, aPlayer); - } - if (GT_ModHandler.canUseElectricItem(aStack, 100000) && aPlayer.isPotionActive(Potion.wither)) { - GT_Utility.removePotion(aPlayer, Potion.wither.id); - GT_ModHandler.useElectricItem(aStack, 100000, aPlayer); - } - } - - if ((mSpecials & 64) != 0) { - aPlayer.setFire(0); - } - - if (!aPlayer.worldObj.isRemote && (mSpecials & 128) != 0) { - float jumpCharge = jumpChargeMap.getOrDefault(aPlayer, 1.0F); - - if (GT_ModHandler.canUseElectricItem(aStack, 1000) && aPlayer.onGround && jumpCharge < 1.0F) { - jumpCharge = 1.0F; - GT_ModHandler.useElectricItem(aStack, 1000, aPlayer); - } - - if (aPlayer.motionY >= 0.0D && jumpCharge > 0.0F && !aPlayer.isInWater()) { - if (jumpCharge < 1.0F) { - jumpCharge = 0.0F; - } - } - - jumpChargeMap.put(aPlayer, jumpCharge); - } - - if ((mSpecials & 256) != 0) { - if (GT_ModHandler.canUseElectricItem(aStack, 100) && aPlayer.isSprinting() - && (aPlayer.onGround && Math.abs(aPlayer.motionX) + Math.abs(aPlayer.motionZ) > 0.10000000149011612D - || aPlayer.isInWater())) { - GT_ModHandler.useElectricItem(aStack, 100, aPlayer); - float bonus = 0.22F; - - if (aPlayer.isInWater()) { - GT_ModHandler.useElectricItem(aStack, 100, aPlayer); - bonus = 0.1F; - - if (aPlayer.motionY > 0) { - aPlayer.motionY += 0.10000000149011612D; - } - } - - aPlayer.moveFlying(0.0F, 1.0F, bonus); - } - } - - if ((mSpecials & 512) != 0) { - if (GT_ModHandler.canUseElectricItem(aStack, 10000)) { - GT_ModHandler.useElectricItem(aStack, 10000, aPlayer); - aPlayer.addPotionEffect(new PotionEffect(Potion.invisibility.getId(), 25, 1, true)); - } - } - - if (!aPlayer.worldObj.isRemote && (mSpecials & (16 | 32)) != 0) { - // if (GregTech_API.sWorldTickCounter%20==0) { - ItemStack tTargetChargeItem = aStack, tTargetDechargeItem = aStack; - - if (GT_ModHandler.chargeElectricItem(tTargetChargeItem, 1, Integer.MAX_VALUE, true, true) < 1) { - tTargetChargeItem = aPlayer.inventory.armorInventory[2]; - } - if (GT_ModHandler.dischargeElectricItem(tTargetDechargeItem, 10, Integer.MAX_VALUE, true, true, true) - < 10) { - tTargetDechargeItem = aPlayer.inventory.armorInventory[2]; - } - - if (tTargetChargeItem == null || !GT_ModHandler.isElectricItem(tTargetChargeItem)) { - tTargetChargeItem = null; - } - - if (aPlayer.worldObj.isDaytime() && aPlayer.worldObj.canBlockSeeTheSky( - MathHelper.floor_double(aPlayer.posX), - MathHelper.floor_double(aPlayer.posY + 1), - MathHelper.floor_double(aPlayer.posZ))) { - if ((mSpecials & 32) != 0 && tTargetChargeItem != null) { - GT_ModHandler.chargeElectricItem(tTargetChargeItem, 20, Integer.MAX_VALUE, true, false); - } - } else { - /* - * TODO: if ((mSpecials & 16) != 0 && tTargetDechargeItem != null && - * GT_ModHandler.canUseElectricItem(tTargetDechargeItem, 10)) { if (aPlayer.worldObj.getBlock - * ((int)aPlayer.posX, (int)aPlayer.posY+1, (int)aPlayer.posZ) == Blocks.air) aPlayer.worldObj.setBlock - * ((int)aPlayer.posX, (int)aPlayer.posY+1, (int)aPlayer.posZ, GregTech_API.sBlockList[3]); - * GT_ModHandler.useElectricItem(tTargetDechargeItem, 10, aPlayer); } - */ - // } - } - } - } - - @Override - public boolean getShareTag() { - return true; - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item aItem, CreativeTabs creativeTab, List outputSubItems) { - ItemStack tCharged = new ItemStack(this, 1), tUncharged = new ItemStack(this, 1, getMaxDamage()); - GT_ModHandler.chargeElectricItem(tCharged, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false); - outputSubItems.add(tCharged); - outputSubItems.add(tUncharged); - } - - public boolean canProvideEnergy(ItemStack aStack) { - if ((mSpecials & 1024) != 0) setCharge(aStack); - return mChargeProvider; - } - - public Item getChargedItem(ItemStack aStack) { - if ((mSpecials & 1024) != 0) setCharge(aStack); - return this; - } - - public Item getEmptyItem(ItemStack aStack) { - if ((mSpecials & 1024) != 0) setCharge(aStack); - return this; - } - - public int getMaxCharge(ItemStack aStack) { - if ((mSpecials & 1024) != 0) setCharge(aStack); - return mCharge; - } - - public int getTier(ItemStack aStack) { - if ((mSpecials & 1024) != 0) setCharge(aStack); - return mTier; - } - - public int getTransferLimit(ItemStack aStack) { - if ((mSpecials & 1024) != 0) setCharge(aStack); - return mTransfer; - } - - @Override - public int getItemEnchantability() { - return 0; - } - - @Override - public boolean isBookEnchantable(ItemStack ingredient, ItemStack bookEnchant) { - return false; - } - - @Override - public boolean getIsRepairable(ItemStack toBeRepaired, ItemStack repairWith) { - return false; - } - - // TODO: @ForgeSubscribe - public void onEntityLivingFallEvent(LivingFallEvent event) { - if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer player) { - for (int i = 0; i < 4; i++) { - ItemStack armor = player.inventory.armorInventory[i]; - if (armor != null && armor.getItem() == this && (mSpecials & 2) != 0) { - int distanceFactor = (int) event.distance - 3; - int energyCost = (this.mDamageEnergyCost * distanceFactor) / 4; - if (energyCost <= GT_ModHandler - .dischargeElectricItem(armor, Integer.MAX_VALUE, Integer.MAX_VALUE, true, true, true)) { - GT_ModHandler.dischargeElectricItem(armor, energyCost, Integer.MAX_VALUE, true, false, true); - event.setCanceled(true); - break; - } - } - } - } - } - - @Override - public ISpecialArmor.ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, - double damage, int slotIndex) { - return new ISpecialArmor.ArmorProperties( - (source == DamageSource.fall && (mSpecials & 2) != 0) ? 10 : 0, - getBaseAbsorptionRatio() * mArmorAbsorbtionPercentage, - mDamageEnergyCost > 0 ? 25 - * GT_ModHandler.dischargeElectricItem(armor, Integer.MAX_VALUE, Integer.MAX_VALUE, true, true, true) - / mDamageEnergyCost : 0); - } - - @Override - public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slotIndex) { - return (int) Math.round(20.0D * getBaseAbsorptionRatio() * mArmorAbsorbtionPercentage); - } - - @Override - public void damageArmor(EntityLivingBase entity, ItemStack itemStack, DamageSource source, int damage, - int slotIndex) { - GT_ModHandler - .dischargeElectricItem(itemStack, damage * mDamageEnergyCost, Integer.MAX_VALUE, true, false, true); - } - - private double getBaseAbsorptionRatio() { - if (mArmorAbsorbtionPercentage <= 0) return 0.00; - return switch (this.armorType) { - case 0, 3 -> 0.15; - case 1 -> 0.40; - case 2 -> 0.30; - default -> 0.00; - }; - } -} diff --git a/src/main/java/gregtech/api/items/GT_Generic_Block.java b/src/main/java/gregtech/api/items/GT_Generic_Block.java deleted file mode 100644 index 7aaef6d5ca..0000000000 --- a/src/main/java/gregtech/api/items/GT_Generic_Block.java +++ /dev/null @@ -1,22 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.GT_Values.W; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.item.ItemBlock; - -import cpw.mods.fml.common.registry.GameRegistry; -import gregtech.api.util.GT_LanguageManager; - -public class GT_Generic_Block extends Block { - - protected final String mUnlocalizedName; - - protected GT_Generic_Block(Class aItemClass, String aName, Material aMaterial) { - super(aMaterial); - setBlockName(mUnlocalizedName = aName); - GameRegistry.registerBlock(this, aItemClass, getUnlocalizedName()); - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + "." + W + ".name", "Any Sub Block of this one"); - } -} diff --git a/src/main/java/gregtech/api/items/GT_Generic_Item.java b/src/main/java/gregtech/api/items/GT_Generic_Item.java deleted file mode 100644 index 3fe2083a96..0000000000 --- a/src/main/java/gregtech/api/items/GT_Generic_Item.java +++ /dev/null @@ -1,162 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.Mods.GregTech; - -import java.util.List; - -import net.minecraft.block.BlockDispenser; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.dispenser.BehaviorDefaultDispenseItem; -import net.minecraft.dispenser.BehaviorProjectileDispense; -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.dispenser.IPosition; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.IProjectile; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; - -import cpw.mods.fml.common.registry.GameRegistry; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.enums.SubTag; -import gregtech.api.interfaces.IProjectileItem; -import gregtech.api.util.GT_Config; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; - -/** - * Extended by most Items, also used as a fallback Item, to prevent the accidental deletion when Errors occur. - */ -public class GT_Generic_Item extends Item implements IProjectileItem { - - private final String mName, mTooltip; - protected IIcon mIcon; - - public GT_Generic_Item(String aUnlocalized, String aEnglish, String aEnglishTooltip) { - super(); - mName = "gt." + aUnlocalized; - GT_LanguageManager.addStringLocalization(mName + ".name", aEnglish); - if (GT_Utility.isStringValid(aEnglishTooltip)) - GT_LanguageManager.addStringLocalization(mTooltip = mName + ".tooltip_main", aEnglishTooltip); - else mTooltip = null; - setCreativeTab(GregTech_API.TAB_GREGTECH); - GameRegistry.registerItem(this, mName, GregTech.ID); - BlockDispenser.dispenseBehaviorRegistry.putObject(this, new GT_Item_Dispense()); - } - - @Override - public final Item setUnlocalizedName(String aName) { - return this; - } - - @Override - public final String getUnlocalizedName() { - return mName; - } - - @Override - public String getUnlocalizedName(ItemStack aStack) { - return getHasSubtypes() ? mName + "." + getDamage(aStack) : mName; - } - - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister aIconRegister) { - mIcon = aIconRegister.registerIcon(GregTech.getResourcePath(GT_Config.troll ? "troll" : mName)); - } - - @Override - public boolean doesSneakBypassUse(World aWorld, int aX, int aY, int aZ, EntityPlayer aPlayer) { - return true; - } - - @Override - public IIcon getIconFromDamage(int aMetaData) { - return mIcon; - } - - public int getTier(ItemStack aStack) { - return 0; - } - - @Override - public void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { - if (getMaxDamage() > 0 && !getHasSubtypes()) - aList.add((aStack.getMaxDamage() - getDamage(aStack)) + " / " + aStack.getMaxDamage()); - if (mTooltip != null) aList.add(GT_LanguageManager.getTranslation(mTooltip)); - if (GT_ModHandler.isElectricItem(aStack)) aList.add("Tier: " + getTier(aStack)); - addAdditionalToolTips(aList, aStack, aPlayer); - } - - protected void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { - // - } - - @Override - public void onCreated(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - isItemStackUsable(aStack); - } - - public boolean isItemStackUsable(ItemStack aStack) { - return true; - } - - public ItemStack onDispense(IBlockSource aSource, ItemStack aStack) { - EnumFacing enumfacing = BlockDispenser.func_149937_b(aSource.getBlockMetadata()); - IPosition iposition = BlockDispenser.func_149939_a(aSource); - ItemStack itemstack1 = aStack.splitStack(1); - BehaviorDefaultDispenseItem.doDispense(aSource.getWorld(), itemstack1, 6, enumfacing, iposition); - return aStack; - } - - @Override - public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY, - double aZ) { - return null; - } - - @Override - public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, EntityLivingBase aEntity, - float aSpeed) { - return null; - } - - @Override - public boolean hasProjectile(SubTag aProjectileType, ItemStack aStack) { - return false; - } - - @Override - public ItemStack getContainerItem(ItemStack aStack) { - return null; - } - - @Override - public boolean hasContainerItem(ItemStack aStack) { - return getContainerItem(aStack) != null; - } - - public String transItem(String aKey, String aEnglish) { - return GT_LanguageManager.addStringLocalization("Item_DESCRIPTION_Index_" + aKey, aEnglish); - } - - public static class GT_Item_Dispense extends BehaviorProjectileDispense { - - @Override - public ItemStack dispenseStack(IBlockSource aSource, ItemStack aStack) { - return ((GT_Generic_Item) aStack.getItem()).onDispense(aSource, aStack); - } - - @Override - protected IProjectile getProjectileEntity(World aWorld, IPosition aPosition) { - return null; - } - } -} diff --git a/src/main/java/gregtech/api/items/GT_MetaBase_Item.java b/src/main/java/gregtech/api/items/GT_MetaBase_Item.java deleted file mode 100644 index 481c0b5a08..0000000000 --- a/src/main/java/gregtech/api/items/GT_MetaBase_Item.java +++ /dev/null @@ -1,622 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.GT_Values.D1; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.util.GT_Utility.formatNumbers; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.inventory.Container; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidContainerItem; - -import gregtech.api.enums.SubTag; -import gregtech.api.interfaces.IItemBehaviour; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; -import ic2.api.item.ElectricItem; -import ic2.api.item.IElectricItem; -import ic2.api.item.IElectricItemManager; -import ic2.api.item.ISpecialElectricItem; - -public abstract class GT_MetaBase_Item extends GT_Generic_Item - implements ISpecialElectricItem, IElectricItemManager, IFluidContainerItem { - - /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */ - private final ConcurrentHashMap>> mItemBehaviors = new ConcurrentHashMap<>(); - - /** - * Creates the Item using these Parameters. - * - * @param aUnlocalized The Unlocalized Name of this Item. - */ - public GT_MetaBase_Item(String aUnlocalized) { - super(aUnlocalized, "Generated Item", null); - setHasSubtypes(true); - setMaxDamage(0); - } - - /** - * Adds a special Item Behaviour to the Item. - *

- * Note: the boolean Behaviours sometimes won't be executed if another boolean Behaviour returned true before. - * - * @param aMetaValue the Meta Value of the Item you want to add it to. [0 - 32765] - * @param aBehavior the Click Behavior you want to add. - * @return the Item itself for convenience in constructing. - */ - public final GT_MetaBase_Item addItemBehavior(int aMetaValue, IItemBehaviour aBehavior) { - if (aMetaValue < 0 || aMetaValue >= 32766 || aBehavior == null) return this; - ArrayList> tList = mItemBehaviors - .computeIfAbsent((short) aMetaValue, k -> new ArrayList<>(1)); - tList.add(aBehavior); - return this; - } - - public abstract Long[] getElectricStats(ItemStack aStack); - - public abstract Long[] getFluidContainerStats(ItemStack aStack); - - @Override - public boolean hasProjectile(SubTag aProjectileType, ItemStack aStack) { - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) - if (tBehavior.hasProjectile(this, aProjectileType, aStack)) return true; - return super.hasProjectile(aProjectileType, aStack); - } - - @Override - public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY, - double aZ) { - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) { - EntityArrow rArrow = tBehavior.getProjectile(this, aProjectileType, aStack, aWorld, aX, aY, aZ); - if (rArrow != null) return rArrow; - } - return super.getProjectile(aProjectileType, aStack, aWorld, aX, aY, aZ); - } - - @Override - public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, EntityLivingBase aEntity, - float aSpeed) { - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) { - EntityArrow rArrow = tBehavior.getProjectile(this, aProjectileType, aStack, aWorld, aEntity, aSpeed); - if (rArrow != null) return rArrow; - } - return super.getProjectile(aProjectileType, aStack, aWorld, aEntity, aSpeed); - } - - @Override - public ItemStack onDispense(IBlockSource aSource, ItemStack aStack) { - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) - if (tBehavior.canDispense(this, aSource, aStack)) return tBehavior.onDispense(this, aSource, aStack); - return super.onDispense(aSource, aStack); - } - - @Override - public boolean isItemStackUsable(ItemStack aStack) { - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) - if (!tBehavior.isItemStackUsable(this, aStack)) return false; - return super.isItemStackUsable(aStack); - } - - @Override - public boolean onLeftClickEntity(ItemStack aStack, EntityPlayer aPlayer, Entity aEntity) { - use(aStack, 0, aPlayer); - isItemStackUsable(aStack); - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - try { - if (tList != null) for (IItemBehaviour tBehavior : tList) - if (tBehavior.onLeftClickEntity(this, aStack, aPlayer, aEntity)) { - if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); - return true; - } - if (aStack.stackSize <= 0) { - aPlayer.destroyCurrentEquippedItem(); - return false; - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return false; - } - - @Override - public boolean onItemUse(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, - int ordinalSide, float hitX, float hitY, float hitZ) { - use(aStack, 0, aPlayer); - isItemStackUsable(aStack); - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - try { - if (tList != null) for (IItemBehaviour tBehavior : tList) - if (tBehavior.onItemUse(this, aStack, aPlayer, aWorld, aX, aY, aZ, ordinalSide, hitX, hitY, hitZ)) { - if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); - return true; - } - if (aStack.stackSize <= 0) { - aPlayer.destroyCurrentEquippedItem(); - return false; - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return false; - } - - @Override - public boolean onItemUseFirst(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, - int ordinalSide, float hitX, float hitY, float hitZ) { - use(aStack, 0, aPlayer); - isItemStackUsable(aStack); - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - try { - if (tList != null) for (IItemBehaviour tBehavior : tList) if (tBehavior.onItemUseFirst( - this, - aStack, - aPlayer, - aWorld, - aX, - aY, - aZ, - ForgeDirection.getOrientation(ordinalSide), - hitX, - hitY, - hitZ)) { - if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); - return true; - } - if (aStack.stackSize <= 0) { - aPlayer.destroyCurrentEquippedItem(); - return false; - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return false; - } - - @Override - public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - use(aStack, 0, aPlayer); - isItemStackUsable(aStack); - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - try { - if (tList != null) for (IItemBehaviour tBehavior : tList) - aStack = tBehavior.onItemRightClick(this, aStack, aWorld, aPlayer); - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return aStack; - } - - @Override - public final void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { - String tKey = getUnlocalizedName(aStack) + ".tooltip"; - String[] tStrings = GT_LanguageManager.getTranslation(tKey) - .split("/n "); - for (String tString : tStrings) - if (GT_Utility.isStringValid(tString) && !tKey.equals(tString)) aList.add(tString); - - Long[] tStats = getElectricStats(aStack); - if (tStats != null) { - if (tStats[3] > 0) { - aList.add( - EnumChatFormatting.AQUA + String.format( - transItem("009", "Contains %s EU Tier: %s"), - formatNumbers(tStats[3]), - "" + (tStats[2] >= 0 ? tStats[2] : 0)) + EnumChatFormatting.GRAY); - } else { - long tCharge = getRealCharge(aStack); - if (tStats[3] == -2 && tCharge <= 0) { - aList.add( - EnumChatFormatting.AQUA + transItem("010", "Empty. You should recycle it properly.") - + EnumChatFormatting.GRAY); - } else { - aList.add( - EnumChatFormatting.AQUA - + String.format( - transItem("011", "%s / %s EU - Voltage: %s"), - formatNumbers(tCharge), - formatNumbers(Math.abs(tStats[0])), - "" + V[(int) (tStats[2] >= 0 ? tStats[2] < V.length ? tStats[2] : V.length - 1 : 1)]) - + EnumChatFormatting.GRAY); - } - } - } - - tStats = getFluidContainerStats(aStack); - if (tStats != null && tStats[0] > 0) { - FluidStack tFluid = getFluidContent(aStack); - aList.add( - EnumChatFormatting.BLUE + ((tFluid == null ? transItem("012", "No Fluids Contained") - : GT_Utility.getFluidName(tFluid, true))) + EnumChatFormatting.GRAY); - aList.add( - EnumChatFormatting.BLUE + String.format( - transItem("013", "%sL / %sL"), - "" + (tFluid == null ? 0 : formatNumbers(tFluid.amount)), - "" + formatNumbers(tStats[0])) + EnumChatFormatting.GRAY); - } - - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) - aList = tBehavior.getAdditionalToolTips(this, aList, aStack); - - addAdditionalToolTips(aList, aStack, aPlayer); - } - - @Override - public void onUpdate(ItemStack aStack, World aWorld, Entity aPlayer, int aTimer, boolean aIsInHand) { - ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); - if (tList != null) for (IItemBehaviour tBehavior : tList) - tBehavior.onUpdate(this, aStack, aWorld, aPlayer, aTimer, aIsInHand); - } - - @Override - public final boolean canProvideEnergy(ItemStack aStack) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null) return false; - return tStats[3] > 0 || (aStack.stackSize == 1 && (tStats[3] == -2 || tStats[3] == -3)); - } - - @Override - public final double getMaxCharge(ItemStack aStack) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null) return 0; - return Math.abs(tStats[0]); - } - - @Override - public final double getTransferLimit(ItemStack aStack) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null) return 0; - return Math.max(tStats[1], tStats[3]); - } - - @Override - public final double charge(ItemStack aStack, double aCharge, int aTier, boolean aIgnoreTransferLimit, - boolean aSimulate) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null || tStats[2] > aTier - || !(tStats[3] == -1 || tStats[3] == -3 || (tStats[3] < 0 && aCharge == Integer.MAX_VALUE)) - || aStack.stackSize != 1) return 0; - long tTransfer = aIgnoreTransferLimit ? (long) aCharge : Math.min(tStats[1], (long) aCharge); - long tChargeBefore = getRealCharge(aStack), tNewCharge = Math.min( - Math.abs(tStats[0]), - Long.MAX_VALUE - tTransfer >= tChargeBefore ? tChargeBefore + tTransfer : Long.MAX_VALUE); - if (!aSimulate) setCharge(aStack, tNewCharge); - return tNewCharge - tChargeBefore; - } - - @Override - public final double discharge(ItemStack aStack, double aCharge, int aTier, boolean aIgnoreTransferLimit, - boolean aBatteryAlike, boolean aSimulate) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null || tStats[2] > aTier) return 0; - if (aBatteryAlike && !canProvideEnergy(aStack)) return 0; - if (tStats[3] > 0) { - if (aCharge < tStats[3] || aStack.stackSize < 1) return 0; - if (!aSimulate) aStack.stackSize--; - return tStats[3]; - } - long tChargeBefore = getRealCharge(aStack), tNewCharge = Math - .max(0, tChargeBefore - (aIgnoreTransferLimit ? (long) aCharge : Math.min(tStats[1], (long) aCharge))); - if (!aSimulate) setCharge(aStack, tNewCharge); - return tChargeBefore - tNewCharge; - } - - @Override - public final double getCharge(ItemStack aStack) { - return getRealCharge(aStack); - } - - @Override - public final boolean canUse(ItemStack aStack, double aAmount) { - return getRealCharge(aStack) >= aAmount; - } - - @Override - public final boolean use(ItemStack aStack, double aAmount, EntityLivingBase aPlayer) { - chargeFromArmor(aStack, aPlayer); - if (aPlayer instanceof EntityPlayer && ((EntityPlayer) aPlayer).capabilities.isCreativeMode) return true; - double tTransfer = discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, true); - if (Math.abs(tTransfer - aAmount) < .0000001) { - discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, false); - chargeFromArmor(aStack, aPlayer); - return true; - } - discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, false); - chargeFromArmor(aStack, aPlayer); - return false; - } - - @Override - public final void chargeFromArmor(ItemStack aStack, EntityLivingBase aPlayer) { - if (aPlayer == null || aPlayer.worldObj.isRemote) return; - for (int i = 1; i < 5; i++) { - ItemStack tArmor = aPlayer.getEquipmentInSlot(i); - if (GT_ModHandler.isElectricItem(tArmor)) { - IElectricItem tArmorItem = (IElectricItem) tArmor.getItem(); - if (tArmorItem.canProvideEnergy(tArmor) && tArmorItem.getTier(tArmor) >= getTier(aStack)) { - double tCharge = ElectricItem.manager.discharge( - tArmor, - charge(aStack, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, true, true), - Integer.MAX_VALUE, - true, - true, - false); - if (tCharge > 0) { - charge(aStack, tCharge, Integer.MAX_VALUE, true, false); - if (aPlayer instanceof EntityPlayer) { - Container tContainer = ((EntityPlayer) aPlayer).openContainer; - if (tContainer != null) tContainer.detectAndSendChanges(); - } - } - } - } - } - } - - /* - * @Override public final int getMaxCharge(ItemStack aStack) { Long[] tStats = getElectricStats(aStack); if (tStats - * == null) return 0; return (int)Math.abs(tStats[0]); } - * @Override public final int getTransferLimit(ItemStack aStack) { Long[] tStats = getElectricStats(aStack); if - * (tStats == null) return 0; return (int)Math.max(tStats[1], tStats[3]); } - * @Override public final int charge(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreTransferLimit, boolean - * aSimulate) { Long[] tStats = getElectricStats(aStack); if (tStats == null || tStats[2] > aTier || !(tStats[3] == - * -1 || tStats[3] == -3 || (tStats[3] < 0 && aCharge == Integer.MAX_VALUE)) || aStack.stackSize != 1) return 0; - * long tChargeBefore = getRealCharge(aStack), tNewCharge = - * aCharge==Integer.MAX_VALUE?Long.MAX_VALUE:Math.min(Math.abs(tStats[0]), tChargeBefore + - * (aIgnoreTransferLimit?aCharge:Math.min(tStats[1], aCharge))); if (!aSimulate) setCharge(aStack, tNewCharge); - * return (int)(tNewCharge-tChargeBefore); } - * @Override public final int discharge(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreTransferLimit, - * boolean aSimulate) { Long[] tStats = getElectricStats(aStack); if (tStats == null || tStats[2] > aTier) return 0; - * if (tStats[3] > 0) { if (aCharge < tStats[3] || aStack.stackSize < 1) return 0; if (!aSimulate) - * aStack.stackSize--; return (int)(long)tStats[3]; } long tChargeBefore = getRealCharge(aStack), tNewCharge = - * Math.max(0, tChargeBefore - (aIgnoreTransferLimit?aCharge:Math.min(tStats[1], aCharge))); if (!aSimulate) - * setCharge(aStack, tNewCharge); return (int)(tChargeBefore-tNewCharge); } - * @Override public final int getCharge(ItemStack aStack) { return (int)Math.min(Integer.MAX_VALUE, - * getRealCharge(aStack)); } - * @Override public final boolean canUse(ItemStack aStack, int aAmount) { return getRealCharge(aStack) >= aAmount; } - * @Override public final boolean use(ItemStack aStack, int aAmount, EntityLivingBase aPlayer) { - * chargeFromArmor(aStack, aPlayer); if (aPlayer instanceof EntityPlayer && - * ((EntityPlayer)aPlayer).capabilities.isCreativeMode) return true; int tTransfer = discharge(aStack, aAmount, - * Integer.MAX_VALUE, true, true); if (tTransfer == aAmount) { discharge(aStack, aAmount, Integer.MAX_VALUE, true, - * false); chargeFromArmor(aStack, aPlayer); return true; } discharge(aStack, aAmount, Integer.MAX_VALUE, true, - * false); chargeFromArmor(aStack, aPlayer); return false; } - * @Override public final void chargeFromArmor(ItemStack aStack, EntityLivingBase aPlayer) { if (aPlayer == null || - * aPlayer.worldObj.isRemote) return; for (int i = 1; i < 5; i++) { ItemStack tArmor = - * aPlayer.getEquipmentInSlot(i); if (GT_ModHandler.isElectricItem(tArmor)) { IElectricItem tArmorItem = - * (IElectricItem)tArmor.getItem(); if (tArmorItem.canProvideEnergy(tArmor) && tArmorItem.getTier(tArmor) >= - * getTier(aStack)) { int tCharge = ElectricItem.manager.discharge(tArmor, charge(aStack, Integer.MAX_VALUE-1, - * Integer.MAX_VALUE, true, true), Integer.MAX_VALUE, true, false); if (tCharge > 0) { charge(aStack, tCharge, - * Integer.MAX_VALUE, true, false); if (aPlayer instanceof EntityPlayer) { Container tContainer = - * ((EntityPlayer)aPlayer).openContainer; if (tContainer != null) tContainer.detectAndSendChanges(); } } } } } } - */ - public final long getRealCharge(ItemStack aStack) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null) return 0; - if (tStats[3] > 0) return (int) (long) tStats[3]; - NBTTagCompound tNBT = aStack.getTagCompound(); - return tNBT == null ? 0 : tNBT.getLong("GT.ItemCharge"); - } - - public final boolean setCharge(ItemStack aStack, long aCharge) { - Long[] tStats = getElectricStats(aStack); - if (tStats == null || tStats[3] > 0) return false; - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) tNBT = new NBTTagCompound(); - tNBT.removeTag("GT.ItemCharge"); - aCharge = Math.min(tStats[0] < 0 ? Math.abs(tStats[0] / 2) : aCharge, Math.abs(tStats[0])); - if (aCharge > 0) { - aStack.setItemDamage(getChargedMetaData(aStack)); - tNBT.setLong("GT.ItemCharge", aCharge); - } else { - aStack.setItemDamage(getEmptyMetaData(aStack)); - } - if (tNBT.hasNoTags()) aStack.setTagCompound(null); - else aStack.setTagCompound(tNBT); - isItemStackUsable(aStack); - return true; - } - - public short getChargedMetaData(ItemStack aStack) { - return (short) aStack.getItemDamage(); - } - - public short getEmptyMetaData(ItemStack aStack) { - return (short) aStack.getItemDamage(); - } - - @Override - public FluidStack getFluid(ItemStack aStack) { - return getFluidContent(aStack); - } - - @Override - public int getCapacity(ItemStack aStack) { - Long[] tStats = getFluidContainerStats(aStack); - return tStats == null ? 0 : (int) Math.max(0, tStats[0]); - } - - @Override - public int fill(ItemStack aStack, FluidStack aFluid, boolean doFill) { - if (aStack == null || aStack.stackSize != 1) return 0; - - ItemStack tStack = GT_Utility.fillFluidContainer(aFluid, aStack, false, false); - if (tStack != null) { - aStack.setItemDamage(tStack.getItemDamage()); - aStack.func_150996_a(tStack.getItem()); - return GT_Utility.getFluidForFilledItem(tStack, false).amount; - } - - Long[] tStats = getFluidContainerStats(aStack); - if (tStats == null || tStats[0] <= 0 - || aFluid == null - || aFluid.getFluid() - .getID() <= 0 - || aFluid.amount <= 0) return 0; - - FluidStack tFluid = getFluidContent(aStack); - - if (tFluid == null || tFluid.getFluid() - .getID() <= 0) { - if (aFluid.amount <= tStats[0]) { - if (doFill) { - setFluidContent(aStack, aFluid); - } - return aFluid.amount; - } - if (doFill) { - tFluid = aFluid.copy(); - tFluid.amount = (int) (long) tStats[0]; - setFluidContent(aStack, tFluid); - } - return (int) (long) tStats[0]; - } - - if (!tFluid.isFluidEqual(aFluid)) return 0; - - int space = (int) (long) tStats[0] - tFluid.amount; - if (aFluid.amount <= space) { - if (doFill) { - tFluid.amount += aFluid.amount; - setFluidContent(aStack, tFluid); - } - return aFluid.amount; - } - if (doFill) { - tFluid.amount = (int) (long) tStats[0]; - setFluidContent(aStack, tFluid); - } - return space; - } - - @Override - public FluidStack drain(ItemStack aStack, int maxDrain, boolean doDrain) { - if (aStack == null || aStack.stackSize != 1) return null; - - FluidStack tFluid = GT_Utility.getFluidForFilledItem(aStack, false); - if (tFluid != null && maxDrain >= tFluid.amount) { - ItemStack tStack = GT_Utility.getContainerItem(aStack, false); - if (tStack == null) { - if (doDrain) aStack.stackSize = 0; - return tFluid; - } - if (doDrain) { - aStack.setItemDamage(tStack.getItemDamage()); - aStack.func_150996_a(tStack.getItem()); - } - return tFluid; - } - - Long[] tStats = getFluidContainerStats(aStack); - if (tStats == null || tStats[0] <= 0) return null; - - tFluid = getFluidContent(aStack); - if (tFluid == null) return null; - - int used = maxDrain; - if (tFluid.amount < used) used = tFluid.amount; - if (doDrain) { - tFluid.amount -= used; - setFluidContent(aStack, tFluid); - } - - FluidStack drained = tFluid.copy(); - drained.amount = used; - return drained; - } - - public FluidStack getFluidContent(ItemStack aStack) { - Long[] tStats = getFluidContainerStats(aStack); - if (tStats == null || tStats[0] <= 0) return GT_Utility.getFluidForFilledItem(aStack, false); - NBTTagCompound tNBT = aStack.getTagCompound(); - return tNBT == null ? null : FluidStack.loadFluidStackFromNBT(tNBT.getCompoundTag("GT.FluidContent")); - } - - public void setFluidContent(ItemStack aStack, FluidStack aFluid) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) tNBT = new NBTTagCompound(); - else tNBT.removeTag("GT.FluidContent"); - if (aFluid != null && aFluid.amount > 0) - tNBT.setTag("GT.FluidContent", aFluid.writeToNBT(new NBTTagCompound())); - if (tNBT.hasNoTags()) aStack.setTagCompound(null); - else aStack.setTagCompound(tNBT); - isItemStackUsable(aStack); - } - - @Override - public int getItemStackLimit(ItemStack aStack) { - Long[] tStats = getElectricStats(aStack); - if (tStats != null && (tStats[3] == -1 || tStats[3] == -2 || tStats[3] == -3) && getRealCharge(aStack) > 0) - return 1; - tStats = getFluidContainerStats(aStack); - if (tStats != null) return (int) (long) tStats[1]; - if (getDamage(aStack) == 32763) return 1; - return 64; - } - - @Override - public final Item getChargedItem(ItemStack itemStack) { - return this; - } - - @Override - public final Item getEmptyItem(ItemStack itemStack) { - return this; - } - - @Override - public final int getTier(ItemStack aStack) { - Long[] tStats = getElectricStats(aStack); - return (int) (tStats == null ? Integer.MAX_VALUE : tStats[2]); - } - - @Override - public final String getToolTip(ItemStack aStack) { - return null; - } // This has its own ToolTip Handler, no need to let the IC2 Handler screw us up at this Point - - @Override - public final IElectricItemManager getManager(ItemStack aStack) { - return this; - } // We are our own Manager - - @Override - public final boolean getShareTag() { - return true; - } // just to be sure. - - @Override - public int getItemEnchantability() { - return 0; - } - - @Override - public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { - return false; - } - - @Override - public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { - return false; - } -} diff --git a/src/main/java/gregtech/api/items/GT_MetaGenerated_Item.java b/src/main/java/gregtech/api/items/GT_MetaGenerated_Item.java deleted file mode 100644 index 465c4bc9d6..0000000000 --- a/src/main/java/gregtech/api/items/GT_MetaGenerated_Item.java +++ /dev/null @@ -1,415 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.GT_Values.D1; -import static gregtech.api.enums.Mods.AppleCore; -import static gregtech.api.enums.Mods.GregTech; -import static gregtech.api.recipe.RecipeMaps.cannerRecipes; -import static gregtech.api.util.GT_RecipeBuilder.SECONDS; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; -import net.minecraft.item.Item; -import net.minecraft.item.ItemFood; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; - -import cpw.mods.fml.common.Optional; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.enums.Mods; -import gregtech.api.enums.SubTag; -import gregtech.api.enums.TC_Aspects.TC_AspectStack; -import gregtech.api.interfaces.IFoodStat; -import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.interfaces.IItemBehaviour; -import gregtech.api.interfaces.IItemContainer; -import gregtech.api.objects.ItemData; -import gregtech.api.util.GT_Config; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; -import gregtech.common.render.items.GT_GeneratedMaterial_Renderer; -import squeek.applecore.api.food.FoodValues; -import squeek.applecore.api.food.IEdible; -import squeek.applecore.api.food.ItemFoodProxy; - -/** - * @author Gregorius Techneticies - *

- * One Item for everything! - *

- * This brilliant Item Class is used for automatically generating all possible variations of Material Items, - * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always - * have to make a new Item SubType for each OreDict Prefix, when adding a new Material. - *

- * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom - * defined, just to save space and MetaData. - *

- * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike - * Item. - */ -@Optional.Interface(iface = "squeek.applecore.api.food.IEdible", modid = Mods.Names.APPLE_CORE) -public abstract class GT_MetaGenerated_Item extends GT_MetaBase_Item implements IGT_ItemWithMaterialRenderer, IEdible { - - /** - * All instances of this Item Class are listed here. This gets used to register the Renderer to all Items of this - * Type, if useStandardMetaItemRenderer() returns true. - *

- * You can also use the unlocalized Name gotten from getUnlocalizedName() as Key if you want to get a specific Item. - */ - public static final ConcurrentHashMap sInstances = new ConcurrentHashMap<>(); - - /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */ - - public final short mOffset, mItemAmount; - public final BitSet mEnabledItems; - public final BitSet mVisibleItems; - public final IIcon[][] mIconList; - - public final ConcurrentHashMap mFoodStats = new ConcurrentHashMap<>(); - public final ConcurrentHashMap mElectricStats = new ConcurrentHashMap<>(); - public final ConcurrentHashMap mFluidContainerStats = new ConcurrentHashMap<>(); - public final ConcurrentHashMap mBurnValues = new ConcurrentHashMap<>(); - - /** - * Creates the Item using these Parameters. - * - * @param aUnlocalized The Unlocalized Name of this Item. - */ - public GT_MetaGenerated_Item(String aUnlocalized, short aOffset, short aItemAmount) { - super(aUnlocalized); - setCreativeTab(GregTech_API.TAB_GREGTECH_MATERIALS); - setHasSubtypes(true); - setMaxDamage(0); - mEnabledItems = new BitSet(aItemAmount); - mVisibleItems = new BitSet(aItemAmount); - - mOffset = (short) Math.min(32766, aOffset); - mItemAmount = (short) Math.min(aItemAmount, 32766 - mOffset); - mIconList = new IIcon[aItemAmount][1]; - - sInstances.put(getUnlocalizedName(), this); - } - - /** - * This adds a Custom Item to the ending Range. - * - * @param aID The Id of the assigned Item [0 - mItemAmount] (The MetaData gets auto-shifted by +mOffset) - * @param aEnglish The Default Localized Name of the created Item - * @param aToolTip The Default ToolTip of the created Item, you can also insert null for having no ToolTip - * @param aRandomData The OreDict Names you want to give the Item. Also used for TC Aspects and some other things. - * @return An ItemStack containing the newly created Item. - */ - public final ItemStack addItem(int aID, String aEnglish, String aToolTip, Object... aRandomData) { - if (aToolTip == null) aToolTip = ""; - if (aID >= 0 && aID < mItemAmount) { - ItemStack rStack = new ItemStack(this, 1, mOffset + aID); - if (mEnabledItems.get(aID)) { - throw new IllegalArgumentException( - String.format("ID %s is already reserved for %s!", aID, rStack.getDisplayName())); - } - mEnabledItems.set(aID); - mVisibleItems.set(aID); - GT_LanguageManager.addStringLocalization(getUnlocalizedName(rStack) + ".name", aEnglish); - GT_LanguageManager.addStringLocalization(getUnlocalizedName(rStack) + ".tooltip", aToolTip); - List tAspects = new ArrayList<>(); - // Important Stuff to do first - for (Object tRandomData : aRandomData) if (tRandomData instanceof SubTag) { - if (tRandomData == SubTag.INVISIBLE) { - mVisibleItems.set(aID, false); - continue; - } - if (tRandomData == SubTag.NO_UNIFICATION) { - GT_OreDictUnificator.addToBlacklist(rStack); - } - } - // now check for the rest - for (Object tRandomData : aRandomData) if (tRandomData != null) { - boolean tUseOreDict = true; - if (tRandomData instanceof IFoodStat) { - setFoodBehavior(mOffset + aID, (IFoodStat) tRandomData); - if (((IFoodStat) tRandomData).getFoodAction(this, rStack) == EnumAction.eat) { - int tFoodValue = ((IFoodStat) tRandomData).getFoodLevel(this, rStack, null); - if (tFoodValue > 0) { - GT_Values.RA.stdBuilder() - .itemInputs(rStack, ItemList.IC2_Food_Can_Empty.get(tFoodValue)) - .itemOutputs( - ((IFoodStat) tRandomData).isRotten(this, rStack, null) - ? ItemList.IC2_Food_Can_Spoiled.get(tFoodValue) - : ItemList.IC2_Food_Can_Filled.get(tFoodValue)) - .duration(tFoodValue * 5 * SECONDS) - .eut(1) - .addTo(cannerRecipes); - } - } - tUseOreDict = false; - } - if (tRandomData instanceof IItemBehaviour) { - // The cast below from is not safe. If you know how to make it safe, please do. - // noinspection unchecked - addItemBehavior(mOffset + aID, (IItemBehaviour) tRandomData); - tUseOreDict = false; - } - if (tRandomData instanceof IItemContainer) { - ((IItemContainer) tRandomData).set(rStack); - tUseOreDict = false; - } - if (tRandomData instanceof SubTag) { - continue; - } - if (tRandomData instanceof TC_AspectStack) { - ((TC_AspectStack) tRandomData).addToAspectList(tAspects); - continue; - } - if (tRandomData instanceof ItemData) { - if (GT_Utility.isStringValid(tRandomData)) GT_OreDictUnificator.registerOre(tRandomData, rStack); - else GT_OreDictUnificator.addItemData(rStack, (ItemData) tRandomData); - continue; - } - if (tUseOreDict) { - GT_OreDictUnificator.registerOre(tRandomData, rStack); - } - } - if (GregTech_API.sThaumcraftCompat != null) - GregTech_API.sThaumcraftCompat.registerThaumcraftAspectsToItem(rStack, tAspects, false); - return rStack; - } - return null; - } - - /** - * Sets a Food Behavior for the Item. - * - * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] - * @param aFoodBehavior the Food Behavior you want to add. - * @return the Item itself for convenience in constructing. - */ - public final GT_MetaGenerated_Item setFoodBehavior(int aMetaValue, IFoodStat aFoodBehavior) { - if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length()) return this; - if (aFoodBehavior == null) mFoodStats.remove((short) aMetaValue); - else mFoodStats.put((short) aMetaValue, aFoodBehavior); - return this; - } - - /** - * Sets the Furnace Burn Value for the Item. - * - * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] - * @param aValue 200 = 1 Burn Process = 500 EU, max = 32767 (that is 81917.5 EU) - * @return the Item itself for convenience in constructing. - */ - public final GT_MetaGenerated_Item setBurnValue(int aMetaValue, int aValue) { - if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length() || aValue < 0) return this; - if (aValue == 0) mBurnValues.remove((short) aMetaValue); - else mBurnValues.put((short) aMetaValue, aValue > Short.MAX_VALUE ? Short.MAX_VALUE : (short) aValue); - return this; - } - - /** - * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] - * @param aMaxCharge Maximum Charge. (if this is == 0 it will remove the Electric Behavior) - * @param aTransferLimit Transfer Limit. - * @param aTier The electric Tier. - * @param aSpecialData If this Item has a Fixed Charge, like a SingleUse Battery (if > 0). Use -1 if you want to - * make this Battery chargeable (the use and canUse Functions will still discharge if you just - * use this) Use -2 if you want to make this Battery dischargeable. Use -3 if you want to make - * this Battery charge/discharge-able. - * @return the Item itself for convenience in constructing. - */ - public final GT_MetaGenerated_Item setElectricStats(int aMetaValue, long aMaxCharge, long aTransferLimit, - long aTier, long aSpecialData, boolean aUseAnimations) { - if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length()) return this; - if (aMaxCharge == 0) mElectricStats.remove((short) aMetaValue); - else { - mElectricStats.put( - (short) aMetaValue, - new Long[] { aMaxCharge, Math.max(0, aTransferLimit), Math.max(-1, aTier), aSpecialData }); - if (aMetaValue >= mOffset && aUseAnimations) mIconList[aMetaValue - mOffset] = Arrays - .copyOf(mIconList[aMetaValue - mOffset], Math.max(9, mIconList[aMetaValue - mOffset].length)); - } - return this; - } - - /** - * - * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] - * @param aCapacity fluid capacity in L or mb - * @param aStacksize item stack size - * @return the Item itself for convenience in constructing. - */ - public final GT_MetaGenerated_Item setFluidContainerStats(int aMetaValue, long aCapacity, long aStacksize) { - if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length()) return this; - if (aCapacity < 0) mElectricStats.remove((short) aMetaValue); - else mFluidContainerStats.put((short) aMetaValue, new Long[] { aCapacity, Math.max(1, aStacksize) }); - return this; - } - - /** - * @return if this MetaGenerated Item should use my Default Renderer System. - */ - public boolean useStandardMetaItemRenderer() { - return true; - } - - @Override - public short[] getRGBa(ItemStack aStack) { - return Materials._NULL.getRGBA(); - } - - /** - * @return the Icon the Material is going to be rendered with. - */ - public IIconContainer getIconContainer(int aMetaData) { - return null; - } - - @Override - public IIcon getIcon(int aMetaData, int pass) { - IIconContainer iconContainer = getIconContainer(aMetaData); - return iconContainer != null ? iconContainer.getIcon() : null; - } - - @Override - public IIcon getOverlayIcon(int aMetaData, int pass) { - IIconContainer iconContainer = getIconContainer(aMetaData); - return iconContainer != null ? iconContainer.getOverlayIcon() : null; - } - - @Override - public boolean shouldUseCustomRenderer(int aMetaData) { - return true; - } - - @Override - public GT_GeneratedMaterial_Renderer getMaterialRenderer(int aMetaData) { - return null; - } - - @Override - public boolean allowMaterialRenderer(int aMetaData) { - return aMetaData < this.mOffset; - } - - /* ---------- INTERNAL OVERRIDES ---------- */ - - @Override - public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); - if (tStat != null && aPlayer.canEat(tStat.alwaysEdible(this, aStack, aPlayer))) - aPlayer.setItemInUse(aStack, 32); - return super.onItemRightClick(aStack, aWorld, aPlayer); - } - - @Override - public int getMaxItemUseDuration(ItemStack aStack) { - return mFoodStats.get((short) getDamage(aStack)) == null ? 0 : 32; - } - - @Override - public EnumAction getItemUseAction(ItemStack aStack) { - IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); - return tStat == null ? EnumAction.none : tStat.getFoodAction(this, aStack); - } - - @Override - public final ItemStack onEaten(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); - if (tStat != null) { - if (AppleCore.isModLoaded()) { - aPlayer.getFoodStats() - .func_151686_a(getFoodProxy(this), aStack); - } else { - aPlayer.getFoodStats() - .addStats(tStat.getFoodLevel(this, aStack, aPlayer), tStat.getSaturation(this, aStack, aPlayer)); - } - tStat.onEaten(this, aStack, aPlayer); - } - return aStack; - } - - @Optional.Method(modid = Mods.Names.APPLE_CORE) - private static ItemFood getFoodProxy(Object edible) { - return new ItemFoodProxy((IEdible) edible); - } - - @Override - @Optional.Method(modid = Mods.Names.APPLE_CORE) - public FoodValues getFoodValues(ItemStack aStack) { - IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); - return tStat == null ? null - : new FoodValues(tStat.getFoodLevel(this, aStack, null), tStat.getSaturation(this, aStack, null)); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { - int j = mEnabledItems.length(); - for (int i = 0; i < j; i++) if (mVisibleItems.get(i) || (D1 && mEnabledItems.get(i))) { - Long[] tStats = mElectricStats.get((short) (mOffset + i)); - if (tStats != null && tStats[3] < 0) { - ItemStack tStack = new ItemStack(this, 1, mOffset + i); - setCharge(tStack, Math.abs(tStats[0])); - isItemStackUsable(tStack); - aList.add(tStack); - } - if (tStats == null || tStats[3] != -2) { - ItemStack tStack = new ItemStack(this, 1, mOffset + i); - isItemStackUsable(tStack); - aList.add(tStack); - } - } - } - - @Override - @SideOnly(Side.CLIENT) - public final void registerIcons(IIconRegister aIconRegister) { - short j = (short) mEnabledItems.length(); - for (short i = 0; i < j; i++) if (mEnabledItems.get(i)) { - for (byte k = 1; k < mIconList[i].length; k++) { - mIconList[i][k] = aIconRegister.registerIcon( - GregTech.getResourcePath(GT_Config.troll ? "troll" : getUnlocalizedName() + "/" + i + "/" + k)); - } - mIconList[i][0] = aIconRegister - .registerIcon(GregTech.getResourcePath(GT_Config.troll ? "troll" : getUnlocalizedName() + "/" + i)); - } - } - - @Override - public final Long[] getElectricStats(ItemStack aStack) { - return mElectricStats.get((short) aStack.getItemDamage()); - } - - @Override - public final Long[] getFluidContainerStats(ItemStack aStack) { - return mFluidContainerStats.get((short) aStack.getItemDamage()); - } - - @Override - public int getItemEnchantability() { - return 0; - } - - @Override - public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { - return false; - } - - @Override - public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { - return false; - } -} diff --git a/src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X01.java b/src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X01.java deleted file mode 100644 index db41a3c35b..0000000000 --- a/src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X01.java +++ /dev/null @@ -1,213 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.GT_Values.M; - -import java.util.List; - -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; - -/** - * @author Gregorius Techneticies - *

- * One Item for everything! - *

- * This brilliant Item Class is used for automatically generating all possible variations of Material Items, - * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always - * have to make a new Item SubType for each OreDict Prefix, when adding a new Material. - *

- * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom - * defined, just to save space and MetaData. - *

- * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike - * Item. - */ -public abstract class GT_MetaGenerated_Item_X01 extends GT_MetaGenerated_Item { - - protected final OrePrefixes mPrefix; - protected final int mIconSetIndex; - - /** - * Creates the Item using these Parameters. This is for the new 1 Item = 1 Prefix System. - * - * @param aUnlocalized The Unlocalized Name of this Item. - * @param aGeneratedPrefix The OreDict Prefix you want to have generated. - * @param aIconSetIndex The TextureSet Index to be used. -1 for Defaulting to the Data contained in the Prefix. - * (this is only to be used for selecting the Icon in getIconContainer, nothing else) - */ - public GT_MetaGenerated_Item_X01(String aUnlocalized, OrePrefixes aGeneratedPrefix, int aIconSetIndex) { - super(aUnlocalized, (short) 32000, (short) 766); - mPrefix = aGeneratedPrefix; - mIconSetIndex = aIconSetIndex >= 0 ? aIconSetIndex - : aGeneratedPrefix.mTextureIndex >= 0 ? aGeneratedPrefix.mTextureIndex : 0; - - for (int i = 0; i < GregTech_API.sGeneratedMaterials.length; i++) { - OrePrefixes tPrefix = mPrefix; - if (tPrefix == null) continue; - Materials tMaterial = GregTech_API.sGeneratedMaterials[i]; - if (tMaterial == null) continue; - if (mPrefix.doGenerateItem(tMaterial)) { - ItemStack tStack = new ItemStack(this, 1, i); - GT_LanguageManager.addStringLocalization( - getUnlocalizedName(tStack) + ".name", - GT_LanguageManager.i18nPlaceholder ? getDefaultLocalizationFormat(tPrefix, tMaterial, i) - : getDefaultLocalization(tPrefix, tMaterial, i)); - GT_LanguageManager.addStringLocalization( - getUnlocalizedName(tStack) + ".tooltip", - tMaterial.getToolTip(tPrefix.mMaterialAmount / M)); - String tOreName = getOreDictString(tPrefix, tMaterial); - tPrefix = OrePrefixes.getOrePrefix(tOreName); - if (tPrefix != null && tPrefix.mIsUnificatable) { - GT_OreDictUnificator.set(tPrefix, OrePrefixes.getMaterial(tOreName, tPrefix), tStack); - } else { - GT_OreDictUnificator.registerOre(tOreName, tStack); - } - } - } - } - - /* ---------- OVERRIDEABLE FUNCTIONS ---------- */ - - /** - * @param aPrefix the OreDict Prefix - * @param aMaterial the Material - * @param aMetaData a Index from [0 - 31999] - * @return the Localized Name when default LangFiles are used. - */ - public String getDefaultLocalization(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { - return aPrefix.getDefaultLocalNameForItem(aMaterial); - } - - /** - * @param aPrefix the OreDict Prefix - * @param aMaterial the Material - * @param aMetaData a Index from [0 - 31999] - * @return the Localized Name Format when default LangFiles are used. - */ - public String getDefaultLocalizationFormat(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { - return aPrefix.getDefaultLocalNameFormatForItem(aMaterial); - } - - /** - * @param aPrefix always != null - * @param aMaterial always != null - * @param aDoShowAllItems this is the Configuration Setting of the User, if he wants to see all the Stuff like Tiny - * Dusts or Crushed Ores as well. - * @return if this Item should be visible in NEI or Creative - */ - public boolean doesShowInCreative(OrePrefixes aPrefix, Materials aMaterial, boolean aDoShowAllItems) { - return true; - } - - /** - * @return the name of the Item to be registered at the OreDict. - */ - public String getOreDictString(OrePrefixes aPrefix, Materials aMaterial) { - return aPrefix.get(aMaterial) - .toString(); - } - - public IIconContainer getIconContainer(int aMetaData, Materials aMaterial) { - return aMaterial.mIconSet.mTextures[mIconSetIndex]; - } - - /* ---------- INTERNAL OVERRIDES ---------- */ - - @Override - public String getItemStackDisplayName(ItemStack aStack) { - String aName = super.getItemStackDisplayName(aStack); - int aDamage = aStack.getItemDamage(); - if (aDamage < 32000 && aDamage >= 0) return Materials.getLocalizedNameForItem(aName, aDamage % 1000); - return aName; - } - - @Override - public ItemStack getContainerItem(ItemStack aStack) { - int aMetaData = aStack.getItemDamage(); - if (aMetaData < GregTech_API.sGeneratedMaterials.length && aMetaData >= 0) { - Materials aMaterial = GregTech_API.sGeneratedMaterials[aMetaData]; - if (aMaterial != null && aMaterial != Materials.Empty && aMaterial != Materials._NULL) { - return GT_Utility.copyAmount(1, mPrefix.mContainerItem); - } - } - return null; - } - - @Override - public short[] getRGBa(ItemStack aStack) { - int aMetaData = getDamage(aStack); - return aMetaData < GregTech_API.sGeneratedMaterials.length - && GregTech_API.sGeneratedMaterials[aMetaData] != null ? GregTech_API.sGeneratedMaterials[aMetaData].mRGBa - : Materials._NULL.mRGBa; - } - - @Override - public final IIconContainer getIconContainer(int aMetaData) { - return aMetaData < GregTech_API.sGeneratedMaterials.length - && GregTech_API.sGeneratedMaterials[aMetaData] != null - ? getIconContainer(aMetaData, GregTech_API.sGeneratedMaterials[aMetaData]) - : null; - } - - @Override - @SideOnly(Side.CLIENT) - public final void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { - for (int i = 0; i < GregTech_API.sGeneratedMaterials.length; i++) - if (mPrefix.doGenerateItem(GregTech_API.sGeneratedMaterials[i]) && doesShowInCreative( - mPrefix, - GregTech_API.sGeneratedMaterials[i], - GregTech_API.sDoShowAllItemsInCreative)) { - ItemStack tStack = new ItemStack(this, 1, i); - isItemStackUsable(tStack); - aList.add(tStack); - } - super.getSubItems(aItem, aCreativeTab, aList); - } - - @Override - public final IIcon getIconFromDamage(int aMetaData) { - if (aMetaData < 0) return null; - if (aMetaData < GregTech_API.sGeneratedMaterials.length) { - Materials tMaterial = GregTech_API.sGeneratedMaterials[aMetaData]; - if (tMaterial == null) return null; - IIconContainer tIcon = getIconContainer(aMetaData, tMaterial); - if (tIcon != null) return tIcon.getIcon(); - return null; - } - return aMetaData >= mOffset && aMetaData - mOffset < mIconList.length ? mIconList[aMetaData - mOffset][0] - : null; - } - - @Override - public int getItemStackLimit(ItemStack aStack) { - return getDamage(aStack) < mOffset ? Math.min(super.getItemStackLimit(aStack), mPrefix.mDefaultStackSize) - : super.getItemStackLimit(aStack); - } - - @Override - public int getItemEnchantability() { - return 0; - } - - @Override - public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { - return false; - } - - @Override - public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { - return false; - } -} diff --git a/src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X32.java b/src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X32.java deleted file mode 100644 index c344397e4e..0000000000 --- a/src/main/java/gregtech/api/items/GT_MetaGenerated_Item_X32.java +++ /dev/null @@ -1,225 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.enums.GT_Values.M; - -import java.util.Arrays; -import java.util.List; - -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; -import gregtech.common.render.items.GT_GeneratedMaterial_Renderer; - -/** - * @author Gregorius Techneticies - *

- * One Item for everything! - *

- * This brilliant Item Class is used for automatically generating all possible variations of Material Items, - * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always - * have to make a new Item SubType for each OreDict Prefix, when adding a new Material. - *

- * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom - * defined, just to save space and MetaData. - *

- * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike - * Item. - */ -public abstract class GT_MetaGenerated_Item_X32 extends GT_MetaGenerated_Item { - - protected final OrePrefixes[] mGeneratedPrefixList; - - /** - * Creates the Item using these Parameters. - * - * @param aUnlocalized The Unlocalized Name of this Item. - * @param aGeneratedPrefixList The OreDict Prefixes you want to have generated. - */ - public GT_MetaGenerated_Item_X32(String aUnlocalized, OrePrefixes... aGeneratedPrefixList) { - super(aUnlocalized, (short) 32000, (short) 766); - mGeneratedPrefixList = Arrays.copyOf(aGeneratedPrefixList, 32); - - for (int i = 0; i < 32000; i++) { - OrePrefixes tPrefix = mGeneratedPrefixList[i / 1000]; - if (tPrefix == null) continue; - if (tPrefix == OrePrefixes.___placeholder___) continue; - Materials tMaterial = GregTech_API.sGeneratedMaterials[i % 1000]; - if (tMaterial == null) continue; - if (doesMaterialAllowGeneration(tPrefix, tMaterial)) { - ItemStack tStack = new ItemStack(this, 1, i); - GT_LanguageManager.addStringLocalization( - getUnlocalizedName(tStack) + ".name", - GT_LanguageManager.i18nPlaceholder ? getDefaultLocalizationFormat(tPrefix, tMaterial, i) - : getDefaultLocalization(tPrefix, tMaterial, i)); - GT_LanguageManager.addStringLocalization( - getUnlocalizedName(tStack) + ".tooltip", - tMaterial.getToolTip(tPrefix.mMaterialAmount / M)); - if (tPrefix.mIsUnificatable) { - GT_OreDictUnificator.set(tPrefix, tMaterial, tStack); - } else { - GT_OreDictUnificator.registerOre(tPrefix.get(tMaterial), tStack); - } - if ((tPrefix == OrePrefixes.stick || tPrefix == OrePrefixes.wireFine || tPrefix == OrePrefixes.ingot) - && (tMaterial == Materials.Lead || tMaterial == Materials.Tin - || tMaterial == Materials.SolderingAlloy)) { - GregTech_API.sSolderingMetalList.add(tStack); - GT_ModHandler.registerBoxableItemToToolBox(tStack); - } - } - } - } - - /* ---------- OVERRIDEABLE FUNCTIONS ---------- */ - - /** - * @return the Color Modulation the Material is going to be rendered with. - */ - @Override - public short[] getRGBa(ItemStack aStack) { - Materials tMaterial = GregTech_API.sGeneratedMaterials[getDamage(aStack) % 1000]; - return tMaterial == null ? Materials._NULL.mRGBa : tMaterial.mRGBa; - } - - /** - * @param aPrefix this can be null, you have to return false in that case - * @param aMaterial this can be null, you have to return false in that case - * @return if this Item should be generated and visible. - */ - public boolean doesMaterialAllowGeneration(OrePrefixes aPrefix, Materials aMaterial) { - // You have to check for at least these Conditions in every Case! So add a super Call like the following for - // this before executing your Code: - // if (!super.doesMaterialAllowGeneration(aPrefix, aMaterial)) return false; - return aPrefix != null && aPrefix.doGenerateItem(aMaterial); - } - - /* ---------- OVERRIDEABLE FUNCTIONS ---------- */ - - /** - * @param aPrefix the OreDict Prefix - * @param aMaterial the Material - * @param aMetaData a Index from [0 - 31999] - * @return the Localized Name when default LangFiles are used. - */ - public String getDefaultLocalization(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { - return aPrefix.getDefaultLocalNameForItem(aMaterial); - } - - /** - * @param aPrefix the OreDict Prefix - * @param aMaterial the Material - * @param aMetaData a Index from [0 - 31999] - * @return the Localized Name Format when default LangFiles are used. - */ - public String getDefaultLocalizationFormat(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { - return aPrefix.getDefaultLocalNameFormatForItem(aMaterial); - } - - /** - * @param aMetaData a Index from [0 - 31999] - * @param aMaterial the Material - * @return an Icon Container for the Item Display. - */ - public final IIconContainer getIconContainer(int aMetaData, Materials aMaterial) { - return mGeneratedPrefixList[aMetaData / 1000] != null - && mGeneratedPrefixList[aMetaData / 1000].mTextureIndex >= 0 - ? aMaterial.mIconSet.mTextures[mGeneratedPrefixList[aMetaData / 1000].mTextureIndex] - : null; - } - - /** - * @param aPrefix always != null - * @param aMaterial always != null - * @param aDoShowAllItems this is the Configuration Setting of the User, if he wants to see all the Stuff like Tiny - * Dusts or Crushed Ores as well. - * @return if this Item should be visible in NEI or Creative - */ - public boolean doesShowInCreative(OrePrefixes aPrefix, Materials aMaterial, boolean aDoShowAllItems) { - return true; - } - - /* ---------- INTERNAL OVERRIDES ---------- */ - - @Override - public String getItemStackDisplayName(ItemStack aStack) { - String aName = super.getItemStackDisplayName(aStack); - int aDamage = aStack.getItemDamage(); - if (aDamage < 32000 && aDamage >= 0) return Materials.getLocalizedNameForItem(aName, aDamage % 1000); - return aName; - } - - @Override - public ItemStack getContainerItem(ItemStack aStack) { - int aDamage = aStack.getItemDamage(); - if (aDamage < 32000 && aDamage >= 0) { - Materials aMaterial = GregTech_API.sGeneratedMaterials[aDamage % 1000]; - if (aMaterial != null && aMaterial != Materials.Empty && aMaterial != Materials._NULL) { - OrePrefixes aPrefix = mGeneratedPrefixList[aDamage / 1000]; - if (aPrefix != null) return GT_Utility.copyAmount(1, aPrefix.mContainerItem); - } - } - return null; - } - - @Override - public final IIconContainer getIconContainer(int aMetaData) { - return GregTech_API.sGeneratedMaterials[aMetaData % 1000] == null ? null - : getIconContainer(aMetaData, GregTech_API.sGeneratedMaterials[aMetaData % 1000]); - } - - @Override - public GT_GeneratedMaterial_Renderer getMaterialRenderer(int aMetaData) { - return GregTech_API.sGeneratedMaterials[aMetaData % 1000] == null ? null - : GregTech_API.sGeneratedMaterials[aMetaData % 1000].renderer; - } - - @Override - @SideOnly(Side.CLIENT) - public final void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { - for (int i = 0; i < 32000; i++) { - OrePrefixes aPrefix = mGeneratedPrefixList[i / 1000]; - Materials aMaterial = GregTech_API.sGeneratedMaterials[i % 1000]; - if (aPrefix != null && aMaterial != null) { - if (doesMaterialAllowGeneration(aPrefix, aMaterial) - && doesShowInCreative(aPrefix, aMaterial, GregTech_API.sDoShowAllItemsInCreative)) { - ItemStack tStack = new ItemStack(this, 1, i); - isItemStackUsable(tStack); - aList.add(tStack); - } - } - } - super.getSubItems(aItem, aCreativeTab, aList); - } - - @Override - public final IIcon getIconFromDamage(int aMetaData) { - if (aMetaData < 0) return null; - if (aMetaData < 32000) { - Materials tMaterial = GregTech_API.sGeneratedMaterials[aMetaData % 1000]; - if (tMaterial == null) return null; - IIconContainer tIcon = getIconContainer(aMetaData, tMaterial); - if (tIcon != null) return tIcon.getIcon(); - return null; - } - return aMetaData - 32000 < mIconList.length ? mIconList[aMetaData - 32000][0] : null; - } - - @Override - public int getItemStackLimit(ItemStack aStack) { - int tDamage = getDamage(aStack); - if (tDamage < 32000 && mGeneratedPrefixList[tDamage / 1000] != null) - return Math.min(super.getItemStackLimit(aStack), mGeneratedPrefixList[tDamage / 1000].mDefaultStackSize); - return super.getItemStackLimit(aStack); - } -} diff --git a/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java b/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java deleted file mode 100644 index cec93169ec..0000000000 --- a/src/main/java/gregtech/api/items/GT_MetaGenerated_Tool.java +++ /dev/null @@ -1,1013 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.util.GT_Utility.formatNumbers; -import static gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_LargeTurbine_Steam.calculateLooseFlow; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.item.EntityMinecart; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.stats.AchievementList; -import net.minecraft.stats.StatList; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; -import net.minecraftforge.common.IShearable; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.world.BlockEvent; - -import appeng.api.implementations.items.IAEWrench; -import buildcraft.api.tools.IToolWrench; -import cpw.mods.fml.common.Mod; -import cpw.mods.fml.common.Optional; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import crazypants.enderio.api.tool.ITool; -import forestry.api.arboriculture.IToolGrafter; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enchants.Enchantment_Radioactivity; -import gregtech.api.enums.Materials; -import gregtech.api.enums.TC_Aspects.TC_AspectStack; -import gregtech.api.interfaces.IDamagableItem; -import gregtech.api.interfaces.IToolStats; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; -import gregtech.common.tools.GT_Tool_Turbine; -import mods.railcraft.api.core.items.IToolCrowbar; -import mrtjp.projectred.api.IScrewdriver; - -/** - * This is an example on how you can create a Tool ItemStack, in this case a Bismuth Wrench: - * GT_MetaGenerated_Tool.sInstances.get("gt.metatool.01").getToolWithStats(GT_MetaGenerated_Tool_01.WRENCH, 1, - * Materials.Bismuth, Materials.Bismuth, null); - */ -@Optional.InterfaceList( - value = { - @Optional.Interface(iface = "forestry.api.arboriculture.IToolGrafter", modid = "ForestryAPI|arboriculture"), - @Optional.Interface(iface = "mods.railcraft.api.core.items.IToolCrowbar", modid = "RailcraftAPI|items"), - @Optional.Interface(iface = "buildcraft.api.tools.IToolWrench", modid = "BuildCraftAPI|tools"), - @Optional.Interface(iface = "crazypants.enderio.api.tool.ITool", modid = "EnderIOAPI|Tools"), - @Optional.Interface(iface = "mrtjp.projectred.api.IScrewdriver", modid = "ProjRed|Core"), }) -public abstract class GT_MetaGenerated_Tool extends GT_MetaBase_Item - implements IDamagableItem, IToolGrafter, IToolCrowbar, IToolWrench, ITool, IScrewdriver, IAEWrench { - - /** - * All instances of this Item Class are listed here. This gets used to register the Renderer to all Items of this - * Type, if useStandardMetaItemRenderer() returns true. - *

- * You can also use the unlocalized Name gotten from getUnlocalizedName() as Key if you want to get a specific Item. - */ - public static final ConcurrentHashMap sInstances = new ConcurrentHashMap<>(); - - /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */ - - public final ConcurrentHashMap mToolStats = new ConcurrentHashMap<>(); - - /** - * Creates the Item using these Parameters. - * - * @param aUnlocalized The Unlocalized Name of this Item. - */ - public GT_MetaGenerated_Tool(String aUnlocalized) { - super(aUnlocalized); - setCreativeTab(GregTech_API.TAB_GREGTECH); - setMaxStackSize(1); - sInstances.put(getUnlocalizedName(), this); - } - - /* ---------- FOR ADDING CUSTOM ITEMS INTO THE REMAINING 766 RANGE ---------- */ - - public static final Materials getPrimaryMaterial(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) return Materials.getRealMaterial(aNBT.getString("PrimaryMaterial")); - } - return Materials._NULL; - } - - public static final Materials getSecondaryMaterial(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) return Materials.getRealMaterial(aNBT.getString("SecondaryMaterial")); - } - return Materials._NULL; - } - - /* ---------- INTERNAL OVERRIDES ---------- */ - - public static final long getToolMaxDamage(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) return aNBT.getLong("MaxDamage"); - } - return 0; - } - - public static final long getToolDamage(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) return aNBT.getLong("Damage"); - } - return 0; - } - - public static final boolean setToolDamage(ItemStack aStack, long aDamage) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) { - aNBT.setLong("Damage", aDamage); - return true; - } - } - return false; - } - - public static final boolean setToolMode(ItemStack aStack, byte aMode) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) { - aNBT.setByte("Mode", aMode); - return true; - } - } - return false; - } - - public static final byte getToolMode(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null) return aNBT.getByte("Mode"); - } - return 0; - } - - /** - * This adds a Custom Item to the ending Range. - * - * @param aID The Id of the assigned Tool Class [0 - 32765] (only even Numbers allowed! Uneven - * ID's are empty electric Items) - * @param aEnglish The Default Localized Name of the created Item - * @param aToolTip The Default ToolTip of the created Item, you can also insert null for having no - * ToolTip - * @param aToolStats The Food Value of this Item. Can be null as well. - * @param aOreDictNamesAndAspects The OreDict Names you want to give the Item. Also used to assign Thaumcraft - * Aspects. - * @return An ItemStack containing the newly created Item, but without specific Stats. - */ - public final ItemStack addTool(int aID, String aEnglish, String aToolTip, IToolStats aToolStats, - Object... aOreDictNamesAndAspects) { - if (aToolTip == null) aToolTip = ""; - if (aID >= 0 && aID < 32766 && aID % 2 == 0) { - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + "." + aID + ".name", aEnglish); - GT_LanguageManager.addStringLocalization(getUnlocalizedName() + "." + aID + ".tooltip", aToolTip); - GT_LanguageManager - .addStringLocalization(getUnlocalizedName() + "." + (aID + 1) + ".name", aEnglish + " (Empty)"); - GT_LanguageManager - .addStringLocalization(getUnlocalizedName() + "." + (aID + 1) + ".tooltip", "You need to recharge it"); - mToolStats.put((short) aID, aToolStats); - mToolStats.put((short) (aID + 1), aToolStats); - aToolStats.onStatsAddedToTool(this, aID); - ItemStack rStack = new ItemStack(this, 1, aID); - List tAspects = new ArrayList<>(); - for (Object tOreDictNameOrAspect : aOreDictNamesAndAspects) { - if (tOreDictNameOrAspect instanceof TC_AspectStack) - ((TC_AspectStack) tOreDictNameOrAspect).addToAspectList(tAspects); - else GT_OreDictUnificator.registerOre(tOreDictNameOrAspect, rStack); - } - if (GregTech_API.sThaumcraftCompat != null) - GregTech_API.sThaumcraftCompat.registerThaumcraftAspectsToItem(rStack, tAspects, false); - GT_ModHandler.registerBoxableItemToToolBox(rStack); - return rStack; - } - return null; - } - - /** - * This Function gets an ItemStack Version of this Tool - * - * @param aToolID the ID of the Tool Class - * @param aAmount Amount of Items (well normally you only need 1) - * @param aPrimaryMaterial Primary Material of this Tool - * @param aSecondaryMaterial Secondary (Rod/Handle) Material of this Tool - * @param aElectricArray The Electric Stats of this Tool (or null if not electric) - */ - public final ItemStack getToolWithStats(int aToolID, int aAmount, Materials aPrimaryMaterial, - Materials aSecondaryMaterial, long[] aElectricArray) { - ItemStack rStack = new ItemStack(this, aAmount, aToolID); - IToolStats tToolStats = getToolStats(rStack); - if (tToolStats != null) { - NBTTagCompound tMainNBT = new NBTTagCompound(), tToolNBT = new NBTTagCompound(); - tToolNBT.setByte("Mode", (byte) 0); - if (aPrimaryMaterial != null) { - tToolNBT.setString("PrimaryMaterial", aPrimaryMaterial.mName); - tToolNBT.setLong( - "MaxDamage", - 100L * (long) (aPrimaryMaterial.mDurability * tToolStats.getMaxDurabilityMultiplier())); - } - if (aSecondaryMaterial != null) tToolNBT.setString("SecondaryMaterial", aSecondaryMaterial.mName); - - if (aElectricArray != null) { - tToolNBT.setBoolean("Electric", true); - tToolNBT.setLong("MaxCharge", aElectricArray[0]); - tToolNBT.setLong("Voltage", aElectricArray[1]); - tToolNBT.setLong("Tier", aElectricArray[2]); - tToolNBT.setLong("SpecialData", aElectricArray[3]); - } - - tMainNBT.setTag("GT.ToolStats", tToolNBT); - rStack.setTagCompound(tMainNBT); - } - isItemStackUsable(rStack); - return rStack; - } - - /** - * Called by the Block Harvesting Event within the GT_Proxy - */ - @Mod.EventHandler - public void onHarvestBlockEvent(ArrayList aDrops, ItemStack aStack, EntityPlayer aPlayer, Block aBlock, - int aX, int aY, int aZ, byte aMetaData, int aFortune, boolean aSilkTouch, BlockEvent.HarvestDropsEvent aEvent) { - IToolStats tStats = getToolStats(aStack); - if (isItemStackUsable(aStack) && getDigSpeed(aStack, aBlock, aMetaData) > 0.0F) doDamage( - aStack, - (long) tStats - .convertBlockDrops(aDrops, aStack, aPlayer, aBlock, aX, aY, aZ, aMetaData, aFortune, aSilkTouch, aEvent) - * tStats.getToolDamagePerDropConversion()); - } - - @Mod.EventHandler - public float onBlockBreakSpeedEvent(float aDefault, ItemStack aStack, EntityPlayer aPlayer, Block aBlock, int aX, - int aY, int aZ, byte aMetaData, PlayerEvent.BreakSpeed aEvent) { - IToolStats tStats = getToolStats(aStack); - return tStats == null ? aDefault - : tStats.getMiningSpeed(aBlock, aMetaData, aDefault, aPlayer, aPlayer.worldObj, aX, aY, aZ); - } - - @Override - public boolean onBlockStartBreak(ItemStack aStack, int aX, int aY, int aZ, EntityPlayer aPlayer) { - if (aPlayer.worldObj.isRemote) { - return false; - } - IToolStats tStats = getToolStats(aStack); - Block aBlock = aPlayer.worldObj.getBlock(aX, aY, aZ); - if (tStats.isChainsaw() && (aBlock instanceof IShearable target)) { - if ((target.isShearable(aStack, aPlayer.worldObj, aX, aY, aZ))) { - ArrayList drops = target.onSheared( - aStack, - aPlayer.worldObj, - aX, - aY, - aZ, - EnchantmentHelper.getEnchantmentLevel(Enchantment.fortune.effectId, aStack)); - for (ItemStack stack : drops) { - float f = 0.7F; - double d = itemRand.nextFloat() * f + (1.0F - f) * 0.5D; - double d1 = itemRand.nextFloat() * f + (1.0F - f) * 0.5D; - double d2 = itemRand.nextFloat() * f + (1.0F - f) * 0.5D; - EntityItem entityitem = new EntityItem(aPlayer.worldObj, aX + d, aY + d1, aZ + d2, stack); - entityitem.delayBeforeCanPickup = 10; - aPlayer.worldObj.spawnEntityInWorld(entityitem); - } - aPlayer.addStat(net.minecraft.stats.StatList.mineBlockStatArray[Block.getIdFromBlock(aBlock)], 1); - onBlockDestroyed(aStack, aPlayer.worldObj, aBlock, aX, aY, aZ, aPlayer); - } - return false; - } - return super.onBlockStartBreak(aStack, aX, aY, aZ, aPlayer); - } - - @Override - public boolean onLeftClickEntity(ItemStack aStack, EntityPlayer aPlayer, Entity aEntity) { - IToolStats tStats = getToolStats(aStack); - if (tStats == null || !isItemStackUsable(aStack)) return true; - GT_Utility.doSoundAtClient(tStats.getEntityHitSound(), 1, 1.0F); - if (super.onLeftClickEntity(aStack, aPlayer, aEntity)) return true; - if (aEntity.canAttackWithItem() && !aEntity.hitByEntity(aPlayer)) { - float tMagicDamage = tStats.getMagicDamageAgainstEntity( - aEntity instanceof EntityLivingBase - ? EnchantmentHelper.getEnchantmentModifierLiving(aPlayer, (EntityLivingBase) aEntity) - : 0.0F, - aEntity, - aStack, - aPlayer), - tDamage = tStats.getNormalDamageAgainstEntity( - (float) aPlayer.getEntityAttribute(SharedMonsterAttributes.attackDamage) - .getAttributeValue() + getToolCombatDamage(aStack), - aEntity, - aStack, - aPlayer); - if (tDamage + tMagicDamage > 0.0F) { - boolean tCriticalHit = aPlayer.fallDistance > 0.0F && !aPlayer.onGround - && !aPlayer.isOnLadder() - && !aPlayer.isInWater() - && !aPlayer.isPotionActive(Potion.blindness) - && aPlayer.ridingEntity == null - && aEntity instanceof EntityLivingBase; - if (tCriticalHit && tDamage > 0.0F) tDamage *= 1.5F; - tDamage += tMagicDamage; - if (aEntity.attackEntityFrom(tStats.getDamageSource(aPlayer, aEntity), tDamage)) { - if (aEntity instanceof EntityLivingBase) - aEntity.setFire(EnchantmentHelper.getFireAspectModifier(aPlayer) * 4); - int tKnockcack = (aPlayer.isSprinting() ? 1 : 0) + (aEntity instanceof EntityLivingBase - ? EnchantmentHelper.getKnockbackModifier(aPlayer, (EntityLivingBase) aEntity) - : 0); - if (tKnockcack > 0) { - aEntity.addVelocity( - -MathHelper.sin(aPlayer.rotationYaw * (float) Math.PI / 180.0F) * tKnockcack * 0.5F, - 0.1D, - MathHelper.cos(aPlayer.rotationYaw * (float) Math.PI / 180.0F) * tKnockcack * 0.5F); - aPlayer.motionX *= 0.6D; - aPlayer.motionZ *= 0.6D; - aPlayer.setSprinting(false); - } - if (tCriticalHit) aPlayer.onCriticalHit(aEntity); - if (tMagicDamage > 0.0F) aPlayer.onEnchantmentCritical(aEntity); - if (tDamage >= 18.0F) aPlayer.triggerAchievement(AchievementList.overkill); - aPlayer.setLastAttacker(aEntity); - if (aEntity instanceof EntityLivingBase) - EnchantmentHelper.func_151384_a((EntityLivingBase) aEntity, aPlayer); - EnchantmentHelper.func_151385_b(aPlayer, aEntity); - if (aEntity instanceof EntityLivingBase) - aPlayer.addStat(StatList.damageDealtStat, Math.round(tDamage * 10.0F)); - aEntity.hurtResistantTime = Math - .max(1, tStats.getHurtResistanceTime(aEntity.hurtResistantTime, aEntity)); - aPlayer.addExhaustion(0.3F); - doDamage(aStack, tStats.getToolDamagePerEntityAttack()); - } - } - } - if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); - return true; - } - - @Override - public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - IToolStats tStats = getToolStats(aStack); - if (tStats != null && tStats.canBlock()) aPlayer.setItemInUse(aStack, 72000); - return super.onItemRightClick(aStack, aWorld, aPlayer); - } - - @Override - public final int getMaxItemUseDuration(ItemStack aStack) { - return 72000; - } - - @Override - public final EnumAction getItemUseAction(ItemStack aStack) { - IToolStats tStats = getToolStats(aStack); - if (tStats != null && tStats.canBlock()) return EnumAction.block; - return EnumAction.none; - } - - @Override - @SideOnly(Side.CLIENT) - public final void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { - for (int i = 0; i < 32766; i += 2) { - if (getToolStats(new ItemStack(this, 1, i)) != null) { - ItemStack tStack = new ItemStack(this, 1, i); - isItemStackUsable(tStack); - aList.add(tStack); - aList.add(getToolWithStats(i, 1, Materials.Neutronium, Materials.Neutronium, null)); - } - } - } - - @Override - @SideOnly(Side.CLIENT) - public final void registerIcons(IIconRegister aIconRegister) { - // - } - - @Override - public final IIcon getIconFromDamage(int aMetaData) { - return null; - } - - @Override - public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { - long tMaxDamage = getToolMaxDamage(aStack); - Materials tMaterial = getPrimaryMaterial(aStack); - IToolStats tStats = getToolStats(aStack); - int tOffset = getElectricStats(aStack) != null ? 2 : 1; - if (tStats != null) { - if (tStats instanceof GT_Tool_Turbine) { - - // Durability -> toolMaxDamage - // % Efficiency -> toolCombatDamage -> toolQuality - // Optimal Flow -> toolSpeed - // EU/t -> toolCombatDamage, toolSpeed - // Overflow Tier -> toolQuality - float aBaseEff = (5f + getToolCombatDamage(aStack)) * 1000f; - - // It was noted by IntelliJ that replacing ((GT_MetaGenerated_Tool) aStack.getItem()) with - // GT_MetaGenerated_Tool can have side effects. This refactoring will need tests. - @SuppressWarnings("AccessStaticViaInstance") - float aOptFlow = (Math.max( - Float.MIN_NORMAL, - ((GT_MetaGenerated_Tool) aStack.getItem()).getToolStats(aStack) - .getSpeedMultiplier() - * ((GT_MetaGenerated_Tool) aStack.getItem()).getPrimaryMaterial(aStack).mToolSpeed - * 50F)); - aList.add( - tOffset + 0, - EnumChatFormatting.GRAY + String.format( - transItem("001", "Durability: %s/%s"), - "" + EnumChatFormatting.GREEN + formatNumbers(tMaxDamage - getToolDamage(aStack)) + " ", - " " + formatNumbers(tMaxDamage)) + EnumChatFormatting.GRAY); - aList.add( - tOffset + 1, - EnumChatFormatting.GRAY + String.format( - transItem("002", "%s lvl %s"), - tMaterial.mLocalizedName + EnumChatFormatting.YELLOW, - "" + getHarvestLevel(aStack, "")) + EnumChatFormatting.GRAY); - aList.add( - tOffset + 2, - EnumChatFormatting.WHITE - + String.format( - transItem("005", "Turbine Efficiency: %s"), - "" + EnumChatFormatting.BLUE + (50.0F + (10.0F * getToolCombatDamage(aStack)))) - + "%" - + EnumChatFormatting.GRAY); - aList.add( - tOffset + 3, - EnumChatFormatting.WHITE + String.format( - transItem("006", "Optimal Steam flow: %s L/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - GT_Utility.safeInt( - (long) (Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed - * (1000 * getPrimaryMaterial(aStack).mSteamMultiplier / 20))))) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 4, - EnumChatFormatting.WHITE + String.format( - transItem("900", "Energy from Optimal Steam Flow: %s EU/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - GT_Utility.safeInt( - (long) (Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed - * (1000 * getPrimaryMaterial(aStack).mSteamMultiplier / 20)) - * (50.0F + (10.0F * getToolCombatDamage(aStack))) - / 200))) - + EnumChatFormatting.GRAY)); - { - float[] calculatedFlow = calculateLooseFlow(aOptFlow, aBaseEff); - float aOptFlowLoose = calculatedFlow[0]; - float aBaseEffLoose = calculatedFlow[1]; - - aList.add( - tOffset + 5, - EnumChatFormatting.AQUA + String.format( - transItem("500", "Turbine Efficiency (Loose): %s"), - "" + EnumChatFormatting.BLUE + (long) aBaseEffLoose / 100 + "%" + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 6, - EnumChatFormatting.AQUA + String.format( - transItem("501", "Optimal Steam flow (Loose): %s L/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers(((long) aOptFlowLoose * getPrimaryMaterial(aStack).mSteamMultiplier)) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 7, - EnumChatFormatting.AQUA + String.format( - transItem("901", "Energy from Optimal Steam Flow (Loose): %s EU/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - ((long) aOptFlowLoose * getPrimaryMaterial(aStack).mSteamMultiplier / 10000) - * ((long) aBaseEffLoose / 2)) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 8, - EnumChatFormatting.GRAY + "(Superheated Steam EU values are 2x those of Steam)"); - } - aList.add( - tOffset + 9, - EnumChatFormatting.WHITE + String.format( - transItem("902", "Optimal SC Steam flow: %s L/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - GT_Utility.safeInt( - (long) (Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed - * (1000f / 20f))))) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 10, - EnumChatFormatting.WHITE + String.format( - transItem("903", "Energy from Optimal SC Steam Flow: %s EU/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - GT_Utility.safeInt( - (long) (Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed - * (1000f / 20f)) - * (50.0F + (10.0F * getToolCombatDamage(aStack)))))) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 11, - EnumChatFormatting.LIGHT_PURPLE + String.format( - transItem("007", "Energy from Optimal Gas Flow: %s EU/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - GT_Utility.safeInt( - (long) (Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed - * 50 - * getPrimaryMaterial(aStack).mGasMultiplier) - * (50.0F + (10.0F * getToolCombatDamage(aStack))) - / 100))) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 12, - EnumChatFormatting.LIGHT_PURPLE + String.format( - transItem("008", "Energy from Optimal Plasma Flow: %s EU/t"), - "" + EnumChatFormatting.GOLD - + formatNumbers( - GT_Utility.safeInt( - (long) (Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed - * 2000 - * getPrimaryMaterial(aStack).mPlasmaMultiplier) - * (50.0F + (10.0F * getToolCombatDamage(aStack))) - * (1.05 / 100)))) - + EnumChatFormatting.GRAY)); - aList.add( - tOffset + 14, - EnumChatFormatting.GRAY + "(EU/t values include efficiency and are not 100% accurate)"); - int toolQualityLevel = GT_MetaGenerated_Tool.getPrimaryMaterial(aStack).mToolQuality; - int overflowMultiplier = 0; - if (toolQualityLevel >= 6) { - overflowMultiplier = 3; - } else if (toolQualityLevel >= 3) { - overflowMultiplier = 2; - } else { - overflowMultiplier = 1; - } - aList.add( - tOffset + 13, - EnumChatFormatting.LIGHT_PURPLE + String.format( - transItem("502", "Overflow Efficiency Tier: %s"), - "" + EnumChatFormatting.GOLD + overflowMultiplier + EnumChatFormatting.GRAY)); - - } else { - aList.add( - tOffset, - EnumChatFormatting.WHITE + String.format( - transItem("001", "Durability: %s/%s"), - "" + EnumChatFormatting.GREEN + formatNumbers(tMaxDamage - getToolDamage(aStack)) + " ", - " " + formatNumbers(tMaxDamage)) + EnumChatFormatting.GRAY); - aList.add( - tOffset + 1, - EnumChatFormatting.WHITE + String.format( - transItem("002", "%s lvl %s"), - tMaterial.mLocalizedName + EnumChatFormatting.YELLOW, - "" + getHarvestLevel(aStack, "")) + EnumChatFormatting.GRAY); - aList.add( - tOffset + 2, - EnumChatFormatting.WHITE + String.format( - transItem("003", "Attack Damage: %s"), - "" + EnumChatFormatting.BLUE + getToolCombatDamage(aStack)) + EnumChatFormatting.GRAY); - aList.add( - tOffset + 3, - EnumChatFormatting.WHITE - + String.format( - transItem("004", "Mining Speed: %s"), - "" + EnumChatFormatting.GOLD - + Math.max( - Float.MIN_NORMAL, - tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed)) - + EnumChatFormatting.GRAY); - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null && aNBT.hasKey("Heat")) { - int tHeat = aNBT.getInteger("Heat"); - long tWorldTime = aPlayer.getEntityWorld() - .getWorldTime(); - if (aNBT.hasKey("HeatTime")) { - long tHeatTime = aNBT.getLong("HeatTime"); - if (tWorldTime > (tHeatTime + 10)) { - tHeat = (int) (tHeat - ((tWorldTime - tHeatTime) / 10)); - if (tHeat < 300 && tHeat > -10000) tHeat = 300; - } - aNBT.setLong("HeatTime", tWorldTime); - if (tHeat > -10000) aNBT.setInteger("Heat", tHeat); - } - - aList.add( - tOffset + 3, - EnumChatFormatting.RED + "Heat: " - + aNBT.getInteger("Heat") - + " K" - + EnumChatFormatting.GRAY); - } - } - } - } - } - - @Override - public Long[] getFluidContainerStats(ItemStack aStack) { - return null; - } - - @Override - public Long[] getElectricStats(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) { - aNBT = aNBT.getCompoundTag("GT.ToolStats"); - if (aNBT != null && aNBT.getBoolean("Electric")) return new Long[] { aNBT.getLong("MaxCharge"), - aNBT.getLong("Voltage"), aNBT.getLong("Tier"), aNBT.getLong("SpecialData") }; - } - return null; - } - - public float getToolCombatDamage(ItemStack aStack) { - IToolStats tStats = getToolStats(aStack); - if (tStats == null) return 0; - return tStats.getBaseDamage() + getPrimaryMaterial(aStack).mToolQuality; - } - - @Override - public final boolean doDamageToItem(ItemStack aStack, int aVanillaDamage) { - return doDamage(aStack, aVanillaDamage * 100L); - } - - public final boolean doDamage(ItemStack aStack, long aAmount) { - if (!isItemStackUsable(aStack)) return false; - Long[] tElectric = getElectricStats(aStack); - if (tElectric == null) { - long tNewDamage = getToolDamage(aStack) + aAmount; - setToolDamage(aStack, tNewDamage); - if (tNewDamage >= getToolMaxDamage(aStack)) { - IToolStats tStats = getToolStats(aStack); - if (tStats == null || GT_Utility.setStack(aStack, tStats.getBrokenItem(aStack)) == null) { - if (tStats != null) GT_Utility.doSoundAtClient(tStats.getBreakingSound(), 1, 1.0F); - if (aStack.stackSize > 0) aStack.stackSize--; - } - } - return true; - } - if (use(aStack, (int) aAmount, null)) { - if (java.util.concurrent.ThreadLocalRandom.current() - .nextInt(0, 25) == 0) { - long tNewDamage = getToolDamage(aStack) + aAmount; - setToolDamage(aStack, tNewDamage); - if (tNewDamage >= getToolMaxDamage(aStack)) { - IToolStats tStats = getToolStats(aStack); - if (tStats == null || GT_Utility.setStack(aStack, tStats.getBrokenItem(aStack)) == null) { - if (tStats != null) GT_Utility.doSoundAtClient(tStats.getBreakingSound(), 1, 1.0F); - if (aStack.stackSize > 0) aStack.stackSize--; - } - } - } - return true; - } - return false; - } - - @Override - public float getDigSpeed(ItemStack aStack, Block aBlock, int aMetaData) { - if (!isItemStackUsable(aStack)) return 0.0F; - IToolStats tStats = getToolStats(aStack); - if (tStats == null || Math.max(0, getHarvestLevel(aStack, "")) < aBlock.getHarvestLevel(aMetaData)) return 0.0F; - return tStats.isMinableBlock(aBlock, (byte) aMetaData) - ? Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed) - : 0.0F; - } - - @Override - public final boolean canHarvestBlock(Block aBlock, ItemStack aStack) { - return getDigSpeed(aStack, aBlock, (byte) 0) > 0.0F; - } - - @Override - public final int getHarvestLevel(ItemStack aStack, String aToolClass) { - IToolStats tStats = getToolStats(aStack); - return tStats == null ? -1 : tStats.getBaseQuality() + getPrimaryMaterial(aStack).mToolQuality; - } - - @Override - public boolean onBlockDestroyed(ItemStack aStack, World aWorld, Block aBlock, int aX, int aY, int aZ, - EntityLivingBase aPlayer) { - if (!isItemStackUsable(aStack)) return false; - IToolStats tStats = getToolStats(aStack); - if (tStats == null) return false; - GT_Utility.doSoundAtClient(tStats.getMiningSound(), 1, 1.0F); - doDamage( - aStack, - (int) Math.max(1, aBlock.getBlockHardness(aWorld, aX, aY, aZ) * tStats.getToolDamagePerBlockBreak())); - return getDigSpeed(aStack, aBlock, aWorld.getBlockMetadata(aX, aY, aZ)) > 0.0F; - } - - @Override - public final ItemStack getContainerItem(ItemStack aStack) { - return getContainerItem(aStack, true); - } - - @Override - public final boolean hasContainerItem(ItemStack aStack) { - return getContainerItem(aStack, false) != null; - } - - private ItemStack getContainerItem(ItemStack aStack, boolean playSound) { - if (!isItemStackUsable(aStack)) return null; - aStack = GT_Utility.copyAmount(1, aStack); - IToolStats tStats = getToolStats(aStack); - if (tStats == null) return null; - doDamage(aStack, tStats.getToolDamagePerContainerCraft()); - aStack = aStack.stackSize > 0 ? aStack : null; - if (playSound && GT_Mod.gregtechproxy.mTicksUntilNextCraftSound <= 0) { - GT_Mod.gregtechproxy.mTicksUntilNextCraftSound = 10; - String sound = (aStack == null) ? tStats.getBreakingSound() : tStats.getCraftingSound(); - GT_Utility.doSoundAtClient(sound, 1, 1.0F); - } - return aStack; - } - - public IToolStats getToolStats(ItemStack aStack) { - isItemStackUsable(aStack); - return getToolStatsInternal(aStack); - } - - public byte getToolMaxMode(ItemStack aStack) { - IToolStats stats = getToolStats(aStack); - if (stats != null) { - return stats.getMaxMode(); - } - return 1; - } - - private IToolStats getToolStatsInternal(ItemStack aStack) { - return aStack == null ? null : mToolStats.get((short) aStack.getItemDamage()); - } - - @Override - public float getSaplingModifier(ItemStack aStack, World aWorld, EntityPlayer aPlayer, int aX, int aY, int aZ) { - IToolStats tStats = getToolStats(aStack); - return tStats != null && tStats.isGrafter() ? Math.min(100.0F, (1 + getHarvestLevel(aStack, "")) * 20.0F) - : 0.0F; - } - - @Override - public boolean canWhack(EntityPlayer aPlayer, ItemStack aStack, int aX, int aY, int aZ) { - if (!isItemStackUsable(aStack)) return false; - IToolStats tStats = getToolStats(aStack); - return tStats != null && tStats.isCrowbar(); - } - - @Override - public void onWhack(EntityPlayer aPlayer, ItemStack aStack, int aX, int aY, int aZ) { - IToolStats tStats = getToolStats(aStack); - if (tStats != null) doDamage(aStack, tStats.getToolDamagePerEntityAttack()); - } - - @Override - public boolean canWrench(EntityPlayer player, int x, int y, int z) { - if (player == null) return false; - return canWrench(player.getHeldItem(), player, x, y, z); - } - - @Override - public boolean canWrench(ItemStack wrench, EntityPlayer player, int x, int y, int z) { - if (wrench == null) return false; - if (!isItemStackUsable(wrench)) return false; - IToolStats tStats = getToolStats(player.getCurrentEquippedItem()); - return tStats != null && tStats.isWrench(); - } - - @Override - public void wrenchUsed(EntityPlayer player, int x, int y, int z) { - if (player == null) return; - if (player.getCurrentEquippedItem() == null) return; - IToolStats tStats = getToolStats(player.getCurrentEquippedItem()); - if (tStats != null) doDamage(player.getCurrentEquippedItem(), tStats.getToolDamagePerEntityAttack()); - } - - @Override - public boolean canUse(ItemStack stack, EntityPlayer player, int x, int y, int z) { - return canWrench(player, x, y, z); - } - - // ProjectRed screwdriver - @Override - public boolean canUse(EntityPlayer player, ItemStack stack) { - if (player == null) return false; - if (GT_Utility.isStackInvalid(stack) || !isItemStackUsable(stack)) return false; - IToolStats tStats = getToolStats(stack); - return tStats != null && tStats.isScrewdriver(); - } - - @Override - public void damageScrewdriver(EntityPlayer player, ItemStack stack) { - if (player == null) return; - if (GT_Utility.isStackInvalid(stack) || !isItemStackUsable(stack)) return; - IToolStats tStats = getToolStats(stack); - if (tStats != null) doDamage(stack, tStats.getToolDamagePerEntityAttack()); - } - - @Override - public void used(ItemStack stack, EntityPlayer player, int x, int y, int z) { - wrenchUsed(player, x, y, z); - } - - @Override - public boolean shouldHideFacades(ItemStack stack, EntityPlayer player) { - if (player == null) return false; - if (player.getCurrentEquippedItem() == null) return false; - if (!isItemStackUsable(player.getCurrentEquippedItem())) return false; - IToolStats tStats = getToolStats(player.getCurrentEquippedItem()); - return tStats.isWrench(); - } - - @Override - public boolean canLink(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { - if (!isItemStackUsable(aStack)) return false; - IToolStats tStats = getToolStats(aStack); - return tStats != null && tStats.isCrowbar(); - } - - @Override - public void onLink(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { - IToolStats tStats = getToolStats(aStack); - if (tStats != null) doDamage(aStack, tStats.getToolDamagePerEntityAttack()); - } - - @Override - public boolean canBoost(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { - if (!isItemStackUsable(aStack)) return false; - IToolStats tStats = getToolStats(aStack); - return tStats != null && tStats.isCrowbar(); - } - - @Override - public void onBoost(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { - IToolStats tStats = getToolStats(aStack); - if (tStats != null) doDamage(aStack, tStats.getToolDamagePerEntityAttack()); - } - - @Override - public void onCreated(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { - IToolStats tStats = getToolStats(aStack); - if (tStats != null && aPlayer != null) tStats.onToolCrafted(aStack, aPlayer); - super.onCreated(aStack, aWorld, aPlayer); - } - - @Override - public final boolean doesContainerItemLeaveCraftingGrid(ItemStack aStack) { - return false; - } - - @Override - public final int getItemStackLimit(ItemStack aStack) { - return 1; - } - - @Override - public boolean isFull3D() { - return true; - } - - @Override - public boolean isItemStackUsable(ItemStack aStack) { - IToolStats tStats = getToolStatsInternal(aStack); - if (aStack.getItemDamage() % 2 != 0 || tStats == null) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) aNBT.removeTag("ench"); - return false; - } - Materials aMaterial = getPrimaryMaterial(aStack); - HashMap tMap = new HashMap<>(), tResult = new HashMap<>(); - if (aMaterial.mEnchantmentTools != null) { - tMap.put(aMaterial.mEnchantmentTools.effectId, (int) aMaterial.mEnchantmentToolsLevel); - if (aMaterial.mEnchantmentTools == Enchantment.fortune) - tMap.put(Enchantment.looting.effectId, (int) aMaterial.mEnchantmentToolsLevel); - if (aMaterial.mEnchantmentTools == Enchantment.knockback) - tMap.put(Enchantment.power.effectId, (int) aMaterial.mEnchantmentToolsLevel); - if (aMaterial.mEnchantmentTools == Enchantment.fireAspect) - tMap.put(Enchantment.flame.effectId, (int) aMaterial.mEnchantmentToolsLevel); - } - Enchantment[] tEnchants = tStats.getEnchantments(aStack); - int[] tLevels = tStats.getEnchantmentLevels(aStack); - for (int i = 0; i < tEnchants.length; i++) if (tLevels[i] > 0) { - Integer tLevel = tMap.get(tEnchants[i].effectId); - tMap.put( - tEnchants[i].effectId, - tLevel == null ? tLevels[i] : tLevel == tLevels[i] ? tLevel + 1 : Math.max(tLevel, tLevels[i])); - } - for (Entry tEntry : tMap.entrySet()) { - if (tEntry.getKey() == 33 || (tEntry.getKey() == 20 && tEntry.getValue() > 2) - || tEntry.getKey() == Enchantment_Radioactivity.INSTANCE.effectId) - tResult.put(tEntry.getKey(), tEntry.getValue()); - else switch (Enchantment.enchantmentsList[tEntry.getKey()].type) { - case weapon: - if (tStats.isWeapon()) tResult.put(tEntry.getKey(), tEntry.getValue()); - break; - case all: - tResult.put(tEntry.getKey(), tEntry.getValue()); - break; - case armor: - case armor_feet: - case armor_head: - case armor_legs: - case armor_torso: - break; - case bow: - if (tStats.isRangedWeapon()) tResult.put(tEntry.getKey(), tEntry.getValue()); - break; - case breakable: - break; - case fishing_rod: - break; - case digger: - if (tStats.isMiningTool()) tResult.put(tEntry.getKey(), tEntry.getValue()); - break; - } - } - EnchantmentHelper.setEnchantments(tResult, aStack); - return true; - } - - @Override - public String getItemStackDisplayName(ItemStack aStack) { - - String result = super.getItemStackDisplayName(aStack); - IToolStats toolStats = getToolStats(aStack); - if (toolStats != null) { - String toolName = toolStats.getToolTypeName(); - if (toolName == null) return result; - - String key = "gt." + toolName + ".mode." + getToolMode(aStack); - if (StatCollector.canTranslate(key)) { - result += " (" + StatCollector.translateToLocal(key) + ")"; - } - } - return result; - - } - - @Override - public short getChargedMetaData(ItemStack aStack) { - return (short) (aStack.getItemDamage() - (aStack.getItemDamage() % 2)); - } - - @Override - public short getEmptyMetaData(ItemStack aStack) { - NBTTagCompound aNBT = aStack.getTagCompound(); - if (aNBT != null) aNBT.removeTag("ench"); - return (short) (aStack.getItemDamage() + 1 - (aStack.getItemDamage() % 2)); - } - - @Override - public int getItemEnchantability() { - return 0; - } - - @Override - public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { - return false; - } - - @Override - public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { - return false; - } -} diff --git a/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java b/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java deleted file mode 100644 index 2509cf6261..0000000000 --- a/src/main/java/gregtech/api/items/GT_RadioactiveCellIC_Item.java +++ /dev/null @@ -1,219 +0,0 @@ -package gregtech.api.items; - -import java.util.ArrayList; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; - -import gregtech.api.enums.GT_Values; -import gregtech.api.recipe.RecipeMaps; -import gregtech.api.util.GT_Utility; -import ic2.api.reactor.IReactor; -import ic2.api.reactor.IReactorComponent; -import ic2.core.IC2Potion; -import ic2.core.init.MainConfig; -import ic2.core.util.ConfigUtil; - -public class GT_RadioactiveCellIC_Item extends GT_RadioactiveCell_Item implements IReactorComponent { - - private static final int MYSTERIOUS_MULTIPLIER_HEAT = 4; - public final int numberOfCells; - public final float sEnergy; - public final int sRadiation; - public final float sHeat; - public final ItemStack sDepleted; - public final boolean sMox; - - public GT_RadioactiveCellIC_Item(String aUnlocalized, String aEnglish, int aCellcount, int maxDamage, float aEnergy, - int aRadiation, float aHeat, ItemStack aDepleted, boolean aMox) { - super(aUnlocalized, aEnglish, aCellcount); - setMaxStackSize(64); - this.maxDmg = maxDamage; - this.numberOfCells = aCellcount; - this.sEnergy = aEnergy; - this.sRadiation = aRadiation; - this.sHeat = aHeat; - this.sDepleted = aDepleted; - this.sMox = aMox; - if (aDepleted != null && aEnergy > 0 && aHeat > 0) { - // avoid adding depleted cells to recipe map - - int pulses = aCellcount / 2 + 1; - - // for the mysterious constant 5.0f, - // see ic2.core.block.reactor.tileentity.TileEntityNuclearReactorElectric.getOfferedEnergy - // don't ask, just accept - float nukePowerMult = 5.0f * ConfigUtil.getFloat(MainConfig.get(), "balance/energy/generator/nuclear"); - GT_Values.RA.stdBuilder() - .itemInputs(new ItemStack(this)) - .itemOutputs(aDepleted) - .setNEIDesc( - aMox ? "MOX Model" : "Uranium Model", - "Neutron Pulse: " + aCellcount, - aCellcount == 1 - ? String.format("Heat: %.1f * n1 * (n1 + 1)", (aHeat * MYSTERIOUS_MULTIPLIER_HEAT) / 2f) - : String.format( - "Heat: %.1f * (%d + n1) * (%d + n1)", - (aHeat * MYSTERIOUS_MULTIPLIER_HEAT) * aCellcount / 2f, - aCellcount, - aCellcount + 1), - String.format( - "Energy: %.1f + n2 * %.1f EU/t", - aEnergy * aCellcount * pulses * nukePowerMult, - aEnergy * nukePowerMult)) - .duration(0) - .eut(0) - .addTo(RecipeMaps.ic2NuclearFakeRecipes); - } - } - - private static int checkPulseable(IReactor reactor, int x, int y, ItemStack me, int mex, int mey, boolean heatrun) { - ItemStack other = reactor.getItemAt(x, y); - if ((other != null) && ((other.getItem() instanceof IReactorComponent)) - && (((IReactorComponent) other.getItem()) - .acceptUraniumPulse(reactor, other, me, x, y, mex, mey, heatrun))) { - return 1; - } - return 0; - } - - @Override - public void processChamber(IReactor reactor, ItemStack yourStack, int x, int y, boolean heatrun) { - if (!reactor.produceEnergy()) { - return; - } - for (int iteration = 0; iteration < this.numberOfCells; iteration++) { - int pulses = 1 + this.numberOfCells / 2; - if (!heatrun) { - for (int i = 0; i < pulses; i++) { - acceptUraniumPulse(reactor, yourStack, yourStack, x, y, x, y, heatrun); - } - checkPulseable(reactor, x - 1, y, yourStack, x, y, heatrun); - checkPulseable(reactor, x + 1, y, yourStack, x, y, heatrun); - checkPulseable(reactor, x, y - 1, yourStack, x, y, heatrun); - checkPulseable(reactor, x, y + 1, yourStack, x, y, heatrun); - } else { - pulses += checkPulseable(reactor, x - 1, y, yourStack, x, y, heatrun) - + checkPulseable(reactor, x + 1, y, yourStack, x, y, heatrun) - + checkPulseable(reactor, x, y - 1, yourStack, x, y, heatrun) - + checkPulseable(reactor, x, y + 1, yourStack, x, y, heatrun); - - // int heat = sumUp(pulses) * 4; - - int heat = triangularNumber(pulses) * MYSTERIOUS_MULTIPLIER_HEAT; - - heat = getFinalHeat(reactor, yourStack, x, y, heat); - - ArrayList heatAcceptors = new ArrayList<>(); - checkHeatAcceptor(reactor, x - 1, y, heatAcceptors); - checkHeatAcceptor(reactor, x + 1, y, heatAcceptors); - checkHeatAcceptor(reactor, x, y - 1, heatAcceptors); - checkHeatAcceptor(reactor, x, y + 1, heatAcceptors); - heat = Math.round(heat * sHeat); - while ((heatAcceptors.size() > 0) && (heat > 0)) { - - int dheat = heat / heatAcceptors.size(); - heat -= dheat; - dheat = ((IReactorComponent) heatAcceptors.get(0).stack.getItem()).alterHeat( - reactor, - heatAcceptors.get(0).stack, - heatAcceptors.get(0).x, - heatAcceptors.get(0).y, - dheat); - heat += dheat; - heatAcceptors.remove(0); - } - if (heat > 0) { - reactor.addHeat(heat); - } - } - } - if (getDamageOfStack(yourStack) >= getMaxDamageEx() - 1) { - reactor.setItemAt(x, y, sDepleted.copy()); - } else if (heatrun) { - damageItemStack(yourStack, 1); - } - } - - protected int getFinalHeat(IReactor reactor, ItemStack stack, int x, int y, int heat) { - if (sMox && reactor.isFluidCooled()) { - float breedereffectiveness = (float) reactor.getHeat() / (float) reactor.getMaxHeat(); - if (breedereffectiveness > 0.5D) { - heat *= 2; - } - } - return heat; - } - - private void checkHeatAcceptor(IReactor reactor, int x, int y, ArrayList heatAcceptors) { - ItemStack thing = reactor.getItemAt(x, y); - if ((thing != null) && ((thing.getItem() instanceof IReactorComponent)) - && (((IReactorComponent) thing.getItem()).canStoreHeat(reactor, thing, x, y))) { - heatAcceptors.add(new ItemStackCoord(thing, x, y)); - } - } - - @Override - public boolean acceptUraniumPulse(IReactor reactor, ItemStack yourStack, ItemStack pulsingStack, int youX, int youY, - int pulseX, int pulseY, boolean heatrun) { - if (!heatrun) { - if (sMox) { - float breedereffectiveness = (float) reactor.getHeat() / (float) reactor.getMaxHeat(); - float ReaktorOutput = 1.5F * breedereffectiveness + 1.0F; - reactor.addOutput(ReaktorOutput * this.sEnergy); - } else { - reactor.addOutput(1.0F * this.sEnergy); - } - } - return true; - } - - @Override - public boolean canStoreHeat(IReactor reactor, ItemStack yourStack, int x, int y) { - return false; - } - - @Override - public int getMaxHeat(IReactor reactor, ItemStack yourStack, int x, int y) { - return 0; - } - - @Override - public int getCurrentHeat(IReactor reactor, ItemStack yourStack, int x, int y) { - return 0; - } - - @Override - public int alterHeat(IReactor reactor, ItemStack yourStack, int x, int y, int heat) { - return heat; - } - - @Override - public float influenceExplosion(IReactor reactor, ItemStack yourStack) { - return 2 * this.numberOfCells; - } - - @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slotIndex, boolean isCurrentItem) { - if (this.sRadiation > 0 && (entity instanceof EntityLivingBase entityLiving)) { - if (!GT_Utility.isWearingFullRadioHazmat(entityLiving)) { - IC2Potion.radiation.applyTo(entityLiving, sRadiation * 20, sRadiation * 10); - } - } - } - - private static class ItemStackCoord { - - public ItemStack stack; - public int x; - public int y; - - public ItemStackCoord(ItemStack stack1, int x1, int y1) { - this.stack = stack1; - this.x = x1; - this.y = y1; - } - } -} diff --git a/src/main/java/gregtech/api/items/GT_RadioactiveCell_Item.java b/src/main/java/gregtech/api/items/GT_RadioactiveCell_Item.java deleted file mode 100644 index c927737889..0000000000 --- a/src/main/java/gregtech/api/items/GT_RadioactiveCell_Item.java +++ /dev/null @@ -1,159 +0,0 @@ -package gregtech.api.items; - -import static gregtech.api.util.GT_Utility.formatNumbers; - -import java.util.List; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; - -import gregtech.common.items.GT_DepletetCell_Item; -import ic2.api.item.IBoxable; -import ic2.core.util.StackUtil; - -public class GT_RadioactiveCell_Item extends GT_Generic_Item implements IBoxable { - - protected int cellCount; - protected int maxDmg; - protected int dura; - - public GT_RadioactiveCell_Item(String aUnlocalized, String aEnglish, int aCellcount) { - super(aUnlocalized, aEnglish, null); - this.setMaxStackSize(64); - this.setMaxDamage(100); - setNoRepair(); - this.cellCount = Math.max(1, aCellcount); - } - - public static int getDurabilityOfStack(ItemStack aStack) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - aStack.setTagCompound(tNBT); - } - return tNBT.getInteger("advDmg"); - } - - protected static int sumUp(int a) { - int b = 0; - for (int c = 1; c <= a; c++) { - b += c; - } - return b; - } - - protected static int triangularNumber(int x) { - return (x * x + x) / 2; - } - - protected boolean outputPulseForStack(ItemStack aStack) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - aStack.setTagCompound(tNBT); - } - tNBT.setInteger("output", tNBT.getInteger("output") + 1); - return false; // (this.pulserate > 0) || (tNBT.getInteger("output") % -this.pulserate == 0); - } - - protected boolean incrementPulseForStack(ItemStack aStack) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - aStack.setTagCompound(tNBT); - } - tNBT.setInteger("pulse", tNBT.getInteger("pulse") + 1); - return false; // (this.pulserate > 0) || (tNBT.getInteger("pulse") % -this.pulserate == 0); - } - - protected void setDurabilityForStack(ItemStack aStack, int aDurability) { - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - aStack.setTagCompound(tNBT); - } - tNBT.setInteger("durability", aDurability); - } - - public int getMaxNuclearDurability() { - return 0; // return this.maxDelay; - } - - public int func_77619_b() { - return 0; - } - - @Override - public boolean isBookEnchantable(ItemStack ingredient, ItemStack bookEnchant) { - return false; - } - - // getIsRepairable - public boolean func_82789_a(ItemStack toBeRepaired, ItemStack repairWith) { - return false; - } - - public void setDamageForStack(ItemStack stack, int advDmg) { - NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); - nbtData.setInteger("advDmg", advDmg); - if (this.maxDmg > 0) { - double p = (double) advDmg / (double) this.maxDmg; - int newDmg = (int) (stack.getMaxDamage() * p); - if (newDmg >= stack.getMaxDamage()) { - newDmg = stack.getMaxDamage() - 1; - } - stack.setItemDamage(newDmg); - this.dura = newDmg; - } - } - - public int getDamageOfStack(ItemStack stack) { - NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); - this.dura = nbtData.getInteger("advDmg"); - return this.dura; - } - - public int getControlTagOfStack(ItemStack stack) { - NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); - return nbtData.getInteger("tag"); - } - - public void setControlTagOfStack(ItemStack stack, int tag) { - NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); - nbtData.setInteger("tag", tag); - } - - public int getMaxDamageEx() { - return this.maxDmg; - } - - public void damageItemStack(ItemStack stack, int Dmg) { - setDamageForStack(stack, getDamageOfStack(stack) + Dmg); - } - - @Override - public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { - super.addAdditionalToolTips(aList, aStack, aPlayer); - // aList.add("Time left: " + (this.maxDelay - getDurabilityOfStack(aStack)) + " secs"); - int rDmg = getDurabilityOfStack(aStack) * 6 / this.maxDmg; - EnumChatFormatting color2 = switch (rDmg) { - case 0, 1 -> EnumChatFormatting.WHITE; - case 2, 3, 4 -> EnumChatFormatting.GRAY; - default -> EnumChatFormatting.DARK_GRAY; - }; - EnumChatFormatting color1 = this instanceof GT_DepletetCell_Item ? color2 = EnumChatFormatting.DARK_GRAY - : EnumChatFormatting.WHITE; - aList.add( - color1 + String.format( - transItem("001", "Durability: %s/%s"), - "" + color2 + formatNumbers(this.maxDmg - getDurabilityOfStack(aStack)) + color1, - "" + formatNumbers(this.maxDmg))); - } - - @Override - public boolean canBeStoredInToolbox(ItemStack itemstack) { - return true; - } -} diff --git a/src/main/java/gregtech/api/items/GT_Tool_Item.java b/src/main/java/gregtech/api/items/GT_Tool_Item.java deleted file mode 100644 index 9f78bdc3fc..0000000000 --- a/src/main/java/gregtech/api/items/GT_Tool_Item.java +++ /dev/null @@ -1,41 +0,0 @@ -package gregtech.api.items; - -import net.minecraft.item.ItemStack; - -import gregtech.api.util.GT_ModHandler; - -/** - * This is just a basic Tool, which has normal durability and could break Blocks. - */ -public class GT_Tool_Item extends GT_Generic_Item { - - public GT_Tool_Item(String aUnlocalized, String aEnglish, String aTooltip, int aMaxDamage, int aEntityDamage, - boolean aSwingIfUsed) { - this(aUnlocalized, aEnglish, aTooltip, aMaxDamage, aEntityDamage, aSwingIfUsed, -1, -1); - } - - public GT_Tool_Item(String aUnlocalized, String aEnglish, String aTooltip, int aMaxDamage, int aEntityDamage, - boolean aSwingIfUsed, int aChargedGTID, int aDisChargedGTID) { - this( - aUnlocalized, - aEnglish, - aTooltip, - aMaxDamage, - aEntityDamage, - aSwingIfUsed, - aChargedGTID, - aDisChargedGTID, - 0, - 0.0F); - } - - public GT_Tool_Item(String aUnlocalized, String aEnglish, String aTooltip, int aMaxDamage, int aEntityDamage, - boolean aSwingIfUsed, int aChargedGTID, int aDisChargedGTID, int aToolQuality, float aToolStrength) { - super(aUnlocalized, aEnglish, aTooltip); - setMaxDamage(aMaxDamage); - setMaxStackSize(1); - setNoRepair(); - setFull3D(); - GT_ModHandler.registerBoxableItemToToolBox(new ItemStack(this)); - } -} diff --git a/src/main/java/gregtech/api/items/ItemBreederCell.java b/src/main/java/gregtech/api/items/ItemBreederCell.java new file mode 100644 index 0000000000..33a4ce3253 --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemBreederCell.java @@ -0,0 +1,153 @@ +package gregtech.api.items; + +import static gregtech.api.util.GTUtility.formatNumbers; + +import java.util.List; +import java.util.function.Supplier; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; + +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.util.GTUtility; +import ic2.api.reactor.IReactor; +import ic2.api.reactor.IReactorComponent; +import ic2.core.IC2Potion; + +/** + * A {@link ic2.core.item.reactor.ItemReactorLithiumCell}, but can be used to produce anything! + * + * @author glee8e + */ +public class ItemBreederCell extends GTGenericItem implements IReactorComponent { + + protected final int mHeatBonusStep; + protected final int mHeatBonusMultiplier; + protected ItemStack mProduct; + protected boolean deflector = false; + protected boolean hidden = false; + protected boolean neiAdded = false; + + public ItemBreederCell(String aUnlocalized, String aEnglish, String aEnglishTooltip, int aHeatBonusStep, + int aHeatBonusMultiplier, int aRequiredPulse, Supplier aProduct) { + super(aUnlocalized, aEnglish, aEnglishTooltip); + this.mHeatBonusStep = aHeatBonusStep; + this.mHeatBonusMultiplier = aHeatBonusMultiplier; + this.setMaxDamage(aRequiredPulse); + setNoRepair(); + GregTechAPI.sAfterGTPostload.add(() -> { + mProduct = aProduct.get(); + if (!hidden && !neiAdded) { + GTValues.RA.stdBuilder() + .itemInputs(new ItemStack(this)) + .itemOutputs(mProduct) + .setNEIDesc( + deflector ? "Neutron reflecting Breeder" : "Heat neutral Breeder", + String.format("Every %d reactor hull heat", mHeatBonusStep), + String.format("increase speed by %d00%%", mHeatBonusMultiplier), + String.format("Required pulses: %d", getMaxDamage())) + .duration(0) + .eut(0) + .addTo(RecipeMaps.ic2NuclearFakeRecipes); + + neiAdded = true; + } + }); + } + + public ItemBreederCell setDeflector() { + deflector = true; + return this; + } + + public ItemBreederCell setHidden() { + hidden = true; + return this; + } + + @Override + public void onUpdate(ItemStack stack, World world, Entity entity, int slotIndex, boolean isCurrentItem) { + if ((entity instanceof EntityLivingBase entityLiving)) { + if (!GTUtility.isWearingFullRadioHazmat(entityLiving)) { + IC2Potion.radiation.applyTo(entityLiving, 20, 1); + } + } + } + + @Override + public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { + aList.add(transItem("019", "Bath with neutron in a hot reactor")); + int rDmg = aStack.getItemDamage() * 4 / getMaxDamage(); + EnumChatFormatting color2 = switch (rDmg) { + case 0 -> EnumChatFormatting.DARK_GRAY; + case 1, 2 -> EnumChatFormatting.GRAY; + default -> EnumChatFormatting.WHITE; + }; + aList.add( + String.format( + transItem("020", "Progress: %s/%s"), + "" + color2 + formatNumbers(aStack.getItemDamage()) + EnumChatFormatting.RESET, + "" + formatNumbers(getMaxDamage()))); + if (aStack.getItemDamage() > 0) aList.add(EnumChatFormatting.RED + transItem("021", "Radiation Hazard")); + } + + @Override + public int getItemStackLimit(ItemStack stack) { + return stack.getItemDamage() == 0 ? maxStackSize : 1; + } + + @Override + public void processChamber(IReactor reactor, ItemStack yourStack, int x, int y, boolean heatrun) {} + + @Override + public boolean acceptUraniumPulse(IReactor reactor, ItemStack yourStack, ItemStack pulsingStack, int youX, int youY, + int pulseX, int pulseY, boolean heatrun) { + if (heatrun) { + int myLevel = getNewDamage(reactor, yourStack); + if (myLevel >= getMaxDamage()) reactor.setItemAt(youX, youY, mProduct.copy()); + else yourStack.setItemDamage(myLevel); + } + + return deflector; + } + + protected int getNewDamage(IReactor reactor, ItemStack stack) { + return stack.getItemDamage() + 1 + reactor.getHeat() / mHeatBonusStep * mHeatBonusMultiplier; + } + + @Override + public boolean canStoreHeat(IReactor reactor, ItemStack yourStack, int x, int y) { + return false; + } + + @Override + public int getMaxHeat(IReactor reactor, ItemStack yourStack, int x, int y) { + return 0; + } + + @Override + public int getCurrentHeat(IReactor reactor, ItemStack yourStack, int x, int y) { + return 0; + } + + @Override + public int alterHeat(IReactor reactor, ItemStack yourStack, int x, int y, int heat) { + return heat; + } + + @Override + public float influenceExplosion(IReactor reactor, ItemStack yourStack) { + return 0.0F; + } + + @Override + public double getDurabilityForDisplay(ItemStack stack) { + return 1.0D - (double) stack.getItemDamageForDisplay() / (double) stack.getMaxDamage(); + } +} diff --git a/src/main/java/gregtech/api/items/ItemCoolantCell.java b/src/main/java/gregtech/api/items/ItemCoolantCell.java new file mode 100644 index 0000000000..31eb6bc599 --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemCoolantCell.java @@ -0,0 +1,82 @@ +package gregtech.api.items; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; + +import gregtech.api.GregTechAPI; +import ic2.core.util.StackUtil; + +public class ItemCoolantCell extends GTGenericItem { + + protected final int heatStorage; + + public ItemCoolantCell(String aUnlocalized, String aEnglish, int aMaxStore) { + super(aUnlocalized, aEnglish, null); + this.setMaxStackSize(1); + this.setMaxDamage(100); + setNoRepair(); + this.heatStorage = aMaxStore; + this.setCreativeTab(GregTechAPI.TAB_GREGTECH); + } + + protected static int getHeatOfStack(ItemStack aStack) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + aStack.setTagCompound(tNBT); + } + return tNBT.getInteger("heat"); + } + + protected void setHeatForStack(ItemStack aStack, int aHeat) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + aStack.setTagCompound(tNBT); + } + tNBT.setInteger("heat", aHeat); + if (this.heatStorage > 0) { + double heatRatio = (double) aHeat / (double) this.heatStorage; + int damage = (int) (aStack.getMaxDamage() * heatRatio); + if (damage >= aStack.getMaxDamage()) { + damage = aStack.getMaxDamage() - 1; + } + aStack.setItemDamage(damage); + } + } + + @Override + public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { + super.addAdditionalToolTips(aList, aStack, aPlayer); + int rHeat = getHeatOfStack(aStack) * 10 / this.heatStorage; + EnumChatFormatting color = switch (rHeat) { + case 0 -> EnumChatFormatting.BLUE; + case 1, 2 -> EnumChatFormatting.GREEN; + case 3, 4, 5, 6 -> EnumChatFormatting.YELLOW; + case 7, 8 -> EnumChatFormatting.RED; + default -> EnumChatFormatting.DARK_RED; + }; + aList.add( + EnumChatFormatting.WHITE + + String.format(transItem("000", "Stored Heat: %s"), "" + color + getHeatOfStack(aStack))); + if (getControlTagOfStack(aStack) == 1) { + aList.add(StatCollector.translateToLocal("ic2.reactoritem.heatwarning.line1")); + aList.add(StatCollector.translateToLocal("ic2.reactoritem.heatwarning.line2")); + } + } + + public int getControlTagOfStack(ItemStack stack) { + NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); + return nbtData.getInteger("tag"); + } + + public void setControlTagOfStack(ItemStack stack, int tag) { + NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); + nbtData.setInteger("tag", tag); + } +} diff --git a/src/main/java/gregtech/api/items/ItemCoolantCellIC.java b/src/main/java/gregtech/api/items/ItemCoolantCellIC.java new file mode 100644 index 0000000000..00643996d3 --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemCoolantCellIC.java @@ -0,0 +1,67 @@ +package gregtech.api.items; + +import net.minecraft.item.ItemStack; + +import ic2.api.reactor.IReactor; +import ic2.api.reactor.IReactorComponent; + +public class ItemCoolantCellIC extends ItemCoolantCell implements IReactorComponent { + + public ItemCoolantCellIC(String aUnlocalized, String aEnglish, int aMaxStore) { + super(aUnlocalized, aEnglish, aMaxStore); + } + + @Override + public void processChamber(IReactor aReactor, ItemStack aStack, int x, int y, boolean aHeatRun) {} + + @Override + public boolean acceptUraniumPulse(IReactor aReactor, ItemStack aStack, ItemStack pulsingStack, int youX, int youY, + int pulseX, int pulseY, boolean aHeatRun) { + return false; + } + + @Override + public boolean canStoreHeat(IReactor aReactor, ItemStack aStack, int x, int y) { + return !aReactor.isFluidCooled() || getControlTagOfStack(aStack) == 0; + } + + @Override + public int getMaxHeat(IReactor aReactor, ItemStack aStack, int x, int y) { + return this.heatStorage; + } + + @Override + public int getCurrentHeat(IReactor aReactor, ItemStack aStack, int x, int y) { + return getHeatOfStack(aStack); + } + + @Override + public float influenceExplosion(IReactor aReactor, ItemStack aStack) { + return 1.0F + this.heatStorage / 30000.0F; + } + + @Override + public int alterHeat(IReactor aReactor, ItemStack aStack, int x, int y, int aHeat) { + int tHeat = getHeatOfStack(aStack); + if ((tHeat == 0) && (getControlTagOfStack(aStack) != 0)) { + setControlTagOfStack(aStack, 0); + } + tHeat += aHeat; + if (tHeat > this.heatStorage) { + aReactor.setItemAt(x, y, null); + aHeat = this.heatStorage - tHeat + 1; + } else { + if (tHeat < 0) { + aHeat = tHeat; + tHeat = 0; + } else { + aHeat = 0; + } + if ((tHeat > 0) && (getControlTagOfStack(aStack) == 0) && (!aReactor.isFluidCooled())) { + setControlTagOfStack(aStack, 1); + } + setHeatForStack(aStack, tHeat); + } + return aHeat; + } +} diff --git a/src/main/java/gregtech/api/items/ItemEnergyArmor.java b/src/main/java/gregtech/api/items/ItemEnergyArmor.java new file mode 100644 index 0000000000..77c8d0991a --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemEnergyArmor.java @@ -0,0 +1,331 @@ +package gregtech.api.items; + +import static gregtech.api.enums.Mods.GregTech; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.common.ISpecialArmor; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingFallEvent; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; + +public class ItemEnergyArmor extends ItemArmor implements ISpecialArmor { + + public static Map jumpChargeMap = new ConcurrentHashMap<>(); + public int mCharge, mTransfer, mTier, mDamageEnergyCost, mSpecials; + public boolean mChargeProvider; + public double mArmorAbsorbtionPercentage; + + public ItemEnergyArmor(int aID, String aUnlocalized, String aEnglish, int aCharge, int aTransfer, int aTier, + int aDamageEnergyCost, int aSpecials, double aArmorAbsorbtionPercentage, boolean aChargeProvider, int aType, + int aArmorIndex) { + super(ArmorMaterial.DIAMOND, aArmorIndex, aType); + setMaxStackSize(1); + setMaxDamage(100); + setNoRepair(); + setUnlocalizedName(aUnlocalized); + GTLanguageManager.addStringLocalization(getUnlocalizedName() + ".name", aEnglish); + mCharge = Math.max(1, aCharge); + mTransfer = Math.max(1, aTransfer); + mTier = Math.max(1, aTier); + mSpecials = aSpecials; + mChargeProvider = aChargeProvider; + mDamageEnergyCost = Math.max(0, aDamageEnergyCost); + mArmorAbsorbtionPercentage = aArmorAbsorbtionPercentage; + + setCreativeTab(GregTechAPI.TAB_GREGTECH); + + MinecraftForge.EVENT_BUS.register(this); + } + + private static void setCharge(ItemStack aStack) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) tNBT = new NBTTagCompound(); + tNBT.setInteger("charge", 1000000000); + aStack.setTagCompound(tNBT); + } + + @Override + public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + ItemStack tStack = aPlayer.inventory.armorInventory[3 - armorType]; + if (tStack != null) { + for (int i = 0; i < 9; i++) { + if (aPlayer.inventory.mainInventory[i] == aStack) { + aPlayer.inventory.armorInventory[3 - armorType] = aPlayer.inventory.mainInventory[i]; + aPlayer.inventory.mainInventory[i] = tStack; + return tStack; + } + } + } + return super.onItemRightClick(aStack, aWorld, aPlayer); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister aIconRegister) { + this.itemIcon = aIconRegister.registerIcon(GregTech.getResourcePath(getUnlocalizedName())); + } + + @Override + public void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { + aList.add("Tier: " + mTier); + if ((mSpecials & 1) != 0) aList.add("Rebreather"); + if ((mSpecials & 2) != 0) aList.add("Inertia Damper"); + if ((mSpecials & 4) != 0) aList.add("Food Replicator"); + if ((mSpecials & 8) != 0) aList.add("Medicine Module"); + if ((mSpecials & 16) != 0) aList.add("Lamp"); + if ((mSpecials & 32) != 0) aList.add("Solarpanel"); + if ((mSpecials & 64) != 0) aList.add("Extinguisher Module"); + if ((mSpecials & 128) != 0) aList.add("Jump Booster"); + if ((mSpecials & 256) != 0) aList.add("Speed Booster"); + if ((mSpecials & 512) != 0) aList.add("Invisibility Field"); + if ((mSpecials & 1024) != 0) aList.add("Infinite Charge"); + } + + @Override + public void onArmorTick(World aWorld, EntityPlayer aPlayer, ItemStack aStack) { + if (mSpecials == 0) return; + + if (!aPlayer.worldObj.isRemote && (mSpecials & 1) != 0) { + int airSupply = aPlayer.getAir(); + if (GTModHandler.canUseElectricItem(aStack, 1000) && airSupply < 50) { + aPlayer.setAir(airSupply + 250); + GTModHandler.useElectricItem(aStack, 1000, aPlayer); + } + } + + if (!aPlayer.worldObj.isRemote && (mSpecials & 4) != 0) { + if (GTModHandler.canUseElectricItem(aStack, 50000) && aPlayer.getFoodStats() + .needFood()) { + aPlayer.getFoodStats() + .addStats(1, 0.0F); + GTModHandler.useElectricItem(aStack, 50000, aPlayer); + } + } + + if ((mSpecials & 8) != 0) { + if (GTModHandler.canUseElectricItem(aStack, 10000) && aPlayer.isPotionActive(Potion.poison)) { + GTUtility.removePotion(aPlayer, Potion.poison.id); + GTModHandler.useElectricItem(aStack, 10000, aPlayer); + } + if (GTModHandler.canUseElectricItem(aStack, 100000) && aPlayer.isPotionActive(Potion.wither)) { + GTUtility.removePotion(aPlayer, Potion.wither.id); + GTModHandler.useElectricItem(aStack, 100000, aPlayer); + } + } + + if ((mSpecials & 64) != 0) { + aPlayer.setFire(0); + } + + if (!aPlayer.worldObj.isRemote && (mSpecials & 128) != 0) { + float jumpCharge = jumpChargeMap.getOrDefault(aPlayer, 1.0F); + + if (GTModHandler.canUseElectricItem(aStack, 1000) && aPlayer.onGround && jumpCharge < 1.0F) { + jumpCharge = 1.0F; + GTModHandler.useElectricItem(aStack, 1000, aPlayer); + } + + if (aPlayer.motionY >= 0.0D && jumpCharge > 0.0F && !aPlayer.isInWater()) { + if (jumpCharge < 1.0F) { + jumpCharge = 0.0F; + } + } + + jumpChargeMap.put(aPlayer, jumpCharge); + } + + if ((mSpecials & 256) != 0) { + if (GTModHandler.canUseElectricItem(aStack, 100) && aPlayer.isSprinting() + && (aPlayer.onGround && Math.abs(aPlayer.motionX) + Math.abs(aPlayer.motionZ) > 0.10000000149011612D + || aPlayer.isInWater())) { + GTModHandler.useElectricItem(aStack, 100, aPlayer); + float bonus = 0.22F; + + if (aPlayer.isInWater()) { + GTModHandler.useElectricItem(aStack, 100, aPlayer); + bonus = 0.1F; + + if (aPlayer.motionY > 0) { + aPlayer.motionY += 0.10000000149011612D; + } + } + + aPlayer.moveFlying(0.0F, 1.0F, bonus); + } + } + + if ((mSpecials & 512) != 0) { + if (GTModHandler.canUseElectricItem(aStack, 10000)) { + GTModHandler.useElectricItem(aStack, 10000, aPlayer); + aPlayer.addPotionEffect(new PotionEffect(Potion.invisibility.getId(), 25, 1, true)); + } + } + + if (!aPlayer.worldObj.isRemote && (mSpecials & (16 | 32)) != 0) { + // if (GregTechAPI.sWorldTickCounter%20==0) { + ItemStack tTargetChargeItem = aStack, tTargetDechargeItem = aStack; + + if (GTModHandler.chargeElectricItem(tTargetChargeItem, 1, Integer.MAX_VALUE, true, true) < 1) { + tTargetChargeItem = aPlayer.inventory.armorInventory[2]; + } + if (GTModHandler.dischargeElectricItem(tTargetDechargeItem, 10, Integer.MAX_VALUE, true, true, true) < 10) { + tTargetDechargeItem = aPlayer.inventory.armorInventory[2]; + } + + if (tTargetChargeItem == null || !GTModHandler.isElectricItem(tTargetChargeItem)) { + tTargetChargeItem = null; + } + + if (aPlayer.worldObj.isDaytime() && aPlayer.worldObj.canBlockSeeTheSky( + MathHelper.floor_double(aPlayer.posX), + MathHelper.floor_double(aPlayer.posY + 1), + MathHelper.floor_double(aPlayer.posZ))) { + if ((mSpecials & 32) != 0 && tTargetChargeItem != null) { + GTModHandler.chargeElectricItem(tTargetChargeItem, 20, Integer.MAX_VALUE, true, false); + } + } else { + /* + * TODO: if ((mSpecials & 16) != 0 && tTargetDechargeItem != null && + * GTModHandler.canUseElectricItem(tTargetDechargeItem, 10)) { if (aPlayer.worldObj.getBlock + * ((int)aPlayer.posX, (int)aPlayer.posY+1, (int)aPlayer.posZ) == Blocks.air) aPlayer.worldObj.setBlock + * ((int)aPlayer.posX, (int)aPlayer.posY+1, (int)aPlayer.posZ, GregTechAPI.sBlockList[3]); + * GTModHandler.useElectricItem(tTargetDechargeItem, 10, aPlayer); } + */ + // } + } + } + } + + @Override + public boolean getShareTag() { + return true; + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item aItem, CreativeTabs creativeTab, List outputSubItems) { + ItemStack tCharged = new ItemStack(this, 1), tUncharged = new ItemStack(this, 1, getMaxDamage()); + GTModHandler.chargeElectricItem(tCharged, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false); + outputSubItems.add(tCharged); + outputSubItems.add(tUncharged); + } + + public boolean canProvideEnergy(ItemStack aStack) { + if ((mSpecials & 1024) != 0) setCharge(aStack); + return mChargeProvider; + } + + public Item getChargedItem(ItemStack aStack) { + if ((mSpecials & 1024) != 0) setCharge(aStack); + return this; + } + + public Item getEmptyItem(ItemStack aStack) { + if ((mSpecials & 1024) != 0) setCharge(aStack); + return this; + } + + public int getMaxCharge(ItemStack aStack) { + if ((mSpecials & 1024) != 0) setCharge(aStack); + return mCharge; + } + + public int getTier(ItemStack aStack) { + if ((mSpecials & 1024) != 0) setCharge(aStack); + return mTier; + } + + public int getTransferLimit(ItemStack aStack) { + if ((mSpecials & 1024) != 0) setCharge(aStack); + return mTransfer; + } + + @Override + public int getItemEnchantability() { + return 0; + } + + @Override + public boolean isBookEnchantable(ItemStack ingredient, ItemStack bookEnchant) { + return false; + } + + @Override + public boolean getIsRepairable(ItemStack toBeRepaired, ItemStack repairWith) { + return false; + } + + // TODO: @ForgeSubscribe + public void onEntityLivingFallEvent(LivingFallEvent event) { + if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer player) { + for (int i = 0; i < 4; i++) { + ItemStack armor = player.inventory.armorInventory[i]; + if (armor != null && armor.getItem() == this && (mSpecials & 2) != 0) { + int distanceFactor = (int) event.distance - 3; + int energyCost = (this.mDamageEnergyCost * distanceFactor) / 4; + if (energyCost <= GTModHandler + .dischargeElectricItem(armor, Integer.MAX_VALUE, Integer.MAX_VALUE, true, true, true)) { + GTModHandler.dischargeElectricItem(armor, energyCost, Integer.MAX_VALUE, true, false, true); + event.setCanceled(true); + break; + } + } + } + } + } + + @Override + public ISpecialArmor.ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, + double damage, int slotIndex) { + return new ISpecialArmor.ArmorProperties( + (source == DamageSource.fall && (mSpecials & 2) != 0) ? 10 : 0, + getBaseAbsorptionRatio() * mArmorAbsorbtionPercentage, + mDamageEnergyCost > 0 + ? 25 * GTModHandler.dischargeElectricItem(armor, Integer.MAX_VALUE, Integer.MAX_VALUE, true, true, true) + / mDamageEnergyCost + : 0); + } + + @Override + public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slotIndex) { + return (int) Math.round(20.0D * getBaseAbsorptionRatio() * mArmorAbsorbtionPercentage); + } + + @Override + public void damageArmor(EntityLivingBase entity, ItemStack itemStack, DamageSource source, int damage, + int slotIndex) { + GTModHandler.dischargeElectricItem(itemStack, damage * mDamageEnergyCost, Integer.MAX_VALUE, true, false, true); + } + + private double getBaseAbsorptionRatio() { + if (mArmorAbsorbtionPercentage <= 0) return 0.00; + return switch (this.armorType) { + case 0, 3 -> 0.15; + case 1 -> 0.40; + case 2 -> 0.30; + default -> 0.00; + }; + } +} diff --git a/src/main/java/gregtech/api/items/ItemRadioactiveCell.java b/src/main/java/gregtech/api/items/ItemRadioactiveCell.java new file mode 100644 index 0000000000..6efc652ef9 --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemRadioactiveCell.java @@ -0,0 +1,159 @@ +package gregtech.api.items; + +import static gregtech.api.util.GTUtility.formatNumbers; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; + +import gregtech.common.items.ItemDepletedCell; +import ic2.api.item.IBoxable; +import ic2.core.util.StackUtil; + +public class ItemRadioactiveCell extends GTGenericItem implements IBoxable { + + protected int cellCount; + protected int maxDmg; + protected int dura; + + public ItemRadioactiveCell(String aUnlocalized, String aEnglish, int aCellcount) { + super(aUnlocalized, aEnglish, null); + this.setMaxStackSize(64); + this.setMaxDamage(100); + setNoRepair(); + this.cellCount = Math.max(1, aCellcount); + } + + public static int getDurabilityOfStack(ItemStack aStack) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + aStack.setTagCompound(tNBT); + } + return tNBT.getInteger("advDmg"); + } + + protected static int sumUp(int a) { + int b = 0; + for (int c = 1; c <= a; c++) { + b += c; + } + return b; + } + + protected static int triangularNumber(int x) { + return (x * x + x) / 2; + } + + protected boolean outputPulseForStack(ItemStack aStack) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + aStack.setTagCompound(tNBT); + } + tNBT.setInteger("output", tNBT.getInteger("output") + 1); + return false; // (this.pulserate > 0) || (tNBT.getInteger("output") % -this.pulserate == 0); + } + + protected boolean incrementPulseForStack(ItemStack aStack) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + aStack.setTagCompound(tNBT); + } + tNBT.setInteger("pulse", tNBT.getInteger("pulse") + 1); + return false; // (this.pulserate > 0) || (tNBT.getInteger("pulse") % -this.pulserate == 0); + } + + protected void setDurabilityForStack(ItemStack aStack, int aDurability) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + aStack.setTagCompound(tNBT); + } + tNBT.setInteger("durability", aDurability); + } + + public int getMaxNuclearDurability() { + return 0; // return this.maxDelay; + } + + public int func_77619_b() { + return 0; + } + + @Override + public boolean isBookEnchantable(ItemStack ingredient, ItemStack bookEnchant) { + return false; + } + + // getIsRepairable + public boolean func_82789_a(ItemStack toBeRepaired, ItemStack repairWith) { + return false; + } + + public void setDamageForStack(ItemStack stack, int advDmg) { + NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); + nbtData.setInteger("advDmg", advDmg); + if (this.maxDmg > 0) { + double p = (double) advDmg / (double) this.maxDmg; + int newDmg = (int) (stack.getMaxDamage() * p); + if (newDmg >= stack.getMaxDamage()) { + newDmg = stack.getMaxDamage() - 1; + } + stack.setItemDamage(newDmg); + this.dura = newDmg; + } + } + + public int getDamageOfStack(ItemStack stack) { + NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); + this.dura = nbtData.getInteger("advDmg"); + return this.dura; + } + + public int getControlTagOfStack(ItemStack stack) { + NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); + return nbtData.getInteger("tag"); + } + + public void setControlTagOfStack(ItemStack stack, int tag) { + NBTTagCompound nbtData = StackUtil.getOrCreateNbtData(stack); + nbtData.setInteger("tag", tag); + } + + public int getMaxDamageEx() { + return this.maxDmg; + } + + public void damageItemStack(ItemStack stack, int Dmg) { + setDamageForStack(stack, getDamageOfStack(stack) + Dmg); + } + + @Override + public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { + super.addAdditionalToolTips(aList, aStack, aPlayer); + // aList.add("Time left: " + (this.maxDelay - getDurabilityOfStack(aStack)) + " secs"); + int rDmg = getDurabilityOfStack(aStack) * 6 / this.maxDmg; + EnumChatFormatting color2 = switch (rDmg) { + case 0, 1 -> EnumChatFormatting.WHITE; + case 2, 3, 4 -> EnumChatFormatting.GRAY; + default -> EnumChatFormatting.DARK_GRAY; + }; + EnumChatFormatting color1 = this instanceof ItemDepletedCell ? color2 = EnumChatFormatting.DARK_GRAY + : EnumChatFormatting.WHITE; + aList.add( + color1 + String.format( + transItem("001", "Durability: %s/%s"), + "" + color2 + formatNumbers(this.maxDmg - getDurabilityOfStack(aStack)) + color1, + "" + formatNumbers(this.maxDmg))); + } + + @Override + public boolean canBeStoredInToolbox(ItemStack itemstack) { + return true; + } +} diff --git a/src/main/java/gregtech/api/items/ItemRadioactiveCellIC.java b/src/main/java/gregtech/api/items/ItemRadioactiveCellIC.java new file mode 100644 index 0000000000..de60fe9c33 --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemRadioactiveCellIC.java @@ -0,0 +1,219 @@ +package gregtech.api.items; + +import java.util.ArrayList; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import gregtech.api.enums.GTValues; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.util.GTUtility; +import ic2.api.reactor.IReactor; +import ic2.api.reactor.IReactorComponent; +import ic2.core.IC2Potion; +import ic2.core.init.MainConfig; +import ic2.core.util.ConfigUtil; + +public class ItemRadioactiveCellIC extends ItemRadioactiveCell implements IReactorComponent { + + private static final int MYSTERIOUS_MULTIPLIER_HEAT = 4; + public final int numberOfCells; + public final float sEnergy; + public final int sRadiation; + public final float sHeat; + public final ItemStack sDepleted; + public final boolean sMox; + + public ItemRadioactiveCellIC(String aUnlocalized, String aEnglish, int aCellcount, int maxDamage, float aEnergy, + int aRadiation, float aHeat, ItemStack aDepleted, boolean aMox) { + super(aUnlocalized, aEnglish, aCellcount); + setMaxStackSize(64); + this.maxDmg = maxDamage; + this.numberOfCells = aCellcount; + this.sEnergy = aEnergy; + this.sRadiation = aRadiation; + this.sHeat = aHeat; + this.sDepleted = aDepleted; + this.sMox = aMox; + if (aDepleted != null && aEnergy > 0 && aHeat > 0) { + // avoid adding depleted cells to recipe map + + int pulses = aCellcount / 2 + 1; + + // for the mysterious constant 5.0f, + // see ic2.core.block.reactor.tileentity.TileEntityNuclearReactorElectric.getOfferedEnergy + // don't ask, just accept + float nukePowerMult = 5.0f * ConfigUtil.getFloat(MainConfig.get(), "balance/energy/generator/nuclear"); + GTValues.RA.stdBuilder() + .itemInputs(new ItemStack(this)) + .itemOutputs(aDepleted) + .setNEIDesc( + aMox ? "MOX Model" : "Uranium Model", + "Neutron Pulse: " + aCellcount, + aCellcount == 1 + ? String.format("Heat: %.1f * n1 * (n1 + 1)", (aHeat * MYSTERIOUS_MULTIPLIER_HEAT) / 2f) + : String.format( + "Heat: %.1f * (%d + n1) * (%d + n1)", + (aHeat * MYSTERIOUS_MULTIPLIER_HEAT) * aCellcount / 2f, + aCellcount, + aCellcount + 1), + String.format( + "Energy: %.1f + n2 * %.1f EU/t", + aEnergy * aCellcount * pulses * nukePowerMult, + aEnergy * nukePowerMult)) + .duration(0) + .eut(0) + .addTo(RecipeMaps.ic2NuclearFakeRecipes); + } + } + + private static int checkPulseable(IReactor reactor, int x, int y, ItemStack me, int mex, int mey, boolean heatrun) { + ItemStack other = reactor.getItemAt(x, y); + if ((other != null) && ((other.getItem() instanceof IReactorComponent)) + && (((IReactorComponent) other.getItem()) + .acceptUraniumPulse(reactor, other, me, x, y, mex, mey, heatrun))) { + return 1; + } + return 0; + } + + @Override + public void processChamber(IReactor reactor, ItemStack yourStack, int x, int y, boolean heatrun) { + if (!reactor.produceEnergy()) { + return; + } + for (int iteration = 0; iteration < this.numberOfCells; iteration++) { + int pulses = 1 + this.numberOfCells / 2; + if (!heatrun) { + for (int i = 0; i < pulses; i++) { + acceptUraniumPulse(reactor, yourStack, yourStack, x, y, x, y, heatrun); + } + checkPulseable(reactor, x - 1, y, yourStack, x, y, heatrun); + checkPulseable(reactor, x + 1, y, yourStack, x, y, heatrun); + checkPulseable(reactor, x, y - 1, yourStack, x, y, heatrun); + checkPulseable(reactor, x, y + 1, yourStack, x, y, heatrun); + } else { + pulses += checkPulseable(reactor, x - 1, y, yourStack, x, y, heatrun) + + checkPulseable(reactor, x + 1, y, yourStack, x, y, heatrun) + + checkPulseable(reactor, x, y - 1, yourStack, x, y, heatrun) + + checkPulseable(reactor, x, y + 1, yourStack, x, y, heatrun); + + // int heat = sumUp(pulses) * 4; + + int heat = triangularNumber(pulses) * MYSTERIOUS_MULTIPLIER_HEAT; + + heat = getFinalHeat(reactor, yourStack, x, y, heat); + + ArrayList heatAcceptors = new ArrayList<>(); + checkHeatAcceptor(reactor, x - 1, y, heatAcceptors); + checkHeatAcceptor(reactor, x + 1, y, heatAcceptors); + checkHeatAcceptor(reactor, x, y - 1, heatAcceptors); + checkHeatAcceptor(reactor, x, y + 1, heatAcceptors); + heat = Math.round(heat * sHeat); + while ((heatAcceptors.size() > 0) && (heat > 0)) { + + int dheat = heat / heatAcceptors.size(); + heat -= dheat; + dheat = ((IReactorComponent) heatAcceptors.get(0).stack.getItem()).alterHeat( + reactor, + heatAcceptors.get(0).stack, + heatAcceptors.get(0).x, + heatAcceptors.get(0).y, + dheat); + heat += dheat; + heatAcceptors.remove(0); + } + if (heat > 0) { + reactor.addHeat(heat); + } + } + } + if (getDamageOfStack(yourStack) >= getMaxDamageEx() - 1) { + reactor.setItemAt(x, y, sDepleted.copy()); + } else if (heatrun) { + damageItemStack(yourStack, 1); + } + } + + protected int getFinalHeat(IReactor reactor, ItemStack stack, int x, int y, int heat) { + if (sMox && reactor.isFluidCooled()) { + float breedereffectiveness = (float) reactor.getHeat() / (float) reactor.getMaxHeat(); + if (breedereffectiveness > 0.5D) { + heat *= 2; + } + } + return heat; + } + + private void checkHeatAcceptor(IReactor reactor, int x, int y, ArrayList heatAcceptors) { + ItemStack thing = reactor.getItemAt(x, y); + if ((thing != null) && ((thing.getItem() instanceof IReactorComponent)) + && (((IReactorComponent) thing.getItem()).canStoreHeat(reactor, thing, x, y))) { + heatAcceptors.add(new ItemStackCoord(thing, x, y)); + } + } + + @Override + public boolean acceptUraniumPulse(IReactor reactor, ItemStack yourStack, ItemStack pulsingStack, int youX, int youY, + int pulseX, int pulseY, boolean heatrun) { + if (!heatrun) { + if (sMox) { + float breedereffectiveness = (float) reactor.getHeat() / (float) reactor.getMaxHeat(); + float ReaktorOutput = 1.5F * breedereffectiveness + 1.0F; + reactor.addOutput(ReaktorOutput * this.sEnergy); + } else { + reactor.addOutput(1.0F * this.sEnergy); + } + } + return true; + } + + @Override + public boolean canStoreHeat(IReactor reactor, ItemStack yourStack, int x, int y) { + return false; + } + + @Override + public int getMaxHeat(IReactor reactor, ItemStack yourStack, int x, int y) { + return 0; + } + + @Override + public int getCurrentHeat(IReactor reactor, ItemStack yourStack, int x, int y) { + return 0; + } + + @Override + public int alterHeat(IReactor reactor, ItemStack yourStack, int x, int y, int heat) { + return heat; + } + + @Override + public float influenceExplosion(IReactor reactor, ItemStack yourStack) { + return 2 * this.numberOfCells; + } + + @Override + public void onUpdate(ItemStack stack, World world, Entity entity, int slotIndex, boolean isCurrentItem) { + if (this.sRadiation > 0 && (entity instanceof EntityLivingBase entityLiving)) { + if (!GTUtility.isWearingFullRadioHazmat(entityLiving)) { + IC2Potion.radiation.applyTo(entityLiving, sRadiation * 20, sRadiation * 10); + } + } + } + + private static class ItemStackCoord { + + public ItemStack stack; + public int x; + public int y; + + public ItemStackCoord(ItemStack stack1, int x1, int y1) { + this.stack = stack1; + this.x = x1; + this.y = y1; + } + } +} diff --git a/src/main/java/gregtech/api/items/ItemTool.java b/src/main/java/gregtech/api/items/ItemTool.java new file mode 100644 index 0000000000..0de68fc90e --- /dev/null +++ b/src/main/java/gregtech/api/items/ItemTool.java @@ -0,0 +1,41 @@ +package gregtech.api.items; + +import net.minecraft.item.ItemStack; + +import gregtech.api.util.GTModHandler; + +/** + * This is just a basic Tool, which has normal durability and could break Blocks. + */ +public class ItemTool extends GTGenericItem { + + public ItemTool(String aUnlocalized, String aEnglish, String aTooltip, int aMaxDamage, int aEntityDamage, + boolean aSwingIfUsed) { + this(aUnlocalized, aEnglish, aTooltip, aMaxDamage, aEntityDamage, aSwingIfUsed, -1, -1); + } + + public ItemTool(String aUnlocalized, String aEnglish, String aTooltip, int aMaxDamage, int aEntityDamage, + boolean aSwingIfUsed, int aChargedGTID, int aDisChargedGTID) { + this( + aUnlocalized, + aEnglish, + aTooltip, + aMaxDamage, + aEntityDamage, + aSwingIfUsed, + aChargedGTID, + aDisChargedGTID, + 0, + 0.0F); + } + + public ItemTool(String aUnlocalized, String aEnglish, String aTooltip, int aMaxDamage, int aEntityDamage, + boolean aSwingIfUsed, int aChargedGTID, int aDisChargedGTID, int aToolQuality, float aToolStrength) { + super(aUnlocalized, aEnglish, aTooltip); + setMaxDamage(aMaxDamage); + setMaxStackSize(1); + setNoRepair(); + setFull3D(); + GTModHandler.registerBoxableItemToToolBox(new ItemStack(this)); + } +} diff --git a/src/main/java/gregtech/api/items/MetaBaseItem.java b/src/main/java/gregtech/api/items/MetaBaseItem.java new file mode 100644 index 0000000000..23726c96e9 --- /dev/null +++ b/src/main/java/gregtech/api/items/MetaBaseItem.java @@ -0,0 +1,622 @@ +package gregtech.api.items; + +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.util.GTUtility.formatNumbers; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.dispenser.IBlockSource; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.inventory.Container; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; + +import gregtech.api.enums.SubTag; +import gregtech.api.interfaces.IItemBehaviour; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; +import ic2.api.item.ElectricItem; +import ic2.api.item.IElectricItem; +import ic2.api.item.IElectricItemManager; +import ic2.api.item.ISpecialElectricItem; + +public abstract class MetaBaseItem extends GTGenericItem + implements ISpecialElectricItem, IElectricItemManager, IFluidContainerItem { + + /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */ + private final ConcurrentHashMap>> mItemBehaviors = new ConcurrentHashMap<>(); + + /** + * Creates the Item using these Parameters. + * + * @param aUnlocalized The Unlocalized Name of this Item. + */ + public MetaBaseItem(String aUnlocalized) { + super(aUnlocalized, "Generated Item", null); + setHasSubtypes(true); + setMaxDamage(0); + } + + /** + * Adds a special Item Behaviour to the Item. + *

+ * Note: the boolean Behaviours sometimes won't be executed if another boolean Behaviour returned true before. + * + * @param aMetaValue the Meta Value of the Item you want to add it to. [0 - 32765] + * @param aBehavior the Click Behavior you want to add. + * @return the Item itself for convenience in constructing. + */ + public final MetaBaseItem addItemBehavior(int aMetaValue, IItemBehaviour aBehavior) { + if (aMetaValue < 0 || aMetaValue >= 32766 || aBehavior == null) return this; + ArrayList> tList = mItemBehaviors + .computeIfAbsent((short) aMetaValue, k -> new ArrayList<>(1)); + tList.add(aBehavior); + return this; + } + + public abstract Long[] getElectricStats(ItemStack aStack); + + public abstract Long[] getFluidContainerStats(ItemStack aStack); + + @Override + public boolean hasProjectile(SubTag aProjectileType, ItemStack aStack) { + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) + if (tBehavior.hasProjectile(this, aProjectileType, aStack)) return true; + return super.hasProjectile(aProjectileType, aStack); + } + + @Override + public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, double aX, double aY, + double aZ) { + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) { + EntityArrow rArrow = tBehavior.getProjectile(this, aProjectileType, aStack, aWorld, aX, aY, aZ); + if (rArrow != null) return rArrow; + } + return super.getProjectile(aProjectileType, aStack, aWorld, aX, aY, aZ); + } + + @Override + public EntityArrow getProjectile(SubTag aProjectileType, ItemStack aStack, World aWorld, EntityLivingBase aEntity, + float aSpeed) { + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) { + EntityArrow rArrow = tBehavior.getProjectile(this, aProjectileType, aStack, aWorld, aEntity, aSpeed); + if (rArrow != null) return rArrow; + } + return super.getProjectile(aProjectileType, aStack, aWorld, aEntity, aSpeed); + } + + @Override + public ItemStack onDispense(IBlockSource aSource, ItemStack aStack) { + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) + if (tBehavior.canDispense(this, aSource, aStack)) return tBehavior.onDispense(this, aSource, aStack); + return super.onDispense(aSource, aStack); + } + + @Override + public boolean isItemStackUsable(ItemStack aStack) { + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) + if (!tBehavior.isItemStackUsable(this, aStack)) return false; + return super.isItemStackUsable(aStack); + } + + @Override + public boolean onLeftClickEntity(ItemStack aStack, EntityPlayer aPlayer, Entity aEntity) { + use(aStack, 0, aPlayer); + isItemStackUsable(aStack); + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + try { + if (tList != null) for (IItemBehaviour tBehavior : tList) + if (tBehavior.onLeftClickEntity(this, aStack, aPlayer, aEntity)) { + if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); + return true; + } + if (aStack.stackSize <= 0) { + aPlayer.destroyCurrentEquippedItem(); + return false; + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return false; + } + + @Override + public boolean onItemUse(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + int ordinalSide, float hitX, float hitY, float hitZ) { + use(aStack, 0, aPlayer); + isItemStackUsable(aStack); + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + try { + if (tList != null) for (IItemBehaviour tBehavior : tList) + if (tBehavior.onItemUse(this, aStack, aPlayer, aWorld, aX, aY, aZ, ordinalSide, hitX, hitY, hitZ)) { + if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); + return true; + } + if (aStack.stackSize <= 0) { + aPlayer.destroyCurrentEquippedItem(); + return false; + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return false; + } + + @Override + public boolean onItemUseFirst(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + int ordinalSide, float hitX, float hitY, float hitZ) { + use(aStack, 0, aPlayer); + isItemStackUsable(aStack); + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + try { + if (tList != null) for (IItemBehaviour tBehavior : tList) if (tBehavior.onItemUseFirst( + this, + aStack, + aPlayer, + aWorld, + aX, + aY, + aZ, + ForgeDirection.getOrientation(ordinalSide), + hitX, + hitY, + hitZ)) { + if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); + return true; + } + if (aStack.stackSize <= 0) { + aPlayer.destroyCurrentEquippedItem(); + return false; + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return false; + } + + @Override + public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + use(aStack, 0, aPlayer); + isItemStackUsable(aStack); + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + try { + if (tList != null) for (IItemBehaviour tBehavior : tList) + aStack = tBehavior.onItemRightClick(this, aStack, aWorld, aPlayer); + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return aStack; + } + + @Override + public final void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { + String tKey = getUnlocalizedName(aStack) + ".tooltip"; + String[] tStrings = GTLanguageManager.getTranslation(tKey) + .split("/n "); + for (String tString : tStrings) + if (GTUtility.isStringValid(tString) && !tKey.equals(tString)) aList.add(tString); + + Long[] tStats = getElectricStats(aStack); + if (tStats != null) { + if (tStats[3] > 0) { + aList.add( + EnumChatFormatting.AQUA + String.format( + transItem("009", "Contains %s EU Tier: %s"), + formatNumbers(tStats[3]), + "" + (tStats[2] >= 0 ? tStats[2] : 0)) + EnumChatFormatting.GRAY); + } else { + long tCharge = getRealCharge(aStack); + if (tStats[3] == -2 && tCharge <= 0) { + aList.add( + EnumChatFormatting.AQUA + transItem("010", "Empty. You should recycle it properly.") + + EnumChatFormatting.GRAY); + } else { + aList.add( + EnumChatFormatting.AQUA + + String.format( + transItem("011", "%s / %s EU - Voltage: %s"), + formatNumbers(tCharge), + formatNumbers(Math.abs(tStats[0])), + "" + V[(int) (tStats[2] >= 0 ? tStats[2] < V.length ? tStats[2] : V.length - 1 : 1)]) + + EnumChatFormatting.GRAY); + } + } + } + + tStats = getFluidContainerStats(aStack); + if (tStats != null && tStats[0] > 0) { + FluidStack tFluid = getFluidContent(aStack); + aList.add( + EnumChatFormatting.BLUE + ((tFluid == null ? transItem("012", "No Fluids Contained") + : GTUtility.getFluidName(tFluid, true))) + EnumChatFormatting.GRAY); + aList.add( + EnumChatFormatting.BLUE + String.format( + transItem("013", "%sL / %sL"), + "" + (tFluid == null ? 0 : formatNumbers(tFluid.amount)), + "" + formatNumbers(tStats[0])) + EnumChatFormatting.GRAY); + } + + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) + aList = tBehavior.getAdditionalToolTips(this, aList, aStack); + + addAdditionalToolTips(aList, aStack, aPlayer); + } + + @Override + public void onUpdate(ItemStack aStack, World aWorld, Entity aPlayer, int aTimer, boolean aIsInHand) { + ArrayList> tList = mItemBehaviors.get((short) getDamage(aStack)); + if (tList != null) for (IItemBehaviour tBehavior : tList) + tBehavior.onUpdate(this, aStack, aWorld, aPlayer, aTimer, aIsInHand); + } + + @Override + public final boolean canProvideEnergy(ItemStack aStack) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null) return false; + return tStats[3] > 0 || (aStack.stackSize == 1 && (tStats[3] == -2 || tStats[3] == -3)); + } + + @Override + public final double getMaxCharge(ItemStack aStack) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null) return 0; + return Math.abs(tStats[0]); + } + + @Override + public final double getTransferLimit(ItemStack aStack) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null) return 0; + return Math.max(tStats[1], tStats[3]); + } + + @Override + public final double charge(ItemStack aStack, double aCharge, int aTier, boolean aIgnoreTransferLimit, + boolean aSimulate) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null || tStats[2] > aTier + || !(tStats[3] == -1 || tStats[3] == -3 || (tStats[3] < 0 && aCharge == Integer.MAX_VALUE)) + || aStack.stackSize != 1) return 0; + long tTransfer = aIgnoreTransferLimit ? (long) aCharge : Math.min(tStats[1], (long) aCharge); + long tChargeBefore = getRealCharge(aStack), tNewCharge = Math.min( + Math.abs(tStats[0]), + Long.MAX_VALUE - tTransfer >= tChargeBefore ? tChargeBefore + tTransfer : Long.MAX_VALUE); + if (!aSimulate) setCharge(aStack, tNewCharge); + return tNewCharge - tChargeBefore; + } + + @Override + public final double discharge(ItemStack aStack, double aCharge, int aTier, boolean aIgnoreTransferLimit, + boolean aBatteryAlike, boolean aSimulate) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null || tStats[2] > aTier) return 0; + if (aBatteryAlike && !canProvideEnergy(aStack)) return 0; + if (tStats[3] > 0) { + if (aCharge < tStats[3] || aStack.stackSize < 1) return 0; + if (!aSimulate) aStack.stackSize--; + return tStats[3]; + } + long tChargeBefore = getRealCharge(aStack), tNewCharge = Math + .max(0, tChargeBefore - (aIgnoreTransferLimit ? (long) aCharge : Math.min(tStats[1], (long) aCharge))); + if (!aSimulate) setCharge(aStack, tNewCharge); + return tChargeBefore - tNewCharge; + } + + @Override + public final double getCharge(ItemStack aStack) { + return getRealCharge(aStack); + } + + @Override + public final boolean canUse(ItemStack aStack, double aAmount) { + return getRealCharge(aStack) >= aAmount; + } + + @Override + public final boolean use(ItemStack aStack, double aAmount, EntityLivingBase aPlayer) { + chargeFromArmor(aStack, aPlayer); + if (aPlayer instanceof EntityPlayer && ((EntityPlayer) aPlayer).capabilities.isCreativeMode) return true; + double tTransfer = discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, true); + if (Math.abs(tTransfer - aAmount) < .0000001) { + discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, false); + chargeFromArmor(aStack, aPlayer); + return true; + } + discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, false); + chargeFromArmor(aStack, aPlayer); + return false; + } + + @Override + public final void chargeFromArmor(ItemStack aStack, EntityLivingBase aPlayer) { + if (aPlayer == null || aPlayer.worldObj.isRemote) return; + for (int i = 1; i < 5; i++) { + ItemStack tArmor = aPlayer.getEquipmentInSlot(i); + if (GTModHandler.isElectricItem(tArmor)) { + IElectricItem tArmorItem = (IElectricItem) tArmor.getItem(); + if (tArmorItem.canProvideEnergy(tArmor) && tArmorItem.getTier(tArmor) >= getTier(aStack)) { + double tCharge = ElectricItem.manager.discharge( + tArmor, + charge(aStack, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, true, true), + Integer.MAX_VALUE, + true, + true, + false); + if (tCharge > 0) { + charge(aStack, tCharge, Integer.MAX_VALUE, true, false); + if (aPlayer instanceof EntityPlayer) { + Container tContainer = ((EntityPlayer) aPlayer).openContainer; + if (tContainer != null) tContainer.detectAndSendChanges(); + } + } + } + } + } + } + + /* + * @Override public final int getMaxCharge(ItemStack aStack) { Long[] tStats = getElectricStats(aStack); if (tStats + * == null) return 0; return (int)Math.abs(tStats[0]); } + * @Override public final int getTransferLimit(ItemStack aStack) { Long[] tStats = getElectricStats(aStack); if + * (tStats == null) return 0; return (int)Math.max(tStats[1], tStats[3]); } + * @Override public final int charge(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreTransferLimit, boolean + * aSimulate) { Long[] tStats = getElectricStats(aStack); if (tStats == null || tStats[2] > aTier || !(tStats[3] == + * -1 || tStats[3] == -3 || (tStats[3] < 0 && aCharge == Integer.MAX_VALUE)) || aStack.stackSize != 1) return 0; + * long tChargeBefore = getRealCharge(aStack), tNewCharge = + * aCharge==Integer.MAX_VALUE?Long.MAX_VALUE:Math.min(Math.abs(tStats[0]), tChargeBefore + + * (aIgnoreTransferLimit?aCharge:Math.min(tStats[1], aCharge))); if (!aSimulate) setCharge(aStack, tNewCharge); + * return (int)(tNewCharge-tChargeBefore); } + * @Override public final int discharge(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreTransferLimit, + * boolean aSimulate) { Long[] tStats = getElectricStats(aStack); if (tStats == null || tStats[2] > aTier) return 0; + * if (tStats[3] > 0) { if (aCharge < tStats[3] || aStack.stackSize < 1) return 0; if (!aSimulate) + * aStack.stackSize--; return (int)(long)tStats[3]; } long tChargeBefore = getRealCharge(aStack), tNewCharge = + * Math.max(0, tChargeBefore - (aIgnoreTransferLimit?aCharge:Math.min(tStats[1], aCharge))); if (!aSimulate) + * setCharge(aStack, tNewCharge); return (int)(tChargeBefore-tNewCharge); } + * @Override public final int getCharge(ItemStack aStack) { return (int)Math.min(Integer.MAX_VALUE, + * getRealCharge(aStack)); } + * @Override public final boolean canUse(ItemStack aStack, int aAmount) { return getRealCharge(aStack) >= aAmount; } + * @Override public final boolean use(ItemStack aStack, int aAmount, EntityLivingBase aPlayer) { + * chargeFromArmor(aStack, aPlayer); if (aPlayer instanceof EntityPlayer && + * ((EntityPlayer)aPlayer).capabilities.isCreativeMode) return true; int tTransfer = discharge(aStack, aAmount, + * Integer.MAX_VALUE, true, true); if (tTransfer == aAmount) { discharge(aStack, aAmount, Integer.MAX_VALUE, true, + * false); chargeFromArmor(aStack, aPlayer); return true; } discharge(aStack, aAmount, Integer.MAX_VALUE, true, + * false); chargeFromArmor(aStack, aPlayer); return false; } + * @Override public final void chargeFromArmor(ItemStack aStack, EntityLivingBase aPlayer) { if (aPlayer == null || + * aPlayer.worldObj.isRemote) return; for (int i = 1; i < 5; i++) { ItemStack tArmor = + * aPlayer.getEquipmentInSlot(i); if (GTModHandler.isElectricItem(tArmor)) { IElectricItem tArmorItem = + * (IElectricItem)tArmor.getItem(); if (tArmorItem.canProvideEnergy(tArmor) && tArmorItem.getTier(tArmor) >= + * getTier(aStack)) { int tCharge = ElectricItem.manager.discharge(tArmor, charge(aStack, Integer.MAX_VALUE-1, + * Integer.MAX_VALUE, true, true), Integer.MAX_VALUE, true, false); if (tCharge > 0) { charge(aStack, tCharge, + * Integer.MAX_VALUE, true, false); if (aPlayer instanceof EntityPlayer) { Container tContainer = + * ((EntityPlayer)aPlayer).openContainer; if (tContainer != null) tContainer.detectAndSendChanges(); } } } } } } + */ + public final long getRealCharge(ItemStack aStack) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null) return 0; + if (tStats[3] > 0) return (int) (long) tStats[3]; + NBTTagCompound tNBT = aStack.getTagCompound(); + return tNBT == null ? 0 : tNBT.getLong("GT.ItemCharge"); + } + + public final boolean setCharge(ItemStack aStack, long aCharge) { + Long[] tStats = getElectricStats(aStack); + if (tStats == null || tStats[3] > 0) return false; + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) tNBT = new NBTTagCompound(); + tNBT.removeTag("GT.ItemCharge"); + aCharge = Math.min(tStats[0] < 0 ? Math.abs(tStats[0] / 2) : aCharge, Math.abs(tStats[0])); + if (aCharge > 0) { + aStack.setItemDamage(getChargedMetaData(aStack)); + tNBT.setLong("GT.ItemCharge", aCharge); + } else { + aStack.setItemDamage(getEmptyMetaData(aStack)); + } + if (tNBT.hasNoTags()) aStack.setTagCompound(null); + else aStack.setTagCompound(tNBT); + isItemStackUsable(aStack); + return true; + } + + public short getChargedMetaData(ItemStack aStack) { + return (short) aStack.getItemDamage(); + } + + public short getEmptyMetaData(ItemStack aStack) { + return (short) aStack.getItemDamage(); + } + + @Override + public FluidStack getFluid(ItemStack aStack) { + return getFluidContent(aStack); + } + + @Override + public int getCapacity(ItemStack aStack) { + Long[] tStats = getFluidContainerStats(aStack); + return tStats == null ? 0 : (int) Math.max(0, tStats[0]); + } + + @Override + public int fill(ItemStack aStack, FluidStack aFluid, boolean doFill) { + if (aStack == null || aStack.stackSize != 1) return 0; + + ItemStack tStack = GTUtility.fillFluidContainer(aFluid, aStack, false, false); + if (tStack != null) { + aStack.setItemDamage(tStack.getItemDamage()); + aStack.func_150996_a(tStack.getItem()); + return GTUtility.getFluidForFilledItem(tStack, false).amount; + } + + Long[] tStats = getFluidContainerStats(aStack); + if (tStats == null || tStats[0] <= 0 + || aFluid == null + || aFluid.getFluid() + .getID() <= 0 + || aFluid.amount <= 0) return 0; + + FluidStack tFluid = getFluidContent(aStack); + + if (tFluid == null || tFluid.getFluid() + .getID() <= 0) { + if (aFluid.amount <= tStats[0]) { + if (doFill) { + setFluidContent(aStack, aFluid); + } + return aFluid.amount; + } + if (doFill) { + tFluid = aFluid.copy(); + tFluid.amount = (int) (long) tStats[0]; + setFluidContent(aStack, tFluid); + } + return (int) (long) tStats[0]; + } + + if (!tFluid.isFluidEqual(aFluid)) return 0; + + int space = (int) (long) tStats[0] - tFluid.amount; + if (aFluid.amount <= space) { + if (doFill) { + tFluid.amount += aFluid.amount; + setFluidContent(aStack, tFluid); + } + return aFluid.amount; + } + if (doFill) { + tFluid.amount = (int) (long) tStats[0]; + setFluidContent(aStack, tFluid); + } + return space; + } + + @Override + public FluidStack drain(ItemStack aStack, int maxDrain, boolean doDrain) { + if (aStack == null || aStack.stackSize != 1) return null; + + FluidStack tFluid = GTUtility.getFluidForFilledItem(aStack, false); + if (tFluid != null && maxDrain >= tFluid.amount) { + ItemStack tStack = GTUtility.getContainerItem(aStack, false); + if (tStack == null) { + if (doDrain) aStack.stackSize = 0; + return tFluid; + } + if (doDrain) { + aStack.setItemDamage(tStack.getItemDamage()); + aStack.func_150996_a(tStack.getItem()); + } + return tFluid; + } + + Long[] tStats = getFluidContainerStats(aStack); + if (tStats == null || tStats[0] <= 0) return null; + + tFluid = getFluidContent(aStack); + if (tFluid == null) return null; + + int used = maxDrain; + if (tFluid.amount < used) used = tFluid.amount; + if (doDrain) { + tFluid.amount -= used; + setFluidContent(aStack, tFluid); + } + + FluidStack drained = tFluid.copy(); + drained.amount = used; + return drained; + } + + public FluidStack getFluidContent(ItemStack aStack) { + Long[] tStats = getFluidContainerStats(aStack); + if (tStats == null || tStats[0] <= 0) return GTUtility.getFluidForFilledItem(aStack, false); + NBTTagCompound tNBT = aStack.getTagCompound(); + return tNBT == null ? null : FluidStack.loadFluidStackFromNBT(tNBT.getCompoundTag("GT.FluidContent")); + } + + public void setFluidContent(ItemStack aStack, FluidStack aFluid) { + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT == null) tNBT = new NBTTagCompound(); + else tNBT.removeTag("GT.FluidContent"); + if (aFluid != null && aFluid.amount > 0) + tNBT.setTag("GT.FluidContent", aFluid.writeToNBT(new NBTTagCompound())); + if (tNBT.hasNoTags()) aStack.setTagCompound(null); + else aStack.setTagCompound(tNBT); + isItemStackUsable(aStack); + } + + @Override + public int getItemStackLimit(ItemStack aStack) { + Long[] tStats = getElectricStats(aStack); + if (tStats != null && (tStats[3] == -1 || tStats[3] == -2 || tStats[3] == -3) && getRealCharge(aStack) > 0) + return 1; + tStats = getFluidContainerStats(aStack); + if (tStats != null) return (int) (long) tStats[1]; + if (getDamage(aStack) == 32763) return 1; + return 64; + } + + @Override + public final Item getChargedItem(ItemStack itemStack) { + return this; + } + + @Override + public final Item getEmptyItem(ItemStack itemStack) { + return this; + } + + @Override + public final int getTier(ItemStack aStack) { + Long[] tStats = getElectricStats(aStack); + return (int) (tStats == null ? Integer.MAX_VALUE : tStats[2]); + } + + @Override + public final String getToolTip(ItemStack aStack) { + return null; + } // This has its own ToolTip Handler, no need to let the IC2 Handler screw us up at this Point + + @Override + public final IElectricItemManager getManager(ItemStack aStack) { + return this; + } // We are our own Manager + + @Override + public final boolean getShareTag() { + return true; + } // just to be sure. + + @Override + public int getItemEnchantability() { + return 0; + } + + @Override + public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { + return false; + } + + @Override + public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { + return false; + } +} diff --git a/src/main/java/gregtech/api/items/MetaGeneratedItem.java b/src/main/java/gregtech/api/items/MetaGeneratedItem.java new file mode 100644 index 0000000000..449b1ced24 --- /dev/null +++ b/src/main/java/gregtech/api/items/MetaGeneratedItem.java @@ -0,0 +1,415 @@ +package gregtech.api.items; + +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.Mods.AppleCore; +import static gregtech.api.enums.Mods.GregTech; +import static gregtech.api.recipe.RecipeMaps.cannerRecipes; +import static gregtech.api.util.GTRecipeBuilder.SECONDS; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.Mods; +import gregtech.api.enums.SubTag; +import gregtech.api.enums.TCAspects.TC_AspectStack; +import gregtech.api.interfaces.IFoodStat; +import gregtech.api.interfaces.IGT_ItemWithMaterialRenderer; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.IItemBehaviour; +import gregtech.api.interfaces.IItemContainer; +import gregtech.api.objects.ItemData; +import gregtech.api.util.GTConfig; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import gregtech.common.render.items.GeneratedMaterialRenderer; +import squeek.applecore.api.food.FoodValues; +import squeek.applecore.api.food.IEdible; +import squeek.applecore.api.food.ItemFoodProxy; + +/** + * @author Gregorius Techneticies + *

+ * One Item for everything! + *

+ * This brilliant Item Class is used for automatically generating all possible variations of Material Items, + * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always + * have to make a new Item SubType for each OreDict Prefix, when adding a new Material. + *

+ * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom + * defined, just to save space and MetaData. + *

+ * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike + * Item. + */ +@Optional.Interface(iface = "squeek.applecore.api.food.IEdible", modid = Mods.Names.APPLE_CORE) +public abstract class MetaGeneratedItem extends MetaBaseItem implements IGT_ItemWithMaterialRenderer, IEdible { + + /** + * All instances of this Item Class are listed here. This gets used to register the Renderer to all Items of this + * Type, if useStandardMetaItemRenderer() returns true. + *

+ * You can also use the unlocalized Name gotten from getUnlocalizedName() as Key if you want to get a specific Item. + */ + public static final ConcurrentHashMap sInstances = new ConcurrentHashMap<>(); + + /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */ + + public final short mOffset, mItemAmount; + public final BitSet mEnabledItems; + public final BitSet mVisibleItems; + public final IIcon[][] mIconList; + + public final ConcurrentHashMap mFoodStats = new ConcurrentHashMap<>(); + public final ConcurrentHashMap mElectricStats = new ConcurrentHashMap<>(); + public final ConcurrentHashMap mFluidContainerStats = new ConcurrentHashMap<>(); + public final ConcurrentHashMap mBurnValues = new ConcurrentHashMap<>(); + + /** + * Creates the Item using these Parameters. + * + * @param aUnlocalized The Unlocalized Name of this Item. + */ + public MetaGeneratedItem(String aUnlocalized, short aOffset, short aItemAmount) { + super(aUnlocalized); + setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + setHasSubtypes(true); + setMaxDamage(0); + mEnabledItems = new BitSet(aItemAmount); + mVisibleItems = new BitSet(aItemAmount); + + mOffset = (short) Math.min(32766, aOffset); + mItemAmount = (short) Math.min(aItemAmount, 32766 - mOffset); + mIconList = new IIcon[aItemAmount][1]; + + sInstances.put(getUnlocalizedName(), this); + } + + /** + * This adds a Custom Item to the ending Range. + * + * @param aID The Id of the assigned Item [0 - mItemAmount] (The MetaData gets auto-shifted by +mOffset) + * @param aEnglish The Default Localized Name of the created Item + * @param aToolTip The Default ToolTip of the created Item, you can also insert null for having no ToolTip + * @param aRandomData The OreDict Names you want to give the Item. Also used for TC Aspects and some other things. + * @return An ItemStack containing the newly created Item. + */ + public final ItemStack addItem(int aID, String aEnglish, String aToolTip, Object... aRandomData) { + if (aToolTip == null) aToolTip = ""; + if (aID >= 0 && aID < mItemAmount) { + ItemStack rStack = new ItemStack(this, 1, mOffset + aID); + if (mEnabledItems.get(aID)) { + throw new IllegalArgumentException( + String.format("ID %s is already reserved for %s!", aID, rStack.getDisplayName())); + } + mEnabledItems.set(aID); + mVisibleItems.set(aID); + GTLanguageManager.addStringLocalization(getUnlocalizedName(rStack) + ".name", aEnglish); + GTLanguageManager.addStringLocalization(getUnlocalizedName(rStack) + ".tooltip", aToolTip); + List tAspects = new ArrayList<>(); + // Important Stuff to do first + for (Object tRandomData : aRandomData) if (tRandomData instanceof SubTag) { + if (tRandomData == SubTag.INVISIBLE) { + mVisibleItems.set(aID, false); + continue; + } + if (tRandomData == SubTag.NO_UNIFICATION) { + GTOreDictUnificator.addToBlacklist(rStack); + } + } + // now check for the rest + for (Object tRandomData : aRandomData) if (tRandomData != null) { + boolean tUseOreDict = true; + if (tRandomData instanceof IFoodStat) { + setFoodBehavior(mOffset + aID, (IFoodStat) tRandomData); + if (((IFoodStat) tRandomData).getFoodAction(this, rStack) == EnumAction.eat) { + int tFoodValue = ((IFoodStat) tRandomData).getFoodLevel(this, rStack, null); + if (tFoodValue > 0) { + GTValues.RA.stdBuilder() + .itemInputs(rStack, ItemList.IC2_Food_Can_Empty.get(tFoodValue)) + .itemOutputs( + ((IFoodStat) tRandomData).isRotten(this, rStack, null) + ? ItemList.IC2_Food_Can_Spoiled.get(tFoodValue) + : ItemList.IC2_Food_Can_Filled.get(tFoodValue)) + .duration(tFoodValue * 5 * SECONDS) + .eut(1) + .addTo(cannerRecipes); + } + } + tUseOreDict = false; + } + if (tRandomData instanceof IItemBehaviour) { + // The cast below from is not safe. If you know how to make it safe, please do. + // noinspection unchecked + addItemBehavior(mOffset + aID, (IItemBehaviour) tRandomData); + tUseOreDict = false; + } + if (tRandomData instanceof IItemContainer) { + ((IItemContainer) tRandomData).set(rStack); + tUseOreDict = false; + } + if (tRandomData instanceof SubTag) { + continue; + } + if (tRandomData instanceof TC_AspectStack) { + ((TC_AspectStack) tRandomData).addToAspectList(tAspects); + continue; + } + if (tRandomData instanceof ItemData) { + if (GTUtility.isStringValid(tRandomData)) GTOreDictUnificator.registerOre(tRandomData, rStack); + else GTOreDictUnificator.addItemData(rStack, (ItemData) tRandomData); + continue; + } + if (tUseOreDict) { + GTOreDictUnificator.registerOre(tRandomData, rStack); + } + } + if (GregTechAPI.sThaumcraftCompat != null) + GregTechAPI.sThaumcraftCompat.registerThaumcraftAspectsToItem(rStack, tAspects, false); + return rStack; + } + return null; + } + + /** + * Sets a Food Behavior for the Item. + * + * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] + * @param aFoodBehavior the Food Behavior you want to add. + * @return the Item itself for convenience in constructing. + */ + public final MetaGeneratedItem setFoodBehavior(int aMetaValue, IFoodStat aFoodBehavior) { + if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length()) return this; + if (aFoodBehavior == null) mFoodStats.remove((short) aMetaValue); + else mFoodStats.put((short) aMetaValue, aFoodBehavior); + return this; + } + + /** + * Sets the Furnace Burn Value for the Item. + * + * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] + * @param aValue 200 = 1 Burn Process = 500 EU, max = 32767 (that is 81917.5 EU) + * @return the Item itself for convenience in constructing. + */ + public final MetaGeneratedItem setBurnValue(int aMetaValue, int aValue) { + if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length() || aValue < 0) return this; + if (aValue == 0) mBurnValues.remove((short) aMetaValue); + else mBurnValues.put((short) aMetaValue, aValue > Short.MAX_VALUE ? Short.MAX_VALUE : (short) aValue); + return this; + } + + /** + * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] + * @param aMaxCharge Maximum Charge. (if this is == 0 it will remove the Electric Behavior) + * @param aTransferLimit Transfer Limit. + * @param aTier The electric Tier. + * @param aSpecialData If this Item has a Fixed Charge, like a SingleUse Battery (if > 0). Use -1 if you want to + * make this Battery chargeable (the use and canUse Functions will still discharge if you just + * use this) Use -2 if you want to make this Battery dischargeable. Use -3 if you want to make + * this Battery charge/discharge-able. + * @return the Item itself for convenience in constructing. + */ + public final MetaGeneratedItem setElectricStats(int aMetaValue, long aMaxCharge, long aTransferLimit, long aTier, + long aSpecialData, boolean aUseAnimations) { + if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length()) return this; + if (aMaxCharge == 0) mElectricStats.remove((short) aMetaValue); + else { + mElectricStats.put( + (short) aMetaValue, + new Long[] { aMaxCharge, Math.max(0, aTransferLimit), Math.max(-1, aTier), aSpecialData }); + if (aMetaValue >= mOffset && aUseAnimations) mIconList[aMetaValue - mOffset] = Arrays + .copyOf(mIconList[aMetaValue - mOffset], Math.max(9, mIconList[aMetaValue - mOffset].length)); + } + return this; + } + + /** + * + * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765] + * @param aCapacity fluid capacity in L or mb + * @param aStacksize item stack size + * @return the Item itself for convenience in constructing. + */ + public final MetaGeneratedItem setFluidContainerStats(int aMetaValue, long aCapacity, long aStacksize) { + if (aMetaValue < 0 || aMetaValue >= mOffset + mEnabledItems.length()) return this; + if (aCapacity < 0) mElectricStats.remove((short) aMetaValue); + else mFluidContainerStats.put((short) aMetaValue, new Long[] { aCapacity, Math.max(1, aStacksize) }); + return this; + } + + /** + * @return if this MetaGenerated Item should use my Default Renderer System. + */ + public boolean useStandardMetaItemRenderer() { + return true; + } + + @Override + public short[] getRGBa(ItemStack aStack) { + return Materials._NULL.getRGBA(); + } + + /** + * @return the Icon the Material is going to be rendered with. + */ + public IIconContainer getIconContainer(int aMetaData) { + return null; + } + + @Override + public IIcon getIcon(int aMetaData, int pass) { + IIconContainer iconContainer = getIconContainer(aMetaData); + return iconContainer != null ? iconContainer.getIcon() : null; + } + + @Override + public IIcon getOverlayIcon(int aMetaData, int pass) { + IIconContainer iconContainer = getIconContainer(aMetaData); + return iconContainer != null ? iconContainer.getOverlayIcon() : null; + } + + @Override + public boolean shouldUseCustomRenderer(int aMetaData) { + return true; + } + + @Override + public GeneratedMaterialRenderer getMaterialRenderer(int aMetaData) { + return null; + } + + @Override + public boolean allowMaterialRenderer(int aMetaData) { + return aMetaData < this.mOffset; + } + + /* ---------- INTERNAL OVERRIDES ---------- */ + + @Override + public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); + if (tStat != null && aPlayer.canEat(tStat.alwaysEdible(this, aStack, aPlayer))) + aPlayer.setItemInUse(aStack, 32); + return super.onItemRightClick(aStack, aWorld, aPlayer); + } + + @Override + public int getMaxItemUseDuration(ItemStack aStack) { + return mFoodStats.get((short) getDamage(aStack)) == null ? 0 : 32; + } + + @Override + public EnumAction getItemUseAction(ItemStack aStack) { + IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); + return tStat == null ? EnumAction.none : tStat.getFoodAction(this, aStack); + } + + @Override + public final ItemStack onEaten(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); + if (tStat != null) { + if (AppleCore.isModLoaded()) { + aPlayer.getFoodStats() + .func_151686_a(getFoodProxy(this), aStack); + } else { + aPlayer.getFoodStats() + .addStats(tStat.getFoodLevel(this, aStack, aPlayer), tStat.getSaturation(this, aStack, aPlayer)); + } + tStat.onEaten(this, aStack, aPlayer); + } + return aStack; + } + + @Optional.Method(modid = Mods.Names.APPLE_CORE) + private static ItemFood getFoodProxy(Object edible) { + return new ItemFoodProxy((IEdible) edible); + } + + @Override + @Optional.Method(modid = Mods.Names.APPLE_CORE) + public FoodValues getFoodValues(ItemStack aStack) { + IFoodStat tStat = mFoodStats.get((short) getDamage(aStack)); + return tStat == null ? null + : new FoodValues(tStat.getFoodLevel(this, aStack, null), tStat.getSaturation(this, aStack, null)); + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { + int j = mEnabledItems.length(); + for (int i = 0; i < j; i++) if (mVisibleItems.get(i) || (D1 && mEnabledItems.get(i))) { + Long[] tStats = mElectricStats.get((short) (mOffset + i)); + if (tStats != null && tStats[3] < 0) { + ItemStack tStack = new ItemStack(this, 1, mOffset + i); + setCharge(tStack, Math.abs(tStats[0])); + isItemStackUsable(tStack); + aList.add(tStack); + } + if (tStats == null || tStats[3] != -2) { + ItemStack tStack = new ItemStack(this, 1, mOffset + i); + isItemStackUsable(tStack); + aList.add(tStack); + } + } + } + + @Override + @SideOnly(Side.CLIENT) + public final void registerIcons(IIconRegister aIconRegister) { + short j = (short) mEnabledItems.length(); + for (short i = 0; i < j; i++) if (mEnabledItems.get(i)) { + for (byte k = 1; k < mIconList[i].length; k++) { + mIconList[i][k] = aIconRegister.registerIcon( + GregTech.getResourcePath(GTConfig.troll ? "troll" : getUnlocalizedName() + "/" + i + "/" + k)); + } + mIconList[i][0] = aIconRegister + .registerIcon(GregTech.getResourcePath(GTConfig.troll ? "troll" : getUnlocalizedName() + "/" + i)); + } + } + + @Override + public final Long[] getElectricStats(ItemStack aStack) { + return mElectricStats.get((short) aStack.getItemDamage()); + } + + @Override + public final Long[] getFluidContainerStats(ItemStack aStack) { + return mFluidContainerStats.get((short) aStack.getItemDamage()); + } + + @Override + public int getItemEnchantability() { + return 0; + } + + @Override + public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { + return false; + } + + @Override + public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { + return false; + } +} diff --git a/src/main/java/gregtech/api/items/MetaGeneratedItemX01.java b/src/main/java/gregtech/api/items/MetaGeneratedItemX01.java new file mode 100644 index 0000000000..29fc849a6f --- /dev/null +++ b/src/main/java/gregtech/api/items/MetaGeneratedItemX01.java @@ -0,0 +1,210 @@ +package gregtech.api.items; + +import static gregtech.api.enums.GTValues.M; + +import java.util.List; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; + +/** + * @author Gregorius Techneticies + *

+ * One Item for everything! + *

+ * This brilliant Item Class is used for automatically generating all possible variations of Material Items, + * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always + * have to make a new Item SubType for each OreDict Prefix, when adding a new Material. + *

+ * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom + * defined, just to save space and MetaData. + *

+ * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike + * Item. + */ +public abstract class MetaGeneratedItemX01 extends MetaGeneratedItem { + + protected final OrePrefixes mPrefix; + protected final int mIconSetIndex; + + /** + * Creates the Item using these Parameters. This is for the new 1 Item = 1 Prefix System. + * + * @param aUnlocalized The Unlocalized Name of this Item. + * @param aGeneratedPrefix The OreDict Prefix you want to have generated. + * @param aIconSetIndex The TextureSet Index to be used. -1 for Defaulting to the Data contained in the Prefix. + * (this is only to be used for selecting the Icon in getIconContainer, nothing else) + */ + public MetaGeneratedItemX01(String aUnlocalized, OrePrefixes aGeneratedPrefix, int aIconSetIndex) { + super(aUnlocalized, (short) 32000, (short) 766); + mPrefix = aGeneratedPrefix; + mIconSetIndex = aIconSetIndex >= 0 ? aIconSetIndex + : aGeneratedPrefix.mTextureIndex >= 0 ? aGeneratedPrefix.mTextureIndex : 0; + + for (int i = 0; i < GregTechAPI.sGeneratedMaterials.length; i++) { + OrePrefixes tPrefix = mPrefix; + if (tPrefix == null) continue; + Materials tMaterial = GregTechAPI.sGeneratedMaterials[i]; + if (tMaterial == null) continue; + if (mPrefix.doGenerateItem(tMaterial)) { + ItemStack tStack = new ItemStack(this, 1, i); + GTLanguageManager.addStringLocalization( + getUnlocalizedName(tStack) + ".name", + GTLanguageManager.i18nPlaceholder ? getDefaultLocalizationFormat(tPrefix, tMaterial, i) + : getDefaultLocalization(tPrefix, tMaterial, i)); + GTLanguageManager.addStringLocalization( + getUnlocalizedName(tStack) + ".tooltip", + tMaterial.getToolTip(tPrefix.mMaterialAmount / M)); + String tOreName = getOreDictString(tPrefix, tMaterial); + tPrefix = OrePrefixes.getOrePrefix(tOreName); + if (tPrefix != null && tPrefix.mIsUnificatable) { + GTOreDictUnificator.set(tPrefix, OrePrefixes.getMaterial(tOreName, tPrefix), tStack); + } else { + GTOreDictUnificator.registerOre(tOreName, tStack); + } + } + } + } + + /* ---------- OVERRIDEABLE FUNCTIONS ---------- */ + + /** + * @param aPrefix the OreDict Prefix + * @param aMaterial the Material + * @param aMetaData a Index from [0 - 31999] + * @return the Localized Name when default LangFiles are used. + */ + public String getDefaultLocalization(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { + return aPrefix.getDefaultLocalNameForItem(aMaterial); + } + + /** + * @param aPrefix the OreDict Prefix + * @param aMaterial the Material + * @param aMetaData a Index from [0 - 31999] + * @return the Localized Name Format when default LangFiles are used. + */ + public String getDefaultLocalizationFormat(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { + return aPrefix.getDefaultLocalNameFormatForItem(aMaterial); + } + + /** + * @param aPrefix always != null + * @param aMaterial always != null + * @param aDoShowAllItems this is the Configuration Setting of the User, if he wants to see all the Stuff like Tiny + * Dusts or Crushed Ores as well. + * @return if this Item should be visible in NEI or Creative + */ + public boolean doesShowInCreative(OrePrefixes aPrefix, Materials aMaterial, boolean aDoShowAllItems) { + return true; + } + + /** + * @return the name of the Item to be registered at the OreDict. + */ + public String getOreDictString(OrePrefixes aPrefix, Materials aMaterial) { + return aPrefix.get(aMaterial) + .toString(); + } + + public IIconContainer getIconContainer(int aMetaData, Materials aMaterial) { + return aMaterial.mIconSet.mTextures[mIconSetIndex]; + } + + /* ---------- INTERNAL OVERRIDES ---------- */ + + @Override + public String getItemStackDisplayName(ItemStack aStack) { + String aName = super.getItemStackDisplayName(aStack); + int aDamage = aStack.getItemDamage(); + if (aDamage < 32000 && aDamage >= 0) return Materials.getLocalizedNameForItem(aName, aDamage % 1000); + return aName; + } + + @Override + public ItemStack getContainerItem(ItemStack aStack) { + int aMetaData = aStack.getItemDamage(); + if (aMetaData < GregTechAPI.sGeneratedMaterials.length && aMetaData >= 0) { + Materials aMaterial = GregTechAPI.sGeneratedMaterials[aMetaData]; + if (aMaterial != null && aMaterial != Materials.Empty && aMaterial != Materials._NULL) { + return GTUtility.copyAmount(1, mPrefix.mContainerItem); + } + } + return null; + } + + @Override + public short[] getRGBa(ItemStack aStack) { + int aMetaData = getDamage(aStack); + return aMetaData < GregTechAPI.sGeneratedMaterials.length && GregTechAPI.sGeneratedMaterials[aMetaData] != null + ? GregTechAPI.sGeneratedMaterials[aMetaData].mRGBa + : Materials._NULL.mRGBa; + } + + @Override + public final IIconContainer getIconContainer(int aMetaData) { + return aMetaData < GregTechAPI.sGeneratedMaterials.length && GregTechAPI.sGeneratedMaterials[aMetaData] != null + ? getIconContainer(aMetaData, GregTechAPI.sGeneratedMaterials[aMetaData]) + : null; + } + + @Override + @SideOnly(Side.CLIENT) + public final void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { + for (int i = 0; i < GregTechAPI.sGeneratedMaterials.length; i++) if (mPrefix + .doGenerateItem(GregTechAPI.sGeneratedMaterials[i]) + && doesShowInCreative(mPrefix, GregTechAPI.sGeneratedMaterials[i], GregTechAPI.sDoShowAllItemsInCreative)) { + ItemStack tStack = new ItemStack(this, 1, i); + isItemStackUsable(tStack); + aList.add(tStack); + } + super.getSubItems(aItem, aCreativeTab, aList); + } + + @Override + public final IIcon getIconFromDamage(int aMetaData) { + if (aMetaData < 0) return null; + if (aMetaData < GregTechAPI.sGeneratedMaterials.length) { + Materials tMaterial = GregTechAPI.sGeneratedMaterials[aMetaData]; + if (tMaterial == null) return null; + IIconContainer tIcon = getIconContainer(aMetaData, tMaterial); + if (tIcon != null) return tIcon.getIcon(); + return null; + } + return aMetaData >= mOffset && aMetaData - mOffset < mIconList.length ? mIconList[aMetaData - mOffset][0] + : null; + } + + @Override + public int getItemStackLimit(ItemStack aStack) { + return getDamage(aStack) < mOffset ? Math.min(super.getItemStackLimit(aStack), mPrefix.mDefaultStackSize) + : super.getItemStackLimit(aStack); + } + + @Override + public int getItemEnchantability() { + return 0; + } + + @Override + public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { + return false; + } + + @Override + public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { + return false; + } +} diff --git a/src/main/java/gregtech/api/items/MetaGeneratedItemX32.java b/src/main/java/gregtech/api/items/MetaGeneratedItemX32.java new file mode 100644 index 0000000000..cb83804ae1 --- /dev/null +++ b/src/main/java/gregtech/api/items/MetaGeneratedItemX32.java @@ -0,0 +1,225 @@ +package gregtech.api.items; + +import static gregtech.api.enums.GTValues.M; + +import java.util.Arrays; +import java.util.List; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import gregtech.common.render.items.GeneratedMaterialRenderer; + +/** + * @author Gregorius Techneticies + *

+ * One Item for everything! + *

+ * This brilliant Item Class is used for automatically generating all possible variations of Material Items, + * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always + * have to make a new Item SubType for each OreDict Prefix, when adding a new Material. + *

+ * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom + * defined, just to save space and MetaData. + *

+ * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike + * Item. + */ +public abstract class MetaGeneratedItemX32 extends MetaGeneratedItem { + + protected final OrePrefixes[] mGeneratedPrefixList; + + /** + * Creates the Item using these Parameters. + * + * @param aUnlocalized The Unlocalized Name of this Item. + * @param aGeneratedPrefixList The OreDict Prefixes you want to have generated. + */ + public MetaGeneratedItemX32(String aUnlocalized, OrePrefixes... aGeneratedPrefixList) { + super(aUnlocalized, (short) 32000, (short) 766); + mGeneratedPrefixList = Arrays.copyOf(aGeneratedPrefixList, 32); + + for (int i = 0; i < 32000; i++) { + OrePrefixes tPrefix = mGeneratedPrefixList[i / 1000]; + if (tPrefix == null) continue; + if (tPrefix == OrePrefixes.___placeholder___) continue; + Materials tMaterial = GregTechAPI.sGeneratedMaterials[i % 1000]; + if (tMaterial == null) continue; + if (doesMaterialAllowGeneration(tPrefix, tMaterial)) { + ItemStack tStack = new ItemStack(this, 1, i); + GTLanguageManager.addStringLocalization( + getUnlocalizedName(tStack) + ".name", + GTLanguageManager.i18nPlaceholder ? getDefaultLocalizationFormat(tPrefix, tMaterial, i) + : getDefaultLocalization(tPrefix, tMaterial, i)); + GTLanguageManager.addStringLocalization( + getUnlocalizedName(tStack) + ".tooltip", + tMaterial.getToolTip(tPrefix.mMaterialAmount / M)); + if (tPrefix.mIsUnificatable) { + GTOreDictUnificator.set(tPrefix, tMaterial, tStack); + } else { + GTOreDictUnificator.registerOre(tPrefix.get(tMaterial), tStack); + } + if ((tPrefix == OrePrefixes.stick || tPrefix == OrePrefixes.wireFine || tPrefix == OrePrefixes.ingot) + && (tMaterial == Materials.Lead || tMaterial == Materials.Tin + || tMaterial == Materials.SolderingAlloy)) { + GregTechAPI.sSolderingMetalList.add(tStack); + GTModHandler.registerBoxableItemToToolBox(tStack); + } + } + } + } + + /* ---------- OVERRIDEABLE FUNCTIONS ---------- */ + + /** + * @return the Color Modulation the Material is going to be rendered with. + */ + @Override + public short[] getRGBa(ItemStack aStack) { + Materials tMaterial = GregTechAPI.sGeneratedMaterials[getDamage(aStack) % 1000]; + return tMaterial == null ? Materials._NULL.mRGBa : tMaterial.mRGBa; + } + + /** + * @param aPrefix this can be null, you have to return false in that case + * @param aMaterial this can be null, you have to return false in that case + * @return if this Item should be generated and visible. + */ + public boolean doesMaterialAllowGeneration(OrePrefixes aPrefix, Materials aMaterial) { + // You have to check for at least these Conditions in every Case! So add a super Call like the following for + // this before executing your Code: + // if (!super.doesMaterialAllowGeneration(aPrefix, aMaterial)) return false; + return aPrefix != null && aPrefix.doGenerateItem(aMaterial); + } + + /* ---------- OVERRIDEABLE FUNCTIONS ---------- */ + + /** + * @param aPrefix the OreDict Prefix + * @param aMaterial the Material + * @param aMetaData a Index from [0 - 31999] + * @return the Localized Name when default LangFiles are used. + */ + public String getDefaultLocalization(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { + return aPrefix.getDefaultLocalNameForItem(aMaterial); + } + + /** + * @param aPrefix the OreDict Prefix + * @param aMaterial the Material + * @param aMetaData a Index from [0 - 31999] + * @return the Localized Name Format when default LangFiles are used. + */ + public String getDefaultLocalizationFormat(OrePrefixes aPrefix, Materials aMaterial, int aMetaData) { + return aPrefix.getDefaultLocalNameFormatForItem(aMaterial); + } + + /** + * @param aMetaData a Index from [0 - 31999] + * @param aMaterial the Material + * @return an Icon Container for the Item Display. + */ + public final IIconContainer getIconContainer(int aMetaData, Materials aMaterial) { + return mGeneratedPrefixList[aMetaData / 1000] != null + && mGeneratedPrefixList[aMetaData / 1000].mTextureIndex >= 0 + ? aMaterial.mIconSet.mTextures[mGeneratedPrefixList[aMetaData / 1000].mTextureIndex] + : null; + } + + /** + * @param aPrefix always != null + * @param aMaterial always != null + * @param aDoShowAllItems this is the Configuration Setting of the User, if he wants to see all the Stuff like Tiny + * Dusts or Crushed Ores as well. + * @return if this Item should be visible in NEI or Creative + */ + public boolean doesShowInCreative(OrePrefixes aPrefix, Materials aMaterial, boolean aDoShowAllItems) { + return true; + } + + /* ---------- INTERNAL OVERRIDES ---------- */ + + @Override + public String getItemStackDisplayName(ItemStack aStack) { + String aName = super.getItemStackDisplayName(aStack); + int aDamage = aStack.getItemDamage(); + if (aDamage < 32000 && aDamage >= 0) return Materials.getLocalizedNameForItem(aName, aDamage % 1000); + return aName; + } + + @Override + public ItemStack getContainerItem(ItemStack aStack) { + int aDamage = aStack.getItemDamage(); + if (aDamage < 32000 && aDamage >= 0) { + Materials aMaterial = GregTechAPI.sGeneratedMaterials[aDamage % 1000]; + if (aMaterial != null && aMaterial != Materials.Empty && aMaterial != Materials._NULL) { + OrePrefixes aPrefix = mGeneratedPrefixList[aDamage / 1000]; + if (aPrefix != null) return GTUtility.copyAmount(1, aPrefix.mContainerItem); + } + } + return null; + } + + @Override + public final IIconContainer getIconContainer(int aMetaData) { + return GregTechAPI.sGeneratedMaterials[aMetaData % 1000] == null ? null + : getIconContainer(aMetaData, GregTechAPI.sGeneratedMaterials[aMetaData % 1000]); + } + + @Override + public GeneratedMaterialRenderer getMaterialRenderer(int aMetaData) { + return GregTechAPI.sGeneratedMaterials[aMetaData % 1000] == null ? null + : GregTechAPI.sGeneratedMaterials[aMetaData % 1000].renderer; + } + + @Override + @SideOnly(Side.CLIENT) + public final void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { + for (int i = 0; i < 32000; i++) { + OrePrefixes aPrefix = mGeneratedPrefixList[i / 1000]; + Materials aMaterial = GregTechAPI.sGeneratedMaterials[i % 1000]; + if (aPrefix != null && aMaterial != null) { + if (doesMaterialAllowGeneration(aPrefix, aMaterial) + && doesShowInCreative(aPrefix, aMaterial, GregTechAPI.sDoShowAllItemsInCreative)) { + ItemStack tStack = new ItemStack(this, 1, i); + isItemStackUsable(tStack); + aList.add(tStack); + } + } + } + super.getSubItems(aItem, aCreativeTab, aList); + } + + @Override + public final IIcon getIconFromDamage(int aMetaData) { + if (aMetaData < 0) return null; + if (aMetaData < 32000) { + Materials tMaterial = GregTechAPI.sGeneratedMaterials[aMetaData % 1000]; + if (tMaterial == null) return null; + IIconContainer tIcon = getIconContainer(aMetaData, tMaterial); + if (tIcon != null) return tIcon.getIcon(); + return null; + } + return aMetaData - 32000 < mIconList.length ? mIconList[aMetaData - 32000][0] : null; + } + + @Override + public int getItemStackLimit(ItemStack aStack) { + int tDamage = getDamage(aStack); + if (tDamage < 32000 && mGeneratedPrefixList[tDamage / 1000] != null) + return Math.min(super.getItemStackLimit(aStack), mGeneratedPrefixList[tDamage / 1000].mDefaultStackSize); + return super.getItemStackLimit(aStack); + } +} diff --git a/src/main/java/gregtech/api/items/MetaGeneratedTool.java b/src/main/java/gregtech/api/items/MetaGeneratedTool.java new file mode 100644 index 0000000000..6487a67a6b --- /dev/null +++ b/src/main/java/gregtech/api/items/MetaGeneratedTool.java @@ -0,0 +1,1013 @@ +package gregtech.api.items; + +import static gregtech.api.util.GTUtility.formatNumbers; +import static gregtech.common.tileentities.machines.multi.MTELargeTurbineSteam.calculateLooseFlow; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.stats.AchievementList; +import net.minecraft.stats.StatList; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.IShearable; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.event.world.BlockEvent; + +import appeng.api.implementations.items.IAEWrench; +import buildcraft.api.tools.IToolWrench; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import crazypants.enderio.api.tool.ITool; +import forestry.api.arboriculture.IToolGrafter; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enchants.EnchantmentRadioactivity; +import gregtech.api.enums.Materials; +import gregtech.api.enums.TCAspects.TC_AspectStack; +import gregtech.api.interfaces.IDamagableItem; +import gregtech.api.interfaces.IToolStats; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import gregtech.common.tools.ToolTurbine; +import mods.railcraft.api.core.items.IToolCrowbar; +import mrtjp.projectred.api.IScrewdriver; + +/** + * This is an example on how you can create a Tool ItemStack, in this case a Bismuth Wrench: + * GT_MetaGenerated_Tool.sInstances.get("gt.metatool.01").getToolWithStats(MetaGeneratedTool01.WRENCH, 1, + * Materials.Bismuth, Materials.Bismuth, null); + */ +@Optional.InterfaceList( + value = { + @Optional.Interface(iface = "forestry.api.arboriculture.IToolGrafter", modid = "ForestryAPI|arboriculture"), + @Optional.Interface(iface = "mods.railcraft.api.core.items.IToolCrowbar", modid = "RailcraftAPI|items"), + @Optional.Interface(iface = "buildcraft.api.tools.IToolWrench", modid = "BuildCraftAPI|tools"), + @Optional.Interface(iface = "crazypants.enderio.api.tool.ITool", modid = "EnderIOAPI|Tools"), + @Optional.Interface(iface = "mrtjp.projectred.api.IScrewdriver", modid = "ProjRed|Core"), }) +public abstract class MetaGeneratedTool extends MetaBaseItem + implements IDamagableItem, IToolGrafter, IToolCrowbar, IToolWrench, ITool, IScrewdriver, IAEWrench { + + /** + * All instances of this Item Class are listed here. This gets used to register the Renderer to all Items of this + * Type, if useStandardMetaItemRenderer() returns true. + *

+ * You can also use the unlocalized Name gotten from getUnlocalizedName() as Key if you want to get a specific Item. + */ + public static final ConcurrentHashMap sInstances = new ConcurrentHashMap<>(); + + /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */ + + public final ConcurrentHashMap mToolStats = new ConcurrentHashMap<>(); + + /** + * Creates the Item using these Parameters. + * + * @param aUnlocalized The Unlocalized Name of this Item. + */ + public MetaGeneratedTool(String aUnlocalized) { + super(aUnlocalized); + setCreativeTab(GregTechAPI.TAB_GREGTECH); + setMaxStackSize(1); + sInstances.put(getUnlocalizedName(), this); + } + + /* ---------- FOR ADDING CUSTOM ITEMS INTO THE REMAINING 766 RANGE ---------- */ + + public static final Materials getPrimaryMaterial(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) return Materials.getRealMaterial(aNBT.getString("PrimaryMaterial")); + } + return Materials._NULL; + } + + public static final Materials getSecondaryMaterial(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) return Materials.getRealMaterial(aNBT.getString("SecondaryMaterial")); + } + return Materials._NULL; + } + + /* ---------- INTERNAL OVERRIDES ---------- */ + + public static final long getToolMaxDamage(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) return aNBT.getLong("MaxDamage"); + } + return 0; + } + + public static final long getToolDamage(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) return aNBT.getLong("Damage"); + } + return 0; + } + + public static final boolean setToolDamage(ItemStack aStack, long aDamage) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) { + aNBT.setLong("Damage", aDamage); + return true; + } + } + return false; + } + + public static final boolean setToolMode(ItemStack aStack, byte aMode) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) { + aNBT.setByte("Mode", aMode); + return true; + } + } + return false; + } + + public static final byte getToolMode(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null) return aNBT.getByte("Mode"); + } + return 0; + } + + /** + * This adds a Custom Item to the ending Range. + * + * @param aID The Id of the assigned Tool Class [0 - 32765] (only even Numbers allowed! Uneven + * ID's are empty electric Items) + * @param aEnglish The Default Localized Name of the created Item + * @param aToolTip The Default ToolTip of the created Item, you can also insert null for having no + * ToolTip + * @param aToolStats The Food Value of this Item. Can be null as well. + * @param aOreDictNamesAndAspects The OreDict Names you want to give the Item. Also used to assign Thaumcraft + * Aspects. + * @return An ItemStack containing the newly created Item, but without specific Stats. + */ + public final ItemStack addTool(int aID, String aEnglish, String aToolTip, IToolStats aToolStats, + Object... aOreDictNamesAndAspects) { + if (aToolTip == null) aToolTip = ""; + if (aID >= 0 && aID < 32766 && aID % 2 == 0) { + GTLanguageManager.addStringLocalization(getUnlocalizedName() + "." + aID + ".name", aEnglish); + GTLanguageManager.addStringLocalization(getUnlocalizedName() + "." + aID + ".tooltip", aToolTip); + GTLanguageManager + .addStringLocalization(getUnlocalizedName() + "." + (aID + 1) + ".name", aEnglish + " (Empty)"); + GTLanguageManager + .addStringLocalization(getUnlocalizedName() + "." + (aID + 1) + ".tooltip", "You need to recharge it"); + mToolStats.put((short) aID, aToolStats); + mToolStats.put((short) (aID + 1), aToolStats); + aToolStats.onStatsAddedToTool(this, aID); + ItemStack rStack = new ItemStack(this, 1, aID); + List tAspects = new ArrayList<>(); + for (Object tOreDictNameOrAspect : aOreDictNamesAndAspects) { + if (tOreDictNameOrAspect instanceof TC_AspectStack) + ((TC_AspectStack) tOreDictNameOrAspect).addToAspectList(tAspects); + else GTOreDictUnificator.registerOre(tOreDictNameOrAspect, rStack); + } + if (GregTechAPI.sThaumcraftCompat != null) + GregTechAPI.sThaumcraftCompat.registerThaumcraftAspectsToItem(rStack, tAspects, false); + GTModHandler.registerBoxableItemToToolBox(rStack); + return rStack; + } + return null; + } + + /** + * This Function gets an ItemStack Version of this Tool + * + * @param aToolID the ID of the Tool Class + * @param aAmount Amount of Items (well normally you only need 1) + * @param aPrimaryMaterial Primary Material of this Tool + * @param aSecondaryMaterial Secondary (Rod/Handle) Material of this Tool + * @param aElectricArray The Electric Stats of this Tool (or null if not electric) + */ + public final ItemStack getToolWithStats(int aToolID, int aAmount, Materials aPrimaryMaterial, + Materials aSecondaryMaterial, long[] aElectricArray) { + ItemStack rStack = new ItemStack(this, aAmount, aToolID); + IToolStats tToolStats = getToolStats(rStack); + if (tToolStats != null) { + NBTTagCompound tMainNBT = new NBTTagCompound(), tToolNBT = new NBTTagCompound(); + tToolNBT.setByte("Mode", (byte) 0); + if (aPrimaryMaterial != null) { + tToolNBT.setString("PrimaryMaterial", aPrimaryMaterial.mName); + tToolNBT.setLong( + "MaxDamage", + 100L * (long) (aPrimaryMaterial.mDurability * tToolStats.getMaxDurabilityMultiplier())); + } + if (aSecondaryMaterial != null) tToolNBT.setString("SecondaryMaterial", aSecondaryMaterial.mName); + + if (aElectricArray != null) { + tToolNBT.setBoolean("Electric", true); + tToolNBT.setLong("MaxCharge", aElectricArray[0]); + tToolNBT.setLong("Voltage", aElectricArray[1]); + tToolNBT.setLong("Tier", aElectricArray[2]); + tToolNBT.setLong("SpecialData", aElectricArray[3]); + } + + tMainNBT.setTag("GT.ToolStats", tToolNBT); + rStack.setTagCompound(tMainNBT); + } + isItemStackUsable(rStack); + return rStack; + } + + /** + * Called by the Block Harvesting Event within the GTProxy + */ + @Mod.EventHandler + public void onHarvestBlockEvent(ArrayList aDrops, ItemStack aStack, EntityPlayer aPlayer, Block aBlock, + int aX, int aY, int aZ, byte aMetaData, int aFortune, boolean aSilkTouch, BlockEvent.HarvestDropsEvent aEvent) { + IToolStats tStats = getToolStats(aStack); + if (isItemStackUsable(aStack) && getDigSpeed(aStack, aBlock, aMetaData) > 0.0F) doDamage( + aStack, + (long) tStats + .convertBlockDrops(aDrops, aStack, aPlayer, aBlock, aX, aY, aZ, aMetaData, aFortune, aSilkTouch, aEvent) + * tStats.getToolDamagePerDropConversion()); + } + + @Mod.EventHandler + public float onBlockBreakSpeedEvent(float aDefault, ItemStack aStack, EntityPlayer aPlayer, Block aBlock, int aX, + int aY, int aZ, byte aMetaData, PlayerEvent.BreakSpeed aEvent) { + IToolStats tStats = getToolStats(aStack); + return tStats == null ? aDefault + : tStats.getMiningSpeed(aBlock, aMetaData, aDefault, aPlayer, aPlayer.worldObj, aX, aY, aZ); + } + + @Override + public boolean onBlockStartBreak(ItemStack aStack, int aX, int aY, int aZ, EntityPlayer aPlayer) { + if (aPlayer.worldObj.isRemote) { + return false; + } + IToolStats tStats = getToolStats(aStack); + Block aBlock = aPlayer.worldObj.getBlock(aX, aY, aZ); + if (tStats.isChainsaw() && (aBlock instanceof IShearable target)) { + if ((target.isShearable(aStack, aPlayer.worldObj, aX, aY, aZ))) { + ArrayList drops = target.onSheared( + aStack, + aPlayer.worldObj, + aX, + aY, + aZ, + EnchantmentHelper.getEnchantmentLevel(Enchantment.fortune.effectId, aStack)); + for (ItemStack stack : drops) { + float f = 0.7F; + double d = itemRand.nextFloat() * f + (1.0F - f) * 0.5D; + double d1 = itemRand.nextFloat() * f + (1.0F - f) * 0.5D; + double d2 = itemRand.nextFloat() * f + (1.0F - f) * 0.5D; + EntityItem entityitem = new EntityItem(aPlayer.worldObj, aX + d, aY + d1, aZ + d2, stack); + entityitem.delayBeforeCanPickup = 10; + aPlayer.worldObj.spawnEntityInWorld(entityitem); + } + aPlayer.addStat(net.minecraft.stats.StatList.mineBlockStatArray[Block.getIdFromBlock(aBlock)], 1); + onBlockDestroyed(aStack, aPlayer.worldObj, aBlock, aX, aY, aZ, aPlayer); + } + return false; + } + return super.onBlockStartBreak(aStack, aX, aY, aZ, aPlayer); + } + + @Override + public boolean onLeftClickEntity(ItemStack aStack, EntityPlayer aPlayer, Entity aEntity) { + IToolStats tStats = getToolStats(aStack); + if (tStats == null || !isItemStackUsable(aStack)) return true; + GTUtility.doSoundAtClient(tStats.getEntityHitSound(), 1, 1.0F); + if (super.onLeftClickEntity(aStack, aPlayer, aEntity)) return true; + if (aEntity.canAttackWithItem() && !aEntity.hitByEntity(aPlayer)) { + float tMagicDamage = tStats.getMagicDamageAgainstEntity( + aEntity instanceof EntityLivingBase + ? EnchantmentHelper.getEnchantmentModifierLiving(aPlayer, (EntityLivingBase) aEntity) + : 0.0F, + aEntity, + aStack, + aPlayer), + tDamage = tStats.getNormalDamageAgainstEntity( + (float) aPlayer.getEntityAttribute(SharedMonsterAttributes.attackDamage) + .getAttributeValue() + getToolCombatDamage(aStack), + aEntity, + aStack, + aPlayer); + if (tDamage + tMagicDamage > 0.0F) { + boolean tCriticalHit = aPlayer.fallDistance > 0.0F && !aPlayer.onGround + && !aPlayer.isOnLadder() + && !aPlayer.isInWater() + && !aPlayer.isPotionActive(Potion.blindness) + && aPlayer.ridingEntity == null + && aEntity instanceof EntityLivingBase; + if (tCriticalHit && tDamage > 0.0F) tDamage *= 1.5F; + tDamage += tMagicDamage; + if (aEntity.attackEntityFrom(tStats.getDamageSource(aPlayer, aEntity), tDamage)) { + if (aEntity instanceof EntityLivingBase) + aEntity.setFire(EnchantmentHelper.getFireAspectModifier(aPlayer) * 4); + int tKnockcack = (aPlayer.isSprinting() ? 1 : 0) + (aEntity instanceof EntityLivingBase + ? EnchantmentHelper.getKnockbackModifier(aPlayer, (EntityLivingBase) aEntity) + : 0); + if (tKnockcack > 0) { + aEntity.addVelocity( + -MathHelper.sin(aPlayer.rotationYaw * (float) Math.PI / 180.0F) * tKnockcack * 0.5F, + 0.1D, + MathHelper.cos(aPlayer.rotationYaw * (float) Math.PI / 180.0F) * tKnockcack * 0.5F); + aPlayer.motionX *= 0.6D; + aPlayer.motionZ *= 0.6D; + aPlayer.setSprinting(false); + } + if (tCriticalHit) aPlayer.onCriticalHit(aEntity); + if (tMagicDamage > 0.0F) aPlayer.onEnchantmentCritical(aEntity); + if (tDamage >= 18.0F) aPlayer.triggerAchievement(AchievementList.overkill); + aPlayer.setLastAttacker(aEntity); + if (aEntity instanceof EntityLivingBase) + EnchantmentHelper.func_151384_a((EntityLivingBase) aEntity, aPlayer); + EnchantmentHelper.func_151385_b(aPlayer, aEntity); + if (aEntity instanceof EntityLivingBase) + aPlayer.addStat(StatList.damageDealtStat, Math.round(tDamage * 10.0F)); + aEntity.hurtResistantTime = Math + .max(1, tStats.getHurtResistanceTime(aEntity.hurtResistantTime, aEntity)); + aPlayer.addExhaustion(0.3F); + doDamage(aStack, tStats.getToolDamagePerEntityAttack()); + } + } + } + if (aStack.stackSize <= 0) aPlayer.destroyCurrentEquippedItem(); + return true; + } + + @Override + public ItemStack onItemRightClick(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + IToolStats tStats = getToolStats(aStack); + if (tStats != null && tStats.canBlock()) aPlayer.setItemInUse(aStack, 72000); + return super.onItemRightClick(aStack, aWorld, aPlayer); + } + + @Override + public final int getMaxItemUseDuration(ItemStack aStack) { + return 72000; + } + + @Override + public final EnumAction getItemUseAction(ItemStack aStack) { + IToolStats tStats = getToolStats(aStack); + if (tStats != null && tStats.canBlock()) return EnumAction.block; + return EnumAction.none; + } + + @Override + @SideOnly(Side.CLIENT) + public final void getSubItems(Item aItem, CreativeTabs aCreativeTab, List aList) { + for (int i = 0; i < 32766; i += 2) { + if (getToolStats(new ItemStack(this, 1, i)) != null) { + ItemStack tStack = new ItemStack(this, 1, i); + isItemStackUsable(tStack); + aList.add(tStack); + aList.add(getToolWithStats(i, 1, Materials.Neutronium, Materials.Neutronium, null)); + } + } + } + + @Override + @SideOnly(Side.CLIENT) + public final void registerIcons(IIconRegister aIconRegister) { + // + } + + @Override + public final IIcon getIconFromDamage(int aMetaData) { + return null; + } + + @Override + public void addAdditionalToolTips(List aList, ItemStack aStack, EntityPlayer aPlayer) { + long tMaxDamage = getToolMaxDamage(aStack); + Materials tMaterial = getPrimaryMaterial(aStack); + IToolStats tStats = getToolStats(aStack); + int tOffset = getElectricStats(aStack) != null ? 2 : 1; + if (tStats != null) { + if (tStats instanceof ToolTurbine) { + + // Durability -> toolMaxDamage + // % Efficiency -> toolCombatDamage -> toolQuality + // Optimal Flow -> toolSpeed + // EU/t -> toolCombatDamage, toolSpeed + // Overflow Tier -> toolQuality + float aBaseEff = (5f + getToolCombatDamage(aStack)) * 1000f; + + // It was noted by IntelliJ that replacing ((GT_MetaGenerated_Tool) aStack.getItem()) with + // GT_MetaGenerated_Tool can have side effects. This refactoring will need tests. + @SuppressWarnings("AccessStaticViaInstance") + float aOptFlow = (Math.max( + Float.MIN_NORMAL, + ((MetaGeneratedTool) aStack.getItem()).getToolStats(aStack) + .getSpeedMultiplier() + * ((MetaGeneratedTool) aStack.getItem()).getPrimaryMaterial(aStack).mToolSpeed + * 50F)); + aList.add( + tOffset + 0, + EnumChatFormatting.GRAY + String.format( + transItem("001", "Durability: %s/%s"), + "" + EnumChatFormatting.GREEN + formatNumbers(tMaxDamage - getToolDamage(aStack)) + " ", + " " + formatNumbers(tMaxDamage)) + EnumChatFormatting.GRAY); + aList.add( + tOffset + 1, + EnumChatFormatting.GRAY + String.format( + transItem("002", "%s lvl %s"), + tMaterial.mLocalizedName + EnumChatFormatting.YELLOW, + "" + getHarvestLevel(aStack, "")) + EnumChatFormatting.GRAY); + aList.add( + tOffset + 2, + EnumChatFormatting.WHITE + + String.format( + transItem("005", "Turbine Efficiency: %s"), + "" + EnumChatFormatting.BLUE + (50.0F + (10.0F * getToolCombatDamage(aStack)))) + + "%" + + EnumChatFormatting.GRAY); + aList.add( + tOffset + 3, + EnumChatFormatting.WHITE + String.format( + transItem("006", "Optimal Steam flow: %s L/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + GTUtility.safeInt( + (long) (Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed + * (1000 * getPrimaryMaterial(aStack).mSteamMultiplier / 20))))) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 4, + EnumChatFormatting.WHITE + String.format( + transItem("900", "Energy from Optimal Steam Flow: %s EU/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + GTUtility.safeInt( + (long) (Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed + * (1000 * getPrimaryMaterial(aStack).mSteamMultiplier / 20)) + * (50.0F + (10.0F * getToolCombatDamage(aStack))) + / 200))) + + EnumChatFormatting.GRAY)); + { + float[] calculatedFlow = calculateLooseFlow(aOptFlow, aBaseEff); + float aOptFlowLoose = calculatedFlow[0]; + float aBaseEffLoose = calculatedFlow[1]; + + aList.add( + tOffset + 5, + EnumChatFormatting.AQUA + String.format( + transItem("500", "Turbine Efficiency (Loose): %s"), + "" + EnumChatFormatting.BLUE + (long) aBaseEffLoose / 100 + "%" + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 6, + EnumChatFormatting.AQUA + String.format( + transItem("501", "Optimal Steam flow (Loose): %s L/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers(((long) aOptFlowLoose * getPrimaryMaterial(aStack).mSteamMultiplier)) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 7, + EnumChatFormatting.AQUA + String.format( + transItem("901", "Energy from Optimal Steam Flow (Loose): %s EU/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + ((long) aOptFlowLoose * getPrimaryMaterial(aStack).mSteamMultiplier / 10000) + * ((long) aBaseEffLoose / 2)) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 8, + EnumChatFormatting.GRAY + "(Superheated Steam EU values are 2x those of Steam)"); + } + aList.add( + tOffset + 9, + EnumChatFormatting.WHITE + String.format( + transItem("902", "Optimal SC Steam flow: %s L/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + GTUtility.safeInt( + (long) (Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed + * (1000f / 20f))))) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 10, + EnumChatFormatting.WHITE + String.format( + transItem("903", "Energy from Optimal SC Steam Flow: %s EU/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + GTUtility.safeInt( + (long) (Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed + * (1000f / 20f)) + * (50.0F + (10.0F * getToolCombatDamage(aStack)))))) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 11, + EnumChatFormatting.LIGHT_PURPLE + String.format( + transItem("007", "Energy from Optimal Gas Flow: %s EU/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + GTUtility.safeInt( + (long) (Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed + * 50 + * getPrimaryMaterial(aStack).mGasMultiplier) + * (50.0F + (10.0F * getToolCombatDamage(aStack))) + / 100))) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 12, + EnumChatFormatting.LIGHT_PURPLE + String.format( + transItem("008", "Energy from Optimal Plasma Flow: %s EU/t"), + "" + EnumChatFormatting.GOLD + + formatNumbers( + GTUtility.safeInt( + (long) (Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed + * 2000 + * getPrimaryMaterial(aStack).mPlasmaMultiplier) + * (50.0F + (10.0F * getToolCombatDamage(aStack))) + * (1.05 / 100)))) + + EnumChatFormatting.GRAY)); + aList.add( + tOffset + 14, + EnumChatFormatting.GRAY + "(EU/t values include efficiency and are not 100% accurate)"); + int toolQualityLevel = MetaGeneratedTool.getPrimaryMaterial(aStack).mToolQuality; + int overflowMultiplier = 0; + if (toolQualityLevel >= 6) { + overflowMultiplier = 3; + } else if (toolQualityLevel >= 3) { + overflowMultiplier = 2; + } else { + overflowMultiplier = 1; + } + aList.add( + tOffset + 13, + EnumChatFormatting.LIGHT_PURPLE + String.format( + transItem("502", "Overflow Efficiency Tier: %s"), + "" + EnumChatFormatting.GOLD + overflowMultiplier + EnumChatFormatting.GRAY)); + + } else { + aList.add( + tOffset, + EnumChatFormatting.WHITE + String.format( + transItem("001", "Durability: %s/%s"), + "" + EnumChatFormatting.GREEN + formatNumbers(tMaxDamage - getToolDamage(aStack)) + " ", + " " + formatNumbers(tMaxDamage)) + EnumChatFormatting.GRAY); + aList.add( + tOffset + 1, + EnumChatFormatting.WHITE + String.format( + transItem("002", "%s lvl %s"), + tMaterial.mLocalizedName + EnumChatFormatting.YELLOW, + "" + getHarvestLevel(aStack, "")) + EnumChatFormatting.GRAY); + aList.add( + tOffset + 2, + EnumChatFormatting.WHITE + String.format( + transItem("003", "Attack Damage: %s"), + "" + EnumChatFormatting.BLUE + getToolCombatDamage(aStack)) + EnumChatFormatting.GRAY); + aList.add( + tOffset + 3, + EnumChatFormatting.WHITE + + String.format( + transItem("004", "Mining Speed: %s"), + "" + EnumChatFormatting.GOLD + + Math.max( + Float.MIN_NORMAL, + tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed)) + + EnumChatFormatting.GRAY); + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null && aNBT.hasKey("Heat")) { + int tHeat = aNBT.getInteger("Heat"); + long tWorldTime = aPlayer.getEntityWorld() + .getWorldTime(); + if (aNBT.hasKey("HeatTime")) { + long tHeatTime = aNBT.getLong("HeatTime"); + if (tWorldTime > (tHeatTime + 10)) { + tHeat = (int) (tHeat - ((tWorldTime - tHeatTime) / 10)); + if (tHeat < 300 && tHeat > -10000) tHeat = 300; + } + aNBT.setLong("HeatTime", tWorldTime); + if (tHeat > -10000) aNBT.setInteger("Heat", tHeat); + } + + aList.add( + tOffset + 3, + EnumChatFormatting.RED + "Heat: " + + aNBT.getInteger("Heat") + + " K" + + EnumChatFormatting.GRAY); + } + } + } + } + } + + @Override + public Long[] getFluidContainerStats(ItemStack aStack) { + return null; + } + + @Override + public Long[] getElectricStats(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) { + aNBT = aNBT.getCompoundTag("GT.ToolStats"); + if (aNBT != null && aNBT.getBoolean("Electric")) return new Long[] { aNBT.getLong("MaxCharge"), + aNBT.getLong("Voltage"), aNBT.getLong("Tier"), aNBT.getLong("SpecialData") }; + } + return null; + } + + public float getToolCombatDamage(ItemStack aStack) { + IToolStats tStats = getToolStats(aStack); + if (tStats == null) return 0; + return tStats.getBaseDamage() + getPrimaryMaterial(aStack).mToolQuality; + } + + @Override + public final boolean doDamageToItem(ItemStack aStack, int aVanillaDamage) { + return doDamage(aStack, aVanillaDamage * 100L); + } + + public final boolean doDamage(ItemStack aStack, long aAmount) { + if (!isItemStackUsable(aStack)) return false; + Long[] tElectric = getElectricStats(aStack); + if (tElectric == null) { + long tNewDamage = getToolDamage(aStack) + aAmount; + setToolDamage(aStack, tNewDamage); + if (tNewDamage >= getToolMaxDamage(aStack)) { + IToolStats tStats = getToolStats(aStack); + if (tStats == null || GTUtility.setStack(aStack, tStats.getBrokenItem(aStack)) == null) { + if (tStats != null) GTUtility.doSoundAtClient(tStats.getBreakingSound(), 1, 1.0F); + if (aStack.stackSize > 0) aStack.stackSize--; + } + } + return true; + } + if (use(aStack, (int) aAmount, null)) { + if (java.util.concurrent.ThreadLocalRandom.current() + .nextInt(0, 25) == 0) { + long tNewDamage = getToolDamage(aStack) + aAmount; + setToolDamage(aStack, tNewDamage); + if (tNewDamage >= getToolMaxDamage(aStack)) { + IToolStats tStats = getToolStats(aStack); + if (tStats == null || GTUtility.setStack(aStack, tStats.getBrokenItem(aStack)) == null) { + if (tStats != null) GTUtility.doSoundAtClient(tStats.getBreakingSound(), 1, 1.0F); + if (aStack.stackSize > 0) aStack.stackSize--; + } + } + } + return true; + } + return false; + } + + @Override + public float getDigSpeed(ItemStack aStack, Block aBlock, int aMetaData) { + if (!isItemStackUsable(aStack)) return 0.0F; + IToolStats tStats = getToolStats(aStack); + if (tStats == null || Math.max(0, getHarvestLevel(aStack, "")) < aBlock.getHarvestLevel(aMetaData)) return 0.0F; + return tStats.isMinableBlock(aBlock, (byte) aMetaData) + ? Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed) + : 0.0F; + } + + @Override + public final boolean canHarvestBlock(Block aBlock, ItemStack aStack) { + return getDigSpeed(aStack, aBlock, (byte) 0) > 0.0F; + } + + @Override + public final int getHarvestLevel(ItemStack aStack, String aToolClass) { + IToolStats tStats = getToolStats(aStack); + return tStats == null ? -1 : tStats.getBaseQuality() + getPrimaryMaterial(aStack).mToolQuality; + } + + @Override + public boolean onBlockDestroyed(ItemStack aStack, World aWorld, Block aBlock, int aX, int aY, int aZ, + EntityLivingBase aPlayer) { + if (!isItemStackUsable(aStack)) return false; + IToolStats tStats = getToolStats(aStack); + if (tStats == null) return false; + GTUtility.doSoundAtClient(tStats.getMiningSound(), 1, 1.0F); + doDamage( + aStack, + (int) Math.max(1, aBlock.getBlockHardness(aWorld, aX, aY, aZ) * tStats.getToolDamagePerBlockBreak())); + return getDigSpeed(aStack, aBlock, aWorld.getBlockMetadata(aX, aY, aZ)) > 0.0F; + } + + @Override + public final ItemStack getContainerItem(ItemStack aStack) { + return getContainerItem(aStack, true); + } + + @Override + public final boolean hasContainerItem(ItemStack aStack) { + return getContainerItem(aStack, false) != null; + } + + private ItemStack getContainerItem(ItemStack aStack, boolean playSound) { + if (!isItemStackUsable(aStack)) return null; + aStack = GTUtility.copyAmount(1, aStack); + IToolStats tStats = getToolStats(aStack); + if (tStats == null) return null; + doDamage(aStack, tStats.getToolDamagePerContainerCraft()); + aStack = aStack.stackSize > 0 ? aStack : null; + if (playSound && GTMod.gregtechproxy.mTicksUntilNextCraftSound <= 0) { + GTMod.gregtechproxy.mTicksUntilNextCraftSound = 10; + String sound = (aStack == null) ? tStats.getBreakingSound() : tStats.getCraftingSound(); + GTUtility.doSoundAtClient(sound, 1, 1.0F); + } + return aStack; + } + + public IToolStats getToolStats(ItemStack aStack) { + isItemStackUsable(aStack); + return getToolStatsInternal(aStack); + } + + public byte getToolMaxMode(ItemStack aStack) { + IToolStats stats = getToolStats(aStack); + if (stats != null) { + return stats.getMaxMode(); + } + return 1; + } + + private IToolStats getToolStatsInternal(ItemStack aStack) { + return aStack == null ? null : mToolStats.get((short) aStack.getItemDamage()); + } + + @Override + public float getSaplingModifier(ItemStack aStack, World aWorld, EntityPlayer aPlayer, int aX, int aY, int aZ) { + IToolStats tStats = getToolStats(aStack); + return tStats != null && tStats.isGrafter() ? Math.min(100.0F, (1 + getHarvestLevel(aStack, "")) * 20.0F) + : 0.0F; + } + + @Override + public boolean canWhack(EntityPlayer aPlayer, ItemStack aStack, int aX, int aY, int aZ) { + if (!isItemStackUsable(aStack)) return false; + IToolStats tStats = getToolStats(aStack); + return tStats != null && tStats.isCrowbar(); + } + + @Override + public void onWhack(EntityPlayer aPlayer, ItemStack aStack, int aX, int aY, int aZ) { + IToolStats tStats = getToolStats(aStack); + if (tStats != null) doDamage(aStack, tStats.getToolDamagePerEntityAttack()); + } + + @Override + public boolean canWrench(EntityPlayer player, int x, int y, int z) { + if (player == null) return false; + return canWrench(player.getHeldItem(), player, x, y, z); + } + + @Override + public boolean canWrench(ItemStack wrench, EntityPlayer player, int x, int y, int z) { + if (wrench == null) return false; + if (!isItemStackUsable(wrench)) return false; + IToolStats tStats = getToolStats(player.getCurrentEquippedItem()); + return tStats != null && tStats.isWrench(); + } + + @Override + public void wrenchUsed(EntityPlayer player, int x, int y, int z) { + if (player == null) return; + if (player.getCurrentEquippedItem() == null) return; + IToolStats tStats = getToolStats(player.getCurrentEquippedItem()); + if (tStats != null) doDamage(player.getCurrentEquippedItem(), tStats.getToolDamagePerEntityAttack()); + } + + @Override + public boolean canUse(ItemStack stack, EntityPlayer player, int x, int y, int z) { + return canWrench(player, x, y, z); + } + + // ProjectRed screwdriver + @Override + public boolean canUse(EntityPlayer player, ItemStack stack) { + if (player == null) return false; + if (GTUtility.isStackInvalid(stack) || !isItemStackUsable(stack)) return false; + IToolStats tStats = getToolStats(stack); + return tStats != null && tStats.isScrewdriver(); + } + + @Override + public void damageScrewdriver(EntityPlayer player, ItemStack stack) { + if (player == null) return; + if (GTUtility.isStackInvalid(stack) || !isItemStackUsable(stack)) return; + IToolStats tStats = getToolStats(stack); + if (tStats != null) doDamage(stack, tStats.getToolDamagePerEntityAttack()); + } + + @Override + public void used(ItemStack stack, EntityPlayer player, int x, int y, int z) { + wrenchUsed(player, x, y, z); + } + + @Override + public boolean shouldHideFacades(ItemStack stack, EntityPlayer player) { + if (player == null) return false; + if (player.getCurrentEquippedItem() == null) return false; + if (!isItemStackUsable(player.getCurrentEquippedItem())) return false; + IToolStats tStats = getToolStats(player.getCurrentEquippedItem()); + return tStats.isWrench(); + } + + @Override + public boolean canLink(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { + if (!isItemStackUsable(aStack)) return false; + IToolStats tStats = getToolStats(aStack); + return tStats != null && tStats.isCrowbar(); + } + + @Override + public void onLink(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { + IToolStats tStats = getToolStats(aStack); + if (tStats != null) doDamage(aStack, tStats.getToolDamagePerEntityAttack()); + } + + @Override + public boolean canBoost(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { + if (!isItemStackUsable(aStack)) return false; + IToolStats tStats = getToolStats(aStack); + return tStats != null && tStats.isCrowbar(); + } + + @Override + public void onBoost(EntityPlayer aPlayer, ItemStack aStack, EntityMinecart cart) { + IToolStats tStats = getToolStats(aStack); + if (tStats != null) doDamage(aStack, tStats.getToolDamagePerEntityAttack()); + } + + @Override + public void onCreated(ItemStack aStack, World aWorld, EntityPlayer aPlayer) { + IToolStats tStats = getToolStats(aStack); + if (tStats != null && aPlayer != null) tStats.onToolCrafted(aStack, aPlayer); + super.onCreated(aStack, aWorld, aPlayer); + } + + @Override + public final boolean doesContainerItemLeaveCraftingGrid(ItemStack aStack) { + return false; + } + + @Override + public final int getItemStackLimit(ItemStack aStack) { + return 1; + } + + @Override + public boolean isFull3D() { + return true; + } + + @Override + public boolean isItemStackUsable(ItemStack aStack) { + IToolStats tStats = getToolStatsInternal(aStack); + if (aStack.getItemDamage() % 2 != 0 || tStats == null) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) aNBT.removeTag("ench"); + return false; + } + Materials aMaterial = getPrimaryMaterial(aStack); + HashMap tMap = new HashMap<>(), tResult = new HashMap<>(); + if (aMaterial.mEnchantmentTools != null) { + tMap.put(aMaterial.mEnchantmentTools.effectId, (int) aMaterial.mEnchantmentToolsLevel); + if (aMaterial.mEnchantmentTools == Enchantment.fortune) + tMap.put(Enchantment.looting.effectId, (int) aMaterial.mEnchantmentToolsLevel); + if (aMaterial.mEnchantmentTools == Enchantment.knockback) + tMap.put(Enchantment.power.effectId, (int) aMaterial.mEnchantmentToolsLevel); + if (aMaterial.mEnchantmentTools == Enchantment.fireAspect) + tMap.put(Enchantment.flame.effectId, (int) aMaterial.mEnchantmentToolsLevel); + } + Enchantment[] tEnchants = tStats.getEnchantments(aStack); + int[] tLevels = tStats.getEnchantmentLevels(aStack); + for (int i = 0; i < tEnchants.length; i++) if (tLevels[i] > 0) { + Integer tLevel = tMap.get(tEnchants[i].effectId); + tMap.put( + tEnchants[i].effectId, + tLevel == null ? tLevels[i] : tLevel == tLevels[i] ? tLevel + 1 : Math.max(tLevel, tLevels[i])); + } + for (Entry tEntry : tMap.entrySet()) { + if (tEntry.getKey() == 33 || (tEntry.getKey() == 20 && tEntry.getValue() > 2) + || tEntry.getKey() == EnchantmentRadioactivity.INSTANCE.effectId) + tResult.put(tEntry.getKey(), tEntry.getValue()); + else switch (Enchantment.enchantmentsList[tEntry.getKey()].type) { + case weapon: + if (tStats.isWeapon()) tResult.put(tEntry.getKey(), tEntry.getValue()); + break; + case all: + tResult.put(tEntry.getKey(), tEntry.getValue()); + break; + case armor: + case armor_feet: + case armor_head: + case armor_legs: + case armor_torso: + break; + case bow: + if (tStats.isRangedWeapon()) tResult.put(tEntry.getKey(), tEntry.getValue()); + break; + case breakable: + break; + case fishing_rod: + break; + case digger: + if (tStats.isMiningTool()) tResult.put(tEntry.getKey(), tEntry.getValue()); + break; + } + } + EnchantmentHelper.setEnchantments(tResult, aStack); + return true; + } + + @Override + public String getItemStackDisplayName(ItemStack aStack) { + + String result = super.getItemStackDisplayName(aStack); + IToolStats toolStats = getToolStats(aStack); + if (toolStats != null) { + String toolName = toolStats.getToolTypeName(); + if (toolName == null) return result; + + String key = "gt." + toolName + ".mode." + getToolMode(aStack); + if (StatCollector.canTranslate(key)) { + result += " (" + StatCollector.translateToLocal(key) + ")"; + } + } + return result; + + } + + @Override + public short getChargedMetaData(ItemStack aStack) { + return (short) (aStack.getItemDamage() - (aStack.getItemDamage() % 2)); + } + + @Override + public short getEmptyMetaData(ItemStack aStack) { + NBTTagCompound aNBT = aStack.getTagCompound(); + if (aNBT != null) aNBT.removeTag("ench"); + return (short) (aStack.getItemDamage() + 1 - (aStack.getItemDamage() % 2)); + } + + @Override + public int getItemEnchantability() { + return 0; + } + + @Override + public boolean isBookEnchantable(ItemStack aStack, ItemStack aBook) { + return false; + } + + @Override + public boolean getIsRepairable(ItemStack aStack, ItemStack aMaterial) { + return false; + } +} diff --git a/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java b/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java index 3c05d8bed0..ed953d9477 100644 --- a/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java +++ b/src/main/java/gregtech/api/logic/AbstractProcessingLogic.java @@ -11,9 +11,9 @@ import gregtech.api.interfaces.tileentity.IVoidable; import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_ParallelHelper; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.OverclockCalculator; +import gregtech.api.util.ParallelHelper; /** * Logic class to calculate result of recipe check from inputs. @@ -23,7 +23,7 @@ public abstract class AbstractProcessingLogic

> recipeMapSupplier; - protected GT_Recipe lastRecipe; + protected GTRecipe lastRecipe; protected RecipeMap lastRecipeMap; protected ItemStack[] outputItems; protected FluidStack[] outputFluids; @@ -229,8 +229,8 @@ public abstract class AbstractProcessingLogic

= 0 && tSlot < inventory.getSlots()) { - inventory.setStackInSlot(tSlot, GT_Utility.loadItem(tNBT)); + inventory.setStackInSlot(tSlot, GTUtility.loadItem(tNBT)); } } } diff --git a/src/main/java/gregtech/api/logic/MuTEProcessingLogic.java b/src/main/java/gregtech/api/logic/MuTEProcessingLogic.java index da53c8875d..0d6bf4cac9 100644 --- a/src/main/java/gregtech/api/logic/MuTEProcessingLogic.java +++ b/src/main/java/gregtech/api/logic/MuTEProcessingLogic.java @@ -24,10 +24,10 @@ import gregtech.api.logic.interfaces.ProcessingLogicHost; import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_ParallelHelper; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.OverclockCalculator; +import gregtech.api.util.ParallelHelper; /** * Processing logic class, dedicated for MultiTileEntities. @@ -81,13 +81,13 @@ public class MuTEProcessingLogic

> extends Abstr } @Nonnull - protected CheckRecipeResult processRecipe(@Nonnull List recipes, @Nonnull ItemInventoryLogic itemInput, + protected CheckRecipeResult processRecipe(@Nonnull List recipes, @Nonnull ItemInventoryLogic itemInput, @Nonnull FluidInventoryLogic fluidInput) { CheckRecipeResult result = CheckRecipeResultRegistry.INTERNAL_ERROR; - for (GT_Recipe recipe : recipes) { + for (GTRecipe recipe : recipes) { Objects.requireNonNull(recipe); - GT_ParallelHelper helper = createParallelHelper(recipe, itemInput, fluidInput); - GT_OverclockCalculator calculator = createOverclockCalculator(recipe); + ParallelHelper helper = createParallelHelper(recipe, itemInput, fluidInput); + OverclockCalculator calculator = createOverclockCalculator(recipe); helper.setCalculator(calculator); helper.build(); result = helper.getResult(); @@ -112,9 +112,9 @@ public class MuTEProcessingLogic

> extends Abstr } @Nonnull - protected GT_ParallelHelper createParallelHelper(@Nonnull GT_Recipe recipe, @Nonnull ItemInventoryLogic itemInput, + protected ParallelHelper createParallelHelper(@Nonnull GTRecipe recipe, @Nonnull ItemInventoryLogic itemInput, @Nonnull FluidInventoryLogic fluidInput) { - return new GT_ParallelHelper().setRecipe(recipe) + return new ParallelHelper().setRecipe(recipe) .setItemInputInventory(itemInput) .setFluidInputInventory(fluidInput) .setAvailableEUt(availableVoltage * availableAmperage) @@ -197,7 +197,7 @@ public class MuTEProcessingLogic

> extends Abstr if (outputItems != null) { NBTTagList itemOutputsNBT = new NBTTagList(); for (ItemStack item : outputItems) { - itemOutputsNBT.appendTag(GT_Utility.saveItem(item)); + itemOutputsNBT.appendTag(GTUtility.saveItem(item)); } logicNBT.setTag("itemOutputs", itemOutputsNBT); } @@ -226,7 +226,7 @@ public class MuTEProcessingLogic

> extends Abstr NBTTagList itemOutputsNBT = logicNBT.getTagList("itemOutputs", TAG_COMPOUND); outputItems = new ItemStack[itemOutputsNBT.tagCount()]; for (int i = 0; i < itemOutputsNBT.tagCount(); i++) { - outputItems[i] = GT_Utility.loadItem(itemOutputsNBT.getCompoundTagAt(i)); + outputItems[i] = GTUtility.loadItem(itemOutputsNBT.getCompoundTagAt(i)); } } if (logicNBT.hasKey("fluidOutputs")) { diff --git a/src/main/java/gregtech/api/logic/PowerLogic.java b/src/main/java/gregtech/api/logic/PowerLogic.java index ad19987a76..afc1877deb 100644 --- a/src/main/java/gregtech/api/logic/PowerLogic.java +++ b/src/main/java/gregtech/api/logic/PowerLogic.java @@ -8,12 +8,12 @@ import javax.annotation.Nonnull; import net.minecraft.nbt.NBTTagCompound; -import gregtech.api.enums.GT_Values.NBT; +import gregtech.api.enums.GTValues.NBT; /** * Power logic for machines. This is used to store all the important variables for a machine to have energy and use it * in any way. - * + * * @author BlueWeabo, Maxim */ public class PowerLogic { @@ -122,7 +122,7 @@ public class PowerLogic { /** * Injecting energy in the multiblock ampere per ampere until full or until we have added the maximum possible * amperes for this tick - * + * * @param voltage At what voltage are the amps? * @param availableAmperage How much amperage do we have available * @return Amount of amperes used @@ -218,7 +218,7 @@ public class PowerLogic { /** * Saves the power logic to its own nbt tag before saving it to the given one. - * + * * @param nbt Tag where you want to save the power logic tag to. */ public void saveToNBT(NBTTagCompound nbt) { @@ -233,7 +233,7 @@ public class PowerLogic { /** * Loads the power logic from its own nbt after getting it from the given one - * + * * @param nbt Tag where the power logic tag was saved to */ public void loadFromNBT(NBTTagCompound nbt) { diff --git a/src/main/java/gregtech/api/logic/ProcessingLogic.java b/src/main/java/gregtech/api/logic/ProcessingLogic.java index 4d203ed80f..63c8f6494e 100644 --- a/src/main/java/gregtech/api/logic/ProcessingLogic.java +++ b/src/main/java/gregtech/api/logic/ProcessingLogic.java @@ -14,9 +14,9 @@ import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.recipe.check.SingleRecipeCheck; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_ParallelHelper; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.OverclockCalculator; +import gregtech.api.util.ParallelHelper; /** * Logic class to calculate result of recipe check from inputs, based on recipemap. @@ -119,10 +119,10 @@ public class ProcessingLogic extends AbstractProcessingLogic { recipeLockableMachine.getSingleRecipeCheck() .getRecipe()).checkRecipeResult; } - Stream matchedRecipes = findRecipeMatches(recipeMap); - Iterable recipeIterable = matchedRecipes::iterator; + Stream matchedRecipes = findRecipeMatches(recipeMap); + Iterable recipeIterable = matchedRecipes::iterator; CheckRecipeResult checkRecipeResult = CheckRecipeResultRegistry.NO_RECIPE; - for (GT_Recipe matchedRecipe : recipeIterable) { + for (GTRecipe matchedRecipe : recipeIterable) { CalculationResult foundResult = validateAndCalculateRecipe(matchedRecipe); if (foundResult.successfullyConsumedInputs) { // Successfully found and set recipe, so return it @@ -143,14 +143,14 @@ public class ProcessingLogic extends AbstractProcessingLogic { * @param recipe The recipe which will be checked and processed */ @Nonnull - private CalculationResult validateAndCalculateRecipe(@Nonnull GT_Recipe recipe) { + private CalculationResult validateAndCalculateRecipe(@Nonnull GTRecipe recipe) { CheckRecipeResult result = validateRecipe(recipe); if (!result.wasSuccessful()) { return CalculationResult.ofFailure(result); } - GT_ParallelHelper helper = createParallelHelper(recipe); - GT_OverclockCalculator calculator = createOverclockCalculator(recipe); + ParallelHelper helper = createParallelHelper(recipe); + OverclockCalculator calculator = createOverclockCalculator(recipe); helper.setCalculator(calculator); helper.build(); @@ -170,7 +170,7 @@ public class ProcessingLogic extends AbstractProcessingLogic { * Override this method if it doesn't work with normal recipemaps. */ @Nonnull - protected Stream findRecipeMatches(@Nullable RecipeMap map) { + protected Stream findRecipeMatches(@Nullable RecipeMap map) { if (map == null) { return Stream.empty(); } @@ -186,8 +186,8 @@ public class ProcessingLogic extends AbstractProcessingLogic { * Override to tweak parallel logic if needed. */ @Nonnull - protected GT_ParallelHelper createParallelHelper(@Nonnull GT_Recipe recipe) { - return new GT_ParallelHelper().setRecipe(recipe) + protected ParallelHelper createParallelHelper(@Nonnull GTRecipe recipe) { + return new ParallelHelper().setRecipe(recipe) .setItemInputs(inputItems) .setFluidInputs(inputFluids) .setAvailableEUt(availableVoltage * availableAmperage) diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java index 2bc560f8e7..aae3ddcebb 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java @@ -1,7 +1,7 @@ package gregtech.api.metatileentity; -import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.NW; +import static gregtech.GTMod.GT_FML_LOGGER; +import static gregtech.api.enums.GTValues.NW; import java.util.ArrayList; import java.util.Arrays; @@ -25,8 +25,8 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; import gregtech.api.enums.SoundResource; import gregtech.api.enums.Textures; import gregtech.api.graphs.Lock; @@ -38,13 +38,13 @@ import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IDebugableTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IPipeRenderedTileEntity; -import gregtech.api.net.GT_Packet_TileEntity; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; +import gregtech.api.net.GTPacketTileEntity; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; import gregtech.common.covers.CoverInfo; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; @@ -59,7 +59,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity public byte mConnections = IConnectable.NO_CONNECTION; protected MetaPipeEntity mMetaTileEntity; - private final int[] mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING]; + private final int[] mTimeStatistics = new int[GregTechAPI.TICKS_FOR_LAG_AVERAGING]; private boolean hasTimeStatisticsStarted; private boolean mWorkUpdate = false, mWorks = true; private byte mColor = 0, oColor = 0, oStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0, @@ -214,7 +214,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity | IConnectable.HAS_HARDENEDFOAM); } if (mTickTimer > 12 && oldConnections != mConnections) - GregTech_API.causeCableUpdate(worldObj, xCoord, yCoord, zCoord); + GregTechAPI.causeCableUpdate(worldObj, xCoord, yCoord, zCoord); } mMetaTileEntity.onPreTick(this, mTickTimer); if (!hasValidMetaTileEntity()) return; @@ -264,14 +264,14 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity } } catch (Throwable e) { e.printStackTrace(); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); } if (isServerSide() && hasTimeStatisticsStarted && hasValidMetaTileEntity()) { tTime = System.nanoTime() - tTime; mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length; mTimeStatistics[mTimeStatisticsIndex] = (int) tTime; - if (tTime > 0 && tTime > (GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING * 1000000L) + if (tTime > 0 && tTime > (GregTechAPI.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING * 1000000L) && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) @@ -296,7 +296,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity if (mSendClientData) { NW.sendPacketToAllPlayersInRange( worldObj, - new GT_Packet_TileEntity( + new GTPacketTileEntity( xCoord, (short) yCoord, zCoord, @@ -438,7 +438,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity tList.add( "Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " - + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + + GregTechAPI.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); } if (mMetaTileEntity != null) { @@ -491,13 +491,13 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity markDirty(); mInventoryChanged = true; if (canAccessData()) mMetaTileEntity - .setInventorySlotContents(aIndex, worldObj.isRemote ? aStack : GT_OreDictUnificator.setStack(true, aStack)); + .setInventorySlotContents(aIndex, worldObj.isRemote ? aStack : GTOreDictUnificator.setStack(true, aStack)); } @Override public String getInventoryName() { if (canAccessData()) return mMetaTileEntity.getInventoryName(); - if (GregTech_API.METATILEENTITIES[mID] != null) return GregTech_API.METATILEENTITIES[mID].getInventoryName(); + if (GregTechAPI.METATILEENTITIES[mID] != null) return GregTechAPI.METATILEENTITIES[mID].getInventoryName(); return ""; } @@ -776,7 +776,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity @Override public ArrayList getDrops() { - final ItemStack rStack = new ItemStack(GregTech_API.sBlockMachines, 1, mID); + final ItemStack rStack = new ItemStack(GregTechAPI.sBlockMachines, 1, mID); final NBTTagCompound tNBT = new NBTTagCompound(); writeCoverNBT(tNBT, true); @@ -799,7 +799,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity // Configure Cover, sneak can also be: screwdriver, wrench, side cutter, soldering iron if (aPlayer.isSneaking()) { final ForgeDirection tSide = (getCoverIDAtSide(side) == 0) - ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) + ? GTUtility.determineWrenchingSide(side, aX, aY, aZ) : side; return (getCoverInfoAtSide(tSide).hasCoverGUI()); } else if (getCoverBehaviorAtSideNew(side).onCoverRightclickClient(side, this, aPlayer, aX, aY, aZ)) { @@ -810,19 +810,19 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity final ItemStack tCurrentItem = aPlayer.inventory.getCurrentItem(); if (tCurrentItem != null) { if (getColorization() >= 0 - && GT_Utility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) { + && GTUtility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) { mMetaTileEntity.markDirty(); tCurrentItem.func_150996_a(Items.bucket); setColorization((byte) -1); return true; } - final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWrenchList)) { + final ForgeDirection tSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sWrenchList)) { if (mMetaTileEntity.onWrenchRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) { mMetaTileEntity.markDirty(); - GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); - GT_Utility.sendSoundToPlayers( + GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -833,15 +833,15 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity } return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sScrewdriverList)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sScrewdriverList)) { if (getCoverIDAtSide(side) == 0 && getCoverIDAtSide(tSide) != 0) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) { setCoverDataAtSide( tSide, getCoverInfoAtSide(tSide).onCoverScrewdriverClick(aPlayer, 0.5F, 0.5F, 0.5F)); mMetaTileEntity.onScrewdriverRightClick(tSide, aPlayer, aX, aY, aZ, tCurrentItem); mMetaTileEntity.markDirty(); - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -851,13 +851,13 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity zCoord); } } else { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { setCoverDataAtSide( side, getCoverInfoAtSide(side).onCoverScrewdriverClick(aPlayer, aX, aY, aZ)); mMetaTileEntity.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ, tCurrentItem); mMetaTileEntity.markDirty(); - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -870,21 +870,21 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sHardHammerList)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sHardHammerList)) { return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSoftHammerList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sSoftHammerList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { if (mWorks) disableWorking(); else enableWorking(); mMetaTileEntity.markDirty(); - GT_Utility.sendChatToPlayer( + GTUtility.sendChatToPlayer( aPlayer, - GT_Utility.trans("090", "Machine Processing: ") - + (isAllowedToWork() ? GT_Utility.trans("088", "Enabled") - : GT_Utility.trans("087", "Disabled"))); - GT_Utility.sendSoundToPlayers( + GTUtility.trans("090", "Machine Processing: ") + + (isAllowedToWork() ? GTUtility.trans("088", "Enabled") + : GTUtility.trans("087", "Disabled"))); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE, 1.0F, @@ -896,11 +896,11 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWireCutterList)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sWireCutterList)) { if (mMetaTileEntity.onWireCutterRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) { mMetaTileEntity.markDirty(); // logic handled internally - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -913,11 +913,11 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSolderingToolList)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sSolderingToolList)) { if (mMetaTileEntity.onSolderingToolRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) { mMetaTileEntity.markDirty(); // logic handled internally - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_BATTERY_USE, 1.0F, @@ -925,16 +925,16 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity xCoord, yCoord, zCoord); - } else if (GT_ModHandler.useSolderingIron(tCurrentItem, aPlayer)) { + } else if (GTModHandler.useSolderingIron(tCurrentItem, aPlayer)) { mMetaTileEntity.markDirty(); mStrongRedstone ^= tSide.flag; - GT_Utility.sendChatToPlayer( + GTUtility.sendChatToPlayer( aPlayer, - GT_Utility.trans("091", "Redstone Output at Side ") + tSide - + GT_Utility.trans("092", " set to: ") - + ((mStrongRedstone & tSide.flag) != 0 ? GT_Utility.trans("093", "Strong") - : GT_Utility.trans("094", "Weak"))); - GT_Utility.sendSoundToPlayers( + GTUtility.trans("091", "Redstone Output at Side ") + tSide + + GTUtility.trans("092", " set to: ") + + ((mStrongRedstone & tSide.flag) != 0 ? GTUtility.trans("093", "Strong") + : GTUtility.trans("094", "Weak"))); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_BATTERY_USE, 3.0F, @@ -954,17 +954,17 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity final CoverInfo coverInfo = getCoverInfoAtSide(coverSide); if (coverInfo.getCoverID() == 0) { - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCovers.keySet())) { - final GT_CoverBehaviorBase coverBehavior = GregTech_API.getCoverBehaviorNew(tCurrentItem); + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sCovers.keySet())) { + final CoverBehaviorBase coverBehavior = GregTechAPI.getCoverBehaviorNew(tCurrentItem); if (coverBehavior.isCoverPlaceable(coverSide, tCurrentItem, this) - && mMetaTileEntity.allowCoverOnSide(coverSide, new GT_ItemStack(tCurrentItem))) { + && mMetaTileEntity.allowCoverOnSide(coverSide, new GTItemStack(tCurrentItem))) { setCoverItemAtSide(coverSide, tCurrentItem); coverBehavior.onPlayerAttach(aPlayer, tCurrentItem, this, side); mMetaTileEntity.markDirty(); if (!aPlayer.capabilities.isCreativeMode) tCurrentItem.stackSize--; - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -976,9 +976,9 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity return true; } } else { - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCrowbarList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { - GT_Utility.sendSoundToPlayers( + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sCrowbarList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + GTUtility.sendSoundToPlayers( worldObj, SoundResource.RANDOM_BREAK, 1.0F, @@ -993,7 +993,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity } } } else if (aPlayer.isSneaking()) { // Sneak click, no tool -> open cover config or turn back. - side = (getCoverIDAtSide(side) == 0) ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) : side; + side = (getCoverIDAtSide(side) == 0) ? GTUtility.determineWrenchingSide(side, aX, aY, aZ) : side; final CoverInfo coverInfo = getCoverInfoAtSide(side); return coverInfo.isValid() && coverInfo.onCoverShiftRightClick(aPlayer); } @@ -1064,7 +1064,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity final CoverInfo coverInfo = getCoverInfoAtSide(ForgeDirection.getOrientation(ordinalSide)); if (canAccessData() && (coverInfo.letsItemsOut(-1) || coverInfo.letsItemsIn(-1))) return mMetaTileEntity.getAccessibleSlotsFromSide(ordinalSide); - return GT_Values.emptyIntArray; + return GTValues.emptyIntArray; } /** @@ -1164,7 +1164,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity @Override public UUID getOwnerUuid() { - return GT_Utility.defaultUuid; + return GTUtility.defaultUuid; } @Override @@ -1276,15 +1276,15 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity @Override public boolean addStackToSlot(int aIndex, ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return true; + if (GTUtility.isStackInvalid(aStack)) return true; if (aIndex < 0 || aIndex >= getSizeInventory()) return false; final ItemStack tStack = getStackInSlot(aIndex); - if (GT_Utility.isStackInvalid(tStack)) { + if (GTUtility.isStackInvalid(tStack)) { setInventorySlotContents(aIndex, aStack); return true; } - aStack = GT_OreDictUnificator.get(aStack); - if (GT_Utility.areStacksEqual(tStack, aStack) + aStack = GTOreDictUnificator.get(aStack); + if (GTUtility.areStacksEqual(tStack, aStack) && tStack.stackSize + aStack.stackSize <= Math.min(aStack.getMaxStackSize(), getInventoryStackLimit())) { markDirty(); tStack.stackSize += aStack.stackSize; @@ -1295,7 +1295,7 @@ public class BaseMetaPipeEntity extends CommonMetaTileEntity @Override public boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount) { - return addStackToSlot(aIndex, GT_Utility.copyAmount(aAmount, aStack)); + return addStackToSlot(aIndex, GTUtility.copyAmount(aAmount, aStack)); } @Override diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index 27a6216cff..1229dfcc5b 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -1,8 +1,8 @@ package gregtech.api.metatileentity; -import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.NW; -import static gregtech.api.enums.GT_Values.V; +import static gregtech.GTMod.GT_FML_LOGGER; +import static gregtech.api.enums.GTValues.NW; +import static gregtech.api.enums.GTValues.V; import static gregtech.api.objects.XSTR.XSTR_INSTANCE; import java.lang.reflect.Field; @@ -54,9 +54,9 @@ import appeng.me.helpers.IGridProxyable; import appeng.tile.TileEvent; import appeng.tile.events.TileEventType; import cpw.mods.fml.relauncher.ReflectionHelper; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; import gregtech.api.enums.ItemList; import gregtech.api.enums.SoundResource; import gregtech.api.enums.Textures; @@ -71,19 +71,19 @@ import gregtech.api.interfaces.tileentity.IDebugableTileEntity; import gregtech.api.interfaces.tileentity.IEnergyConnected; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IGregtechWailaProvider; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch; -import gregtech.api.net.GT_Packet_TileEntity; -import gregtech.api.objects.GT_ItemStack; +import gregtech.api.metatileentity.implementations.MTEBasicMachine; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.net.GTPacketTileEntity; +import gregtech.api.objects.GTItemStack; import gregtech.api.objects.blockupdate.BlockUpdateHandler; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; import gregtech.api.util.shutdown.ShutDownReason; import gregtech.api.util.shutdown.ShutDownReasonRegistry; -import gregtech.common.GT_Pollution; +import gregtech.common.Pollution; import gregtech.common.covers.CoverInfo; import ic2.api.Direction; import mcp.mobius.waila.api.IWailaConfigHandler; @@ -102,7 +102,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity .findField(EntityItem.class, "health", "field_70291_e"); private final boolean[] mActiveEUInputs = new boolean[] { false, false, false, false, false, false }; private final boolean[] mActiveEUOutputs = new boolean[] { false, false, false, false, false, false }; - private final int[] mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING]; + private final int[] mTimeStatistics = new int[GregTechAPI.TICKS_FOR_LAG_AVERAGING]; private boolean hasTimeStatisticsStarted; public long mLastSoundTick = 0; public boolean mWasShutdown = false; @@ -125,7 +125,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity private long oOutput = 0, mAcceptedAmperes = Long.MAX_VALUE; private long mLastCheckTick = 0; private String mOwnerName = ""; - private UUID mOwnerUuid = GT_Utility.defaultUuid; + private UUID mOwnerUuid = GTUtility.defaultUuid; private NBTTagCompound mRecipeStuff = new NBTTagCompound(); private int cableUpdateDelay = 30; @@ -242,7 +242,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity */ public void chargeItem(ItemStack aStack) { decreaseStoredEU( - GT_ModHandler.chargeElectricItem( + GTModHandler.chargeElectricItem( aStack, (int) Math.min(Integer.MAX_VALUE, getStoredEU()), (int) Math.min(Integer.MAX_VALUE, mMetaTileEntity.getOutputTier()), @@ -256,7 +256,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity */ public void dischargeItem(ItemStack aStack) { increaseStoredEnergyUnits( - GT_ModHandler.dischargeElectricItem( + GTModHandler.dischargeElectricItem( aStack, (int) Math.min(Integer.MAX_VALUE, getEUCapacity() - getStoredEU()), (int) Math.min(Integer.MAX_VALUE, mMetaTileEntity.getInputTier()), @@ -351,7 +351,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } if (mNeedsUpdate) { - if (GT_Mod.gregtechproxy.mUseBlockUpdateHandler) { + if (GTMod.gregtechproxy.mUseBlockUpdateHandler) { BlockUpdateHandler.Instance.enqueueBlockUpdate(worldObj, getLocation()); } else { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); @@ -424,7 +424,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (mMetaTileEntity.isEnetOutput() && oOutput > 0) { final long tOutputVoltage = Math - .max(oOutput, oOutput + (1L << Math.max(0, GT_Utility.getTier(oOutput) - 1))); + .max(oOutput, oOutput + (1L << Math.max(0, GTUtility.getTier(oOutput) - 1))); final long tUsableAmperage = Math.min( getOutputAmperage(), (getStoredEU() - mMetaTileEntity.getMinimumStoredEU()) / tOutputVoltage); @@ -436,7 +436,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } } if (getEUCapacity() > 0) { - if (GregTech_API.sMachineFireExplosions && getRandomNumber(1000) == 0) { + if (GregTechAPI.sMachineFireExplosions && getRandomNumber(1000) == 0) { final Block tBlock = getBlockAtSide(ForgeDirection.getOrientation(getRandomNumber(6))); if (tBlock instanceof BlockFire) doEnergyExplosion(); } @@ -446,7 +446,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return; } - if (GregTech_API.sMachineRainExplosions) { + if (GregTechAPI.sMachineRainExplosions) { if (mMetaTileEntity.willExplodeInRain()) { if (getRandomNumber(1000) == 0 && isRainPossible()) { // Short-circuit so raincheck happens before isRainExposed, @@ -457,12 +457,12 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (worldObj.isRaining() && isRainExposed()) { if (getRandomNumber(10) == 0) { try { - GT_Mod.achievements.issueAchievement( + GTMod.achievements.issueAchievement( this.getWorldObj() .getPlayerEntityByName(mOwnerName), "badweather"); } catch (Exception ignored) {} - GT_Log.exp.println( + GTLog.exp.println( "Machine at: " + this.getXCoord() + " | " + this.getYCoord() @@ -473,7 +473,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity + " explosion due to rain!"); doEnergyExplosion(); } else { - GT_Log.exp.println( + GTLog.exp.println( "Machine at: " + this.getXCoord() + " | " + this.getYCoord() @@ -489,16 +489,16 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity mRunningThroughTick = false; return; } - if (GregTech_API.sMachineThunderExplosions && worldObj.isThundering() + if (GregTechAPI.sMachineThunderExplosions && worldObj.isThundering() && getRandomNumber(3) == 0 && isRainExposed()) { try { - GT_Mod.achievements.issueAchievement( + GTMod.achievements.issueAchievement( this.getWorldObj() .getPlayerEntityByName(mOwnerName), "badweather"); } catch (Exception ignored) {} - GT_Log.exp.println( + GTLog.exp.println( "Machine at: " + this.getXCoord() + " | " + this.getYCoord() @@ -591,8 +591,8 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity tData = mMetaTileEntity.getUpdateData(); if (tData != oUpdateData) sendBlockEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, oUpdateData = tData); - if (mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) { - tData = ((GT_MetaTileEntity_Hatch) mMetaTileEntity).getTexturePage(); + if (mMetaTileEntity instanceof MTEHatch) { + tData = ((MTEHatch) mMetaTileEntity).getTexturePage(); if (tData != oTexturePage) sendBlockEvent( GregTechTileClientEvents.CHANGE_CUSTOM_DATA, (byte) ((oTexturePage = tData) | 0x80)); // set last bit as a flag for page @@ -628,12 +628,12 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } } catch (Throwable e) { e.printStackTrace(); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); try { mMetaTileEntity.onTickFail(this, mTickTimer); } catch (Throwable ex) { ex.printStackTrace(); - ex.printStackTrace(GT_Log.err); + ex.printStackTrace(GTLog.err); } } @@ -641,7 +641,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity tTime = System.nanoTime() - tTime; mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length; mTimeStatistics[mTimeStatisticsIndex] = (int) tTime; - if (tTime > 0 && tTime > (GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING * 1_000_000L) + if (tTime > 0 && tTime > (GregTechAPI.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING * 1_000_000L) && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) @@ -684,7 +684,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (mSendClientData) { NW.sendPacketToAllPlayersInRange( worldObj, - new GT_Packet_TileEntity( + new GTPacketTileEntity( xCoord, (short) yCoord, zCoord, @@ -699,8 +699,8 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity | (mRedstone ? 16 : 0) | (mLockUpgrade ? 32 : 0) | (mWorks ? 64 : 0)), - oTexturePage = (hasValidMetaTileEntity() && mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) - ? ((GT_MetaTileEntity_Hatch) mMetaTileEntity).getTexturePage() + oTexturePage = (hasValidMetaTileEntity() && mMetaTileEntity instanceof MTEHatch) + ? ((MTEHatch) mMetaTileEntity).getTexturePage() : 0, oUpdateData = hasValidMetaTileEntity() ? mMetaTileEntity.getUpdateData() : 0, oRedstoneData = (byte) (((mSidedRedstone[0] > 0) ? 1 : 0) | ((mSidedRedstone[1] > 0) ? 2 : 0) @@ -747,9 +747,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity try { mMetaTileEntity.receiveClientEvent((byte) aEventID, (byte) aValue); } catch (Throwable e) { - GT_Log.err.println( + GTLog.err.println( "Encountered Exception while receiving Data from the Server, the Client should've been crashed by now, but I prevented that. Please report immediately to GregTech Intergalactical!!!"); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); } } @@ -768,8 +768,8 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (hasValidMetaTileEntity()) { if ((aValue & 0x80) == 0) // Is texture index mMetaTileEntity.onValueUpdate((byte) (aValue & 0x7F)); - else if (mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) // is texture page and hatch - ((GT_MetaTileEntity_Hatch) mMetaTileEntity).onTexturePageUpdate((byte) (aValue & 0x7F)); + else if (mMetaTileEntity instanceof MTEHatch) // is texture page and hatch + ((MTEHatch) mMetaTileEntity).onTexturePageUpdate((byte) (aValue & 0x7F)); } } case GregTechTileClientEvents.CHANGE_COLOR -> { @@ -836,11 +836,11 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity int samples = mTimeStatistics.length - amountOfZero; if (samples > 0) { tList.add( - "Average CPU load of ~" + GT_Utility.formatNumbers(tAverageTime / samples) + "Average CPU load of ~" + GTUtility.formatNumbers(tAverageTime / samples) + "ns over " - + GT_Utility.formatNumbers(samples) + + GTUtility.formatNumbers(samples) + " ticks with worst time of " - + GT_Utility.formatNumbers(tWorstTime) + + GTUtility.formatNumbers(tWorstTime) + "ns."); } } else { @@ -848,9 +848,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity tList.add("Just started tick time statistics."); } tList.add( - "Recorded " + GT_Utility.formatNumbers(mMetaTileEntity.mSoundRequests) + "Recorded " + GTUtility.formatNumbers(mMetaTileEntity.mSoundRequests) + " sound requests in " - + GT_Utility.formatNumbers(mTickTimer - mLastCheckTick) + + GTUtility.formatNumbers(mTickTimer - mLastCheckTick) + " ticks."); mLastCheckTick = mTickTimer; mMetaTileEntity.mSoundRequests = 0; @@ -858,7 +858,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity tList.add( "Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " - + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + + GregTechAPI.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); } tList.add( @@ -867,8 +867,8 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } if (aLogLevel > 0) { if (getSteamCapacity() > 0 && hasSteamEngineUpgrade()) tList.add( - GT_Utility.formatNumbers(getStoredSteam()) + " of " - + GT_Utility.formatNumbers(getSteamCapacity()) + GTUtility.formatNumbers(getStoredSteam()) + " of " + + GTUtility.formatNumbers(getSteamCapacity()) + " Steam"); tList.add( "Machine is " + (mActive ? EnumChatFormatting.GREEN + "active" + EnumChatFormatting.RESET @@ -907,7 +907,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (mMetaTileEntity.shouldTriggerBlockUpdate()) { // If we're triggering a block update this will call onMachineBlockUpdate() - GregTech_API.causeMachineUpdate(worldObj, xCoord, yCoord, zCoord); + GregTechAPI.causeMachineUpdate(worldObj, xCoord, yCoord, zCoord); } else { // If we're not trigger a cascading one, call the update here. onMachineBlockUpdate(); @@ -934,14 +934,14 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity markDirty(); mMetaTileEntity.setInventorySlotContents( aIndex, - worldObj.isRemote ? aStack : GT_OreDictUnificator.setStack(true, aStack)); + worldObj.isRemote ? aStack : GTOreDictUnificator.setStack(true, aStack)); } } @Override public String getInventoryName() { if (canAccessData()) return mMetaTileEntity.getInventoryName(); - if (GregTech_API.METATILEENTITIES[mID] != null) return GregTech_API.METATILEENTITIES[mID].getInventoryName(); + if (GregTechAPI.METATILEENTITIES[mID] != null) return GregTechAPI.METATILEENTITIES[mID].getInventoryName(); return ""; } @@ -1374,7 +1374,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity public void doEnergyExplosion() { if (getUniversalEnergyCapacity() > 0 && getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 5) { - GT_Log.exp.println( + GTLog.exp.println( "Energy Explosion, injected " + getUniversalEnergyStored() + "EU >= " + getUniversalEnergyCapacity() / 5D @@ -1383,7 +1383,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity doExplosion( oOutput * (getUniversalEnergyStored() >= getUniversalEnergyCapacity() ? 4 : getUniversalEnergyStored() >= getUniversalEnergyCapacity() / 2 ? 2 : 1)); - GT_Mod.achievements.issueAchievement( + GTMod.achievements.issueAchievement( this.getWorldObj() .getPlayerEntityByName(mOwnerName), "electricproblems"); @@ -1394,7 +1394,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity public void doExplosion(long aAmount) { if (canAccessData()) { // This is only for Electric Machines - if (GregTech_API.sMachineWireFire && mMetaTileEntity.isElectric()) { + if (GregTechAPI.sMachineWireFire && mMetaTileEntity.isElectric()) { try { mReleaseEnergy = true; IEnergyConnected.Util.emitEnergyToNetwork(V[5], Math.max(1, getStoredEU() / V[5]), this); @@ -1403,7 +1403,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity mReleaseEnergy = false; // Normal Explosion Code mMetaTileEntity.onExplosion(); - if (GT_Mod.gregtechproxy.mExplosionItemDrop) { + if (GTMod.gregtechproxy.mExplosionItemDrop) { for (int i = 0; i < this.getSizeInventory(); i++) { final ItemStack tItem = this.getStackInSlot(i); if ((tItem != null) && (tItem.stackSize > 0) && (this.isValidSlot(i))) { @@ -1415,12 +1415,12 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (mRecipeStuff != null) { for (int i = 0; i < 9; i++) { if (this.getRandomNumber(100) < 50) { - dropItems(GT_Utility.loadItem(mRecipeStuff, "Ingredient." + i)); + dropItems(GTUtility.loadItem(mRecipeStuff, "Ingredient." + i)); } } } - GT_Pollution.addPollution((TileEntity) this, GT_Mod.gregtechproxy.mPollutionOnExplosion); + Pollution.addPollution((TileEntity) this, GTMod.gregtechproxy.mPollutionOnExplosion); mMetaTileEntity.doExplosion(aAmount); } } @@ -1453,7 +1453,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity @Override public ArrayList getDrops() { - final ItemStack rStack = new ItemStack(GregTech_API.sBlockMachines, 1, mID); + final ItemStack rStack = new ItemStack(GregTechAPI.sBlockMachines, 1, mID); final NBTTagCompound tNBT = new NBTTagCompound(); if (mRecipeStuff != null && !mRecipeStuff.hasNoTags()) tNBT.setTag("GT.CraftingComponents", mRecipeStuff); if (mMuffler) tNBT.setBoolean("mMuffler", mMuffler); @@ -1486,7 +1486,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity // Configure Cover, sneak can also be: screwdriver, wrench, side cutter, soldering iron if (aPlayer.isSneaking()) { final ForgeDirection tSide = (getCoverIDAtSide(side) == 0) - ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) + ? GTUtility.determineWrenchingSide(side, aX, aY, aZ) : side; return (getCoverBehaviorAtSideNew(tSide).hasCoverGUI()); } else if (getCoverBehaviorAtSideNew(side).onCoverRightclickClient(side, this, aPlayer, aX, aY, aZ)) { @@ -1502,17 +1502,17 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity final ItemStack tCurrentItem = aPlayer.inventory.getCurrentItem(); if (tCurrentItem != null) { if (getColorization() >= 0 - && GT_Utility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) { + && GTUtility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) { tCurrentItem.func_150996_a(Items.bucket); setColorization((byte) (getColorization() >= 16 ? -2 : -1)); return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWrenchList)) { - if (aPlayer.isSneaking() && mMetaTileEntity instanceof GT_MetaTileEntity_BasicMachine - && ((GT_MetaTileEntity_BasicMachine) mMetaTileEntity) - .setMainFacing(GT_Utility.determineWrenchingSide(side, aX, aY, aZ))) { - GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); - GT_Utility.sendSoundToPlayers( + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sWrenchList)) { + if (aPlayer.isSneaking() && mMetaTileEntity instanceof MTEBasicMachine + && ((MTEBasicMachine) mMetaTileEntity) + .setMainFacing(GTUtility.determineWrenchingSide(side, aX, aY, aZ))) { + GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -1523,14 +1523,14 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity cableUpdateDelay = 10; } else if (mMetaTileEntity.onWrenchRightClick( side, - GT_Utility.determineWrenchingSide(side, aX, aY, aZ), + GTUtility.determineWrenchingSide(side, aX, aY, aZ), aPlayer, aX, aY, aZ, tCurrentItem)) { - GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); - GT_Utility.sendSoundToPlayers( + GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -1543,8 +1543,8 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sScrewdriverList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sScrewdriverList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) { setCoverDataAtSide( side, getCoverBehaviorAtSideNew(side).onCoverScrewdriverClick( @@ -1557,7 +1557,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity aY, aZ)); mMetaTileEntity.onScrewdriverRightClick(side, aPlayer, aX, aY, aZ, tCurrentItem); - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -1569,18 +1569,18 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sHardHammerList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sHardHammerList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { mInputDisabled = !mInputDisabled; if (mInputDisabled) mOutputDisabled = !mOutputDisabled; - GT_Utility.sendChatToPlayer( + GTUtility.sendChatToPlayer( aPlayer, - GT_Utility.trans("086", "Auto-Input: ") + (mInputDisabled - ? GT_Utility.trans("087", "Disabled") - : GT_Utility.trans("088", "Enabled") + GT_Utility.trans("089", " Auto-Output: ") - + (mOutputDisabled ? GT_Utility.trans("087", "Disabled") - : GT_Utility.trans("088", "Enabled")))); - GT_Utility.sendSoundToPlayers( + GTUtility.trans("086", "Auto-Input: ") + + (mInputDisabled ? GTUtility.trans("087", "Disabled") + : GTUtility.trans("088", "Enabled") + GTUtility.trans("089", " Auto-Output: ") + + (mOutputDisabled ? GTUtility.trans("087", "Disabled") + : GTUtility.trans("088", "Enabled")))); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.RANDOM_ANVIL_USE, 1.0F, @@ -1592,19 +1592,19 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSoftHammerList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sSoftHammerList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { if (mWorks) disableWorking(); else enableWorking(); { - String tChat = GT_Utility.trans("090", "Machine Processing: ") - + (isAllowedToWork() ? GT_Utility.trans("088", "Enabled") - : GT_Utility.trans("087", "Disabled")); + String tChat = GTUtility.trans("090", "Machine Processing: ") + + (isAllowedToWork() ? GTUtility.trans("088", "Enabled") + : GTUtility.trans("087", "Disabled")); if (getMetaTileEntity() != null && getMetaTileEntity().hasAlternativeModeText()) tChat = getMetaTileEntity().getAlternativeModeText(); - GT_Utility.sendChatToPlayer(aPlayer, tChat); + GTUtility.sendChatToPlayer(aPlayer, tChat); } - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_RUBBER_TRAMPOLINE, 1.0F, @@ -1616,11 +1616,11 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSolderingToolList)) { - final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sSolderingToolList)) { + final ForgeDirection tSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); if (mMetaTileEntity.onSolderingToolRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) { // logic handled internally - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_BATTERY_USE, 1.0F, @@ -1628,15 +1628,15 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity xCoord, yCoord, zCoord); - } else if (GT_ModHandler.useSolderingIron(tCurrentItem, aPlayer)) { + } else if (GTModHandler.useSolderingIron(tCurrentItem, aPlayer)) { mStrongRedstone ^= tSide.flag; - GT_Utility.sendChatToPlayer( + GTUtility.sendChatToPlayer( aPlayer, - GT_Utility.trans("091", "Redstone Output at Side ") + tSide - + GT_Utility.trans("092", " set to: ") - + ((mStrongRedstone & tSide.flag) != 0 ? GT_Utility.trans("093", "Strong") - : GT_Utility.trans("094", "Weak"))); - GT_Utility.sendSoundToPlayers( + GTUtility.trans("091", "Redstone Output at Side ") + tSide + + GTUtility.trans("092", " set to: ") + + ((mStrongRedstone & tSide.flag) != 0 ? GTUtility.trans("093", "Strong") + : GTUtility.trans("094", "Weak"))); + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_BATTERY_USE, 3.0F, @@ -1651,11 +1651,11 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return true; } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWireCutterList)) { - final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sWireCutterList)) { + final ForgeDirection tSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); if (mMetaTileEntity.onWireCutterRightClick(side, tSide, aPlayer, aX, aY, aZ, tCurrentItem)) { // logic handled internally - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -1670,20 +1670,19 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } ForgeDirection coverSide = side; - if (getCoverIDAtSide(side) == 0) coverSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); + if (getCoverIDAtSide(side) == 0) coverSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); if (getCoverIDAtSide(coverSide) == 0) { - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCovers.keySet())) { - final GT_CoverBehaviorBase coverBehavior = GregTech_API - .getCoverBehaviorNew(tCurrentItem); + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sCovers.keySet())) { + final CoverBehaviorBase coverBehavior = GregTechAPI.getCoverBehaviorNew(tCurrentItem); if (coverBehavior.isCoverPlaceable(coverSide, tCurrentItem, this) - && mMetaTileEntity.allowCoverOnSide(coverSide, new GT_ItemStack(tCurrentItem))) { + && mMetaTileEntity.allowCoverOnSide(coverSide, new GTItemStack(tCurrentItem))) { setCoverItemAtSide(coverSide, tCurrentItem); coverBehavior.onPlayerAttach(aPlayer, tCurrentItem, this, coverSide); if (!aPlayer.capabilities.isCreativeMode) tCurrentItem.stackSize--; - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -1696,9 +1695,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity return true; } } else { - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCrowbarList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { - GT_Utility.sendSoundToPlayers( + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sCrowbarList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + GTUtility.sendSoundToPlayers( worldObj, SoundResource.RANDOM_BREAK, 1.0F, @@ -1709,15 +1708,15 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity dropCover(coverSide, side, false); } return true; - } else if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sJackhammerList)) { + } else if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sJackhammerList)) { // Configuration of delicate electronics calls for a tool with precision and subtlety. - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { final CoverInfo info = getCoverInfoAtSide(coverSide); if (info != CoverInfo.EMPTY_INFO) { - final GT_CoverBehaviorBase behavior = info.getCoverBehavior(); + final CoverBehaviorBase behavior = info.getCoverBehavior(); if (behavior.allowsTickRateAddition()) { info.onCoverJackhammer(aPlayer); - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_DRILL_DRILL_SOFT, 1.0F, @@ -1727,7 +1726,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity zCoord); } else { - GT_Utility.sendChatToPlayer( + GTUtility.sendChatToPlayer( aPlayer, StatCollector.translateToLocal("gt.cover.info.chat.tick_rate_not_allowed")); } @@ -1738,7 +1737,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } // End item != null } else if (aPlayer.isSneaking()) { // Sneak click, no tool -> open cover config if possible. - side = (getCoverIDAtSide(side) == 0) ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) : side; + side = (getCoverIDAtSide(side) == 0) ? GTUtility.determineWrenchingSide(side, aX, aY, aZ) : side; return getCoverIDAtSide(side) > 0 && getCoverBehaviorAtSideNew(side).onCoverShiftRightClick( side, getCoverIDAtSide(side), @@ -1762,7 +1761,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (isUpgradable() && tCurrentItem != null) { if (ItemList.Upgrade_Muffler.isStackEqual(aPlayer.inventory.getCurrentItem())) { if (addMufflerUpgrade()) { - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.RANDOM_CLICK, 1.0F, @@ -1779,7 +1778,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity mLockUpgrade = true; setOwnerName(aPlayer.getDisplayName()); setOwnerUuid(aPlayer.getUniqueID()); - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.RANDOM_CLICK, 1.0F, @@ -1799,9 +1798,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity if (!aPlayer.isSneaking() && hasValidMetaTileEntity()) return mMetaTileEntity.onRightclick(this, aPlayer, side, aX, aY, aZ); } catch (Throwable e) { - GT_Log.err.println( + GTLog.err.println( "Encountered Exception while rightclicking TileEntity, the Game should've crashed now, but I prevented that. Please report immediately to GregTech Intergalactical!!!"); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); e.printStackTrace(); } @@ -1813,9 +1812,9 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity try { if (aPlayer != null && hasValidMetaTileEntity()) mMetaTileEntity.onLeftclick(this, aPlayer); } catch (Throwable e) { - GT_Log.err.println( + GTLog.err.println( "Encountered Exception while leftclicking TileEntity, the Game should've crashed now, but I prevented that. Please report immediately to GregTech Intergalactical!!!"); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); } } @@ -1859,7 +1858,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity final CoverInfo coverInfo = getCoverInfoAtSide(ForgeDirection.getOrientation(ordinalSide)); if (canAccessData() && (coverInfo.letsItemsOut(-1) || coverInfo.letsItemsIn(-1))) return mMetaTileEntity.getAccessibleSlotsFromSide(ordinalSide); - return GT_Values.emptyIntArray; + return GTValues.emptyIntArray; } /** @@ -1998,13 +1997,13 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity @Override public String getOwnerName() { - if (GT_Utility.isStringInvalid(mOwnerName)) return "Player"; + if (GTUtility.isStringInvalid(mOwnerName)) return "Player"; return mOwnerName; } @Override public String setOwnerName(String aName) { - if (GT_Utility.isStringInvalid(aName)) return mOwnerName = "Player"; + if (GTUtility.isStringInvalid(aName)) return mOwnerName = "Player"; return mOwnerName = aName; } @@ -2041,7 +2040,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity || getStoredEU() >= getEUCapacity() || mMetaTileEntity.maxAmperesIn() <= mAcceptedAmperes) return 0; if (aVoltage > getInputVoltage()) { - GT_Log.exp + GTLog.exp .println("Energy Explosion, injected " + aVoltage + "EU/t in a " + getInputVoltage() + "EU/t Machine!"); doExplosion(aVoltage); return 0; @@ -2245,15 +2244,15 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity @Override public boolean addStackToSlot(int slotIndex, ItemStack stack) { - if (GT_Utility.isStackInvalid(stack)) return true; + if (GTUtility.isStackInvalid(stack)) return true; if (slotIndex < 0 || slotIndex >= getSizeInventory()) return false; final ItemStack toStack = getStackInSlot(slotIndex); - if (GT_Utility.isStackInvalid(toStack)) { + if (GTUtility.isStackInvalid(toStack)) { setInventorySlotContents(slotIndex, stack); return true; } - final ItemStack fromStack = GT_OreDictUnificator.get(stack); - if (GT_Utility.areStacksEqual(toStack, fromStack) && toStack.stackSize + fromStack.stackSize + final ItemStack fromStack = GTOreDictUnificator.get(stack); + if (GTUtility.areStacksEqual(toStack, fromStack) && toStack.stackSize + fromStack.stackSize <= Math.min(fromStack.getMaxStackSize(), getInventoryStackLimit())) { toStack.stackSize += fromStack.stackSize; markDirty(); @@ -2264,7 +2263,7 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity @Override public boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount) { - return addStackToSlot(aIndex, GT_Utility.copyAmount(aAmount, aStack)); + return addStackToSlot(aIndex, GTUtility.copyAmount(aAmount, aStack)); } @Override @@ -2343,13 +2342,13 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity final int newInputSize; final int oldOutputSize; final int newOutputSize; - final int chemistryUpdateVersion = GT_Mod.calculateTotalGTVersion(509, 31); - final int configCircuitAdditionVersion = GT_Mod.calculateTotalGTVersion(509, 40); - final int wireAdditionVersion = GT_Mod.calculateTotalGTVersion(509, 41); - final int disassemblerRemoveVersion = GT_Mod.calculateTotalGTVersion(509, 42, 44); + final int chemistryUpdateVersion = GTMod.calculateTotalGTVersion(509, 31); + final int configCircuitAdditionVersion = GTMod.calculateTotalGTVersion(509, 40); + final int wireAdditionVersion = GTMod.calculateTotalGTVersion(509, 41); + final int disassemblerRemoveVersion = GTMod.calculateTotalGTVersion(509, 42, 44); if (nbtVersion < 1000000) nbtVersion *= 1000; // 4 is old GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT - if (nbtVersion < configCircuitAdditionVersion && getMetaTileEntity() instanceof GT_MetaTileEntity_BasicMachine + if (nbtVersion < configCircuitAdditionVersion && getMetaTileEntity() instanceof MTEBasicMachine && slotIndex >= 4) slotIndex += 1; if (mID >= 211 && mID <= 218) { // Assembler if (nbtVersion < chemistryUpdateVersion) { @@ -2415,10 +2414,10 @@ public class BaseMetaTileEntity extends CommonMetaTileEntity } int indexShift = 0; - if (slotIndex >= GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT + oldInputSize) { + if (slotIndex >= MTEBasicMachine.OTHER_SLOT_COUNT + oldInputSize) { indexShift += newInputSize - oldInputSize; } - if (slotIndex >= GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT + oldInputSize + oldOutputSize) { + if (slotIndex >= MTEBasicMachine.OTHER_SLOT_COUNT + oldInputSize + oldOutputSize) { indexShift += newOutputSize - oldOutputSize; } return slotIndex + indexShift; diff --git a/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java index c2cef8628d..7b18565165 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java @@ -1,6 +1,6 @@ package gregtech.api.metatileentity; -import static gregtech.api.enums.GT_Values.NW; +import static gregtech.api.enums.GTValues.NW; import java.util.Arrays; import java.util.List; @@ -47,10 +47,10 @@ import com.gtnewhorizons.modularui.common.widget.TextWidget; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; -import gregtech.GT_Mod; +import gregtech.GTMod; import gregtech.api.enums.Dyes; -import gregtech.api.enums.GT_Values; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.enums.GTValues; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.gui.modularui.GUITextureSet; import gregtech.api.interfaces.IConfigurationCircuitSupport; import gregtech.api.interfaces.modularui.IAddGregtechLogo; @@ -60,11 +60,11 @@ import gregtech.api.interfaces.tileentity.IGTEnet; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords; import gregtech.api.interfaces.tileentity.IIC2Enet; -import gregtech.api.net.GT_Packet_Block_Event; -import gregtech.api.net.GT_Packet_SetConfigurationCircuit; +import gregtech.api.net.GTPacketBlockEvent; +import gregtech.api.net.GTPacketSetConfigurationCircuit; +import gregtech.api.util.GTUtil; +import gregtech.api.util.GTUtility; import gregtech.api.util.GT_TooltipDataCache; -import gregtech.api.util.GT_Util; -import gregtech.api.util.GT_Utility; import gregtech.common.gui.modularui.uifactory.SelectItemUIFactory; import ic2.api.energy.event.EnergyTileLoadEvent; import ic2.api.energy.event.EnergyTileUnloadEvent; @@ -103,7 +103,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje public static ForgeDirection getSideForPlayerPlacing(Entity player, ForgeDirection defaultFacing, boolean[] aAllowedFacings) { - final ForgeDirection facingFromPlayer = GT_Utility.getSideFromPlayerFacing(player); + final ForgeDirection facingFromPlayer = GTUtility.getSideFromPlayerFacing(player); if (facingFromPlayer != ForgeDirection.UNKNOWN && aAllowedFacings[facingFromPlayer.ordinal()]) return facingFromPlayer; @@ -424,13 +424,13 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje @Override public final boolean getOpacity(int x, int y, int z) { if (ignoreUnloadedChunks && crossedChunkBorder(x, z) && !worldObj.blockExists(x, y, z)) return false; - return GT_Utility.isOpaqueBlock(worldObj, x, y, z); + return GTUtility.isOpaqueBlock(worldObj, x, y, z); } @Override public final boolean getAir(int x, int y, int z) { if (ignoreUnloadedChunks && crossedChunkBorder(x, z) && !worldObj.blockExists(x, y, z)) return true; - return GT_Utility.isBlockAir(worldObj, x, y, z); + return GTUtility.isBlockAir(worldObj, x, y, z); } @Override @@ -540,7 +540,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje public final void sendBlockEvent(byte aID, byte aValue) { NW.sendPacketToAllPlayersInRange( worldObj, - new GT_Packet_Block_Event(xCoord, (short) yCoord, zCoord, aID, aValue), + new GTPacketBlockEvent(xCoord, (short) yCoord, zCoord, aID, aValue), xCoord, zCoord); } @@ -554,7 +554,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje } public final void setOnFire() { - GT_Utility.setCoordsOnFire(worldObj, xCoord, yCoord, zCoord, false); + GTUtility.setCoordsOnFire(worldObj, xCoord, yCoord, zCoord, false); } public final void setToFire() { @@ -666,7 +666,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje } protected void addTitleToUI(ModularWindow.Builder builder, String title) { - if (GT_Mod.gregtechproxy.mTitleTabStyle == 2) { + if (GTMod.gregtechproxy.mTitleTabStyle == 2) { addTitleItemIconStyle(builder, title); } else { addTitleTextStyle(builder, title); @@ -691,7 +691,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje final TextWidget text = new TextWidget(title).setDefaultColor(getTitleColor()) .setTextAlignment(Alignment.CenterLeft) .setMaxWidth(titleWidth); - if (GT_Mod.gregtechproxy.mTitleTabStyle == 1) { + if (GTMod.gregtechproxy.mTitleTabStyle == 1) { tab.setDrawable(getGUITextureSet().getTitleTabAngular()) .setPos(0, -(titleHeight + TAB_PADDING) + 1) .setSize(getGUIWidth(), titleHeight + TAB_PADDING * 2); @@ -852,9 +852,9 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje } } else { final List tCircuits = ccs.getConfigurationCircuits(); - final int index = GT_Utility.findMatchingStackInList(tCircuits, cursorStack); + final int index = GTUtility.findMatchingStackInList(tCircuits, cursorStack); if (index < 0) { - int curIndex = GT_Utility + int curIndex = GTUtility .findMatchingStackInList(tCircuits, inv.getStackInSlot(ccs.getCircuitSlot())) + 1; if (clickData.mouseButton == 0) { curIndex += 1; @@ -894,7 +894,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje }) .disableShiftInsert() .setHandlePhantomActionClient(true) - .setBackground(getGUITextureSet().getItemSlot(), GT_UITextures.OVERLAY_SLOT_INT_CIRCUIT) + .setBackground(getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_INT_CIRCUIT) .setGTTooltip(() -> mTooltipCache.getData("GT5U.machines.select_circuit.tooltip")) .setTooltipShowUpDelay(TOOLTIP_DELAY) .setPos(ccs.getCircuitSlotX() - 1, ccs.getCircuitSlotY() - 1)); @@ -913,7 +913,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje getStackForm(0), this::onCircuitSelected, circuits, - GT_Utility.findMatchingStackInList(circuits, inv.getStackInSlot(ccs.getCircuitSlot()))) + GTUtility.findMatchingStackInList(circuits, inv.getStackInSlot(ccs.getCircuitSlot()))) .setAnotherWindow(true, dialogOpened) .setGuiTint(getGUIColorization()) .setCurrentGetter(() -> inv.getStackInSlot(ccs.getCircuitSlot())) @@ -926,7 +926,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje if (!(this instanceof IInventory inv)) return; - GT_Values.NW.sendToServer(new GT_Packet_SetConfigurationCircuit(this, selected)); + GTValues.NW.sendToServer(new GTPacketSetConfigurationCircuit(this, selected)); // we will not do any validation on client side // it doesn't get to actually decide what inventory contains anyway inv.setInventorySlotContents(ccs.getCircuitSlot(), selected); @@ -943,7 +943,7 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje protected Supplier COLOR_TEXT_RED = () -> getTextColorOrDefault("text_red", 0xff0000); public int getGUIColorization() { - return GT_Util.getRGBaInt(Dyes.dyeWhite.getRGBA()); + return GTUtil.getRGBaInt(Dyes.dyeWhite.getRGBA()); } public ItemStack getStackForm(long aAmount) { diff --git a/src/main/java/gregtech/api/metatileentity/CommonMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/CommonMetaTileEntity.java index c3528d44d7..3b0c9cc89f 100644 --- a/src/main/java/gregtech/api/metatileentity/CommonMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/CommonMetaTileEntity.java @@ -1,6 +1,6 @@ package gregtech.api.metatileentity; -import static gregtech.GT_Mod.GT_FML_LOGGER; +import static gregtech.GTMod.GT_FML_LOGGER; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -16,8 +16,8 @@ import appeng.api.crafting.ICraftingIconProvider; import appeng.api.implementations.tiles.ISoundP2PHandler; import appeng.me.cache.helpers.TunnelCollection; import appeng.parts.p2p.PartP2PSound; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; import gregtech.api.enums.ItemList; import gregtech.api.gui.modularui.GUITextureSet; import gregtech.api.interfaces.IConfigurationCircuitSupport; @@ -27,9 +27,9 @@ import gregtech.api.interfaces.modularui.IAddUIWidgets; import gregtech.api.interfaces.modularui.IBindPlayerInventoryUI; import gregtech.api.interfaces.modularui.IGetTitleColor; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Utility; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtility; public abstract class CommonMetaTileEntity extends CoverableTileEntity implements IGregTechTileEntity, ICraftingIconProvider, ISoundP2PHandler { @@ -37,11 +37,11 @@ public abstract class CommonMetaTileEntity extends CoverableTileEntity protected boolean mNeedsBlockUpdate = true, mNeedsUpdate = true, mSendClientData = false, mInventoryChanged = false; protected boolean createNewMetatileEntity(short aID) { - if (aID <= 0 || aID >= GregTech_API.METATILEENTITIES.length || GregTech_API.METATILEENTITIES[aID] == null) { - GT_Log.err.println("MetaID " + aID + " not loadable => locking TileEntity!"); + if (aID <= 0 || aID >= GregTechAPI.METATILEENTITIES.length || GregTechAPI.METATILEENTITIES[aID] == null) { + GTLog.err.println("MetaID " + aID + " not loadable => locking TileEntity!"); } else { if (hasValidMetaTileEntity()) getMetaTileEntity().setBaseMetaTileEntity(null); - GregTech_API.METATILEENTITIES[aID].newMetaEntity(this) + GregTechAPI.METATILEENTITIES[aID].newMetaEntity(this) .setBaseMetaTileEntity(this); mTickTimer = 0; mID = aID; @@ -53,7 +53,7 @@ public abstract class CommonMetaTileEntity extends CoverableTileEntity protected void saveMetaTileNBT(NBTTagCompound aNBT) { try { if (hasValidMetaTileEntity()) { - aNBT.setInteger("nbtVersion", GT_Mod.NBT_VERSION); + aNBT.setInteger("nbtVersion", GTMod.NBT_VERSION); final NBTTagList tItemList = new NBTTagList(); for (int i = 0; i < getMetaTileEntity().getRealInventory().length; i++) { final ItemStack tStack = getMetaTileEntity().getRealInventory()[i]; @@ -70,12 +70,12 @@ public abstract class CommonMetaTileEntity extends CoverableTileEntity getMetaTileEntity().saveNBTData(aNBT); } catch (Throwable e) { GT_FML_LOGGER.error("Encountered CRITICAL ERROR while saving MetaTileEntity."); - GT_Mod.logStackTrace(e); + GTMod.logStackTrace(e); } } } catch (Throwable e) { GT_FML_LOGGER.error("Encountered CRITICAL ERROR while saving MetaTileEntity."); - GT_Mod.logStackTrace(e); + GTMod.logStackTrace(e); } } @@ -87,7 +87,7 @@ public abstract class CommonMetaTileEntity extends CoverableTileEntity final NBTTagCompound tTag = tItemList.getCompoundTagAt(i); final int tSlot = migrateInventoryIndex(tTag.getInteger("IntSlot"), nbtVersion); if (tSlot >= 0 && tSlot < getMetaTileEntity().getRealInventory().length) { - ItemStack loadedStack = GT_Utility.loadItem(tTag); + ItemStack loadedStack = GTUtility.loadItem(tTag); // We move away from fluid display item in TEs if (loadedStack != null && loadedStack.getItem() == ItemList.Display_Fluid.getItem()) { loadedStack = null; @@ -100,7 +100,7 @@ public abstract class CommonMetaTileEntity extends CoverableTileEntity getMetaTileEntity().loadNBTData(aNBT); } catch (Throwable e) { GT_FML_LOGGER.error("Encountered Exception while loading MetaTileEntity."); - GT_Mod.logStackTrace(e); + GTMod.logStackTrace(e); } } } @@ -175,7 +175,7 @@ public abstract class CommonMetaTileEntity extends CoverableTileEntity } @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { return hasValidMetaTileEntity() && getMetaTileEntity().allowCoverOnSide(side, aCoverID); } diff --git a/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java b/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java index 429e0fc04c..bf62a1ce74 100644 --- a/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/CoverableTileEntity.java @@ -1,9 +1,9 @@ package gregtech.api.metatileentity; -import static gregtech.api.enums.GT_Values.E; -import static gregtech.api.enums.GT_Values.NW; -import static gregtech.api.util.GT_LanguageManager.FACES; -import static gregtech.api.util.GT_LanguageManager.getTranslation; +import static gregtech.api.enums.GTValues.E; +import static gregtech.api.enums.GTValues.NW; +import static gregtech.api.util.GTLanguageManager.FACES; +import static gregtech.api.util.GTLanguageManager.getTranslation; import java.util.ArrayList; import java.util.Arrays; @@ -48,23 +48,23 @@ import com.gtnewhorizons.modularui.common.widget.MultiChildWidget; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; import gregtech.api.enums.Textures; import gregtech.api.gui.modularui.GUITextureSet; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.ICoverable; import gregtech.api.interfaces.tileentity.IGregtechWailaProvider; -import gregtech.api.net.GT_Packet_RequestCoverData; -import gregtech.api.net.GT_Packet_SendCoverData; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; +import gregtech.api.net.GTPacketRequestCoverData; +import gregtech.api.net.GTPacketSendCoverData; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; import gregtech.api.util.ISerializableObject; -import gregtech.common.GT_Client; +import gregtech.common.GTClient; +import gregtech.common.covers.CoverFluidfilter; import gregtech.common.covers.CoverInfo; -import gregtech.common.covers.GT_Cover_Fluidfilter; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import mcp.mobius.waila.api.IWailaConfigHandler; @@ -105,7 +105,7 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov .saveDataToNBT()); } if (tList.tagCount() > 0) { - aNBT.setTag(GT_Values.NBT.COVERS, tList); + aNBT.setTag(GTValues.NBT.COVERS, tList); // Backwards compat, in case of a revert... for now aNBT.setIntArray("mCoverSides", coverSides); } @@ -124,7 +124,7 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov : new byte[] { 15, 15, 15, 15, 15, 15 }; mStrongRedstone = aNBT.getByte("mStrongRedstone"); - if (aNBT.hasKey(GT_Values.NBT.COVERS)) { + if (aNBT.hasKey(GTValues.NBT.COVERS)) { readCoverInfoNBT(aNBT); } else if (aNBT.hasKey("mCoverSides")) { readLegacyCoverInfoNBT(aNBT); @@ -132,7 +132,7 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov } public void readCoverInfoNBT(NBTTagCompound aNBT) { - final NBTTagList tList = aNBT.getTagList(GT_Values.NBT.COVERS, 10); + final NBTTagList tList = aNBT.getTagList(GTValues.NBT.COVERS, 10); for (byte i = 0; i < tList.tagCount(); i++) { final NBTTagCompound tNBT = tList.getCompoundTagAt(i); final CoverInfo coverInfo = new CoverInfo(this, tNBT); @@ -152,12 +152,12 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov if (coverIDs[ordinalSide] == 0) continue; final CoverInfo coverInfo = new CoverInfo(side, coverIDs[ordinalSide], this, null); - final GT_CoverBehaviorBase coverBehavior = coverInfo.getCoverBehavior(); - if (coverBehavior == GregTech_API.sNoBehavior) continue; + final CoverBehaviorBase coverBehavior = coverInfo.getCoverBehavior(); + if (coverBehavior == GregTechAPI.sNoBehavior) continue; ISerializableObject coverData = null; if (hasOldCoverData) { - if (coverBehavior instanceof GT_Cover_Fluidfilter) { + if (coverBehavior instanceof CoverFluidfilter) { final String filterKey = String.format("fluidFilter%d", ordinalSide); if (aNBT.hasKey(filterKey)) { coverData = coverInfo.getCoverBehavior() @@ -229,12 +229,12 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov return true; } - public abstract boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID); + public abstract boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID); protected void checkDropCover() { for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { final int coverId = getCoverIDAtSide(side); - if (coverId != 0 && !allowCoverOnSide(side, new GT_ItemStack(coverId))) dropCover(side, side, true); + if (coverId != 0 && !allowCoverOnSide(side, new GTItemStack(coverId))) dropCover(side, side, true); } } @@ -256,20 +256,20 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov public final ITexture getCoverTexture(ForgeDirection side) { final CoverInfo coverInfo = getCoverInfoAtSide(side); if (!coverInfo.isValid()) return null; - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x1) != 0) { return Textures.BlockIcons.HIDDEN_TEXTURE[0]; // See through } final ITexture coverTexture = (!(this instanceof BaseMetaPipeEntity)) ? coverInfo.getSpecialCoverFGTexture() : coverInfo.getSpecialCoverTexture(); - return coverTexture != null ? coverTexture : GregTech_API.sCovers.get(new GT_ItemStack(getCoverIDAtSide(side))); + return coverTexture != null ? coverTexture : GregTechAPI.sCovers.get(new GTItemStack(getCoverIDAtSide(side))); } protected void requestCoverDataIfNeeded() { if (worldObj == null || !worldObj.isRemote) return; for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { final CoverInfo coverInfo = getCoverInfoAtSide(side); - if (coverInfo.isDataNeededOnClient()) NW.sendToServer(new GT_Packet_RequestCoverData(coverInfo, this)); + if (coverInfo.isDataNeededOnClient()) NW.sendToServer(new GTPacketRequestCoverData(coverInfo, this)); } } @@ -318,15 +318,15 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov @Override @Deprecated - public GT_CoverBehavior getCoverBehaviorAtSide(ForgeDirection side) { - final GT_CoverBehaviorBase behavior = getCoverInfoAtSide(side).getCoverBehavior(); - if (behavior instanceof GT_CoverBehavior) return (GT_CoverBehavior) behavior; - return GregTech_API.sNoBehavior; + public CoverBehavior getCoverBehaviorAtSide(ForgeDirection side) { + final CoverBehaviorBase behavior = getCoverInfoAtSide(side).getCoverBehavior(); + if (behavior instanceof CoverBehavior) return (CoverBehavior) behavior; + return GregTechAPI.sNoBehavior; } @Override public void setCoverItemAtSide(ForgeDirection side, ItemStack aCover) { - GregTech_API.getCoverBehaviorNew(aCover) + GregTechAPI.getCoverBehaviorNew(aCover) .placeCover(side, aCover, this); } @@ -366,7 +366,7 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov } @Override - public GT_CoverBehaviorBase getCoverBehaviorAtSideNew(ForgeDirection side) { + public CoverBehaviorBase getCoverBehaviorAtSideNew(ForgeDirection side) { return getCoverInfoAtSide(side).getCoverBehavior(); } @@ -546,11 +546,7 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { final CoverInfo coverInfo = getCoverInfoAtSide(side); if (coverInfo.needsUpdate()) { - NW.sendPacketToAllPlayersInRange( - worldObj, - new GT_Packet_SendCoverData(coverInfo, this), - xCoord, - zCoord); + NW.sendPacketToAllPlayersInRange(worldObj, new GTPacketSendCoverData(coverInfo, this), xCoord, zCoord); coverInfo.setNeedsUpdate(false); } } @@ -562,11 +558,11 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov final NBTTagCompound tag = accessor.getNBTData(); final ForgeDirection currentFacing = accessor.getSide(); - final NBTTagList tList = tag.getTagList(GT_Values.NBT.COVERS, 10); + final NBTTagList tList = tag.getTagList(GTValues.NBT.COVERS, 10); for (byte i = 0; i < tList.tagCount(); i++) { final NBTTagCompound tNBT = tList.getCompoundTagAt(i); final CoverInfo coverInfo = new CoverInfo(this, tNBT); - if (!coverInfo.isValid() || coverInfo.getCoverBehavior() == GregTech_API.sNoBehavior) continue; + if (!coverInfo.isValid() || coverInfo.getCoverBehavior() == GregTechAPI.sNoBehavior) continue; final ItemStack coverStack = coverInfo.getDisplayStack(); if (coverStack != null) { @@ -608,12 +604,12 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov */ public static void addInstalledCoversInformation(NBTTagCompound aNBT, List aList) { if (aNBT == null || aList == null) return; - final NBTTagList tList = aNBT.getTagList(GT_Values.NBT.COVERS, 10); + final NBTTagList tList = aNBT.getTagList(GTValues.NBT.COVERS, 10); for (byte i = 0; i < tList.tagCount(); i++) { final NBTTagCompound tNBT = tList.getCompoundTagAt(i); final CoverInfo coverInfo = new CoverInfo(null, tNBT); - if (!coverInfo.isValid() || coverInfo.getCoverBehavior() == GregTech_API.sNoBehavior) continue; + if (!coverInfo.isValid() || coverInfo.getCoverBehavior() == GregTechAPI.sNoBehavior) continue; final ItemStack coverStack = coverInfo.getDisplayStack(); if (coverStack != null) { @@ -634,8 +630,8 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov final int i = tSide.ordinal(); final int coverId = mCoverSides[i]; if (coverId == 0) continue; - final GT_CoverBehaviorBase behavior = GregTech_API.getCoverBehaviorNew(coverId); - if (behavior == null || behavior == GregTech_API.sNoBehavior) continue; + final CoverBehaviorBase behavior = GregTechAPI.getCoverBehaviorNew(coverId); + if (behavior == null || behavior == GregTechAPI.sNoBehavior) continue; if (!aNBT.hasKey(CoverableTileEntity.COVER_DATA_NBT_KEYS[i])) continue; final ISerializableObject dataObject = behavior .createDataObject(aNBT.getTag(CoverableTileEntity.COVER_DATA_NBT_KEYS[i])); @@ -676,12 +672,12 @@ public abstract class CoverableTileEntity extends BaseTileEntity implements ICov public void addCoverTabs(ModularWindow.Builder builder, UIBuildContext buildContext) { final int COVER_TAB_LEFT = -16, COVER_TAB_TOP = 1, COVER_TAB_HEIGHT = 20, COVER_TAB_WIDTH = 18, COVER_TAB_SPACING = 2, ICON_SIZE = 16; - final boolean flipHorizontally = GT_Mod.gregtechproxy.mCoverTabsFlipped; + final boolean flipHorizontally = GTMod.gregtechproxy.mCoverTabsFlipped; final Column columnWidget = new Column(); builder.widget(columnWidget); final int xPos = flipHorizontally ? (getGUIWidth() - COVER_TAB_LEFT - COVER_TAB_WIDTH) : COVER_TAB_LEFT; - if (GT_Mod.gregtechproxy.mCoverTabsVisible) { + if (GTMod.gregtechproxy.mCoverTabsVisible) { columnWidget.setPos(xPos, COVER_TAB_TOP) .setEnabled( widget -> ((Column) widget).getChildren() diff --git a/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java index 8971db2d92..194aef8547 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java @@ -1,6 +1,6 @@ package gregtech.api.metatileentity; -import static gregtech.api.enums.GT_Values.GT; +import static gregtech.api.enums.GTValues.GT; import java.io.File; import java.util.ArrayList; @@ -30,9 +30,9 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gnu.trove.list.TIntList; import gnu.trove.list.array.TIntArrayList; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; import gregtech.api.enums.Dyes; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.Textures; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IConnectable; @@ -40,15 +40,15 @@ import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IColoredTileEntity; import gregtech.api.interfaces.tileentity.ICoverable; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_Util; -import gregtech.api.util.GT_Utility; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTUtil; +import gregtech.api.util.GTUtility; import gregtech.api.util.ISerializableObject; import gregtech.api.util.WorldSpawnedEventBuilder; -import gregtech.common.GT_Client; +import gregtech.common.GTClient; import gregtech.common.covers.CoverInfo; /** @@ -107,10 +107,10 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { } public MetaPipeEntity(int aID, String aBasicName, String aRegionalName, int aInvSlotCount, boolean aAddInfo) { - if (GregTech_API.sPostloadStarted || !GregTech_API.sPreloadStarted) + if (GregTechAPI.sPostloadStarted || !GregTechAPI.sPreloadStarted) throw new IllegalAccessError("This Constructor has to be called in the load Phase"); - if (GregTech_API.METATILEENTITIES[aID] == null) { - GregTech_API.METATILEENTITIES[aID] = this; + if (GregTechAPI.METATILEENTITIES[aID] == null) { + GregTechAPI.METATILEENTITIES[aID] = this; } else { throw new IllegalArgumentException("MetaMachine-Slot Nr. " + aID + " is already occupied!"); } @@ -118,7 +118,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { .toLowerCase(Locale.ENGLISH); setBaseMetaTileEntity(new BaseMetaPipeEntity()); getBaseMetaTileEntity().setMetaTileID((short) aID); - GT_LanguageManager.addStringLocalization("gt.blockmachines." + mName + ".name", aRegionalName); + GTLanguageManager.addStringLocalization("gt.blockmachines." + mName + ".name", aRegionalName); mInventory = new ItemStack[aInvSlotCount]; if (aAddInfo && GT.isClientSide()) { @@ -129,7 +129,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { protected final void addInfo(int aID) { if (!GT.isClientSide()) return; - ItemStack tStack = new ItemStack(GregTech_API.sBlockMachines, 1, aID); + ItemStack tStack = new ItemStack(GregTechAPI.sBlockMachines, 1, aID); Objects.requireNonNull(tStack.getItem()) .addInformation(tStack, null, new ArrayList<>(), true); } @@ -187,7 +187,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { @Override public ItemStack getStackForm(long aAmount) { - return new ItemStack(GregTech_API.sBlockMachines, (int) aAmount, getBaseMetaTileEntity().getMetaTileID()); + return new ItemStack(GregTechAPI.sBlockMachines, (int) aAmount, getBaseMetaTileEntity().getMetaTileID()); } public boolean isCoverOnSide(BaseMetaPipeEntity aPipe, EntityLivingBase aEntity) { @@ -254,7 +254,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { } @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { return true; } @@ -322,7 +322,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { @Override public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isClientSide() && GT_Client.changeDetected == 4) { + if (aBaseMetaTileEntity.isClientSide() && GTClient.changeDetected == 4) { /* * Client tick counter that is set to 5 on hiding pipes and covers. It triggers a texture update next client * tick when reaching 4, with provision for 3 more update tasks, spreading client change detection related @@ -598,8 +598,8 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { @Override public String getInventoryName() { - if (GregTech_API.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()] != null) - return GregTech_API.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()].getMetaName(); + if (GregTechAPI.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()] != null) + return GregTechAPI.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()].getMetaName(); return ""; } @@ -615,7 +615,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { @Override public ItemStack decrStackSize(int aIndex, int aAmount) { - ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copyOrNull(tStack); + ItemStack tStack = getStackInSlot(aIndex), rStack = GTUtility.copyOrNull(tStack); if (tStack != null) { if (tStack.stackSize <= aAmount) { if (setStackToZeroInsteadOfNull(aIndex)) tStack.stackSize = 0; @@ -647,7 +647,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { public boolean canInsertItem(int slotIndex, ItemStack itemStack, int ordinalSide) { return isValidSlot(slotIndex) && itemStack != null && slotIndex < mInventory.length - && (mInventory[slotIndex] == null || GT_Utility.areStacksEqual(itemStack, mInventory[slotIndex])) + && (mInventory[slotIndex] == null || GTUtility.areStacksEqual(itemStack, mInventory[slotIndex])) && allowPutStack(getBaseMetaTileEntity(), slotIndex, ForgeDirection.getOrientation(ordinalSide), itemStack); } @@ -796,12 +796,12 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { @Override public void doExplosion(long aExplosionPower) { - float tStrength = GT_Values.getExplosionPowerForVoltage(aExplosionPower); + float tStrength = GTValues.getExplosionPowerForVoltage(aExplosionPower); int tX = getBaseMetaTileEntity().getXCoord(), tY = getBaseMetaTileEntity().getYCoord(), tZ = getBaseMetaTileEntity().getZCoord(); World tWorld = getBaseMetaTileEntity().getWorld(); tWorld.setBlock(tX, tY, tZ, Blocks.air); - if (GregTech_API.sMachineExplosions) { + if (GregTechAPI.sMachineExplosions) { new WorldSpawnedEventBuilder.ExplosionEffectEventBuilder().setStrength(tStrength) .setSmoking(true) .setPosition(tX + 0.5, tY + 0.5, tZ + 0.5) @@ -949,7 +949,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { return (mConnections & sideDirection.flag) != 0; } - public boolean letsIn(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + public boolean letsIn(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { return false; } @@ -958,7 +958,7 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { return false; } - public boolean letsOut(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + public boolean letsOut(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { return false; } @@ -967,12 +967,12 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { return false; } - public boolean letsIn(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + public boolean letsIn(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) { return false; } - public boolean letsOut(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + public boolean letsOut(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) { return false; } @@ -1000,13 +1000,13 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable { @Override public int getGUIColorization() { Dyes dye = Dyes.dyeWhite; - if (GregTech_API.sColoredGUI) { - if (GregTech_API.sMachineMetalGUI) { + if (GregTechAPI.sColoredGUI) { + if (GregTechAPI.sMachineMetalGUI) { dye = Dyes.MACHINE_METAL; } else if (getBaseMetaTileEntity() != null) { dye = Dyes.getDyeFromIndex(getBaseMetaTileEntity().getColorization()); } } - return GT_Util.getRGBInt(dye.getRGBA()); + return GTUtil.getRGBInt(dye.getRGBA()); } } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index d4f8aa6ba4..1008a64507 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -38,27 +38,27 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gnu.trove.list.TIntList; import gnu.trove.list.array.TIntArrayList; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; import gregtech.api.enums.Dyes; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.SoundResource; import gregtech.api.enums.SteamVariant; -import gregtech.api.gui.GT_GUIColorOverride; +import gregtech.api.gui.GUIColorOverride; import gregtech.api.gui.modularui.GUITextureSet; import gregtech.api.interfaces.ICleanroom; import gregtech.api.interfaces.ICleanroomReceiver; import gregtech.api.interfaces.IConfigurationCircuitSupport; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; +import gregtech.api.metatileentity.implementations.MTECable; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtil; +import gregtech.api.util.GTUtility; import gregtech.api.util.GT_TooltipDataCache; -import gregtech.api.util.GT_Util; -import gregtech.api.util.GT_Utility; -import gregtech.common.GT_Client; +import gregtech.common.GTClient; import gregtech.common.covers.CoverInfo; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; @@ -90,7 +90,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei */ public final ItemStackHandler inventoryHandler; - protected GT_GUIColorOverride colorOverride; + protected GUIColorOverride colorOverride; protected GT_TooltipDataCache mTooltipCache = new GT_TooltipDataCache(); @Override @@ -128,18 +128,18 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei * @param aID the machine ID */ public MetaTileEntity(int aID, String aBasicName, String aRegionalName, int aInvSlotCount) { - if (GregTech_API.sPostloadStarted || !GregTech_API.sPreloadStarted) + if (GregTechAPI.sPostloadStarted || !GregTechAPI.sPreloadStarted) throw new IllegalAccessError("This Constructor has to be called in the load Phase"); - if (GregTech_API.METATILEENTITIES[aID] == null) { - GregTech_API.METATILEENTITIES[aID] = this; + if (GregTechAPI.METATILEENTITIES[aID] == null) { + GregTechAPI.METATILEENTITIES[aID] = this; } else { throw new IllegalArgumentException("MetaMachine-Slot Nr. " + aID + " is already occupied!"); } mName = aBasicName.replace(" ", "_") .toLowerCase(Locale.ENGLISH); - setBaseMetaTileEntity(GregTech_API.constructBaseMetaTileEntity()); + setBaseMetaTileEntity(GregTechAPI.constructBaseMetaTileEntity()); getBaseMetaTileEntity().setMetaTileID((short) aID); - GT_LanguageManager.addStringLocalization("gt.blockmachines." + mName + ".name", aRegionalName); + GTLanguageManager.addStringLocalization("gt.blockmachines." + mName + ".name", aRegionalName); mInventory = new ItemStack[aInvSlotCount]; inventoryHandler = new ItemStackHandler(mInventory); } @@ -151,7 +151,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei mInventory = new ItemStack[aInvSlotCount]; mName = aName; inventoryHandler = new ItemStackHandler(mInventory); - colorOverride = GT_GUIColorOverride.get(getGUITextureSet().getMainBackground().location); + colorOverride = GUIColorOverride.get(getGUITextureSet().getMainBackground().location); } @Override @@ -179,12 +179,12 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public ItemStack getStackForm(long aAmount) { - return new ItemStack(GregTech_API.sBlockMachines, (int) aAmount, getBaseMetaTileEntity().getMetaTileID()); + return new ItemStack(GregTechAPI.sBlockMachines, (int) aAmount, getBaseMetaTileEntity().getMetaTileID()); } @Override public String getLocalName() { - return GT_LanguageManager.getTranslation("gt.blockmachines." + mName + ".name"); + return GTLanguageManager.getTranslation("gt.blockmachines." + mName + ".name"); } @Override @@ -219,7 +219,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei } @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aStack) { + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aStack) { return true; } @@ -254,8 +254,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei if (!aPlayer.isSneaking()) return false; final ForgeDirection oppositeSide = wrenchingSide.getOpposite(); final TileEntity tTileEntity = getBaseMetaTileEntity().getTileEntityAtSide(wrenchingSide); - if ((tTileEntity instanceof IGregTechTileEntity gtTE) - && (gtTE.getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable)) { + if ((tTileEntity instanceof IGregTechTileEntity gtTE) && (gtTE.getMetaTileEntity() instanceof MTECable)) { // The tile entity we're facing is a cable, let's try to connect to it return gtTE.getMetaTileEntity() @@ -276,8 +275,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei if (!aPlayer.isSneaking()) return false; final ForgeDirection oppositeSide = wrenchingSide.getOpposite(); TileEntity tTileEntity = getBaseMetaTileEntity().getTileEntityAtSide(wrenchingSide); - if ((tTileEntity instanceof IGregTechTileEntity gtTE) - && (gtTE.getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable)) { + if ((tTileEntity instanceof IGregTechTileEntity gtTE) && (gtTE.getMetaTileEntity() instanceof MTECable)) { // The tile entity we're facing is a cable, let's try to connect to it return gtTE.getMetaTileEntity() @@ -311,7 +309,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public void onExplosion() { - GT_Log.exp.println( + GTLog.exp.println( "Machine at " + this.getBaseMetaTileEntity() .getXCoord() + " | " @@ -338,7 +336,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isClientSide() && GT_Client.changeDetected == 4) { + if (aBaseMetaTileEntity.isClientSide() && GTClient.changeDetected == 4) { /* * Client tick counter that is set to 5 on hiding pipes and covers. It triggers a texture update next client * tick when reaching 4, with provision for 3 more update tasks, spreading client change detection related @@ -633,14 +631,14 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei * Determines the Tier of the Machine, used for de-charging Tools. */ public long getInputTier() { - return GT_Utility.getTier(getBaseMetaTileEntity().getInputVoltage()); + return GTUtility.getTier(getBaseMetaTileEntity().getInputVoltage()); } /** * Determines the Tier of the Machine, used for charging Tools. */ public long getOutputTier() { - return GT_Utility.getTier(getBaseMetaTileEntity().getOutputVoltage()); + return GTUtility.getTier(getBaseMetaTileEntity().getOutputVoltage()); } /** @@ -888,7 +886,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei markDirty(); if (this instanceof IConfigurationCircuitSupport ccs) { if (ccs.allowSelectCircuit() && aIndex == ccs.getCircuitSlot() && aStack != null) { - mInventory[aIndex] = GT_Utility.copyAmount(0, aStack); + mInventory[aIndex] = GTUtility.copyAmount(0, aStack); return; } } @@ -897,8 +895,8 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public String getInventoryName() { - if (GregTech_API.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()] != null) - return GregTech_API.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()].getMetaName(); + if (GregTechAPI.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()] != null) + return GregTechAPI.METATILEENTITIES[getBaseMetaTileEntity().getMetaTileID()].getMetaName(); return ""; } @@ -914,7 +912,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public ItemStack decrStackSize(int aIndex, int aAmount) { - ItemStack tStack = getStackInSlot(aIndex), rStack = GT_Utility.copyOrNull(tStack); + ItemStack tStack = getStackInSlot(aIndex), rStack = GTUtility.copyOrNull(tStack); if (tStack != null) { if (tStack.stackSize <= aAmount) { if (setStackToZeroInsteadOfNull(aIndex)) { @@ -949,7 +947,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei public boolean canInsertItem(int aIndex, ItemStack aStack, int ordinalSide) { return isValidSlot(aIndex) && aStack != null && aIndex < mInventory.length - && (mInventory[aIndex] == null || GT_Utility.areStacksEqual(aStack, mInventory[aIndex])) + && (mInventory[aIndex] == null || GTUtility.areStacksEqual(aStack, mInventory[aIndex])) && allowPutStack(getBaseMetaTileEntity(), aIndex, ForgeDirection.getOrientation(ordinalSide), aStack); } @@ -986,7 +984,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public int fill(ForgeDirection side, FluidStack aFluid, boolean doFill) { - if (getBaseMetaTileEntity().hasSteamEngineUpgrade() && GT_ModHandler.isSteam(aFluid) && aFluid.amount > 1) { + if (getBaseMetaTileEntity().hasSteamEngineUpgrade() && GTModHandler.isSteam(aFluid) && aFluid.amount > 1) { int tSteam = (int) Math.min( Integer.MAX_VALUE, Math.min( @@ -1114,15 +1112,14 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei @Override public void doExplosion(long aExplosionPower) { - float tStrength = GT_Values.getExplosionPowerForVoltage(aExplosionPower); + float tStrength = GTValues.getExplosionPowerForVoltage(aExplosionPower); final int tX = getBaseMetaTileEntity().getXCoord(); final int tY = getBaseMetaTileEntity().getYCoord(); final int tZ = getBaseMetaTileEntity().getZCoord(); final World tWorld = getBaseMetaTileEntity().getWorld(); - GT_Utility.sendSoundToPlayers(tWorld, SoundResource.IC2_MACHINES_MACHINE_OVERLOAD, 1.0F, -1, tX, tY, tZ); + GTUtility.sendSoundToPlayers(tWorld, SoundResource.IC2_MACHINES_MACHINE_OVERLOAD, 1.0F, -1, tX, tY, tZ); tWorld.setBlock(tX, tY, tZ, Blocks.air); - if (GregTech_API.sMachineExplosions) - tWorld.createExplosion(null, tX + 0.5, tY + 0.5, tZ + 0.5, tStrength, true); + if (GregTechAPI.sMachineExplosions) tWorld.createExplosion(null, tX + 0.5, tY + 0.5, tZ + 0.5, tStrength, true); } @Override @@ -1266,16 +1263,16 @@ public abstract class MetaTileEntity implements IMetaTileEntity, ICleanroomRecei if (this.colorOverride.sLoaded()) { if (this.colorOverride.sGuiTintingEnabled() && getBaseMetaTileEntity() != null) { dye = Dyes.getDyeFromIndex(getBaseMetaTileEntity().getColorization()); - return this.colorOverride.getGuiTintOrDefault(dye.mName, GT_Util.getRGBInt(dye.getRGBA())); + return this.colorOverride.getGuiTintOrDefault(dye.mName, GTUtil.getRGBInt(dye.getRGBA())); } - } else if (GregTech_API.sColoredGUI) { - if (GregTech_API.sMachineMetalGUI) { + } else if (GregTechAPI.sColoredGUI) { + if (GregTechAPI.sMachineMetalGUI) { dye = Dyes.MACHINE_METAL; } else if (getBaseMetaTileEntity() != null) { dye = Dyes.getDyeFromIndex(getBaseMetaTileEntity().getColorization()); } } - return GT_Util.getRGBInt(dye.getRGBA()); + return GTUtil.getRGBInt(dye.getRGBA()); } @Override diff --git a/src/main/java/gregtech/api/metatileentity/TileIC2EnergySink.java b/src/main/java/gregtech/api/metatileentity/TileIC2EnergySink.java index 6fecb840b4..a793dbbe34 100644 --- a/src/main/java/gregtech/api/metatileentity/TileIC2EnergySink.java +++ b/src/main/java/gregtech/api/metatileentity/TileIC2EnergySink.java @@ -9,21 +9,21 @@ import gregtech.api.interfaces.metatileentity.IConnectable; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.metatileentity.IMetaTileEntityCable; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; -import gregtech.api.util.GT_Utility; +import gregtech.api.metatileentity.implementations.MTECable; +import gregtech.api.util.GTUtility; import ic2.api.energy.tile.IEnergySink; public class TileIC2EnergySink extends TileEntity implements IEnergySink { private final IGregTechTileEntity myMeta; - private GT_MetaPipeEntity_Cable cableMeta = null; + private MTECable cableMeta = null; public TileIC2EnergySink(IGregTechTileEntity meta) { if (meta == null) throw new NullPointerException("no null metas"); myMeta = meta; final IMetaTileEntity metaTile = myMeta.getMetaTileEntity(); if (metaTile instanceof IMetaTileEntityCable) { - cableMeta = (GT_MetaPipeEntity_Cable) metaTile; + cableMeta = (MTECable) metaTile; } setWorldObj(meta.getWorld()); xCoord = meta.getXCoord(); @@ -62,7 +62,7 @@ public class TileIC2EnergySink extends TileEntity implements IEnergySink { */ @Override public int getSinkTier() { - return GT_Utility.getTier(cableMeta != null ? cableMeta.mVoltage : myMeta.getInputVoltage()); + return GTUtility.getTier(cableMeta != null ? cableMeta.mVoltage : myMeta.getInputVoltage()); } /** diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java deleted file mode 100644 index e44860963f..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java +++ /dev/null @@ -1,649 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Mods.GalacticraftCore; -import static net.minecraftforge.common.util.ForgeDirection.DOWN; -import static net.minecraftforge.common.util.ForgeDirection.EAST; -import static net.minecraftforge.common.util.ForgeDirection.NORTH; -import static net.minecraftforge.common.util.ForgeDirection.SOUTH; -import static net.minecraftforge.common.util.ForgeDirection.UP; -import static net.minecraftforge.common.util.ForgeDirection.WEST; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import cofh.api.energy.IEnergyReceiver; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.Dyes; -import gregtech.api.enums.Materials; -import gregtech.api.enums.TextureSet; -import gregtech.api.enums.Textures; -import gregtech.api.graphs.Node; -import gregtech.api.graphs.NodeList; -import gregtech.api.graphs.PowerNode; -import gregtech.api.graphs.PowerNodes; -import gregtech.api.graphs.consumers.ConsumerNode; -import gregtech.api.graphs.paths.PowerNodePath; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IConnectable; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.metatileentity.IMetaTileEntityCable; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.interfaces.tileentity.IEnergyConnected; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.logic.interfaces.PowerLogicHost; -import gregtech.api.metatileentity.BaseMetaPipeEntity; -import gregtech.api.metatileentity.MetaPipeEntity; -import gregtech.api.objects.GT_Cover_None; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_GC_Compat; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.ISerializableObject; -import gregtech.common.GT_Client; -import gregtech.common.covers.CoverInfo; -import gregtech.common.covers.GT_Cover_SolarPanel; -import ic2.api.energy.EnergyNet; -import ic2.api.energy.tile.IEnergyEmitter; -import ic2.api.energy.tile.IEnergySink; -import ic2.api.energy.tile.IEnergySource; -import ic2.api.energy.tile.IEnergyTile; -import ic2.api.reactor.IReactorChamber; -import mcp.mobius.waila.api.IWailaConfigHandler; -import mcp.mobius.waila.api.IWailaDataAccessor; - -public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTileEntityCable { - - public final float mThickNess; - public final Materials mMaterial; - public final long mCableLossPerMeter, mAmperage, mVoltage; - public final boolean mInsulated, mCanShock; - - public int mTransferredAmperage = 0; - - public GT_MetaPipeEntity_Cable(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, - long aCableLossPerMeter, long aAmperage, long aVoltage, boolean aInsulated, boolean aCanShock) { - super(aID, aName, aNameRegional, 0); - mThickNess = aThickNess; - mMaterial = aMaterial; - mAmperage = aAmperage; - mVoltage = aVoltage; - mInsulated = aInsulated; - mCanShock = aCanShock; - mCableLossPerMeter = aCableLossPerMeter; - } - - public GT_MetaPipeEntity_Cable(String aName, float aThickNess, Materials aMaterial, long aCableLossPerMeter, - long aAmperage, long aVoltage, boolean aInsulated, boolean aCanShock) { - super(aName, 0); - mThickNess = aThickNess; - mMaterial = aMaterial; - mAmperage = aAmperage; - mVoltage = aVoltage; - mInsulated = aInsulated; - mCanShock = aCanShock; - mCableLossPerMeter = aCableLossPerMeter; - } - - @Override - public byte getTileEntityBaseType() { - return (byte) (mInsulated ? 9 : 8); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaPipeEntity_Cable( - mName, - mThickNess, - mMaterial, - mCableLossPerMeter, - mAmperage, - mVoltage, - mInsulated, - mCanShock); - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, - int facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { - if (!mInsulated) return new ITexture[] { TextureFactory - .of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], Dyes.getModulation(colorIndex, mMaterial.mRGBa)) }; - if (active) { - float tThickNess = getThickNess(); - if (tThickNess < 0.124F) return new ITexture[] { TextureFactory - .of(Textures.BlockIcons.INSULATION_FULL, Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - if (tThickNess < 0.374F) // 0.375 x1 - return new ITexture[] { - TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), - TextureFactory.of( - Textures.BlockIcons.INSULATION_TINY, - Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - if (tThickNess < 0.499F) // 0.500 x2 - return new ITexture[] { - TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), - TextureFactory.of( - Textures.BlockIcons.INSULATION_SMALL, - Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - if (tThickNess < 0.624F) // 0.625 x4 - return new ITexture[] { - TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), - TextureFactory.of( - Textures.BlockIcons.INSULATION_MEDIUM, - Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - if (tThickNess < 0.749F) // 0.750 x8 - return new ITexture[] { - TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), - TextureFactory.of( - Textures.BlockIcons.INSULATION_MEDIUM_PLUS, - Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - if (tThickNess < 0.874F) // 0.825 x12 - return new ITexture[] { - TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), - TextureFactory.of( - Textures.BlockIcons.INSULATION_LARGE, - Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - return new ITexture[] { - TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), - TextureFactory.of( - Textures.BlockIcons.INSULATION_HUGE, - Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - } - return new ITexture[] { TextureFactory - .of(Textures.BlockIcons.INSULATION_FULL, Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; - } - - @Override - public void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity aEntity) { - - if (!mCanShock) return; - - final BaseMetaPipeEntity baseEntity = (BaseMetaPipeEntity) getBaseMetaTileEntity(); - - if (!(aEntity instanceof EntityLivingBase livingEntity)) return; - if (!(baseEntity.getNodePath() instanceof PowerNodePath powerPath)) return; - - if (isCoverOnSide(baseEntity, livingEntity)) return; - if ((baseEntity.mConnections & IConnectable.HAS_HARDENEDFOAM) == 1) return; - - final long amperage = powerPath.getAmperage(); - final long voltage = powerPath.getVoltage(); - - if (amperage == 0L) return; - - GT_Utility.applyElectricityDamage(livingEntity, voltage, amperage); - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return false; - } - - @Override - public boolean isValidSlot(int aIndex) { - return true; - } - - @Override - public final boolean renderInside(ForgeDirection side) { - return false; - } - - @Override - public int getProgresstime() { - return (int) mTransferredAmperage * 64; - } - - @Override - public int maxProgresstime() { - return (int) mAmperage * 64; - } - - @Override - public long injectEnergyUnits(ForgeDirection side, long voltage, long amperage) { - if (!isConnectedAtSide(side) && side != ForgeDirection.UNKNOWN) return 0; - if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) - .letsEnergyIn()) return 0; - return transferElectricity(side, voltage, amperage, (HashSet) null); - } - - @Override - @Deprecated - public long transferElectricity(ForgeDirection side, long aVoltage, long aAmperage, - ArrayList aAlreadyPassedTileEntityList) { - return transferElectricity(side, aVoltage, aAmperage, new HashSet<>(aAlreadyPassedTileEntityList)); - } - - @Override - public long transferElectricity(ForgeDirection side, long voltage, long amperage, - HashSet alreadyPassedSet) { - if (!getBaseMetaTileEntity().isServerSide() || !isConnectedAtSide(side) && side != ForgeDirection.UNKNOWN) - return 0; - final BaseMetaPipeEntity tBase = (BaseMetaPipeEntity) getBaseMetaTileEntity(); - if (!(tBase.getNode() instanceof PowerNode tNode)) return 0; - int tPlace = 0; - final Node[] tToPower = new Node[tNode.mConsumers.size()]; - if (tNode.mHadVoltage) { - for (ConsumerNode consumer : tNode.mConsumers) { - if (consumer.needsEnergy()) tToPower[tPlace++] = consumer; - } - } else { - tNode.mHadVoltage = true; - for (ConsumerNode consumer : tNode.mConsumers) { - tToPower[tPlace++] = consumer; - } - } - return PowerNodes.powerNode(tNode, null, new NodeList(tToPower), (int) voltage, (int) amperage); - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aTick % 20 == 0 && aBaseMetaTileEntity.isServerSide() - && (!GT_Mod.gregtechproxy.gt6Cable || mCheckConnections)) { - checkConnections(); - } - } - - @Override - public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, - float aX, float aY, float aZ) { - if (GT_Mod.gregtechproxy.gt6Cable - && GT_ModHandler.damageOrDechargeItem(aPlayer.inventory.getCurrentItem(), 1, 500, aPlayer)) { - if (isConnectedAtSide(wrenchingSide)) { - disconnect(wrenchingSide); - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("215", "Disconnected")); - } else if (!GT_Mod.gregtechproxy.costlyCableConnection) { - if (connect(wrenchingSide) > 0) - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("214", "Connected")); - } - return true; - } - return false; - } - - @Override - public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, - float aX, float aY, float aZ) { - if (GT_Mod.gregtechproxy.gt6Cable - && GT_ModHandler.damageOrDechargeItem(aPlayer.inventory.getCurrentItem(), 1, 500, aPlayer)) { - if (isConnectedAtSide(wrenchingSide)) { - disconnect(wrenchingSide); - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("215", "Disconnected")); - } else if (!GT_Mod.gregtechproxy.costlyCableConnection || GT_ModHandler.consumeSolderingMaterial(aPlayer)) { - if (connect(wrenchingSide) > 0) - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("214", "Connected")); - } - return true; - } - return false; - } - - @Override - public boolean letsIn(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return coverBehavior.letsEnergyIn(side, aCoverID, aCoverVariable, aTileEntity); - } - - @Override - public boolean letsOut(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return coverBehavior.letsEnergyOut(side, aCoverID, aCoverVariable, aTileEntity); - } - - @Override - public boolean letsIn(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return coverBehavior.letsEnergyIn(side, aCoverID, aCoverVariable, aTileEntity); - } - - @Override - public boolean letsOut(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return coverBehavior.letsEnergyOut(side, aCoverID, aCoverVariable, aTileEntity); - } - - @Override - public boolean letsIn(CoverInfo coverInfo) { - return coverInfo.letsEnergyIn(); - } - - @Override - public boolean letsOut(CoverInfo coverInfo) { - return coverInfo.letsEnergyOut(); - } - - @Override - public boolean canConnect(ForgeDirection side, TileEntity tileEntity) { - final IGregTechTileEntity baseMetaTile = getBaseMetaTileEntity(); - final GT_CoverBehaviorBase coverBehavior = baseMetaTile.getCoverBehaviorAtSideNew(side); - final ForgeDirection oppositeSide = side.getOpposite(); - - // GT Machine handling - if ((tileEntity instanceof PowerLogicHost powerLogic && powerLogic.getPowerLogic(oppositeSide) != null) - || ((tileEntity instanceof IEnergyConnected energyConnected) - && (energyConnected.inputEnergyFrom(oppositeSide, false) - || energyConnected.outputsEnergyTo(oppositeSide, false)))) - return true; - - // Solar Panel Compat - if (coverBehavior instanceof GT_Cover_SolarPanel) return true; - - // ((tIsGregTechTileEntity && tIsTileEntityCable) && (tAlwaysLookConnected || tLetEnergyIn || tLetEnergyOut) ) - // --> Not needed - if (GalacticraftCore.isModLoaded() && GT_GC_Compat.canConnect(tileEntity, oppositeSide)) return true; - - // AE2-p2p Compat - if (tileEntity instanceof appeng.tile.powersink.IC2 ic2sink - && ic2sink.acceptsEnergyFrom((TileEntity) baseMetaTile, oppositeSide)) return true; - - // IC2 Compat - { - final TileEntity ic2Energy; - - if (tileEntity instanceof IReactorChamber) - ic2Energy = (TileEntity) ((IReactorChamber) tileEntity).getReactor(); - else ic2Energy = (tileEntity == null || tileEntity instanceof IEnergyTile || EnergyNet.instance == null) - ? tileEntity - : EnergyNet.instance - .getTileEntity(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord); - - // IC2 Sink Compat - if ((ic2Energy instanceof IEnergySink) - && ((IEnergySink) ic2Energy).acceptsEnergyFrom((TileEntity) baseMetaTile, oppositeSide)) return true; - - // IC2 Source Compat - if (GT_Mod.gregtechproxy.ic2EnergySourceCompat && (ic2Energy instanceof IEnergySource)) { - if (((IEnergySource) ic2Energy).emitsEnergyTo((TileEntity) baseMetaTile, oppositeSide)) { - return true; - } - } - } - // RF Output Compat - if (GregTech_API.mOutputRF && tileEntity instanceof IEnergyReceiver - && ((IEnergyReceiver) tileEntity).canConnectEnergy(oppositeSide)) return true; - - // RF Input Compat - return GregTech_API.mInputRF && (tileEntity instanceof IEnergyEmitter - && ((IEnergyEmitter) tileEntity).emitsEnergyTo((TileEntity) baseMetaTile, oppositeSide)); - } - - @Override - public boolean getGT6StyleConnection() { - // Yes if GT6 Cables are enabled - return GT_Mod.gregtechproxy.gt6Cable; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public String[] getDescription() { - return new String[] { - StatCollector.translateToLocal("GT5U.item.cable.max_voltage") + ": %%%" - + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(mVoltage) - + " (" - + GT_Utility.getColoredTierNameFromVoltage(mVoltage) - + EnumChatFormatting.GREEN - + ")" - + EnumChatFormatting.GRAY, - StatCollector.translateToLocal("GT5U.item.cable.max_amperage") + ": %%%" - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mAmperage) - + EnumChatFormatting.GRAY, - StatCollector.translateToLocal("GT5U.item.cable.loss") + ": %%%" - + EnumChatFormatting.RED - + GT_Utility.formatNumbers(mCableLossPerMeter) - + EnumChatFormatting.GRAY - + "%%% " - + StatCollector.translateToLocal("GT5U.item.cable.eu_volt") }; - } - - @Override - public float getThickNess() { - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) return 0.0625F; - return mThickNess; - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - if (GT_Mod.gregtechproxy.gt6Cable) aNBT.setByte("mConnections", mConnections); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - if (GT_Mod.gregtechproxy.gt6Cable) { - mConnections = aNBT.getByte("mConnections"); - } - } - - @Override - public boolean isGivingInformation() { - return true; - } - - @Override - public String[] getInfoData() { - final BaseMetaPipeEntity base = (BaseMetaPipeEntity) getBaseMetaTileEntity(); - final PowerNodePath path = (PowerNodePath) base.getNodePath(); - - if (path == null) - return new String[] { EnumChatFormatting.RED + "Failed to get Power Node info" + EnumChatFormatting.RESET }; - - final long currAmp = path.getAmperage(); - final long currVoltage = path.getVoltage(); - - final double avgAmp = path.getAvgAmperage(); - final double avgVoltage = path.getAvgVoltage(); - - final long maxVoltageOut = (mVoltage - mCableLossPerMeter) * mAmperage; - - return new String[] { - "Amperage: " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(currAmp) - + EnumChatFormatting.RESET - + " / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mAmperage) - + EnumChatFormatting.RESET - + " A", - "Voltage Out: " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(currVoltage) - + EnumChatFormatting.RESET - + " / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(maxVoltageOut) - + EnumChatFormatting.RESET - + " EU/t", - "Avg Amperage (20t): " + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(avgAmp) - + EnumChatFormatting.RESET - + " A", - "Avg Output (20t): " + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(avgVoltage) - + EnumChatFormatting.RESET - + " EU/t" }; - } - - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x2) != 0) - return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1); - else return getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); - } - - private AxisAlignedBB getActualCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { - float tSpace = (1f - mThickNess) / 2; - float spaceDown = tSpace; - float spaceUp = 1f - tSpace; - float spaceNorth = tSpace; - float spaceSouth = 1f - tSpace; - float spaceWest = tSpace; - float spaceEast = 1f - tSpace; - - if (getBaseMetaTileEntity().getCoverIDAtSide(DOWN) != 0) { - spaceDown = spaceNorth = spaceWest = 0; - spaceSouth = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(UP) != 0) { - spaceNorth = spaceWest = 0; - spaceUp = spaceSouth = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(NORTH) != 0) { - spaceDown = spaceNorth = spaceWest = 0; - spaceUp = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(SOUTH) != 0) { - spaceDown = spaceWest = 0; - spaceUp = spaceSouth = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(WEST) != 0) { - spaceDown = spaceNorth = spaceWest = 0; - spaceUp = spaceSouth = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(EAST) != 0) { - spaceDown = spaceNorth = 0; - spaceUp = spaceSouth = spaceEast = 1; - } - - byte tConn = ((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections; - if ((tConn & DOWN.flag) != 0) spaceDown = 0f; - if ((tConn & UP.flag) != 0) spaceUp = 1f; - if ((tConn & NORTH.flag) != 0) spaceNorth = 0f; - if ((tConn & SOUTH.flag) != 0) spaceSouth = 1f; - if ((tConn & WEST.flag) != 0) spaceWest = 0f; - if ((tConn & EAST.flag) != 0) spaceEast = 1f; - - return AxisAlignedBB.getBoundingBox( - aX + spaceWest, - aY + spaceDown, - aZ + spaceNorth, - aX + spaceEast, - aY + spaceUp, - aZ + spaceSouth); - } - - @Override - public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, - List outputAABB, Entity collider) { - super.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider); - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x2) != 0) { - final AxisAlignedBB aabb = getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); - if (inputAABB.intersectsWith(aabb)) outputAABB.add(aabb); - } - } - - @Override - public boolean shouldJoinIc2Enet() { - if (!GT_Mod.gregtechproxy.ic2EnergySourceCompat) return false; - - if (mConnections != 0) { - final IGregTechTileEntity baseMeta = getBaseMetaTileEntity(); - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (isConnectedAtSide(side)) { - final TileEntity tTileEntity = baseMeta.getTileEntityAtSide(side); - final TileEntity tEmitter = (tTileEntity == null || tTileEntity instanceof IEnergyTile - || EnergyNet.instance == null) - ? tTileEntity - : EnergyNet.instance.getTileEntity( - tTileEntity.getWorldObj(), - tTileEntity.xCoord, - tTileEntity.yCoord, - tTileEntity.zCoord); - - if (tEmitter instanceof IEnergyEmitter) return true; - } - } - } - return false; - } - - @Override - public void reloadLocks() { - final BaseMetaPipeEntity pipe = (BaseMetaPipeEntity) getBaseMetaTileEntity(); - if (pipe.getNode() != null) { - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (isConnectedAtSide(side)) { - final CoverInfo coverInfo = pipe.getCoverInfoAtSide(side); - if (coverInfo.getCoverBehavior() instanceof GT_Cover_None) continue; - if (!letsIn(coverInfo) || !letsOut(coverInfo)) { - pipe.addToLock(pipe, side); - } else { - pipe.removeFromLock(pipe, side); - } - } - } - } else { - boolean dontAllow = false; - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (isConnectedAtSide(side)) { - final CoverInfo coverInfo = pipe.getCoverInfoAtSide(side); - if (coverInfo.getCoverBehavior() instanceof GT_Cover_None) continue; - - if (!letsIn(coverInfo) || !letsOut(coverInfo)) { - dontAllow = true; - } - } - } - if (dontAllow) { - pipe.addToLock(pipe, DOWN); - } else { - pipe.removeFromLock(pipe, DOWN); - } - } - } - - @Override - public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - - currenttip.add( - StatCollector.translateToLocal("GT5U.item.cable.max_voltage") + ": " - + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(mVoltage) - + " (" - + GT_Utility.getColoredTierNameFromVoltage(mVoltage) - + EnumChatFormatting.GREEN - + ")"); - currenttip.add( - StatCollector.translateToLocal("GT5U.item.cable.max_amperage") + ": " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mAmperage)); - currenttip.add( - StatCollector.translateToLocal("GT5U.item.cable.loss") + ": " - + EnumChatFormatting.RED - + GT_Utility.formatNumbers(mCableLossPerMeter) - + EnumChatFormatting.RESET - + " " - + StatCollector.translateToLocal("GT5U.item.cable.eu_volt")); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java deleted file mode 100644 index cafd1c9cb7..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid.java +++ /dev/null @@ -1,979 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES; -import static gregtech.api.enums.GT_Values.D1; -import static gregtech.api.enums.Mods.TinkerConstruct; -import static gregtech.api.enums.Mods.Translocator; -import static gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid.Border.BOTTOM; -import static gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid.Border.LEFT; -import static gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid.Border.RIGHT; -import static gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid.Border.TOP; -import static gregtech.api.objects.XSTR.XSTR_INSTANCE; -import static net.minecraftforge.common.util.ForgeDirection.DOWN; -import static net.minecraftforge.common.util.ForgeDirection.EAST; -import static net.minecraftforge.common.util.ForgeDirection.NORTH; -import static net.minecraftforge.common.util.ForgeDirection.SOUTH; -import static net.minecraftforge.common.util.ForgeDirection.UP; -import static net.minecraftforge.common.util.ForgeDirection.WEST; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidHandler; - -import org.apache.commons.lang3.tuple.MutableTriple; - -import cpw.mods.fml.common.Optional; -import gregtech.GT_Mod; -import gregtech.api.enums.Dyes; -import gregtech.api.enums.Materials; -import gregtech.api.enums.Mods; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.ParticleFX; -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.Textures; -import gregtech.api.enums.ToolModes; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.items.GT_MetaGenerated_Tool; -import gregtech.api.metatileentity.BaseMetaPipeEntity; -import gregtech.api.metatileentity.MetaPipeEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.ISerializableObject; -import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; -import gregtech.common.GT_Client; -import gregtech.common.config.other.ConfigGeneral; -import gregtech.common.covers.CoverInfo; -import gregtech.common.covers.GT_Cover_Drain; -import gregtech.common.covers.GT_Cover_FluidRegulator; - -public class GT_MetaPipeEntity_Fluid extends MetaPipeEntity { - - protected static final EnumMap> FACE_BORDER_MAP = new EnumMap<>( - ForgeDirection.class); - - static { - FACE_BORDER_MAP.put(DOWN, borderMap(NORTH, SOUTH, EAST, WEST)); - FACE_BORDER_MAP.put(UP, borderMap(NORTH, SOUTH, WEST, EAST)); - FACE_BORDER_MAP.put(NORTH, borderMap(UP, DOWN, EAST, WEST)); - FACE_BORDER_MAP.put(SOUTH, borderMap(UP, DOWN, WEST, EAST)); - FACE_BORDER_MAP.put(WEST, borderMap(UP, DOWN, NORTH, SOUTH)); - FACE_BORDER_MAP.put(EAST, borderMap(UP, DOWN, SOUTH, NORTH)); - } - - protected static final Map RESTR_TEXTURE_MAP = new HashMap<>(); - - static { - RESTR_TEXTURE_MAP.put(TOP.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UP); - RESTR_TEXTURE_MAP.put(BOTTOM.mask, Textures.BlockIcons.PIPE_RESTRICTOR_DOWN); - RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UD); - RESTR_TEXTURE_MAP.put(LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_LEFT); - RESTR_TEXTURE_MAP.put(TOP.mask | LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UL); - RESTR_TEXTURE_MAP.put(BOTTOM.mask | LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_DL); - RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask | LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_NR); - RESTR_TEXTURE_MAP.put(RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_RIGHT); - RESTR_TEXTURE_MAP.put(TOP.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UR); - RESTR_TEXTURE_MAP.put(BOTTOM.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_DR); - RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_NL); - RESTR_TEXTURE_MAP.put(LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_LR); - RESTR_TEXTURE_MAP.put(TOP.mask | LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_ND); - RESTR_TEXTURE_MAP.put(BOTTOM.mask | LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_NU); - RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask | LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR); - } - - public final float mThickNess; - public final Materials mMaterial; - public final int mCapacity, mHeatResistance, mPipeAmount; - public final boolean mGasProof; - public final FluidStack[] mFluids; - public byte mLastReceivedFrom = 0, oLastReceivedFrom = 0; - /** - * Bitmask for whether disable fluid input form each side. - */ - public byte mDisableInput = 0; - - public GT_MetaPipeEntity_Fluid(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, - int aCapacity, int aHeatResistance, boolean aGasProof) { - this(aID, aName, aNameRegional, aThickNess, aMaterial, aCapacity, aHeatResistance, aGasProof, 1); - } - - public GT_MetaPipeEntity_Fluid(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, - int aCapacity, int aHeatResistance, boolean aGasProof, int aFluidTypes) { - super(aID, aName, aNameRegional, 0, false); - mThickNess = aThickNess; - mMaterial = aMaterial; - mCapacity = aCapacity; - mGasProof = aGasProof; - mHeatResistance = aHeatResistance; - mPipeAmount = aFluidTypes; - mFluids = new FluidStack[mPipeAmount]; - addInfo(aID); - } - - public GT_MetaPipeEntity_Fluid(String aName, float aThickNess, Materials aMaterial, int aCapacity, - int aHeatResistance, boolean aGasProof, int aFluidTypes) { - super(aName, 0); - mThickNess = aThickNess; - mMaterial = aMaterial; - mCapacity = aCapacity; - mGasProof = aGasProof; - mHeatResistance = aHeatResistance; - mPipeAmount = aFluidTypes; - mFluids = new FluidStack[mPipeAmount]; - } - - @Override - public byte getTileEntityBaseType() { - return (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaPipeEntity_Fluid( - mName, - mThickNess, - mMaterial, - mCapacity, - mHeatResistance, - mGasProof, - mPipeAmount); - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, int aConnections, - int colorIndex, boolean aConnected, boolean redstoneLevel) { - if (side == ForgeDirection.UNKNOWN) return Textures.BlockIcons.ERROR_RENDERING; - final float tThickNess = getThickNess(); - if (mDisableInput == 0) - return new ITexture[] { aConnected ? getBaseTexture(tThickNess, mPipeAmount, mMaterial, colorIndex) - : TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(colorIndex, mMaterial.mRGBa)) }; - int borderMask = 0; - for (Border border : Border.values()) { - if (isInputDisabledAtSide(getSideAtBorder(side, border))) borderMask |= border.mask; - } - - return new ITexture[] { aConnected ? getBaseTexture(tThickNess, mPipeAmount, mMaterial, colorIndex) - : TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(colorIndex, mMaterial.mRGBa)), - getRestrictorTexture(borderMask) }; - } - - protected static ITexture getBaseTexture(float aThickNess, int aPipeAmount, Materials aMaterial, int colorIndex) { - if (aPipeAmount >= 9) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeNonuple.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - if (aPipeAmount >= 4) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeQuadruple.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - if (aThickNess < 0.124F) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - if (aThickNess < 0.374F) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeTiny.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - if (aThickNess < 0.499F) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeSmall.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - if (aThickNess < 0.749F) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeMedium.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - if (aThickNess < 0.874F) return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeLarge.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - return TextureFactory.of( - aMaterial.mIconSet.mTextures[OrePrefixes.pipeHuge.mTextureIndex], - Dyes.getModulation(colorIndex, aMaterial.mRGBa)); - } - - protected static ITexture getRestrictorTexture(int borderMask) { - final IIconContainer restrictorIcon = RESTR_TEXTURE_MAP.get(borderMask); - return restrictorIcon != null ? TextureFactory.of(restrictorIcon) : null; - } - - @Override - public void onValueUpdate(byte aValue) { - mDisableInput = aValue; - } - - @Override - public byte getUpdateData() { - return mDisableInput; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return false; - } - - @Override - public boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public final boolean renderInside(ForgeDirection side) { - return false; - } - - @Override - public int getProgresstime() { - return getFluidAmount(); - } - - @Override - public int maxProgresstime() { - return getCapacity(); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - for (int i = 0; i < mPipeAmount; i++) if (mFluids[i] != null) - aNBT.setTag("mFluid" + (i == 0 ? "" : i), mFluids[i].writeToNBT(new NBTTagCompound())); - aNBT.setByte("mLastReceivedFrom", mLastReceivedFrom); - if (GT_Mod.gregtechproxy.gt6Pipe) { - aNBT.setByte("mConnections", mConnections); - aNBT.setByte("mDisableInput", mDisableInput); - } - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - for (int i = 0; i < mPipeAmount; i++) - mFluids[i] = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid" + (i == 0 ? "" : i))); - mLastReceivedFrom = aNBT.getByte("mLastReceivedFrom"); - if (GT_Mod.gregtechproxy.gt6Pipe) { - mConnections = aNBT.getByte("mConnections"); - mDisableInput = aNBT.getByte("mDisableInput"); - } - } - - @Override - public void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity aEntity) { - if ((((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections & -128) == 0 - && aEntity instanceof EntityLivingBase) { - for (FluidStack tFluid : mFluids) { - if (tFluid != null) { - final int tTemperature = tFluid.getFluid() - .getTemperature(tFluid); - if (tTemperature > 320 - && !isCoverOnSide((BaseMetaPipeEntity) getBaseMetaTileEntity(), (EntityLivingBase) aEntity)) { - GT_Utility.applyHeatDamage((EntityLivingBase) aEntity, (tTemperature - 300) / 50.0F); - break; - } else if (tTemperature < 260 - && !isCoverOnSide((BaseMetaPipeEntity) getBaseMetaTileEntity(), (EntityLivingBase) aEntity)) { - GT_Utility.applyFrostDamage((EntityLivingBase) aEntity, (270 - tTemperature) / 25.0F); - break; - } - } - } - } - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isServerSide() && aTick % 5 == 0) { - mLastReceivedFrom &= 63; - if (mLastReceivedFrom == 63) { - mLastReceivedFrom = 0; - } - - if (!GT_Mod.gregtechproxy.gt6Pipe || mCheckConnections) checkConnections(); - - final boolean shouldDistribute = (oLastReceivedFrom == mLastReceivedFrom); - for (int i = 0, j = aBaseMetaTileEntity.getRandomNumber(mPipeAmount); i < mPipeAmount; i++) { - final int index = (i + j) % mPipeAmount; - if (mFluids[index] != null && mFluids[index].amount <= 0) mFluids[index] = null; - if (mFluids[index] == null) continue; - - if (checkEnvironment(index, aBaseMetaTileEntity)) return; - - if (shouldDistribute) { - distributeFluid(index, aBaseMetaTileEntity); - mLastReceivedFrom = 0; - } - } - - oLastReceivedFrom = mLastReceivedFrom; - } - } - - private boolean checkEnvironment(int index, IGregTechTileEntity aBaseMetaTileEntity) { - // Check for hot liquids that melt the pipe or gasses that escape and burn/freeze people - final FluidStack tFluid = mFluids[index]; - - if (tFluid != null && tFluid.amount > 0) { - final int tTemperature = tFluid.getFluid() - .getTemperature(tFluid); - if (tTemperature > mHeatResistance) { - if (aBaseMetaTileEntity.getRandomNumber(100) == 0) { - // Poof - GT_Log.exp.println( - "Set Pipe to Fire due to to low heat resistance at " + aBaseMetaTileEntity.getXCoord() - + " | " - + aBaseMetaTileEntity.getYCoord() - + " | " - + aBaseMetaTileEntity.getZCoord() - + " DIMID: " - + aBaseMetaTileEntity.getWorld().provider.dimensionId); - aBaseMetaTileEntity.setToFire(); - return true; - } - // Mmhmm, Fire - aBaseMetaTileEntity.setOnFire(); - GT_Log.exp.println( - "Set Blocks around Pipe to Fire due to to low heat resistance at " + aBaseMetaTileEntity.getXCoord() - + " | " - + aBaseMetaTileEntity.getYCoord() - + " | " - + aBaseMetaTileEntity.getZCoord() - + " DIMID: " - + aBaseMetaTileEntity.getWorld().provider.dimensionId); - } - if (!mGasProof && tFluid.getFluid() - .isGaseous(tFluid)) { - tFluid.amount -= 5; - sendSound((byte) 9); - if (tTemperature > 320) { - try { - for (EntityLivingBase tLiving : getBaseMetaTileEntity().getWorld() - .getEntitiesWithinAABB( - EntityLivingBase.class, - AxisAlignedBB.getBoundingBox( - getBaseMetaTileEntity().getXCoord() - 2, - getBaseMetaTileEntity().getYCoord() - 2, - getBaseMetaTileEntity().getZCoord() - 2, - getBaseMetaTileEntity().getXCoord() + 3, - getBaseMetaTileEntity().getYCoord() + 3, - getBaseMetaTileEntity().getZCoord() + 3))) { - GT_Utility.applyHeatDamage(tLiving, (tTemperature - 300) / 25.0F); - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - } else if (tTemperature < 260) { - try { - for (EntityLivingBase tLiving : getBaseMetaTileEntity().getWorld() - .getEntitiesWithinAABB( - EntityLivingBase.class, - AxisAlignedBB.getBoundingBox( - getBaseMetaTileEntity().getXCoord() - 2, - getBaseMetaTileEntity().getYCoord() - 2, - getBaseMetaTileEntity().getZCoord() - 2, - getBaseMetaTileEntity().getXCoord() + 3, - getBaseMetaTileEntity().getYCoord() + 3, - getBaseMetaTileEntity().getZCoord() + 3))) { - GT_Utility.applyFrostDamage(tLiving, (270 - tTemperature) / 12.5F); - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - } - } - if (tFluid.amount <= 0) mFluids[index] = null; - } - return false; - } - - private void distributeFluid(int index, IGregTechTileEntity aBaseMetaTileEntity) { - final FluidStack tFluid = mFluids[index]; - if (tFluid == null) return; - - // Tank, From, Amount to receive - final List> tTanks = new ArrayList<>(); - final int amount = tFluid.amount; - final byte tOffset = (byte) getBaseMetaTileEntity().getRandomNumber(6); - for (final byte i : ALL_VALID_SIDES) { - // Get a list of tanks accepting fluids, and what side they're on - final ForgeDirection side = ForgeDirection.getOrientation((i + tOffset) % 6); - final ForgeDirection oppositeSide = side.getOpposite(); - final IFluidHandler tTank = aBaseMetaTileEntity.getITankContainerAtSide(side); - final IGregTechTileEntity gTank = tTank instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTank : null; - - if (isConnectedAtSide(side) && tTank != null - && (mLastReceivedFrom & side.flag) == 0 - && getBaseMetaTileEntity().getCoverInfoAtSide(side) - .letsFluidOut(tFluid.getFluid()) - && (gTank == null || gTank.getCoverInfoAtSide(oppositeSide) - .letsFluidIn(tFluid.getFluid()))) { - if (tTank.fill(oppositeSide, tFluid, false) > 0) { - tTanks.add(new MutableTriple<>(tTank, oppositeSide, 0)); - } - tFluid.amount = amount; // Because some mods do actually modify input fluid stack - } - } - - // How much of this fluid is available for distribution? - final double tAmount = Math.max(1, Math.min(mCapacity * 10, tFluid.amount)); - - final FluidStack maxFluid = tFluid.copy(); - maxFluid.amount = Integer.MAX_VALUE; - - double availableCapacity = 0; - // Calculate available capacity for distribution from all tanks - for (final MutableTriple tEntry : tTanks) { - tEntry.right = tEntry.left.fill(tEntry.middle, maxFluid, false); - availableCapacity += tEntry.right; - } - - // Now distribute - for (final MutableTriple tEntry : tTanks) { - // Distribue fluids based on percentage available space at destination - if (availableCapacity > tAmount) - tEntry.right = (int) Math.floor(tEntry.right * tAmount / availableCapacity); - - // If the percent is not enough to give at least 1L, try to give 1L - if (tEntry.right == 0) tEntry.right = (int) Math.min(1, tAmount); - - if (tEntry.right <= 0) continue; - - final int tFilledAmount = tEntry.left - .fill(tEntry.middle, drainFromIndex(tEntry.right, false, index), false); - - if (tFilledAmount > 0) tEntry.left.fill(tEntry.middle, drainFromIndex(tFilledAmount, true, index), true); - - if (mFluids[index] == null || mFluids[index].amount <= 0) return; - } - } - - public void connectPipeOnSide(ForgeDirection side, EntityPlayer entityPlayer) { - if (!isConnectedAtSide(side)) { - if (connect(side) > 0) GT_Utility.sendChatToPlayer(entityPlayer, GT_Utility.trans("214", "Connected")); - } else { - disconnect(side); - GT_Utility.sendChatToPlayer(entityPlayer, GT_Utility.trans("215", "Disconnected")); - } - } - - public void blockPipeOnSide(ForgeDirection side, EntityPlayer entityPlayer, byte mask) { - if (isInputDisabledAtSide(side)) { - mDisableInput &= ~mask; - GT_Utility.sendChatToPlayer(entityPlayer, GT_Utility.trans("212", "Input enabled")); - if (!isConnectedAtSide(side)) connect(side); - } else { - mDisableInput |= mask; - GT_Utility.sendChatToPlayer(entityPlayer, GT_Utility.trans("213", "Input disabled")); - } - } - - @Override - public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, - float aX, float aY, float aZ, ItemStack aTool) { - - if (GT_Mod.gregtechproxy.gt6Pipe) { - final int mode = GT_MetaGenerated_Tool.getToolMode(aTool); - IGregTechTileEntity currentPipeBase = getBaseMetaTileEntity(); - GT_MetaPipeEntity_Fluid currentPipe = (GT_MetaPipeEntity_Fluid) currentPipeBase.getMetaTileEntity(); - final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); - final byte tMask = (byte) (tSide.flag); - - if (mode == ToolModes.REGULAR.get()) { - if (entityPlayer.isSneaking()) { - currentPipe.blockPipeOnSide(tSide, entityPlayer, tMask); - } else currentPipe.connectPipeOnSide(tSide, entityPlayer); - return true; - } - - if (mode == ToolModes.WRENCH_LINE.get()) { - - boolean initialState = entityPlayer.isSneaking() ? currentPipe.isInputDisabledAtSide(tSide) - : currentPipe.isConnectedAtSide(tSide); - - boolean wasActionPerformed = false; - - int limit = ConfigGeneral.pipeWrenchingChainRange; - for (int connected = 0; connected < limit; connected++) { - - TileEntity nextPipeBaseTile = currentPipeBase.getTileEntityAtSide(tSide); - - // if next tile doesn't exist or if next tile is not GT tile - if (!(nextPipeBaseTile instanceof IGregTechTileEntity nextPipeBase)) { - return wasActionPerformed; - } - - // if next tile is wrong color - if (!currentPipe.connectableColor(nextPipeBaseTile)) { - return wasActionPerformed; - } - - GT_MetaPipeEntity_Fluid nextPipe = nextPipeBase - .getMetaTileEntity() instanceof GT_MetaPipeEntity_Fluid - ? (GT_MetaPipeEntity_Fluid) nextPipeBase.getMetaTileEntity() - : null; - - // if next tile entity is not a pipe - if (nextPipe == null) { - return wasActionPerformed; - } - - // if pipes are same size - if (mPipeAmount != nextPipe.mPipeAmount) { - return wasActionPerformed; - } - - // making sure next pipe has same fluid - for (int i = 0; i < mPipeAmount; i++) { - if (mFluids[i] != null && nextPipe.mFluids[i] != null) { - if (!mFluids[i].isFluidEqual(nextPipe.mFluids[i])) { - return wasActionPerformed; - } - } else if (mFluids[i] != nextPipe.mFluids[i]) { - return wasActionPerformed; - } - } - - boolean currentState = entityPlayer.isSneaking() ? currentPipe.isInputDisabledAtSide(tSide) - : currentPipe.isConnectedAtSide(tSide); - - /* - * Making sure next pipe will have same action applied to it - * e.g. Connecting pipe won`t trigger disconnect if next pipe is already connected - */ - if (currentState != initialState) { - return wasActionPerformed; - } - - if (entityPlayer.isSneaking()) { - currentPipe.blockPipeOnSide(tSide, entityPlayer, tMask); - } else currentPipe.connectPipeOnSide(tSide, entityPlayer); - - wasActionPerformed = true; - - currentPipeBase = (IGregTechTileEntity) nextPipeBase; - currentPipe = nextPipe; - - } - return wasActionPerformed; - } - } - return false; - } - - @Override - public boolean letsIn(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return coverBehavior.letsFluidIn(side, aCoverID, aCoverVariable, null, aTileEntity); - } - - @Override - public boolean letsOut(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return coverBehavior.letsFluidOut(side, aCoverID, aCoverVariable, null, aTileEntity); - } - - @Override - public boolean letsIn(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return coverBehavior.letsFluidIn(side, aCoverID, aCoverVariable, null, aTileEntity); - } - - @Override - public boolean letsOut(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return coverBehavior.letsFluidOut(side, aCoverID, aCoverVariable, null, aTileEntity); - } - - @Override - public boolean letsIn(CoverInfo coverInfo) { - return coverInfo.letsFluidIn(null); - } - - @Override - public boolean letsOut(CoverInfo coverInfo) { - return coverInfo.letsFluidOut(null); - } - - @Override - public boolean canConnect(ForgeDirection side, TileEntity tileEntity) { - if (tileEntity == null) return false; - - final ForgeDirection tSide = side.getOpposite(); - final IGregTechTileEntity baseMetaTile = getBaseMetaTileEntity(); - if (baseMetaTile == null) return false; - - final GT_CoverBehaviorBase coverBehavior = baseMetaTile.getCoverBehaviorAtSideNew(side); - final IGregTechTileEntity gTileEntity = (tileEntity instanceof IGregTechTileEntity) - ? (IGregTechTileEntity) tileEntity - : null; - - if (coverBehavior instanceof GT_Cover_Drain - || (TinkerConstruct.isModLoaded() && isTConstructFaucet(tileEntity))) return true; - - final IFluidHandler fTileEntity = (tileEntity instanceof IFluidHandler) ? (IFluidHandler) tileEntity : null; - - if (fTileEntity != null) { - final FluidTankInfo[] tInfo = fTileEntity.getTankInfo(tSide); - if (tInfo != null) { - return tInfo.length > 0 || (Translocator.isModLoaded() && isTranslocator(tileEntity)) - || gTileEntity != null - && gTileEntity.getCoverBehaviorAtSideNew(tSide) instanceof GT_Cover_FluidRegulator; - } - } - return false; - } - - @Optional.Method(modid = Mods.Names.TINKER_CONSTRUCT) - private boolean isTConstructFaucet(TileEntity tTileEntity) { - // Tinker Construct Faucets return a null tank info, so check the class - return tTileEntity instanceof tconstruct.smeltery.logic.FaucetLogic; - } - - @Optional.Method(modid = Mods.Names.TRANSLOCATOR) - private boolean isTranslocator(TileEntity tTileEntity) { - // Translocators return a TankInfo, but it's of 0 length - so check the class if we see this pattern - return tTileEntity instanceof codechicken.translocator.TileLiquidTranslocator; - } - - @Override - public boolean getGT6StyleConnection() { - // Yes if GT6 pipes are enabled - return GT_Mod.gregtechproxy.gt6Pipe; - } - - @Override - public void doSound(byte aIndex, double aX, double aY, double aZ) { - super.doSound(aIndex, aX, aY, aZ); - if (aIndex == 9) { - GT_Utility.doSoundAtClient(SoundResource.RANDOM_FIZZ, 5, 1.0F, aX, aY, aZ); - - new ParticleEventBuilder().setIdentifier(ParticleFX.CLOUD) - .setWorld(getBaseMetaTileEntity().getWorld()) - .times( - 6, - (x, i) -> x - .setMotion( - ForgeDirection.getOrientation(i).offsetX / 5.0, - ForgeDirection.getOrientation(i).offsetY / 5.0, - ForgeDirection.getOrientation(i).offsetZ / 5.0) - .setPosition( - aX - 0.5 + XSTR_INSTANCE.nextFloat(), - aY - 0.5 + XSTR_INSTANCE.nextFloat(), - aZ - 0.5 + XSTR_INSTANCE.nextFloat()) - .run()); - } - } - - @Override - public final int getCapacity() { - return mCapacity * 20 * mPipeAmount; - } - - @Override - public FluidTankInfo getInfo() { - for (FluidStack tFluid : mFluids) { - if (tFluid != null) return new FluidTankInfo(tFluid, mCapacity * 20); - } - return new FluidTankInfo(null, mCapacity * 20); - } - - @Override - public FluidTankInfo[] getTankInfo(ForgeDirection side) { - if (getCapacity() <= 0 && !getBaseMetaTileEntity().hasSteamEngineUpgrade()) return new FluidTankInfo[] {}; - ArrayList tList = new ArrayList<>(); - for (FluidStack tFluid : mFluids) tList.add(new FluidTankInfo(tFluid, mCapacity * 20)); - return tList.toArray(new FluidTankInfo[mPipeAmount]); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public final FluidStack getFluid() { - for (FluidStack tFluid : mFluids) { - if (tFluid != null) return tFluid; - } - return null; - } - - @Override - public final int getFluidAmount() { - int rAmount = 0; - for (FluidStack tFluid : mFluids) { - if (tFluid != null) rAmount += tFluid.amount; - } - return rAmount; - } - - @Override - public final int fill_default(ForgeDirection side, FluidStack aFluid, boolean doFill) { - if (aFluid == null || aFluid.getFluid() - .getID() <= 0) return 0; - - int index = -1; - for (int i = 0; i < mPipeAmount; i++) { - if (mFluids[i] != null && mFluids[i].isFluidEqual(aFluid)) { - index = i; - break; - } else if ((mFluids[i] == null || mFluids[i].getFluid() - .getID() <= 0) && index < 0) { - index = i; - } - } - - return fill_default_intoIndex(side, aFluid, doFill, index); - } - - private int fill_default_intoIndex(ForgeDirection side, FluidStack aFluid, boolean doFill, int index) { - if (index < 0 || index >= mPipeAmount) return 0; - if (aFluid == null || aFluid.getFluid() - .getID() <= 0) return 0; - - final int ordinalSide = side.ordinal(); - - if (mFluids[index] == null || mFluids[index].getFluid() - .getID() <= 0) { - if (aFluid.amount * mPipeAmount <= getCapacity()) { - if (doFill) { - mFluids[index] = aFluid.copy(); - mLastReceivedFrom |= (1 << ordinalSide); - } - return aFluid.amount; - } - if (doFill) { - mFluids[index] = aFluid.copy(); - mLastReceivedFrom |= (1 << ordinalSide); - mFluids[index].amount = getCapacity() / mPipeAmount; - } - return getCapacity() / mPipeAmount; - } - - if (!mFluids[index].isFluidEqual(aFluid)) return 0; - - final int space = getCapacity() / mPipeAmount - mFluids[index].amount; - if (aFluid.amount <= space) { - if (doFill) { - mFluids[index].amount += aFluid.amount; - mLastReceivedFrom |= (1 << ordinalSide); - } - return aFluid.amount; - } - if (doFill) { - mFluids[index].amount = getCapacity() / mPipeAmount; - mLastReceivedFrom |= (1 << ordinalSide); - } - return space; - } - - @Override - public final FluidStack drain(int maxDrain, boolean doDrain) { - FluidStack drained; - for (int i = 0; i < mPipeAmount; i++) { - if ((drained = drainFromIndex(maxDrain, doDrain, i)) != null) return drained; - } - return null; - } - - private FluidStack drainFromIndex(int maxDrain, boolean doDrain, int index) { - if (index < 0 || index >= mPipeAmount) return null; - if (mFluids[index] == null) return null; - if (mFluids[index].amount <= 0) { - mFluids[index] = null; - return null; - } - - int used = maxDrain; - if (mFluids[index].amount < used) used = mFluids[index].amount; - - if (doDrain) { - mFluids[index].amount -= used; - } - - final FluidStack drained = mFluids[index].copy(); - drained.amount = used; - - if (mFluids[index].amount <= 0) { - mFluids[index] = null; - } - - return drained; - } - - @Override - public int getTankPressure() { - return getFluidAmount() - (getCapacity() / 2); - } - - @Override - public String[] getDescription() { - List descriptions = new ArrayList<>(); - descriptions.add( - EnumChatFormatting.BLUE + "Fluid Capacity: %%%" - + GT_Utility.formatNumbers(mCapacity * 20L) - + "%%% L/sec" - + EnumChatFormatting.GRAY); - descriptions.add( - EnumChatFormatting.RED + "Heat Limit: %%%" - + GT_Utility.formatNumbers(mHeatResistance) - + "%%% K" - + EnumChatFormatting.GRAY); - if (!mGasProof) { - descriptions.add(EnumChatFormatting.DARK_GREEN + "Cannot handle gas" + EnumChatFormatting.GRAY); - } - if (mPipeAmount != 1) { - descriptions.add(EnumChatFormatting.AQUA + "Pipe Amount: %%%" + mPipeAmount + EnumChatFormatting.GRAY); - } - return descriptions.toArray(new String[0]); - } - - @Override - public float getThickNess() { - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) return 0.0625F; - return mThickNess; - } - - @Override - public boolean isLiquidInput(ForgeDirection side) { - return !isInputDisabledAtSide(side); - } - - @Override - public boolean isLiquidOutput(ForgeDirection side) { - return true; - } - - public boolean isInputDisabledAtSide(ForgeDirection side) { - return (mDisableInput & side.flag) != 0; - } - - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x2) != 0) - return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1); - else return getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); - } - - private AxisAlignedBB getActualCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { - final float tSpace = (1f - mThickNess) / 2; - float tSide0 = tSpace; - float tSide1 = 1f - tSpace; - float tSide2 = tSpace; - float tSide3 = 1f - tSpace; - float tSide4 = tSpace; - float tSide5 = 1f - tSpace; - - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.DOWN) != 0) { - tSide0 = tSide2 = tSide4 = 0; - tSide3 = tSide5 = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.UP) != 0) { - tSide2 = tSide4 = 0; - tSide1 = tSide3 = tSide5 = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.NORTH) != 0) { - tSide0 = tSide2 = tSide4 = 0; - tSide1 = tSide5 = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.SOUTH) != 0) { - tSide0 = tSide4 = 0; - tSide1 = tSide3 = tSide5 = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.WEST) != 0) { - tSide0 = tSide2 = tSide4 = 0; - tSide1 = tSide3 = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.EAST) != 0) { - tSide0 = tSide2 = 0; - tSide1 = tSide3 = tSide5 = 1; - } - - final byte tConn = ((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections; - if ((tConn & ForgeDirection.DOWN.flag) != 0) tSide0 = 0f; - if ((tConn & ForgeDirection.UP.flag) != 0) tSide1 = 1f; - if ((tConn & ForgeDirection.NORTH.flag) != 0) tSide2 = 0f; - if ((tConn & ForgeDirection.SOUTH.flag) != 0) tSide3 = 1f; - if ((tConn & ForgeDirection.WEST.flag) != 0) tSide4 = 0f; - if ((tConn & ForgeDirection.EAST.flag) != 0) tSide5 = 1f; - - return AxisAlignedBB - .getBoundingBox(aX + tSide4, aY + tSide0, aZ + tSide2, aX + tSide5, aY + tSide1, aZ + tSide3); - } - - @Override - public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, - List outputAABB, Entity collider) { - super.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider); - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x2) != 0) { - final AxisAlignedBB aabb = getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); - if (inputAABB.intersectsWith(aabb)) outputAABB.add(aabb); - } - } - - @Override - public FluidStack drain(ForgeDirection side, FluidStack aFluid, boolean doDrain) { - if (aFluid == null) return null; - for (int i = 0; i < mFluids.length; ++i) { - final FluidStack f = mFluids[i]; - if (f == null || !f.isFluidEqual(aFluid)) continue; - return drainFromIndex(aFluid.amount, doDrain, i); - } - return null; - } - - private static EnumMap borderMap(ForgeDirection topSide, ForgeDirection bottomSide, - ForgeDirection leftSide, ForgeDirection rightSide) { - final EnumMap sideMap = new EnumMap<>(Border.class); - sideMap.put(TOP, topSide); - sideMap.put(BOTTOM, bottomSide); - sideMap.put(LEFT, leftSide); - sideMap.put(RIGHT, rightSide); - return sideMap; - } - - protected static ForgeDirection getSideAtBorder(ForgeDirection side, Border border) { - return FACE_BORDER_MAP.get(side) - .get(border); - } - - protected enum Border { - - TOP(), - BOTTOM(), - LEFT(), - RIGHT(); - - public final int mask; - - Border() { - mask = 1 << this.ordinal(); - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java deleted file mode 100644 index 7cb2b3a9bd..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java +++ /dev/null @@ -1,119 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Dyes; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaPipeEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_LanguageManager; - -public class GT_MetaPipeEntity_Frame extends MetaPipeEntity { - - private static final String localizedDescFormat = GT_LanguageManager - .addStringLocalization("gt.blockmachines.gt_frame.desc.format", "Just something you can put covers on."); - public final Materials mMaterial; - - public GT_MetaPipeEntity_Frame(int aID, String aName, String aNameRegional, Materials aMaterial) { - super(aID, aName, aNameRegional, 0); - mMaterial = aMaterial; - // Hide TileEntity frame in NEI, since we have the block version now that should always be used - codechicken.nei.api.API.hideItem(this.getStackForm(1)); - } - - public GT_MetaPipeEntity_Frame(String aName, Materials aMaterial) { - super(aName, 0); - mMaterial = aMaterial; - } - - @Override - public byte getTileEntityBaseType() { - return (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaPipeEntity_Frame(mName, mMaterial); - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, int connections, - int colorIndex, boolean active, boolean redstoneLevel) { - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.frameGt.mTextureIndex], - Dyes.getModulation(colorIndex, mMaterial.mRGBa)) }; - } - - @Override - public String[] getDescription() { - return localizedDescFormat.split("\\R"); - } - - @Override - public final boolean isSimpleMachine() { - return true; - } - - @Override - public final boolean isFacingValid(ForgeDirection facing) { - return false; - } - - @Override - public final boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public final boolean renderInside(ForgeDirection side) { - return true; - } - - @Override - public final float getThickNess() { - return 1.0F; - } - - @Override - public final void saveNBTData(NBTTagCompound aNBT) { - /* Do nothing */ - } - - @Override - public final void loadNBTData(NBTTagCompound aNBT) { - /* Do nothing */ - } - - @Override - public final boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public final boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public int connect(ForgeDirection side) { - return 0; - } - - @Override - public void disconnect(ForgeDirection side) { - /* Do nothing */ - } - - @Override - public boolean isMachineBlockUpdateRecursive() { - return true; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java deleted file mode 100644 index 660230660e..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item.java +++ /dev/null @@ -1,530 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES; -import static gregtech.api.enums.Textures.BlockIcons.PIPE_RESTRICTOR; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.ISidedInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.tileentity.TileEntityDispenser; -import net.minecraft.tileentity.TileEntityHopper; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.GT_Mod; -import gregtech.api.enums.Dyes; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.metatileentity.IMetaTileEntityItemPipe; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.BaseMetaPipeEntity; -import gregtech.api.metatileentity.MetaPipeEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.ISerializableObject; -import gregtech.common.GT_Client; -import gregtech.common.covers.CoverInfo; - -public class GT_MetaPipeEntity_Item extends MetaPipeEntity implements IMetaTileEntityItemPipe { - - public final float mThickNess; - public final Materials mMaterial; - public final int mStepSize; - public final int mTickTime; - public int mTransferredItems = 0; - public long mCurrentTransferStartTick = 0; - public ForgeDirection mLastReceivedFrom = ForgeDirection.UNKNOWN, oLastReceivedFrom = ForgeDirection.UNKNOWN; - public boolean mIsRestrictive = false; - private int[] cacheSides; - - public GT_MetaPipeEntity_Item(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, - int aInvSlotCount, int aStepSize, boolean aIsRestrictive, int aTickTime) { - super(aID, aName, aNameRegional, aInvSlotCount, false); - mIsRestrictive = aIsRestrictive; - mThickNess = aThickNess; - mMaterial = aMaterial; - mStepSize = aStepSize; - mTickTime = aTickTime; - addInfo(aID); - } - - public GT_MetaPipeEntity_Item(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, - int aInvSlotCount, int aStepSize, boolean aIsRestrictive) { - this(aID, aName, aNameRegional, aThickNess, aMaterial, aInvSlotCount, aStepSize, aIsRestrictive, 20); - } - - public GT_MetaPipeEntity_Item(String aName, float aThickNess, Materials aMaterial, int aInvSlotCount, int aStepSize, - boolean aIsRestrictive, int aTickTime) { - super(aName, aInvSlotCount); - mIsRestrictive = aIsRestrictive; - mThickNess = aThickNess; - mMaterial = aMaterial; - mStepSize = aStepSize; - mTickTime = aTickTime; - } - - @Override - public byte getTileEntityBaseType() { - return (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaPipeEntity_Item( - mName, - mThickNess, - mMaterial, - mInventory.length, - mStepSize, - mIsRestrictive, - mTickTime); - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, int aConnections, - int aColorIndex, boolean aConnected, boolean redstoneLevel) { - if (mIsRestrictive) { - if (aConnected) { - float tThickNess = getThickNess(); - if (tThickNess < 0.124F) return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - if (tThickNess < 0.374F) // 0.375 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeTiny.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - if (tThickNess < 0.499F) // 0.500 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeSmall.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - if (tThickNess < 0.749F) // 0.750 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeMedium.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - if (tThickNess < 0.874F) // 0.825 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeLarge.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeHuge.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - } - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; - } - if (aConnected) { - float tThickNess = getThickNess(); - if (tThickNess < 0.124F) return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - if (tThickNess < 0.374F) // 0.375 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeTiny.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - if (tThickNess < 0.499F) // 0.500 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeSmall.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - if (tThickNess < 0.749F) // 0.750 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeMedium.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - if (tThickNess < 0.874F) // 0.825 - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeLarge.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipeHuge.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - } - return new ITexture[] { TextureFactory.of( - mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], - Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return false; - } - - @Override - public boolean isValidSlot(int ignoredSlotIndex) { - return true; - } - - @Override - public final boolean renderInside(ForgeDirection side) { - return false; - } - - @Override - public int getProgresstime() { - return getPipeContent() * 64; - } - - @Override - public int maxProgresstime() { - return getMaxPipeCapacity() * 64; - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - aNBT.setByte("mLastReceivedFrom", (byte) mLastReceivedFrom.ordinal()); - if (GT_Mod.gregtechproxy.gt6Pipe) aNBT.setByte("mConnections", mConnections); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - mLastReceivedFrom = ForgeDirection.getOrientation(aNBT.getByte("mLastReceivedFrom")); - if (GT_Mod.gregtechproxy.gt6Pipe) { - mConnections = aNBT.getByte("mConnections"); - } - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isServerSide() && (aTick - mCurrentTransferStartTick) % 10 == 0) { - if ((aTick - mCurrentTransferStartTick) % mTickTime == 0) { - mTransferredItems = 0; - mCurrentTransferStartTick = 0; - } - - if (!GT_Mod.gregtechproxy.gt6Pipe || mCheckConnections) checkConnections(); - - if (oLastReceivedFrom == mLastReceivedFrom) { - doTickProfilingInThisTick = false; - - final ArrayList tPipeList = new ArrayList<>(); - - for (boolean temp = true; temp && !isInventoryEmpty() && pipeCapacityCheck();) { - temp = false; - tPipeList.clear(); - for (IMetaTileEntityItemPipe tTileEntity : GT_Utility - .sortMapByValuesAcending( - IMetaTileEntityItemPipe.Util.scanPipes(this, new HashMap<>(), 0, false, false)) - .keySet()) { - if (temp) break; - tPipeList.add(tTileEntity); - while (!temp && !isInventoryEmpty() && tTileEntity.sendItemStack(aBaseMetaTileEntity)) - for (IMetaTileEntityItemPipe tPipe : tPipeList) - if (!tPipe.incrementTransferCounter(1)) temp = true; - } - } - } - - if (isInventoryEmpty()) mLastReceivedFrom = ForgeDirection.UNKNOWN; - oLastReceivedFrom = mLastReceivedFrom; - } - } - - @Override - public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, - float aX, float aY, float aZ) { - if (GT_Mod.gregtechproxy.gt6Pipe) { - final ForgeDirection tSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); - if (isConnectedAtSide(tSide)) { - disconnect(tSide); - GT_Utility.sendChatToPlayer(entityPlayer, GT_Utility.trans("215", "Disconnected")); - } else { - if (connect(tSide) > 0) GT_Utility.sendChatToPlayer(entityPlayer, GT_Utility.trans("214", "Connected")); - } - return true; - } - return false; - } - - @Override - public boolean letsIn(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return coverBehavior.letsItemsIn(side, aCoverID, aCoverVariable, -1, aTileEntity); - } - - @Override - public boolean letsOut(GT_CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return coverBehavior.letsItemsOut(side, aCoverID, aCoverVariable, -1, aTileEntity); - } - - @Override - public boolean letsIn(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return coverBehavior.letsItemsIn(side, aCoverID, aCoverVariable, -1, aTileEntity); - } - - @Override - public boolean letsOut(GT_CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return coverBehavior.letsItemsOut(side, aCoverID, aCoverVariable, -1, aTileEntity); - } - - @Override - public boolean letsIn(CoverInfo coverInfo) { - return coverInfo.letsItemsOut(-1); - } - - @Override - public boolean letsOut(CoverInfo coverInfo) { - return coverInfo.letsItemsOut(-1); - } - - @Override - public boolean canConnect(ForgeDirection side, TileEntity tileEntity) { - if (tileEntity == null) return false; - - final ForgeDirection oppositeSide = side.getOpposite(); - boolean connectable = GT_Utility.isConnectableNonInventoryPipe(tileEntity, oppositeSide); - - final IGregTechTileEntity gTileEntity = (tileEntity instanceof IGregTechTileEntity) - ? (IGregTechTileEntity) tileEntity - : null; - if (gTileEntity != null) { - if (gTileEntity.getMetaTileEntity() == null) return false; - if (gTileEntity.getMetaTileEntity() - .connectsToItemPipe(oppositeSide)) return true; - connectable = true; - } - - if (tileEntity instanceof IInventory) { - if (((IInventory) tileEntity).getSizeInventory() <= 0) return false; - connectable = true; - } - if (tileEntity instanceof ISidedInventory) { - final int[] tSlots = ((ISidedInventory) tileEntity).getAccessibleSlotsFromSide(oppositeSide.ordinal()); - if (tSlots == null || tSlots.length == 0) return false; - connectable = true; - } - - return connectable; - } - - @Override - public boolean getGT6StyleConnection() { - // Yes if GT6 pipes are enabled - return GT_Mod.gregtechproxy.gt6Pipe; - } - - @Override - public boolean incrementTransferCounter(int aIncrement) { - if (mTransferredItems == 0) mCurrentTransferStartTick = getBaseMetaTileEntity().getTimer(); - mTransferredItems += aIncrement; - return pipeCapacityCheck(); - } - - @Override - public boolean sendItemStack(Object aSender) { - if (pipeCapacityCheck()) { - final byte tOffset = (byte) getBaseMetaTileEntity().getRandomNumber(6); - for (final byte i : ALL_VALID_SIDES) { - final ForgeDirection tSide = ForgeDirection.getOrientation((i + tOffset) % 6); - if (isConnectedAtSide(tSide) - && (isInventoryEmpty() || (tSide != mLastReceivedFrom || aSender != getBaseMetaTileEntity()))) { - if (insertItemStackIntoTileEntity(aSender, tSide)) return true; - } - } - } - return false; - } - - @Override - public boolean insertItemStackIntoTileEntity(Object aSender, ForgeDirection side) { - if (getBaseMetaTileEntity().getCoverInfoAtSide(side) - .letsItemsOut(-1)) { - final TileEntity tInventory = getBaseMetaTileEntity().getTileEntityAtSide(side); - if (tInventory != null && !(tInventory instanceof BaseMetaPipeEntity)) { - if ((!(tInventory instanceof TileEntityHopper) && !(tInventory instanceof TileEntityDispenser)) - || getBaseMetaTileEntity().getMetaIDAtSide(side) != side.getOpposite() - .ordinal()) { - return GT_Utility.moveMultipleItemStacks( - aSender, - tInventory, - ForgeDirection.UNKNOWN, - side.getOpposite(), - null, - false, - (byte) 64, - (byte) 1, - (byte) 64, - (byte) 1, - 1) > 0; - } - } - } - return false; - } - - @Override - public boolean pipeCapacityCheck() { - return mTransferredItems <= 0 || getPipeContent() < getMaxPipeCapacity(); - } - - private int getPipeContent() { - return mTransferredItems; - } - - private int getMaxPipeCapacity() { - return Math.max(1, getPipeCapacity()); - } - - /** - * Amount of ItemStacks this Pipe can conduct per Second. - */ - public int getPipeCapacity() { - return mInventory.length; - } - - @Override - public int getStepSize() { - return mStepSize; - } - - @Override - public boolean canInsertItem(int aIndex, ItemStack aStack, int ordinalSide) { - return isConnectedAtSide(ForgeDirection.getOrientation(ordinalSide)) - && super.canInsertItem(aIndex, aStack, ordinalSide); - } - - @Override - public boolean canExtractItem(int aIndex, ItemStack aStack, int ordinalSide) { - return isConnectedAtSide(ForgeDirection.getOrientation(ordinalSide)); - } - - @Override - public int[] getAccessibleSlotsFromSide(int ordinalSide) { - final IGregTechTileEntity tTileEntity = getBaseMetaTileEntity(); - final CoverInfo coverInfo = tTileEntity.getCoverInfoAtSide(ForgeDirection.getOrientation(ordinalSide)); - final boolean tAllow = coverInfo.letsItemsIn(-2) || coverInfo.letsItemsOut(-2); - if (tAllow) { - if (cacheSides == null) cacheSides = super.getAccessibleSlotsFromSide(ordinalSide); - return cacheSides; - } else { - return GT_Values.emptyIntArray; - } - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return isConnectedAtSide(side); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (!isConnectedAtSide(side)) return false; - if (isInventoryEmpty()) mLastReceivedFrom = side; - return mLastReceivedFrom == side && mInventory[aIndex] == null; - } - - @Override - public String[] getDescription() { - if (mTickTime == 20) return new String[] { "Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/sec", - "Routing Value: %%%" + GT_Utility.formatNumbers(mStepSize) }; - else if (mTickTime % 20 == 0) return new String[] { - "Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + (mTickTime / 20) + "%%% sec", - "Routing Value: %%%" + GT_Utility.formatNumbers(mStepSize) }; - else return new String[] { - "Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + mTickTime + "%%% ticks", - "Routing Value: %%%" + GT_Utility.formatNumbers(mStepSize) }; - } - - private boolean isInventoryEmpty() { - for (ItemStack tStack : mInventory) if (tStack != null) return false; - return true; - } - - @Override - public float getThickNess() { - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) return 0.0625F; - return mThickNess; - } - - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x2) != 0) - return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1); - else return getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); - } - - private AxisAlignedBB getActualCollisionBoundingBoxFromPool(World ignoredAWorld, int aX, int aY, int aZ) { - final float tSpace = (1f - mThickNess) / 2; - float spaceDown = tSpace; - float spaceUp = 1f - tSpace; - float spaceNorth = tSpace; - float spaceSouth = 1f - tSpace; - float spaceWest = tSpace; - float spaceEast = 1f - tSpace; - - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.DOWN) != 0) { - spaceDown = spaceNorth = spaceWest = 0; - spaceSouth = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.UP) != 0) { - spaceNorth = spaceWest = 0; - spaceUp = spaceSouth = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.NORTH) != 0) { - spaceDown = spaceNorth = spaceWest = 0; - spaceUp = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.SOUTH) != 0) { - spaceDown = spaceWest = 0; - spaceUp = spaceSouth = spaceEast = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.WEST) != 0) { - spaceDown = spaceNorth = spaceWest = 0; - spaceUp = spaceSouth = 1; - } - if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.EAST) != 0) { - spaceDown = spaceNorth = 0; - spaceUp = spaceSouth = spaceEast = 1; - } - - final byte tConn = ((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections; - if ((tConn & ForgeDirection.DOWN.flag) != 0) spaceDown = 0f; - if ((tConn & ForgeDirection.UP.flag) != 0) spaceUp = 1f; - if ((tConn & ForgeDirection.NORTH.flag) != 0) spaceNorth = 0f; - if ((tConn & ForgeDirection.SOUTH.flag) != 0) spaceSouth = 1f; - if ((tConn & ForgeDirection.WEST.flag) != 0) spaceWest = 0f; - if ((tConn & ForgeDirection.EAST.flag) != 0) spaceEast = 1f; - - return AxisAlignedBB.getBoundingBox( - aX + spaceWest, - aY + spaceDown, - aZ + spaceNorth, - aX + spaceEast, - aY + spaceUp, - aZ + spaceSouth); - } - - @Override - public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, - List outputAABB, Entity collider) { - super.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider); - if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x2) != 0) { - final AxisAlignedBB aabb = getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); - if (inputAABB.intersectsWith(aabb)) outputAABB.add(aabb); - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicBatteryBuffer.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicBatteryBuffer.java deleted file mode 100644 index cff63caeb5..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicBatteryBuffer.java +++ /dev/null @@ -1,436 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; - -import java.util.List; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; -import com.gtnewhorizons.modularui.common.widget.SlotGroup; - -import gregtech.api.enums.Textures; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.items.GT_MetaBase_Item; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; -import ic2.api.item.IElectricItem; -import mcp.mobius.waila.api.IWailaConfigHandler; -import mcp.mobius.waila.api.IWailaDataAccessor; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple - * Machine - */ -public class GT_MetaTileEntity_BasicBatteryBuffer extends GT_MetaTileEntity_TieredMachineBlock - implements IAddUIWidgets { - - public boolean mCharge = false, mDecharge = false; - public int mBatteryCount = 0, mChargeableCount = 0; - private long count = 0; - private long mStored = 0; - private long mMax = 0; - - public GT_MetaTileEntity_BasicBatteryBuffer(int aID, String aName, String aNameRegional, int aTier, - String aDescription, int aSlotCount) { - super(aID, aName, aNameRegional, aTier, aSlotCount, aDescription); - } - - public GT_MetaTileEntity_BasicBatteryBuffer(String aName, int aTier, String aDescription, ITexture[][][] aTextures, - int aSlotCount) { - super(aName, aTier, aSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicBatteryBuffer(String aName, int aTier, String[] aDescription, - ITexture[][][] aTextures, int aSlotCount) { - super(aName, aTier, aSlotCount, aDescription, aTextures); - } - - @Override - public String[] getDescription() { - String[] desc = new String[mDescriptionArray.length + 1]; - System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); - desc[mDescriptionArray.length] = mInventory.length + " Slots"; - return desc; - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[2][17][]; - for (byte i = -1; i < 16; i++) { - rTextures[0][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; - rTextures[1][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - mInventory.length == 16 ? Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier] - : mInventory.length > 4 ? Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] - : Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - } - return rTextures; - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, - int colorIndex, boolean aActive, boolean redstoneLevel) { - return mTextures[side == aFacing ? 1 : 0][colorIndex + 1]; - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_BasicBatteryBuffer(mName, mTier, mDescriptionArray, mTextures, mInventory.length); - } - - @Override - public boolean isSimpleMachine() { - return false; - } - - @Override - public boolean isElectric() { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isEnetInput() { - return true; - } - - @Override - public boolean isEnetOutput() { - return true; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return side != getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean isTeleporterCompatible() { - return false; - } - - @Override - public long getMinimumStoredEU() { - return V[mTier] * 16L * mInventory.length; - } - - @Override - public long maxEUStore() { - return V[mTier] * 64L * mInventory.length; - } - - @Override - public long maxEUInput() { - return V[mTier]; - } - - @Override - public long maxEUOutput() { - return V[mTier]; - } - - @Override - public long maxAmperesIn() { - return mChargeableCount * 2L; - } - - @Override - public long maxAmperesOut() { - return mBatteryCount; - } - - @Override - public int rechargerSlotStartIndex() { - return 0; - } - - @Override - public int dechargerSlotStartIndex() { - return 0; - } - - @Override - public int rechargerSlotCount() { - return mCharge ? mInventory.length : 0; - } - - @Override - public int dechargerSlotCount() { - return mDecharge ? mInventory.length : 0; - } - - @Override - public int getProgresstime() { - return (int) getBaseMetaTileEntity().getUniversalEnergyStored(); - } - - @Override - public int maxProgresstime() { - return (int) getBaseMetaTileEntity().getUniversalEnergyCapacity(); - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - // - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - // - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide()) { - mCharge = aBaseMetaTileEntity.getStoredEU() / 2 > aBaseMetaTileEntity.getEUCapacity() / 3; - mDecharge = aBaseMetaTileEntity.getStoredEU() < aBaseMetaTileEntity.getEUCapacity() / 3; - mBatteryCount = 0; - mChargeableCount = 0; - for (ItemStack tStack : mInventory) if (GT_ModHandler.isElectricItem(tStack, mTier)) { - if (GT_ModHandler.isChargerItem(tStack)) mBatteryCount++; - mChargeableCount++; - } - } - count++; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (GT_ModHandler.isElectricItem(aStack) && aStack.getUnlocalizedName() - .startsWith("gt.metaitem.01.")) { - String name = aStack.getUnlocalizedName(); - if (name.equals("gt.metaitem.01.32510") || name.equals("gt.metaitem.01.32511") - || name.equals("gt.metaitem.01.32520") - || name.equals("gt.metaitem.01.32521") - || name.equals("gt.metaitem.01.32530") - || name.equals("gt.metaitem.01.32531")) { - return ic2.api.item.ElectricItem.manager.getCharge(aStack) == 0; - } - } - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (!GT_Utility.isStackValid(aStack)) { - return false; - } - return mInventory[aIndex] == null && GT_ModHandler.isElectricItem(aStack, this.mTier); - } - - @Override - public int getInventoryStackLimit() { - return 1; - } - - public long[] getStoredEnergy() { - boolean scaleOverflow = false; - boolean storedOverflow = false; - long tScale = getBaseMetaTileEntity().getEUCapacity(); - long tStored = getBaseMetaTileEntity().getStoredEU(); - long tStep = 0; - if (mInventory != null) { - for (ItemStack aStack : mInventory) { - if (GT_ModHandler.isElectricItem(aStack)) { - - if (aStack.getItem() instanceof GT_MetaBase_Item) { - Long[] stats = ((GT_MetaBase_Item) aStack.getItem()).getElectricStats(aStack); - if (stats != null) { - if (stats[0] > Long.MAX_VALUE / 2) { - scaleOverflow = true; - } - tScale = tScale + stats[0]; - tStep = ((GT_MetaBase_Item) aStack.getItem()).getRealCharge(aStack); - if (tStep > Long.MAX_VALUE / 2) { - storedOverflow = true; - } - tStored = tStored + tStep; - } - } else if (aStack.getItem() instanceof IElectricItem) { - tStored = tStored + (long) ic2.api.item.ElectricItem.manager.getCharge(aStack); - tScale = tScale + (long) ((IElectricItem) aStack.getItem()).getMaxCharge(aStack); - } - } - } - } - if (scaleOverflow) { - tScale = Long.MAX_VALUE; - } - if (storedOverflow) { - tStored = Long.MAX_VALUE; - } - return new long[] { tStored, tScale }; - } - - @Override - public String[] getInfoData() { - updateStorageInfo(); - - return new String[] { EnumChatFormatting.BLUE + getLocalName() + EnumChatFormatting.RESET, "Stored Items:", - EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mStored) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mMax) - + EnumChatFormatting.RESET - + " EU", - "Average input:", GT_Utility.formatNumbers(getBaseMetaTileEntity().getAverageElectricInput()) + " EU/t", - "Average output:", GT_Utility.formatNumbers(getBaseMetaTileEntity().getAverageElectricOutput()) + " EU/t" }; - } - - private void updateStorageInfo() { - if (mMax == 0 || (count > 20)) { - long[] tmp = getStoredEnergy(); - mStored = tmp[0]; - mMax = tmp[1]; - count = 0; - } - } - - @Override - public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - NBTTagCompound tag = accessor.getNBTData(); - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.stored", - GT_Utility.formatNumbers(tag.getLong("mStored")), - GT_Utility.formatNumbers(tag.getLong("mMax")))); - long avgIn = tag.getLong("AvgIn"); - long avgOut = tag.getLong("AvgOut"); - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.avg_in_with_amperage", - GT_Utility.formatNumbers(avgIn), - GT_Utility.getAmperageForTier(avgIn, (byte) getInputTier()), - GT_Utility.getColoredTierNameFromTier((byte) getInputTier()))); - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.avg_out_with_amperage", - GT_Utility.formatNumbers(avgOut), - GT_Utility.getAmperageForTier(avgOut, (byte) getOutputTier()), - GT_Utility.getColoredTierNameFromTier((byte) getOutputTier()))); - super.getWailaBody(itemStack, currenttip, accessor, config); - } - - @Override - public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, - int z) { - updateStorageInfo(); - super.getWailaNBTData(player, tile, tag, world, x, y, z); - tag.setLong("mStored", mStored); - tag.setLong("mMax", mMax); - tag.setLong("AvgIn", getBaseMetaTileEntity().getAverageElectricInput()); - tag.setLong("AvgOut", getBaseMetaTileEntity().getAverageElectricOutput()); - } - - @Override - public boolean isGivingInformation() { - return true; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - switch (mInventory.length) { - case 4 -> builder.widget( - SlotGroup.ofItemHandler(inventoryHandler, 2) - .startFromSlot(0) - .endAtSlot(3) - .slotCreator(index -> new BaseSlot(inventoryHandler, index) { - - @Override - public int getSlotStackLimit() { - return 1; - } - }) - .background(getGUITextureSet().getItemSlot()) - .build() - .setPos(70, 25)); - case 9 -> builder.widget( - SlotGroup.ofItemHandler(inventoryHandler, 3) - .startFromSlot(0) - .endAtSlot(8) - .slotCreator(index -> new BaseSlot(inventoryHandler, index) { - - @Override - public int getSlotStackLimit() { - return 1; - } - }) - .background(getGUITextureSet().getItemSlot()) - .build() - .setPos(61, 16)); - case 16 -> builder.widget( - SlotGroup.ofItemHandler(inventoryHandler, 4) - .startFromSlot(0) - .endAtSlot(15) - .slotCreator(index -> new BaseSlot(inventoryHandler, index) { - - @Override - public int getSlotStackLimit() { - return 1; - } - }) - .background(getGUITextureSet().getItemSlot()) - .build() - .setPos(52, 7)); - default -> builder.widget( - SlotGroup.ofItemHandler(inventoryHandler, 1) - .startFromSlot(0) - .endAtSlot(0) - .slotCreator(index -> new BaseSlot(inventoryHandler, index) { - - @Override - public int getSlotStackLimit() { - return 1; - } - }) - .background(getGUITextureSet().getItemSlot()) - .build() - .setPos(79, 34)); - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java deleted file mode 100644 index 7a968afc4b..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicGenerator.java +++ /dev/null @@ -1,339 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidContainerItem; -import net.minecraftforge.fluids.IFluidHandler; - -import gregtech.api.enums.ItemList; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.Textures; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.interfaces.tileentity.RecipeMapWorkable; -import gregtech.api.objects.ItemData; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.recipe.maps.FuelBackend; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; -import gregtech.common.GT_Pollution; - -public abstract class GT_MetaTileEntity_BasicGenerator extends GT_MetaTileEntity_BasicTank - implements RecipeMapWorkable { - - public GT_MetaTileEntity_BasicGenerator(int aID, String aName, String aNameRegional, int aTier, String aDescription, - ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, 3, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicGenerator(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, 3, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicGenerator(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 3, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicGenerator(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 3, aDescription, aTextures); - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[10][17][]; - for (byte i = -1; i < 16; i++) { - rTextures[0][i + 1] = getFront(i); - rTextures[1][i + 1] = getBack(i); - rTextures[2][i + 1] = getBottom(i); - rTextures[3][i + 1] = getTop(i); - rTextures[4][i + 1] = getSides(i); - rTextures[5][i + 1] = getFrontActive(i); - rTextures[6][i + 1] = getBackActive(i); - rTextures[7][i + 1] = getBottomActive(i); - rTextures[8][i + 1] = getTopActive(i); - rTextures[9][i + 1] = getSidesActive(i); - } - return rTextures; - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, - ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { - return mTextures[(active ? 5 : 0) + (side == facingDirection ? 0 - : side == facingDirection.getOpposite() ? 1 - : side == ForgeDirection.DOWN ? 2 : side == ForgeDirection.UP ? 3 : 4)][colorIndex + 1]; - } - - @Override - public String[] getDescription() { - String[] desc = new String[mDescriptionArray.length + 1]; - System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); - desc[mDescriptionArray.length] = "Fuel Efficiency: " + getEfficiency() + "%"; - return desc; - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - public ITexture[] getFront(byte aColor) { - return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getBack(byte aColor) { - return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getBottom(byte aColor) { - return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getTop(byte aColor) { - return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getSides(byte aColor) { - return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getFrontActive(byte aColor) { - return getFront(aColor); - } - - public ITexture[] getBackActive(byte aColor) { - return getBack(aColor); - } - - public ITexture[] getBottomActive(byte aColor) { - return getBottom(aColor); - } - - public ITexture[] getTopActive(byte aColor) { - return getTop(aColor); - } - - public ITexture[] getSidesActive(byte aColor) { - return getSides(aColor); - } - - @Override - public boolean isFacingValid(ForgeDirection side) { - return true; - } - - @Override - public boolean isSimpleMachine() { - return false; - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex < 2; - } - - @Override - public boolean isEnetOutput() { - return true; - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public long maxEUOutput() { - return getBaseMetaTileEntity().isAllowedToWork() ? V[mTier] : 0L; - } - - @Override - public long maxEUStore() { - return Math.max(getEUVar(), V[mTier] * 80L + getMinimumStoredEU()); - } - - @Override - public boolean doesFillContainers() { - return getBaseMetaTileEntity().isAllowedToWork(); - // return false; - } - - @Override - public boolean doesEmptyContainers() { - return getBaseMetaTileEntity().isAllowedToWork(); - } - - @Override - public boolean canTankBeFilled() { - return getBaseMetaTileEntity().isAllowedToWork(); - } - - @Override - public boolean canTankBeEmptied() { - return getBaseMetaTileEntity().isAllowedToWork(); - } - - @Override - public boolean displaysItemStack() { - return true; - } - - @Override - public boolean displaysStackSize() { - return false; - } - - @Override - public boolean isFluidInputAllowed(FluidStack aFluid) { - return getFuelValue(aFluid) > 0; - } - - @Override - public boolean isLiquidOutput(ForgeDirection side) { - // return super.isLiquidOutput(aSide); - return false; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isAllowedToWork() && aTick % 10 == 0) { - if (mFluid != null) { - long tFuelValue = getFuelValue(mFluid), tConsumed = consumedFluidPerOperation(mFluid); - if (tFuelValue > 0 && tConsumed > 0 && mFluid.amount >= tConsumed) { - long tFluidAmountToUse = Math.min( - mFluid.amount / tConsumed, - (maxEUStore() - aBaseMetaTileEntity.getUniversalEnergyStored()) / tFuelValue); - if (tFluidAmountToUse > 0 - && aBaseMetaTileEntity.increaseStoredEnergyUnits(tFluidAmountToUse * tFuelValue, true)) { - // divided by two because this is called every 10 ticks, not 20 - GT_Pollution.addPollution(getBaseMetaTileEntity(), getPollution() / 2); - mFluid.amount -= tFluidAmountToUse * tConsumed; - } - } - } - - if (mInventory[getInputSlot()] != null - && aBaseMetaTileEntity.getUniversalEnergyStored() < (maxEUOutput() * 20 + getMinimumStoredEU()) - && ((GT_Utility.getFluidForFilledItem(mInventory[getInputSlot()], true) != null) - || solidFuelOverride(mInventory[getInputSlot()]))) { - long tFuelValue = getFuelValue(mInventory[getInputSlot()]); - if (tFuelValue <= 0) tFuelValue = getFuelValue(mInventory[getInputSlot()], true); - // System.out.println(" tFuelValue : " + tFuelValue ); - if (tFuelValue > 0) { - ItemStack tEmptyContainer = getEmptyContainer(mInventory[getInputSlot()]); - if (aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), tEmptyContainer)) { - aBaseMetaTileEntity.increaseStoredEnergyUnits(tFuelValue, true); - aBaseMetaTileEntity.decrStackSize(getInputSlot(), 1); - // divided by two because this is called every 10 ticks, not 20 - GT_Pollution.addPollution(getBaseMetaTileEntity(), getPollution() / 2); - } - } - } - } - - if (aBaseMetaTileEntity.isServerSide()) aBaseMetaTileEntity.setActive( - aBaseMetaTileEntity.isAllowedToWork() - && aBaseMetaTileEntity.getUniversalEnergyStored() >= maxEUOutput() + getMinimumStoredEU()); - } - - /** - * @param stack the fuel stack - * @return if the stack is a solid fuel - */ - public boolean solidFuelOverride(ItemStack stack) { - // this could be used for a coal generator for example aswell... - ItemData association = GT_OreDictUnificator.getAssociation(stack); - // if it is a gregtech Item, make sure its not a VOLUMETRIC_FLASK or any type of cell, else do vanilla checks - if (association != null) { - return !OrePrefixes.CELL_TYPES.contains(association.mPrefix) - && !GT_Utility.areStacksEqual(ItemList.VOLUMETRIC_FLASK.get(1L), stack, true); - } else { - return stack != null && // when the stack is null its not a solid - stack.getItem() != null && // when the item in the stack is null its not a solid - !(stack.getItem() instanceof IFluidContainerItem) && // when the item is a fluid container its not a - // solid... - !(stack.getItem() instanceof IFluidHandler) && // when the item is a fluid handler its not a - // solid... - !stack.getItem() - .getUnlocalizedName() - .contains("bucket"); // since we cant really check for - // buckets... - } - } - - public abstract int getPollution(); - - @Override - public abstract RecipeMap getRecipeMap(); - - public abstract int getEfficiency(); - - public int consumedFluidPerOperation(FluidStack aLiquid) { - return 1; - } - - public int getFuelValue(FluidStack aLiquid) { - long value = getFuelValue(aLiquid, true); - return (value > Integer.MAX_VALUE) ? 0 : (int) value; - } - - public long getFuelValue(FluidStack aLiquid, boolean aLong) { - RecipeMap tRecipes = getRecipeMap(); - if (aLiquid == null || !(tRecipes.getBackend() instanceof FuelBackend tFuels)) return 0; - GT_Recipe tFuel = tFuels.findFuel(aLiquid); - if (tFuel == null) return 0; - - return (long) tFuel.mSpecialValue * getEfficiency() * consumedFluidPerOperation(aLiquid) / 100; - } - - public int getFuelValue(ItemStack aStack) { - long value = getFuelValue(aStack, true); - return (value > Integer.MAX_VALUE) ? 0 : (int) value; - } - - public long getFuelValue(ItemStack aStack, boolean aLong) { - if (GT_Utility.isStackInvalid(aStack) || getRecipeMap() == null) return 0; - GT_Recipe tFuel = getRecipeMap().findRecipe(getBaseMetaTileEntity(), false, Long.MAX_VALUE, null, aStack); - if (tFuel == null) return 0; - - long liters = 10L; // 1000mb/100 - return (long) tFuel.mSpecialValue * liters * getEfficiency(); - } - - public ItemStack getEmptyContainer(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack) || getRecipeMap() == null) return null; - GT_Recipe tFuel = getRecipeMap().findRecipe(getBaseMetaTileEntity(), false, Long.MAX_VALUE, null, aStack); - if (tFuel != null) return GT_Utility.copyOrNull(tFuel.getOutput(0)); - return GT_Utility.getContainerItem(aStack, true); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return super.allowPutStack(aBaseMetaTileEntity, aIndex, side, aStack) && (getFuelValue(aStack, true) > 0 - || getFuelValue(GT_Utility.getFluidForFilledItem(aStack, true), true) > 0); - } - - @Override - public int getCapacity() { - return 16000; - } - - @Override - public int getTankPressure() { - return -100; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull.java deleted file mode 100644 index e5766eee39..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull.java +++ /dev/null @@ -1,175 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -public class GT_MetaTileEntity_BasicHull extends GT_MetaTileEntity_BasicTank { - - public GT_MetaTileEntity_BasicHull(int aID, String aName, String aNameRegional, int aTier, String aDescription, - ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, 1, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicHull(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicHull(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicHull(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_BasicHull(mName, mTier, mInventory.length, mDescriptionArray, mTextures); - } - - @Override - public boolean isElectric() { - return true; - } - - @Override - public boolean isEnetInput() { - return true; - } - - @Override - public boolean isEnetOutput() { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return !isOutputFacing(side); - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public long getMinimumStoredEU() { - return 512; - } - - @Override - public long maxEUStore() { - return 512 + V[mTier] * 50; - } - - @Override - public long maxEUInput() { - return V[mTier]; - } - - @Override - public long maxEUOutput() { - return V[mTier]; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return true; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return true; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return true; - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, - int colorIndex, boolean aConnected, boolean redstoneLevel) { - return mTextures[Math.min(2, side.ordinal()) + (side == aFacing ? 3 : 0)][colorIndex + 1]; - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[6][17][]; - for (byte i = -1; i < 16; i++) { - rTextures[0][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; - rTextures[1][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; - rTextures[2][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; - rTextures[3][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - rTextures[4][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - rTextures[5][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - } - return rTextures; - } - - @Override - public boolean doesFillContainers() { - return false; - } - - @Override - public boolean doesEmptyContainers() { - return false; - } - - @Override - public boolean canTankBeFilled() { - return true; - } - - @Override - public boolean canTankBeEmptied() { - return true; - } - - @Override - public boolean displaysItemStack() { - return false; - } - - @Override - public boolean displaysStackSize() { - return false; - } - - @Override - public int getCapacity() { - return (mTier + 1) * 1000; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull_NonElectric.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull_NonElectric.java deleted file mode 100644 index b6584b50ab..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicHull_NonElectric.java +++ /dev/null @@ -1,78 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -public abstract class GT_MetaTileEntity_BasicHull_NonElectric extends GT_MetaTileEntity_BasicHull { - - public GT_MetaTileEntity_BasicHull_NonElectric(int aID, String aName, String aNameRegional, int aTier, - String aDescription) { - super(aID, aName, aNameRegional, aTier, aDescription); - } - - public GT_MetaTileEntity_BasicHull_NonElectric(String aName, int aTier, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, 1, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicHull_NonElectric(String aName, int aTier, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, 1, aDescription, aTextures); - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, - ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { - return mTextures[Math.min(2, sideDirection.ordinal())][colorIndex + 1]; - } - - @Override - public boolean isElectric() { - return false; - } - - @Override - public boolean isEnetInput() { - return false; - } - - @Override - public boolean isEnetOutput() { - return false; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return false; - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return false; - } - - @Override - public long getMinimumStoredEU() { - return 0; - } - - @Override - public long maxEUStore() { - return 0; - } - - @Override - public long maxEUInput() { - return 0; - } - - @Override - public long maxEUOutput() { - return 0; - } - - @Override - public abstract ITexture[][][] getTextureSet(ITexture[] aTextures); -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java deleted file mode 100644 index 377646f85a..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java +++ /dev/null @@ -1,1563 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.GT_Values.debugCleanroom; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_CASINGS; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; -import static gregtech.api.metatileentity.BaseTileEntity.FLUID_TRANSFER_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.ITEM_TRANSFER_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.NEI_TRANSFER_STEAM_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.NEI_TRANSFER_VOLTAGE_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.POWER_SOURCE_KEY; -import static gregtech.api.metatileentity.BaseTileEntity.SPECIAL_SLOT_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.STALLED_STUTTERING_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.STALLED_VENT_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; -import static gregtech.api.metatileentity.BaseTileEntity.UNUSED_SLOT_TOOLTIP; -import static gregtech.api.util.GT_RecipeConstants.EXPLODE; -import static gregtech.api.util.GT_RecipeConstants.ON_FIRE; -import static gregtech.api.util.GT_Utility.moveMultipleItemStacks; -import static net.minecraftforge.common.util.ForgeDirection.DOWN; -import static net.minecraftforge.common.util.ForgeDirection.UNKNOWN; -import static net.minecraftforge.common.util.ForgeDirection.UP; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.annotation.Nonnull; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidHandler; - -import org.apache.commons.lang3.tuple.Pair; - -import com.gtnewhorizons.modularui.api.drawable.IDrawable; -import com.gtnewhorizons.modularui.api.math.Pos2d; -import com.gtnewhorizons.modularui.api.math.Size; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.fluid.FluidStackTank; -import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; -import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; -import com.gtnewhorizons.modularui.common.widget.ProgressBar; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; - -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.SoundResource; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.gui.modularui.SteamTexture; -import gregtech.api.interfaces.ICleanroom; -import gregtech.api.interfaces.IConfigurationCircuitSupport; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddGregtechLogo; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.interfaces.tileentity.IOverclockDescriptionProvider; -import gregtech.api.interfaces.tileentity.RecipeMapWorkable; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.objects.overclockdescriber.EUOverclockDescriber; -import gregtech.api.objects.overclockdescriber.OverclockDescriber; -import gregtech.api.recipe.BasicUIProperties; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_ClientPreference; -import gregtech.api.util.GT_CoverBehaviorBase; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_TooltipDataCache; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.GT_Waila; -import gregtech.common.gui.modularui.UIHelper; -import mcp.mobius.waila.api.IWailaConfigHandler; -import mcp.mobius.waila.api.IWailaDataAccessor; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple - * Machine - */ -public abstract class GT_MetaTileEntity_BasicMachine extends GT_MetaTileEntity_BasicTank implements RecipeMapWorkable, - IConfigurationCircuitSupport, IOverclockDescriptionProvider, IAddGregtechLogo, IAddUIWidgets { - - /** - * return values for checkRecipe() - */ - protected static final int DID_NOT_FIND_RECIPE = 0, FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS = 1, - FOUND_AND_SUCCESSFULLY_USED_RECIPE = 2; - - public static final int OTHER_SLOT_COUNT = 5; - public final ItemStack[] mOutputItems; - public final int mInputSlotCount, mAmperage; - public boolean mAllowInputFromOutputSide = false, mFluidTransfer = false, mItemTransfer = false, - mHasBeenUpdated = false, mStuttering = false, mCharge = false, mDecharge = false; - public boolean mDisableFilter = true; - public boolean mDisableMultiStack = true; - public int mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mOutputBlocked = 0; - public ForgeDirection mMainFacing = ForgeDirection.WEST; - public FluidStack mOutputFluid; - protected final OverclockDescriber overclockDescriber; - - /** - * Contains the Recipe which has been previously used, or null if there was no previous Recipe, which could have - * been buffered - */ - protected GT_Recipe mLastRecipe = null; - - private FluidStack mFluidOut; - protected final FluidStackTank fluidOutputTank = new FluidStackTank( - () -> mFluidOut, - fluidStack -> mFluidOut = fluidStack, - this::getCapacity); - - /** - * Registers machine with single-line description. - * - * @param aOverlays 0 = SideFacingActive 1 = SideFacingInactive 2 = FrontFacingActive 3 = FrontFacingInactive 4 = - * TopFacingActive 5 = TopFacingInactive 6 = BottomFacingActive 7 = BottomFacingInactive ----- Not - * all Array Elements have to be initialised, you can also just use 8 Parameters for the Default - * Pipe Texture Overlays ----- 8 = BottomFacingPipeActive 9 = BottomFacingPipeInactive 10 = - * TopFacingPipeActive 11 = TopFacingPipeInactive 12 = SideFacingPipeActive 13 = - * SideFacingPipeInactive - */ - public GT_MetaTileEntity_BasicMachine(int aID, String aName, String aNameRegional, int aTier, int aAmperage, - String aDescription, int aInputSlotCount, int aOutputSlotCount, ITexture... aOverlays) { - super( - aID, - aName, - aNameRegional, - aTier, - OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, - aDescription, - aOverlays); - mInputSlotCount = Math.max(0, aInputSlotCount); - mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)]; - mAmperage = aAmperage; - overclockDescriber = createOverclockDescriber(); - } - - /** - * Registers machine with multi-line descriptions. - */ - public GT_MetaTileEntity_BasicMachine(int aID, String aName, String aNameRegional, int aTier, int aAmperage, - String[] aDescription, int aInputSlotCount, int aOutputSlotCount, ITexture... aOverlays) { - super( - aID, - aName, - aNameRegional, - aTier, - OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, - aDescription, - aOverlays); - mInputSlotCount = Math.max(0, aInputSlotCount); - mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)]; - mAmperage = aAmperage; - overclockDescriber = createOverclockDescriber(); - } - - /** - * For {@link #newMetaEntity}. - */ - public GT_MetaTileEntity_BasicMachine(String aName, int aTier, int aAmperage, String[] aDescription, - ITexture[][][] aTextures, int aInputSlotCount, int aOutputSlotCount) { - super(aName, aTier, OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, aDescription, aTextures); - mInputSlotCount = Math.max(0, aInputSlotCount); - mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)]; - mAmperage = aAmperage; - overclockDescriber = createOverclockDescriber(); - } - - /** - * To be called by the constructor to initialize this instance's overclock behavior - */ - protected OverclockDescriber createOverclockDescriber() { - return new EUOverclockDescriber(mTier, mAmperage); - } - - protected boolean isValidMainFacing(ForgeDirection side) { - return (side.flag & (UP.flag | DOWN.flag | UNKNOWN.flag)) == 0; // Horizontal - } - - public boolean setMainFacing(ForgeDirection side) { - if (!isValidMainFacing(side)) return false; - mMainFacing = side; - if (getBaseMetaTileEntity().getFrontFacing() == mMainFacing) { - getBaseMetaTileEntity().setFrontFacing(side.getOpposite()); - } - onFacingChange(); - onMachineBlockUpdate(); - return true; - } - - @Override - public void onFacingChange() { - super.onFacingChange(); - // Set up the correct facing (front towards player, output opposite) client-side before the server packet - // arrives - if (mMainFacing == UNKNOWN) { - IGregTechTileEntity te = getBaseMetaTileEntity(); - if (te != null && te.getWorld().isRemote) { - mMainFacing = te.getFrontFacing(); - te.setFrontFacing(te.getBackFacing()); - } - } - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[14][17][]; - aTextures = Arrays.copyOf(aTextures, 14); - - for (int i = 0; i < aTextures.length; i++) if (aTextures[i] != null) for (byte c = -1; c < 16; c++) { - if (rTextures[i][c + 1] == null) - rTextures[i][c + 1] = new ITexture[] { MACHINE_CASINGS[mTier][c + 1], aTextures[i] }; - } - - for (byte c = -1; c < 16; c++) { - if (rTextures[0][c + 1] == null) rTextures[0][c + 1] = getSideFacingActive(c); - if (rTextures[1][c + 1] == null) rTextures[1][c + 1] = getSideFacingInactive(c); - if (rTextures[2][c + 1] == null) rTextures[2][c + 1] = getFrontFacingActive(c); - if (rTextures[3][c + 1] == null) rTextures[3][c + 1] = getFrontFacingInactive(c); - if (rTextures[4][c + 1] == null) rTextures[4][c + 1] = getTopFacingActive(c); - if (rTextures[5][c + 1] == null) rTextures[5][c + 1] = getTopFacingInactive(c); - if (rTextures[6][c + 1] == null) rTextures[6][c + 1] = getBottomFacingActive(c); - if (rTextures[7][c + 1] == null) rTextures[7][c + 1] = getBottomFacingInactive(c); - if (rTextures[8][c + 1] == null) rTextures[8][c + 1] = getBottomFacingPipeActive(c); - if (rTextures[9][c + 1] == null) rTextures[9][c + 1] = getBottomFacingPipeInactive(c); - if (rTextures[10][c + 1] == null) rTextures[10][c + 1] = getTopFacingPipeActive(c); - if (rTextures[11][c + 1] == null) rTextures[11][c + 1] = getTopFacingPipeInactive(c); - if (rTextures[12][c + 1] == null) rTextures[12][c + 1] = getSideFacingPipeActive(c); - if (rTextures[13][c + 1] == null) rTextures[13][c + 1] = getSideFacingPipeInactive(c); - } - return rTextures; - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, - ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { - final int textureIndex; - if ((mMainFacing.flag & (UP.flag | DOWN.flag)) != 0) { // UP or DOWN - if (sideDirection == facingDirection) { - textureIndex = active ? 2 : 3; - } else { - textureIndex = switch (sideDirection) { - case DOWN -> active ? 6 : 7; - case UP -> active ? 4 : 5; - default -> active ? 0 : 1; - }; - } - } else { - if (sideDirection == mMainFacing) { - textureIndex = active ? 2 : 3; - } else { - if (showPipeFacing() && sideDirection == facingDirection) { - textureIndex = switch (sideDirection) { - case DOWN -> active ? 8 : 9; - case UP -> active ? 10 : 11; - default -> active ? 12 : 13; - }; - } else { - textureIndex = switch (sideDirection) { - case DOWN -> active ? 6 : 7; - case UP -> active ? 4 : 5; - default -> active ? 0 : 1; - }; - } - } - } - return mTextures[textureIndex][colorIndex + 1]; - } - - @Override - public boolean isSimpleMachine() { - return false; - } - - @Override - public boolean isOverclockerUpgradable() { - return false; - } - - @Override - public boolean isTransformerUpgradable() { - return false; - } - - @Override - public boolean isElectric() { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex > 0 && super.isValidSlot(aIndex) - && aIndex != getCircuitSlot() - && aIndex != OTHER_SLOT_COUNT + mInputSlotCount + mOutputItems.length; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - // Either mMainFacing or mMainFacing is horizontal - return ((facing.flag | mMainFacing.flag) & ~(UP.flag | DOWN.flag | UNKNOWN.flag)) != 0; - } - - @Override - public boolean isEnetInput() { - return true; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return side != mMainFacing; - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return false; - } - - @Override - public boolean isTeleporterCompatible() { - return false; - } - - @Override - public boolean isLiquidInput(ForgeDirection side) { - return side != mMainFacing && (mAllowInputFromOutputSide || side != getBaseMetaTileEntity().getFrontFacing()); - } - - @Override - public boolean isLiquidOutput(ForgeDirection side) { - return side != mMainFacing; - } - - @Override - public long getMinimumStoredEU() { - return V[mTier] * 16L; - } - - @Override - public long maxEUStore() { - return V[mTier] * 64L; - } - - @Override - public long maxEUInput() { - return V[mTier]; - } - - @Override - public long maxSteamStore() { - return maxEUStore(); - } - - @Override - public long maxAmperesIn() { - return ((long) mEUt * 2L) / V[mTier] + 1L; - } - - @Override - public int getInputSlot() { - return OTHER_SLOT_COUNT; - } - - @Override - public int getOutputSlot() { - return OTHER_SLOT_COUNT + mInputSlotCount; - } - - public int getSpecialSlotIndex() { - return 3; - } - - @Override - public int getStackDisplaySlot() { - return 2; - } - - @Override - public int rechargerSlotStartIndex() { - return 1; - } - - @Override - public int dechargerSlotStartIndex() { - return 1; - } - - @Override - public int rechargerSlotCount() { - return mCharge ? 1 : 0; - } - - @Override - public int dechargerSlotCount() { - return mDecharge ? 1 : 0; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public int getProgresstime() { - return mProgresstime; - } - - @Override - public int maxProgresstime() { - return mMaxProgresstime; - } - - @Override - public int increaseProgress(int aProgress) { - mProgresstime += aProgress; - return mMaxProgresstime - mProgresstime; - } - - @Override - public boolean isFluidInputAllowed(FluidStack aFluid) { - return getFillableStack() != null || (getRecipeMap() != null && getRecipeMap().containsInput(aFluid)); - } - - @Override - public boolean isFluidChangingAllowed() { - return true; - } - - @Override - public boolean doesFillContainers() { - return false; - } - - @Override - public boolean doesEmptyContainers() { - return false; - } - - @Override - public boolean canTankBeFilled() { - return true; - } - - @Override - public boolean canTankBeEmptied() { - return true; - } - - @Override - public boolean displaysItemStack() { - return true; - } - - @Override - public boolean displaysStackSize() { - return true; - } - - @Override - public FluidStack getDrainableStack() { - return mFluidOut; - } - - @Override - public FluidStack setDrainableStack(FluidStack aFluid) { - markDirty(); - mFluidOut = aFluid; - return mFluidOut; - } - - @Override - public boolean isDrainableStackSeparate() { - return true; - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - if (aBaseMetaTileEntity.isClientSide()) return true; - if (!GT_Mod.gregtechproxy.mForceFreeFace) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (aBaseMetaTileEntity.getAirAtSide(side)) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - } - GT_Utility.sendChatToPlayer(aPlayer, "No free Side!"); - return true; - } - - @Override - public void initDefaultModes(NBTTagCompound aNBT) { - mMainFacing = ForgeDirection.UNKNOWN; - if (!getBaseMetaTileEntity().getWorld().isRemote) { - final GT_ClientPreference tPreference = GT_Mod.gregtechproxy - .getClientPreference(getBaseMetaTileEntity().getOwnerUuid()); - if (tPreference != null) { - mDisableFilter = !tPreference.isSingleBlockInitialFilterEnabled(); - mDisableMultiStack = !tPreference.isSingleBlockInitialMultiStackEnabled(); - } - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setBoolean("mFluidTransfer", mFluidTransfer); - aNBT.setBoolean("mItemTransfer", mItemTransfer); - aNBT.setBoolean("mHasBeenUpdated", mHasBeenUpdated); - aNBT.setBoolean("mAllowInputFromOutputSide", mAllowInputFromOutputSide); - aNBT.setBoolean("mDisableFilter", mDisableFilter); - aNBT.setBoolean("mDisableMultiStack", mDisableMultiStack); - aNBT.setInteger("mEUt", mEUt); - aNBT.setInteger("mMainFacing", mMainFacing.ordinal()); - aNBT.setInteger("mProgresstime", mProgresstime); - aNBT.setInteger("mMaxProgresstime", mMaxProgresstime); - if (mOutputFluid != null) aNBT.setTag("mOutputFluid", mOutputFluid.writeToNBT(new NBTTagCompound())); - if (mFluidOut != null) aNBT.setTag("mFluidOut", mFluidOut.writeToNBT(new NBTTagCompound())); - - for (int i = 0; i < mOutputItems.length; i++) - if (mOutputItems[i] != null) GT_Utility.saveItem(aNBT, "mOutputItem" + i, mOutputItems[i]); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - mFluidTransfer = aNBT.getBoolean("mFluidTransfer"); - mItemTransfer = aNBT.getBoolean("mItemTransfer"); - mHasBeenUpdated = aNBT.getBoolean("mHasBeenUpdated"); - mAllowInputFromOutputSide = aNBT.getBoolean("mAllowInputFromOutputSide"); - mDisableFilter = aNBT.getBoolean("mDisableFilter"); - mDisableMultiStack = aNBT.getBoolean("mDisableMultiStack"); - mEUt = aNBT.getInteger("mEUt"); - mMainFacing = ForgeDirection.getOrientation(aNBT.getInteger("mMainFacing")); - mProgresstime = aNBT.getInteger("mProgresstime"); - mMaxProgresstime = aNBT.getInteger("mMaxProgresstime"); - mOutputFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mOutputFluid")); - mFluidOut = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluidOut")); - - for (int i = 0; i < mOutputItems.length; i++) mOutputItems[i] = GT_Utility.loadItem(aNBT, "mOutputItem" + i); - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - - if (aBaseMetaTileEntity.isServerSide()) { - mCharge = aBaseMetaTileEntity.getStoredEU() / 2 > aBaseMetaTileEntity.getEUCapacity() / 3; - mDecharge = aBaseMetaTileEntity.getStoredEU() < aBaseMetaTileEntity.getEUCapacity() / 3; - - doDisplayThings(); - - boolean tSucceeded = false; - - if (mMaxProgresstime > 0 && (mProgresstime >= 0 || aBaseMetaTileEntity.isAllowedToWork())) { - markDirty(); - aBaseMetaTileEntity.setActive(true); - if (mProgresstime < 0 || drainEnergyForProcess(mEUt)) { - if (++mProgresstime >= mMaxProgresstime) { - for (int i = 0; i < mOutputItems.length; i++) - for (int j = 0; j < mOutputItems.length; j++) if (aBaseMetaTileEntity - .addStackToSlot(getOutputSlot() + ((j + i) % mOutputItems.length), mOutputItems[i])) - break; - if (mOutputFluid != null) - if (getDrainableStack() == null) setDrainableStack(mOutputFluid.copy()); - else if (mOutputFluid.isFluidEqual(getDrainableStack())) - getDrainableStack().amount += mOutputFluid.amount; - Arrays.fill(mOutputItems, null); - mOutputFluid = null; - mEUt = 0; - mProgresstime = 0; - mMaxProgresstime = 0; - mStuttering = false; - tSucceeded = true; - endProcess(); - } - if (mProgresstime > 5) mStuttering = false; - } else { - if (!mStuttering) { - stutterProcess(); - if (canHaveInsufficientEnergy()) mProgresstime = -100; - mStuttering = true; - } - } - } else { - aBaseMetaTileEntity.setActive(false); - } - - boolean tRemovedOutputFluid = false; - - if (doesAutoOutputFluids() && getDrainableStack() != null - && aBaseMetaTileEntity.getFrontFacing() != mMainFacing - && (tSucceeded || aTick % 20 == 0)) { - IFluidHandler tTank = aBaseMetaTileEntity.getITankContainerAtSide(aBaseMetaTileEntity.getFrontFacing()); - if (tTank != null) { - FluidStack tDrained = drain(1000, false); - if (tDrained != null) { - final int tFilledAmount = tTank.fill(aBaseMetaTileEntity.getBackFacing(), tDrained, false); - if (tFilledAmount > 0) - tTank.fill(aBaseMetaTileEntity.getBackFacing(), drain(tFilledAmount, true), true); - } - } - if (getDrainableStack() == null) tRemovedOutputFluid = true; - } - - if (doesAutoOutput() && !isOutputEmpty() - && aBaseMetaTileEntity.getFrontFacing() != mMainFacing - && (tSucceeded || mOutputBlocked % 300 == 1 - || aBaseMetaTileEntity.hasInventoryBeenModified() - || aTick % 600 == 0)) { - TileEntity tTileEntity2 = aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getFrontFacing()); - long tStoredEnergy = aBaseMetaTileEntity.getUniversalEnergyStored(); - int tMaxStacks = (int) (tStoredEnergy / 64L); - if (tMaxStacks > mOutputItems.length) tMaxStacks = mOutputItems.length; - - moveMultipleItemStacks( - aBaseMetaTileEntity, - tTileEntity2, - aBaseMetaTileEntity.getFrontFacing(), - aBaseMetaTileEntity.getBackFacing(), - null, - false, - (byte) 64, - (byte) 1, - (byte) 64, - (byte) 1, - tMaxStacks); - } - - if (mOutputBlocked != 0) if (isOutputEmpty()) mOutputBlocked = 0; - else mOutputBlocked++; - - if (allowToCheckRecipe()) { - if (mMaxProgresstime <= 0 && aBaseMetaTileEntity.isAllowedToWork() - && (tRemovedOutputFluid || tSucceeded - || aBaseMetaTileEntity.hasInventoryBeenModified() - || aTick % 600 == 0 - || aBaseMetaTileEntity.hasWorkJustBeenEnabled()) - && hasEnoughEnergyToCheckRecipe()) { - if (checkRecipe() == FOUND_AND_SUCCESSFULLY_USED_RECIPE) { - if (getSpecialSlot() != null && getSpecialSlot().stackSize <= 0) - mInventory[getSpecialSlotIndex()] = null; - for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++) - if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; - for (int i = 0; i < mOutputItems.length; i++) { - mOutputItems[i] = GT_Utility.copyOrNull(mOutputItems[i]); - if (mOutputItems[i] != null && mOutputItems[i].stackSize > 64) - mOutputItems[i].stackSize = 64; - mOutputItems[i] = GT_OreDictUnificator.get(true, mOutputItems[i]); - } - if (mFluid != null && mFluid.amount <= 0) mFluid = null; - mMaxProgresstime = Math.max(1, mMaxProgresstime); - if (GT_Utility.isDebugItem(mInventory[dechargerSlotStartIndex()])) { - mEUt = mMaxProgresstime = 1; - } - startProcess(); - } else { - mMaxProgresstime = 0; - Arrays.fill(mOutputItems, null); - mOutputFluid = null; - } - } - } else { - if (!mStuttering) { - stutterProcess(); - mStuttering = true; - } - } - } - // Only using mNeedsSteamVenting right now and assigning it to 64 to space in the range for more single block - // machine problems. - // Value | Class | Field - // 1 | GT_MetaTileEntity_BasicMachine | mStuttering - // 64 | GT_MetaTileEntity_BasicMachine_Bronze | mNeedsSteamVenting - aBaseMetaTileEntity.setErrorDisplayID((aBaseMetaTileEntity.getErrorDisplayID() & ~127)); // | (mStuttering ? 1 : - // 0)); - } - - protected void doDisplayThings() { - if (!isValidMainFacing(mMainFacing) && isValidMainFacing(getBaseMetaTileEntity().getFrontFacing())) { - mMainFacing = getBaseMetaTileEntity().getFrontFacing(); - } - if (isValidMainFacing(mMainFacing) && !mHasBeenUpdated) { - mHasBeenUpdated = true; - getBaseMetaTileEntity().setFrontFacing(getBaseMetaTileEntity().getBackFacing()); - } - } - - protected boolean hasEnoughEnergyToCheckRecipe() { - return getBaseMetaTileEntity().isUniversalEnergyStored(getMinimumStoredEU() / 2); - } - - protected boolean drainEnergyForProcess(long aEUt) { - return getBaseMetaTileEntity().decreaseStoredEnergyUnits(aEUt, false); - } - - /** - * Calculates overclock based on {@link #overclockDescriber}. - */ - protected void calculateCustomOverclock(GT_Recipe recipe) { - GT_OverclockCalculator calculator = overclockDescriber.createCalculator( - new GT_OverclockCalculator().setRecipeEUt(recipe.mEUt) - .setDuration(recipe.mDuration) - .setOneTickDiscount(true), - recipe); - calculator.calculate(); - mEUt = (int) calculator.getConsumption(); - mMaxProgresstime = calculator.getDuration(); - } - - /** - * Helper method for calculating simple overclock. - */ - protected void calculateOverclockedNess(int eut, int duration) { - GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(eut) - .setEUt(V[mTier] * mAmperage) - .setDuration(duration) - .setOneTickDiscount(true) - .calculate(); - mEUt = (int) calculator.getConsumption(); - mMaxProgresstime = calculator.getDuration(); - } - - protected ItemStack getSpecialSlot() { - return mInventory[getSpecialSlotIndex()]; - } - - protected ItemStack getOutputAt(int aIndex) { - return mInventory[getOutputSlot() + aIndex]; - } - - protected ItemStack[] getAllOutputs() { - ItemStack[] rOutputs = new ItemStack[mOutputItems.length]; - for (int i = 0; i < mOutputItems.length; i++) rOutputs[i] = getOutputAt(i); - return rOutputs; - } - - protected boolean canOutput(GT_Recipe aRecipe) { - return aRecipe != null && (aRecipe.mNeedsEmptyOutput ? isOutputEmpty() && getDrainableStack() == null - : canOutput(aRecipe.getFluidOutput(0)) && canOutput(aRecipe.mOutputs)); - } - - protected boolean canOutput(ItemStack... aOutputs) { - if (aOutputs == null) return true; - ItemStack[] tOutputSlots = getAllOutputs(); - for (int i = 0; i < tOutputSlots.length && i < aOutputs.length; i++) - if (tOutputSlots[i] != null && aOutputs[i] != null - && (!GT_Utility.areStacksEqual(tOutputSlots[i], aOutputs[i], false) - || tOutputSlots[i].stackSize + aOutputs[i].stackSize > tOutputSlots[i].getMaxStackSize())) { - mOutputBlocked++; - return false; - } - return true; - } - - protected boolean canOutput(FluidStack aOutput) { - if (aOutput == null) return true; - FluidStack drainableStack = getDrainableStack(); - if (drainableStack != null && !drainableStack.isFluidEqual(aOutput)) return false; - return (drainableStack != null ? drainableStack.amount : 0) + aOutput.amount <= getCapacity(); - } - - protected ItemStack getInputAt(int aIndex) { - return mInventory[getInputSlot() + aIndex]; - } - - protected ItemStack[] getAllInputs() { - int tRealInputSlotCount = this.mInputSlotCount + (allowSelectCircuit() ? 1 : 0); - ItemStack[] rInputs = new ItemStack[tRealInputSlotCount]; - for (int i = 0; i < mInputSlotCount; i++) rInputs[i] = getInputAt(i); - if (allowSelectCircuit()) rInputs[mInputSlotCount] = getStackInSlot(getCircuitSlot()); - return rInputs; - } - - protected boolean isOutputEmpty() { - boolean rIsEmpty = true; - for (ItemStack tOutputSlotContent : getAllOutputs()) if (tOutputSlotContent != null) { - rIsEmpty = false; - break; - } - return rIsEmpty; - } - - @Override - public void onValueUpdate(byte aValue) { - mMainFacing = ForgeDirection.getOrientation(aValue); - } - - @Override - public byte getUpdateData() { - return (byte) mMainFacing.ordinal(); - } - - @Override - public void doSound(byte aIndex, double aX, double aY, double aZ) { - super.doSound(aIndex, aX, aY, aZ); - if (aIndex == 8) GT_Utility.doSoundAtClient(SoundResource.IC2_MACHINES_INTERRUPT_ONE, 100, 1.0F, aX, aY, aZ); - } - - public boolean doesAutoOutput() { - return mItemTransfer; - } - - public boolean doesAutoOutputFluids() { - return mFluidTransfer; - } - - public boolean allowToCheckRecipe() { - return true; - } - - public boolean showPipeFacing() { - return true; - } - - /** - * Called whenever the Machine successfully started a Process, useful for Sound Effects - */ - public void startProcess() { - // - } - - /** - * Called whenever the Machine successfully finished a Process, useful for Sound Effects - */ - public void endProcess() { - // - } - - /** - * Called whenever the Machine aborted a Process, useful for Sound Effects - */ - public void abortProcess() { - // - } - - /** - * Called whenever the Machine aborted a Process but still works on it, useful for Sound Effects - */ - public void stutterProcess() { - if (useStandardStutterSound()) sendSound((byte) 8); - } - - /** - * If this Machine can have the Insufficient Energy Line Problem - */ - public boolean canHaveInsufficientEnergy() { - return true; - } - - public boolean useStandardStutterSound() { - return true; - } - - @Override - public String[] getInfoData() { - return new String[] { "Progress:", - EnumChatFormatting.GREEN + GT_Utility.formatNumbers((mProgresstime / 20)) - + EnumChatFormatting.RESET - + " s / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mMaxProgresstime / 20) - + EnumChatFormatting.RESET - + " s", - "Stored Energy:", - EnumChatFormatting.GREEN + GT_Utility.formatNumbers(getBaseMetaTileEntity().getStoredEU()) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(getBaseMetaTileEntity().getEUCapacity()) - + EnumChatFormatting.RESET - + " EU", - "Probably uses: " + EnumChatFormatting.RED - + GT_Utility.formatNumbers(mEUt) - + EnumChatFormatting.RESET - + " EU/t at " - + EnumChatFormatting.RED - + GT_Utility.formatNumbers(mEUt == 0 ? 0 : mAmperage) - + EnumChatFormatting.RESET - + " A" }; - } - - @Override - public boolean isGivingInformation() { - return true; - } - - @Override - public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { - if (side == getBaseMetaTileEntity().getFrontFacing() || side == mMainFacing) { - if (aPlayer.isSneaking()) { - mDisableFilter = !mDisableFilter; - GT_Utility.sendChatToPlayer( - aPlayer, - StatCollector.translateToLocal("GT5U.hatch.disableFilter." + mDisableFilter)); - } else { - mAllowInputFromOutputSide = !mAllowInputFromOutputSide; - GT_Utility.sendChatToPlayer( - aPlayer, - mAllowInputFromOutputSide ? GT_Utility.trans("095", "Input from Output Side allowed") - : GT_Utility.trans("096", "Input from Output Side forbidden")); - } - } - } - - @Override - public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, - EntityPlayer entityPlayer, float aX, float aY, float aZ) { - if (!entityPlayer.isSneaking()) return false; - final boolean click = super.onSolderingToolRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); - if (click) return true; - if (wrenchingSide != mMainFacing) return false; - mDisableMultiStack = !mDisableMultiStack; - GT_Utility.sendChatToPlayer( - entityPlayer, - StatCollector.translateToLocal("GT5U.hatch.disableMultiStack." + mDisableMultiStack)); - return true; - } - - @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { - if (side != mMainFacing) return true; - GT_CoverBehaviorBase tBehavior = GregTech_API.getCoverBehaviorNew(aCoverID.toStack()); - return tBehavior.isGUIClickable( - side, - GT_Utility.stackToInt(aCoverID.toStack()), - tBehavior.createDataObject(), - getBaseMetaTileEntity()); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side != mMainFacing && aIndex >= getOutputSlot() && aIndex < getOutputSlot() + mOutputItems.length; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (side == mMainFacing || aIndex < getInputSlot() - || aIndex >= getInputSlot() + mInputSlotCount - || (!mAllowInputFromOutputSide && side == aBaseMetaTileEntity.getFrontFacing())) return false; - for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++) - if (GT_Utility.areStacksEqual(GT_OreDictUnificator.get(aStack), mInventory[i]) && mDisableMultiStack) - return i == aIndex; - return mDisableFilter || allowPutStackValidated(aBaseMetaTileEntity, aIndex, side, aStack); - } - - /** - * Test if given stack can be inserted into specified slot. If mDisableMultiStack is false, before execution of this - * method it is ensured there is no such kind of item inside any input slots already. Otherwise, you don't need to - * check for it anyway. - */ - protected boolean allowPutStackValidated(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return !mDisableMultiStack || mInventory[aIndex] == null; - } - - @Override - public boolean allowSelectCircuit() { - return false; - } - - protected final ItemStack[] appendSelectedCircuit(ItemStack... inputs) { - if (allowSelectCircuit()) { - ItemStack circuit = getStackInSlot(getCircuitSlot()); - if (circuit != null) { - ItemStack[] result = Arrays.copyOf(inputs, inputs.length + 1); - result[inputs.length] = circuit; - return result; - } - } - return inputs; - } - - @Override - public int getCircuitSlot() { - return 4; - } - - @Override - public int getCircuitGUISlot() { - return 3; - } - - @Override - public List getConfigurationCircuits() { - return GregTech_API.getConfigurationCircuitList(mTier); - } - - @Override - public RecipeMap getRecipeMap() { - return null; - } - - /** - * Override this to check the Recipes yourself, super calls to this could be useful if you just want to add a - * special case - *

- * I thought about Enum too, but Enum doesn't add support for people adding other return Systems. - *

- * Funny how Eclipse marks the word Enum as not correctly spelled. - * - * @return see constants above - */ - public int checkRecipe() { - return checkRecipe(false); - } - - public static boolean isValidForLowGravity(GT_Recipe tRecipe, int dimId) { - return // TODO check or get a better solution - DimensionManager.getProvider(dimId) - .getClass() - .getName() - .contains("Orbit") - || DimensionManager.getProvider(dimId) - .getClass() - .getName() - .endsWith("Space") - || DimensionManager.getProvider(dimId) - .getClass() - .getName() - .endsWith("Asteroids") - || DimensionManager.getProvider(dimId) - .getClass() - .getName() - .endsWith("SS") - || DimensionManager.getProvider(dimId) - .getClass() - .getName() - .contains("SpaceStation"); - } - - /** - * - * @param skipOC disables OverclockedNess calculation and check - if you do you must implement your own method... - * @return DID_NOT_FIND_RECIPE = 0, FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS = 1, - * FOUND_AND_SUCCESSFULLY_USED_RECIPE = 2; - */ - public int checkRecipe(boolean skipOC) { - RecipeMap tMap = getRecipeMap(); - if (tMap == null) return DID_NOT_FIND_RECIPE; - GT_Recipe tRecipe = tMap.findRecipeQuery() - .items(getAllInputs()) - .fluids(getFillableStack()) - .specialSlot(getSpecialSlot()) - .voltage(V[mTier]) - .cachedRecipe(mLastRecipe) - .find(); - if (tRecipe == null) { - return DID_NOT_FIND_RECIPE; - } - if (tRecipe.getMetadataOrDefault(EXPLODE, false) && getBaseMetaTileEntity() != null) { - getBaseMetaTileEntity().doExplosion(V[mTier] * 4); - return DID_NOT_FIND_RECIPE; - } - if (tRecipe.getMetadataOrDefault(ON_FIRE, false) && getBaseMetaTileEntity() != null) { - getBaseMetaTileEntity().setOnFire(); - return DID_NOT_FIND_RECIPE; - } - - if (GT_Mod.gregtechproxy.mLowGravProcessing && (tRecipe.mSpecialValue == -100 || tRecipe.mSpecialValue == -300) - && !isValidForLowGravity(tRecipe, getBaseMetaTileEntity().getWorld().provider.dimensionId)) - return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; - if (tRecipe.mCanBeBuffered) mLastRecipe = tRecipe; - if (!canOutput(tRecipe)) { - mOutputBlocked++; - return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; - } - ICleanroom cleanroom = getCleanroom(); - if (tRecipe.mSpecialValue == -200 || tRecipe.mSpecialValue == -300) { - if (cleanroom == null || !cleanroom.isValidCleanroom() || cleanroom.getCleanness() == 0) { - return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; - } - } - if (!tRecipe.isRecipeInputEqual(true, new FluidStack[] { getFillableStack() }, getAllInputs())) - return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; - for (int i = 0; i < mOutputItems.length; i++) - if (getBaseMetaTileEntity().getRandomNumber(10000) < tRecipe.getOutputChance(i)) - mOutputItems[i] = tRecipe.getOutput(i); - if (tRecipe.mSpecialValue == -200 || tRecipe.mSpecialValue == -300) { - assert cleanroom != null; - for (int i = 0; i < mOutputItems.length; i++) if (mOutputItems[i] != null - && getBaseMetaTileEntity().getRandomNumber(10000) > cleanroom.getCleanness()) { - if (debugCleanroom) { - GT_Log.out.println( - "BasicMachine: Voiding output due to cleanness failure. Cleanness = " - + cleanroom.getCleanness()); - } - mOutputItems[i] = null; - } - } - mOutputFluid = tRecipe.getFluidOutput(0); - if (!skipOC) { - calculateCustomOverclock(tRecipe); - // In case recipe is too OP for that machine - if (mMaxProgresstime == Integer.MAX_VALUE - 1 && mEUt == Integer.MAX_VALUE - 1) - return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; - } - return FOUND_AND_SUCCESSFULLY_USED_RECIPE; - } - - public ITexture[] getSideFacingActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getSideFacingInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getFrontFacingActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getFrontFacingInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getTopFacingActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getTopFacingInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getBottomFacingActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getBottomFacingInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; - } - - public ITexture[] getBottomFacingPipeActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - public ITexture[] getBottomFacingPipeInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - public ITexture[] getTopFacingPipeActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - public ITexture[] getTopFacingPipeInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - public ITexture[] getSideFacingPipeActive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - public ITexture[] getSideFacingPipeInactive(byte aColor) { - return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - final NBTTagCompound tag = accessor.getNBTData(); - - if (tag.getBoolean("stutteringSingleBlock")) { - currenttip.add("Status: insufficient energy"); - } else { - boolean isActive = tag.getBoolean("isActiveSingleBlock"); - if (isActive) { - int mEUt = tag.getInteger("eut"); - if (!isSteampowered()) { - if (mEUt > 0) { - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.use_with_amperage", - GT_Utility.formatNumbers(mEUt), - GT_Utility.getAmperageForTier(mEUt, (byte) getInputTier()), - GT_Utility.getColoredTierNameFromTier((byte) getInputTier()))); - } else if (mEUt < 0) { - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.produce_with_amperage", - GT_Utility.formatNumbers(-mEUt), - GT_Utility.getAmperageForTier(-mEUt, (byte) getOutputTier()), - GT_Utility.getColoredTierNameFromTier((byte) getOutputTier()))); - } - } else { - if (mEUt > 0) { - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.use", - GT_Utility.formatNumbers(mEUt), - GT_Utility.getColoredTierNameFromVoltage(mEUt))); - } else if (mEUt < 0) { - currenttip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.produce", - GT_Utility.formatNumbers(-mEUt), - GT_Utility.getColoredTierNameFromVoltage(-mEUt))); - } - } - } - currenttip.add( - GT_Waila.getMachineProgressString( - isActive, - tag.getInteger("maxProgressSingleBlock"), - tag.getInteger("progressSingleBlock"))); - } - - currenttip.add( - String.format( - "Machine Facing: %s", - ForgeDirection.getOrientation(tag.getInteger("mainFacingSingleBlock")) - .name())); - - currenttip.add( - String.format( - "Output Facing: %s", - ForgeDirection.getOrientation(tag.getInteger("outputFacingSingleBlock")) - .name())); - } - - @Override - public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, - int z) { - super.getWailaNBTData(player, tile, tag, world, x, y, z); - - tag.setInteger("progressSingleBlock", mProgresstime); - tag.setInteger("maxProgressSingleBlock", mMaxProgresstime); - tag.setInteger("mainFacingSingleBlock", mMainFacing.ordinal()); - tag.setBoolean("stutteringSingleBlock", mStuttering); - - final IGregTechTileEntity tileEntity = getBaseMetaTileEntity(); - if (tileEntity != null) { - tag.setBoolean("isActiveSingleBlock", tileEntity.isActive()); - tag.setInteger( - "outputFacingSingleBlock", - tileEntity.getFrontFacing() - .ordinal()); - if (tileEntity.isActive()) tag.setInteger("eut", mEUt); - } - } - - @Nonnull - @Override - public OverclockDescriber getOverclockDescriber() { - return overclockDescriber; - } - - // GUI stuff - - @Override - public int getCircuitSlotX() { - return 153; - } - - @Override - public int getCircuitSlotY() { - return 63; - } - - @Override - public void addGregTechLogo(ModularWindow.Builder builder) { - if (getRecipeMap() != null) { - getRecipeMap().getFrontend() - .addGregTechLogo(builder, new Pos2d(0, 0)); - } else { - builder.widget( - new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo()) - .setSize(17, 17) - .setPos(152, 63)); - } - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - if (!isSteampowered()) { - builder.widget(createFluidAutoOutputButton()); - builder.widget(createItemAutoOutputButton()); - } - - BasicUIProperties uiProperties = getUIProperties(); - addIOSlots(builder, uiProperties); - - builder.widget(createChargerSlot(79, 62)); - - addProgressBar(builder, uiProperties); - - builder.widget( - createErrorStatusArea( - builder, - isSteampowered() ? GT_UITextures.PICTURE_STALLED_STEAM : GT_UITextures.PICTURE_STALLED_ELECTRICITY)); - } - - /** - * Override to specify UI properties if this machine doesn't work with recipemap. - */ - protected BasicUIProperties getUIProperties() { - if (getRecipeMap() != null) { - BasicUIProperties originalProperties = getRecipeMap().getFrontend() - .getUIProperties(); - return originalProperties.toBuilder() - .maxItemInputs(mInputSlotCount) - .maxItemOutputs(mOutputItems.length) - .maxFluidInputs(Math.min(originalProperties.maxFluidInputs, 1)) - .maxFluidOutputs(Math.min(originalProperties.maxFluidOutputs, 1)) - .build(); - } - return BasicUIProperties.builder() - .maxItemInputs(mInputSlotCount) - .maxItemOutputs(mOutputItems.length) - .maxFluidInputs(getCapacity() != 0 ? 1 : 0) - .maxFluidOutputs(0) - .build(); - } - - /** - * Adds item I/O, special item, and fluid I/O slots. - */ - protected void addIOSlots(ModularWindow.Builder builder, BasicUIProperties uiProperties) { - UIHelper.forEachSlots( - (i, backgrounds, pos) -> builder.widget(createItemInputSlot(i, backgrounds, pos)), - (i, backgrounds, pos) -> builder.widget(createItemOutputSlot(i, backgrounds, pos)), - (i, backgrounds, pos) -> builder.widget(createSpecialSlot(backgrounds, pos, uiProperties)), - (i, backgrounds, pos) -> builder.widget(createFluidInputSlot(backgrounds, pos)), - (i, backgrounds, pos) -> builder.widget(createFluidOutputSlot(backgrounds, pos)), - getGUITextureSet().getItemSlot(), - getGUITextureSet().getFluidSlot(), - uiProperties, - uiProperties.maxItemInputs, - uiProperties.maxItemOutputs, - uiProperties.maxFluidInputs, - uiProperties.maxFluidOutputs, - getSteamVariant(), - Pos2d.ZERO); - } - - protected void addProgressBar(ModularWindow.Builder builder, BasicUIProperties uiProperties) { - boolean isSteamPowered = isSteampowered(); - RecipeMap recipeMap = getRecipeMap(); - if (!isSteamPowered && uiProperties.progressBarTexture == null) { - if (recipeMap != null) { - // Require progress bar texture for machines working with recipemap, otherwise permit - throw new RuntimeException("Missing progressbar texture for " + recipeMap.unlocalizedName); - } else { - return; - } - } - if (isSteamPowered && uiProperties.progressBarTextureSteam == null) { - if (recipeMap != null) { - throw new RuntimeException("Missing steam progressbar texture for " + recipeMap.unlocalizedName); - } else { - return; - } - } - - builder.widget( - setNEITransferRect( - new ProgressBar() - .setProgress(() -> maxProgresstime() != 0 ? (float) getProgresstime() / maxProgresstime() : 0) - .setTexture( - isSteamPowered ? uiProperties.progressBarTextureSteam.get(getSteamVariant()) - : uiProperties.progressBarTexture.get(), - uiProperties.progressBarImageSize) - .setDirection(uiProperties.progressBarDirection) - .setPos(uiProperties.progressBarPos) - .setSize(uiProperties.progressBarSize), - uiProperties.neiTransferRectId)); - addProgressBarSpecialTextures(builder, uiProperties); - } - - /** - * Override this as needed instead of calling. - */ - protected SlotWidget createItemInputSlot(int index, IDrawable[] backgrounds, Pos2d pos) { - return (SlotWidget) new SlotWidget(inventoryHandler, getInputSlot() + index).setAccess(true, true) - .setBackground(backgrounds) - .setPos(pos); - } - - /** - * Override this as needed instead of calling. - */ - protected SlotWidget createItemOutputSlot(int index, IDrawable[] backgrounds, Pos2d pos) { - return (SlotWidget) new SlotWidget(inventoryHandler, getOutputSlot() + index).setAccess(true, false) - .setBackground(backgrounds) - .setPos(pos); - } - - /** - * Override this as needed instead of calling. - */ - protected SlotWidget createSpecialSlot(IDrawable[] backgrounds, Pos2d pos, BasicUIProperties uiProperties) { - return (SlotWidget) new SlotWidget(inventoryHandler, getSpecialSlotIndex()).setAccess(true, true) - .disableShiftInsert() - .setGTTooltip( - () -> mTooltipCache.getData(uiProperties.useSpecialSlot ? SPECIAL_SLOT_TOOLTIP : UNUSED_SLOT_TOOLTIP)) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setBackground(backgrounds) - .setPos(pos); - } - - protected FluidSlotWidget createFluidInputSlot(IDrawable[] backgrounds, Pos2d pos) { - return (FluidSlotWidget) new FluidSlotWidget(fluidTank).setBackground(backgrounds) - .setPos(pos); - } - - protected FluidSlotWidget createFluidOutputSlot(IDrawable[] backgrounds, Pos2d pos) { - return (FluidSlotWidget) new FluidSlotWidget(fluidOutputTank).setInteraction(true, false) - .setBackground(backgrounds) - .setPos(pos); - } - - @Override - protected SlotWidget createChargerSlot(int x, int y) { - if (isSteampowered()) { - return (SlotWidget) createChargerSlot(x, y, UNUSED_SLOT_TOOLTIP, new String[0]) - .setBackground(getGUITextureSet().getItemSlot()); - } else { - return super.createChargerSlot(x, y); - } - } - - protected CycleButtonWidget createItemAutoOutputButton() { - return (CycleButtonWidget) new CycleButtonWidget().setToggle(() -> mItemTransfer, val -> mItemTransfer = val) - .setStaticTexture(GT_UITextures.OVERLAY_BUTTON_AUTOOUTPUT_ITEM) - .setVariableBackground(GT_UITextures.BUTTON_STANDARD_TOGGLE) - .setGTTooltip(() -> mTooltipCache.getData(ITEM_TRANSFER_TOOLTIP)) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(25, 62) - .setSize(18, 18); - } - - protected CycleButtonWidget createFluidAutoOutputButton() { - return (CycleButtonWidget) new CycleButtonWidget().setToggle(() -> mFluidTransfer, val -> mFluidTransfer = val) - .setStaticTexture(GT_UITextures.OVERLAY_BUTTON_AUTOOUTPUT_FLUID) - .setVariableBackground(GT_UITextures.BUTTON_STANDARD_TOGGLE) - .setGTTooltip(() -> mTooltipCache.getData(FLUID_TRANSFER_TOOLTIP)) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(7, 62) - .setSize(18, 18); - } - - protected Widget setNEITransferRect(Widget widget, String transferRectID) { - if (GT_Utility.isStringInvalid(transferRectID)) { - return widget; - } - final String transferRectTooltip; - if (isSteampowered()) { - transferRectTooltip = StatCollector - .translateToLocalFormatted(NEI_TRANSFER_STEAM_TOOLTIP, overclockDescriber.getTierString()); - } else { - transferRectTooltip = StatCollector - .translateToLocalFormatted(NEI_TRANSFER_VOLTAGE_TOOLTIP, overclockDescriber.getTierString()); - } - widget.setNEITransferRect(transferRectID, new Object[] { overclockDescriber }, transferRectTooltip); - return widget; - } - - protected void addProgressBarSpecialTextures(ModularWindow.Builder builder, BasicUIProperties uiProperties) { - if (isSteampowered()) { - for (Pair> specialTexture : uiProperties.specialTexturesSteam) { - builder.widget( - new DrawableWidget().setDrawable( - specialTexture.getLeft() - .get(getSteamVariant())) - .setSize( - specialTexture.getRight() - .getLeft()) - .setPos( - specialTexture.getRight() - .getRight())); - } - } else { - for (Pair> specialTexture : uiProperties.specialTextures) { - builder.widget( - new DrawableWidget().setDrawable(specialTexture.getLeft()) - .setSize( - specialTexture.getRight() - .getLeft()) - .setPos( - specialTexture.getRight() - .getRight())); - } - } - } - - protected DrawableWidget createErrorStatusArea(ModularWindow.Builder builder, IDrawable picture) { - return (DrawableWidget) new DrawableWidget().setDrawable(picture) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setEnabled( - widget -> !widget.getTooltip() - .isEmpty()) - .dynamicTooltip(this::getErrorDescriptions) - .dynamicTooltipShift(this::getErrorDescriptionsShift) - .setPos(79, 44) - .setSize(18, 18) - .attachSyncer( - new FakeSyncWidget.BooleanSyncer(() -> mStuttering, val -> mStuttering = val), - builder, - (widget, val) -> widget.notifyTooltipChange()) - .attachSyncer( - new FakeSyncWidget.IntegerSyncer( - () -> getBaseMetaTileEntity().getErrorDisplayID(), - val -> getBaseMetaTileEntity().setErrorDisplayID(val)), - builder, - (widget, val) -> widget.notifyTooltipChange()); - } - - protected List getErrorDescriptions() { - final GT_TooltipDataCache.TooltipData tooltip = getErrorTooltip(); - return tooltip != null ? tooltip.text : Collections.emptyList(); - } - - protected List getErrorDescriptionsShift() { - final GT_TooltipDataCache.TooltipData tooltip = getErrorTooltip(); - return tooltip != null ? tooltip.shiftText : Collections.emptyList(); - } - - protected GT_TooltipDataCache.TooltipData getErrorTooltip() { - if (isSteampowered()) { - if ((getBaseMetaTileEntity().getErrorDisplayID() & 64) != 0) { - return mTooltipCache.getData(STALLED_VENT_TOOLTIP); - } - } - if (mStuttering) { - return mTooltipCache.getData( - STALLED_STUTTERING_TOOLTIP, - StatCollector.translateToLocal(POWER_SOURCE_KEY + (isSteampowered() ? "steam" : "power"))); - } - return null; - } - - protected static int getCapacityForTier(int tier) { - return switch (tier) { - case 0 -> 8000; - case 1 -> 16000; - case 2 -> 32000; - case 3 -> 64000; - case 4 -> 128000; - default -> 256000; - }; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java deleted file mode 100644 index 5eb648d560..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java +++ /dev/null @@ -1,387 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.D1; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_BOTTOM; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_SIDE; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_TOP; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZE_BOTTOM; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZE_SIDE; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZE_TOP; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; -import static gregtech.api.objects.XSTR.XSTR_INSTANCE; - -import java.util.Arrays; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.drawable.IDrawable; -import com.gtnewhorizons.modularui.api.math.Pos2d; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; - -import gregtech.api.GregTech_API; -import gregtech.api.enums.Dyes; -import gregtech.api.enums.ParticleFX; -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.SteamVariant; -import gregtech.api.enums.TierEU; -import gregtech.api.gui.modularui.GUITextureSet; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.objects.overclockdescriber.OverclockDescriber; -import gregtech.api.objects.overclockdescriber.SteamOverclockDescriber; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple - * Machine - */ -public abstract class GT_MetaTileEntity_BasicMachine_Bronze extends GT_MetaTileEntity_BasicMachine { - - private static final String TT_machineType = "GT5U.MBTT.MachineType"; - private static final int NEEDS_STEAM_VENTING = 64; - public boolean mNeedsSteamVenting = false; - - public GT_MetaTileEntity_BasicMachine_Bronze(int aID, String aName, String aNameRegional, String aDescription, - int aInputSlotCount, int aOutputSlotCount, boolean aHighPressure) { - super(aID, aName, aNameRegional, aHighPressure ? 2 : 1, 0, aDescription, aInputSlotCount, aOutputSlotCount); - } - - public GT_MetaTileEntity_BasicMachine_Bronze(String aName, String[] aDescription, ITexture[][][] aTextures, - int aInputSlotCount, int aOutputSlotCount, boolean aHighPressure) { - super(aName, aHighPressure ? 2 : 1, 0, aDescription, aTextures, aInputSlotCount, aOutputSlotCount); - } - - protected boolean isBricked() { - return false; - } - - @Override - public OverclockDescriber createOverclockDescriber() { - return new SteamOverclockDescriber(SteamVariant.BRONZE, 1, 2); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setBoolean("mNeedsSteamVenting", mNeedsSteamVenting); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - mNeedsSteamVenting = aNBT.getBoolean("mNeedsSteamVenting"); - } - - @Override - public boolean isElectric() { - return false; - } - - @Override - public boolean isEnetInput() { - return false; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return false; - } - - @Override - public long maxEUStore() { - return 0; - } - - @Override - public long maxEUInput() { - return 0; - } - - @Override - public int rechargerSlotCount() { - return 0; - } - - @Override - public int dechargerSlotCount() { - return 0; - } - - @Override - public boolean isSteampowered() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return super.isFacingValid(facing) && facing != mMainFacing; - } - - @Override - public long getMinimumStoredEU() { - return 1000; - } - - @Override - public long maxSteamStore() { - return 16000; - } - - @Override - public boolean isLiquidInput(ForgeDirection side) { - return side != mMainFacing; - } - - @Override - public boolean isLiquidOutput(ForgeDirection side) { - return side != mMainFacing; - } - - @Override - public boolean doesAutoOutput() { - return false; - } - - @Override - public boolean allowToCheckRecipe() { - if (mNeedsSteamVenting - && getBaseMetaTileEntity().getCoverIDAtSide(getBaseMetaTileEntity().getFrontFacing()) == 0 - && !GT_Utility.hasBlockHitBox( - getBaseMetaTileEntity().getWorld(), - getBaseMetaTileEntity().getOffsetX(getBaseMetaTileEntity().getFrontFacing(), 1), - getBaseMetaTileEntity().getOffsetY(getBaseMetaTileEntity().getFrontFacing(), 1), - getBaseMetaTileEntity().getOffsetZ(getBaseMetaTileEntity().getFrontFacing(), 1))) { - sendSound((byte) 9); - mNeedsSteamVenting = false; - try { - for (EntityLivingBase tLiving : getBaseMetaTileEntity().getWorld() - .getEntitiesWithinAABB( - EntityLivingBase.class, - AxisAlignedBB.getBoundingBox( - getBaseMetaTileEntity().getOffsetX(getBaseMetaTileEntity().getFrontFacing(), 1), - getBaseMetaTileEntity().getOffsetY(getBaseMetaTileEntity().getFrontFacing(), 1), - getBaseMetaTileEntity().getOffsetZ(getBaseMetaTileEntity().getFrontFacing(), 1), - getBaseMetaTileEntity().getOffsetX(getBaseMetaTileEntity().getFrontFacing(), 1) + 1, - getBaseMetaTileEntity().getOffsetY(getBaseMetaTileEntity().getFrontFacing(), 1) + 1, - getBaseMetaTileEntity().getOffsetZ(getBaseMetaTileEntity().getFrontFacing(), 1) + 1))) { - GT_Utility.applyHeatDamage(tLiving, getSteamDamage()); - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - } - return !mNeedsSteamVenting; - } - - @Override - public int checkRecipe() { - GT_Recipe tRecipe = getRecipeMap().findRecipe(getBaseMetaTileEntity(), false, TierEU.LV, null, getAllInputs()); - if ((tRecipe != null) && (canOutput(tRecipe.mOutputs)) - && (tRecipe.isRecipeInputEqual(true, null, getAllInputs()))) { - this.mOutputItems[0] = tRecipe.getOutput(0); - calculateCustomOverclock(tRecipe); - return FOUND_AND_SUCCESSFULLY_USED_RECIPE; - } - return DID_NOT_FIND_RECIPE; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - // Super already zeroed out setErrorDisplayID, add additional error codes here. - aBaseMetaTileEntity.setErrorDisplayID(aBaseMetaTileEntity.getErrorDisplayID() | (mNeedsSteamVenting ? 64 : 0)); - } - - @Override - public void endProcess() { - if (isSteampowered()) mNeedsSteamVenting = true; - } - - @Override - public void doSound(byte aIndex, double aX, double aY, double aZ) { - super.doSound(aIndex, aX, aY, aZ); - if (aIndex == 9) { - GT_Utility.doSoundAtClient(SoundResource.RANDOM_FIZZ, 5, 1.0F, aX, aY, aZ); - - new ParticleEventBuilder().setIdentifier(ParticleFX.CLOUD) - .setWorld(getBaseMetaTileEntity().getWorld()) - .setMotion( - getBaseMetaTileEntity().getFrontFacing().offsetX / 5.0, - getBaseMetaTileEntity().getFrontFacing().offsetY / 5.0, - getBaseMetaTileEntity().getFrontFacing().offsetZ / 5.0) - .times( - 8, - x -> x - .setPosition( - aX - 0.5 + XSTR_INSTANCE.nextFloat(), - aY - 0.5 + XSTR_INSTANCE.nextFloat(), - aZ - 0.5 + XSTR_INSTANCE.nextFloat()) - .run()); - } - } - - @Override - public boolean isGivingInformation() { - return false; - } - - @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { - return GregTech_API.getCoverBehaviorNew(aCoverID.toStack()) - .isSimpleCover() && super.allowCoverOnSide(side, aCoverID); - } - - public float getSteamDamage() { - return 6.0F * mTier; - } - - @Override - public ITexture[] getSideFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getSideFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getFrontFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getFrontFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getTopFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getTopFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getBottomFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getBottomFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getBottomFacingPipeActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getBottomFacingPipeInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getTopFacingPipeActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getTopFacingPipeInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getSideFacingPipeActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getSideFacingPipeInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public SteamVariant getSteamVariant() { - return SteamVariant.BRONZE; - } - - @Override - public GUITextureSet getGUITextureSet() { - return GUITextureSet.STEAM.apply(getSteamVariant()); - } - - @Override - public void addGregTechLogo(ModularWindow.Builder builder) { - builder.widget( - new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo()) - .setSize(17, 17) - .setPos(152, 63)); - } - - @Override - protected FluidSlotWidget createFluidInputSlot(IDrawable[] backgrounds, Pos2d pos) { - return null; - } - - @Override - protected FluidSlotWidget createFluidOutputSlot(IDrawable[] backgrounds, Pos2d pos) { - return null; - } - - @Override - public String[] getDescription() { - String[] description = Arrays.copyOf(mDescriptionArray, mDescriptionArray.length + 1); - description[mDescriptionArray.length] = StatCollector.translateToLocal(TT_machineType) + ": " - + EnumChatFormatting.YELLOW - + StatCollector.translateToLocal(this.getRecipeMap().unlocalizedName) - + EnumChatFormatting.RESET; - return description; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_GT_Recipe.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_GT_Recipe.java deleted file mode 100644 index a10e735843..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_GT_Recipe.java +++ /dev/null @@ -1,818 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.GT_Values.VN; -import static gregtech.api.enums.GT_Values.W; -import static gregtech.api.enums.GT_Values.ticksBetweenSounds; -import static gregtech.api.objects.XSTR.XSTR_INSTANCE; -import static net.minecraftforge.common.util.ForgeDirection.UP; - -import java.util.Locale; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.oredict.OreDictionary; - -import com.gtnewhorizons.modularui.api.drawable.FallbackableUITexture; -import com.gtnewhorizons.modularui.api.drawable.UITexture; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.ParticleFX; -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.Textures.BlockIcons.CustomIcon; -import gregtech.api.enums.Tier; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.BaseMetaTileEntity; -import gregtech.api.recipe.BasicUIProperties; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.ExternalMaterials; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple - * Machine - */ -public class GT_MetaTileEntity_BasicMachine_GT_Recipe extends GT_MetaTileEntity_BasicMachine { - - private final RecipeMap mRecipes; - private final int mTankCapacity; - private final SpecialEffects mSpecialEffect; - private final ResourceLocation mSoundResourceLocation; - private FallbackableUITexture progressBarTexture; - private int recipeCatalystPriority; - - /** - * Registers machine with single-line description, specific tank capacity, and sound specified by ResourceLocation. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(int aID, String aName, String aNameRegional, int aTier, - String aDescription, RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, - ResourceLocation aSound, SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { - this( - aID, - aName, - aNameRegional, - aTier, - new String[] { aDescription }, - aRecipes, - aInputSlots, - aOutputSlots, - aTankCapacity, - aSound, - aSpecialEffect, - aOverlays, - aRecipe); - } - - /** - * Registers machine with multi-line descriptions, specific tank capacity, and sound specified by ResourceLocation. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription, RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, - ResourceLocation aSound, SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { - super( - aID, - aName, - aNameRegional, - aTier, - aRecipes.getAmperage(), - aDescription, - aInputSlots, - aOutputSlots, - TextureFactory.of( - TextureFactory.of( - new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE_ACTIVE")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE_ACTIVE_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory - .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory.of( - new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT_ACTIVE")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT_ACTIVE_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory - .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory.of( - new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP_ACTIVE")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP_ACTIVE_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory - .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory.of( - new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM_ACTIVE")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM_ACTIVE_GLOW"))) - .glow() - .build()), - TextureFactory.of( - TextureFactory - .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM")), - TextureFactory.builder() - .addIcon( - (new CustomIcon( - "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM_GLOW"))) - .glow() - .build())); - this.mTankCapacity = aTankCapacity; - this.mSpecialEffect = aSpecialEffect; - this.mRecipes = aRecipes; - this.mSoundResourceLocation = aSound; - this.progressBarTexture = mRecipes.getFrontend() - .getUIProperties().progressBarTexture; - - // TODO: CHECK - if (aRecipe != null) { - for (int i = 3; i < aRecipe.length; i++) { - if (!(aRecipe[i] instanceof X)) continue; - - // spotless:off - aRecipe[i] = switch ((X) aRecipe[i]) { - case CIRCUIT -> Tier.ELECTRIC[this.mTier].mManagingObject; - case BETTER_CIRCUIT -> Tier.ELECTRIC[this.mTier].mBetterManagingObject; - case HULL -> Tier.ELECTRIC[this.mTier].mHullObject; - case WIRE -> Tier.ELECTRIC[this.mTier].mConductingObject; - case WIRE4 -> Tier.ELECTRIC[this.mTier].mLargerConductingObject; - case STICK_DISTILLATION -> OrePrefixes.stick.get(Materials.Blaze); - - case GLASS -> switch (this.mTier) { - case 0, 1, 2, 3 -> new ItemStack(Blocks.glass, 1, W); - case 4, 5, 6, 7, 8 -> "blockGlass" + VN[aTier]; - default -> "blockGlass" + VN[8]; - }; - - case PLATE -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.plate.get(Materials.Steel); - case 2 -> OrePrefixes.plate.get(Materials.Aluminium); - case 3 -> OrePrefixes.plate.get(Materials.StainlessSteel); - case 4 -> OrePrefixes.plate.get(Materials.Titanium); - case 5 -> OrePrefixes.plate.get(Materials.TungstenSteel); - case 6 -> OrePrefixes.plate.get(Materials.HSSG); - case 7 -> OrePrefixes.plate.get(Materials.HSSE); - default -> OrePrefixes.plate.get(Materials.Neutronium); - }; - - case PIPE -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.pipeMedium.get(Materials.Bronze); - case 2 -> OrePrefixes.pipeMedium.get(Materials.Steel); - case 3 -> OrePrefixes.pipeMedium.get(Materials.StainlessSteel); - case 4 -> OrePrefixes.pipeMedium.get(Materials.Titanium); - case 5 -> OrePrefixes.pipeMedium.get(Materials.TungstenSteel); - case 6 -> OrePrefixes.pipeSmall.get(Materials.Ultimate); - case 7 -> OrePrefixes.pipeMedium.get(Materials.Ultimate); - case 8 -> OrePrefixes.pipeLarge.get(Materials.Ultimate); - default -> OrePrefixes.pipeHuge.get(Materials.Ultimate); - }; - - case COIL_HEATING -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); - case 2 -> OrePrefixes.wireGt02.get(Materials.Cupronickel); - case 3 -> OrePrefixes.wireGt02.get(Materials.Kanthal); - case 4 -> OrePrefixes.wireGt02.get(Materials.Nichrome); - case 5 -> OrePrefixes.wireGt02.get(Materials.TPV); - case 6 -> OrePrefixes.wireGt02.get(Materials.HSSG); - case 7 -> OrePrefixes.wireGt02.get(Materials.Naquadah); - case 8 -> OrePrefixes.wireGt02.get(Materials.NaquadahAlloy); - case 9 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); - default -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); - }; - - case COIL_HEATING_DOUBLE -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); - case 2 -> OrePrefixes.wireGt04.get(Materials.Cupronickel); - case 3 -> OrePrefixes.wireGt04.get(Materials.Kanthal); - case 4 -> OrePrefixes.wireGt04.get(Materials.Nichrome); - case 5 -> OrePrefixes.wireGt04.get(Materials.TPV); - case 6 -> OrePrefixes.wireGt04.get(Materials.HSSG); - case 7 -> OrePrefixes.wireGt04.get(Materials.Naquadah); - case 8 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); - case 9 -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); - default -> OrePrefixes.wireGt16.get(Materials.NaquadahAlloy); - }; - - case STICK_MAGNETIC -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.stick.get(Materials.IronMagnetic); - case 2, 3 -> OrePrefixes.stick.get(Materials.SteelMagnetic); - case 4, 5 -> OrePrefixes.stick.get(Materials.NeodymiumMagnetic); - case 6, 7, 8, 9 -> OrePrefixes.stick.get(Materials.SamariumMagnetic); - default -> OrePrefixes.stick.get(Materials.TengamAttuned); - }; - - case STICK_ELECTROMAGNETIC -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.stick.get(Materials.AnyIron); - case 2, 3 -> OrePrefixes.stick.get(Materials.Steel); - case 4 -> OrePrefixes.stick.get(Materials.Neodymium); - default -> OrePrefixes.stick.get(Materials.VanadiumGallium); - }; - - case COIL_ELECTRIC -> switch (this.mTier) { - case 0 -> OrePrefixes.wireGt01.get(Materials.Lead); - case 1 -> OrePrefixes.wireGt02.get(Materials.Tin); - case 2 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); - case 3 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); - case 4 -> OrePrefixes.wireGt08.get(Materials.AnnealedCopper); - case 5 -> OrePrefixes.wireGt16.get(Materials.AnnealedCopper); - case 6 -> OrePrefixes.wireGt04.get(Materials.YttriumBariumCuprate); - case 7 -> OrePrefixes.wireGt08.get(Materials.Iridium); - default -> OrePrefixes.wireGt16.get(Materials.Osmium); - }; - - case ROBOT_ARM -> switch (this.mTier) { - case 0, 1 -> ItemList.Robot_Arm_LV; - case 2 -> ItemList.Robot_Arm_MV; - case 3 -> ItemList.Robot_Arm_HV; - case 4 -> ItemList.Robot_Arm_EV; - case 5 -> ItemList.Robot_Arm_IV; - case 6 -> ItemList.Robot_Arm_LuV; - case 7 -> ItemList.Robot_Arm_ZPM; - case 8 -> ItemList.Robot_Arm_UV; - case 9 -> ItemList.Robot_Arm_UHV; - case 10 -> ItemList.Robot_Arm_UEV; - case 11 -> ItemList.Robot_Arm_UIV; - case 12 -> ItemList.Robot_Arm_UMV; - case 13 -> ItemList.Robot_Arm_UXV; - default -> ItemList.Robot_Arm_MAX; - }; - - case PUMP -> switch (this.mTier) { - case 0, 1 -> ItemList.Electric_Pump_LV; - case 2 -> ItemList.Electric_Pump_MV; - case 3 -> ItemList.Electric_Pump_HV; - case 4 -> ItemList.Electric_Pump_EV; - case 5 -> ItemList.Electric_Pump_IV; - case 6 -> ItemList.Electric_Pump_LuV; - case 7 -> ItemList.Electric_Pump_ZPM; - case 8 -> ItemList.Electric_Pump_UV; - case 9 -> ItemList.Electric_Pump_UHV; - case 10 -> ItemList.Electric_Pump_UEV; - case 11 -> ItemList.Electric_Pump_UIV; - case 12 -> ItemList.Electric_Pump_UMV; - case 13 -> ItemList.Electric_Pump_UXV; - default -> ItemList.Electric_Pump_MAX; - }; - - case MOTOR -> switch (this.mTier) { - case 0, 1 -> ItemList.Electric_Motor_LV; - case 2 -> ItemList.Electric_Motor_MV; - case 3 -> ItemList.Electric_Motor_HV; - case 4 -> ItemList.Electric_Motor_EV; - case 5 -> ItemList.Electric_Motor_IV; - case 6 -> ItemList.Electric_Motor_LuV; - case 7 -> ItemList.Electric_Motor_ZPM; - case 8 -> ItemList.Electric_Motor_UV; - case 9 -> ItemList.Electric_Motor_UHV; - case 10 -> ItemList.Electric_Motor_UEV; - case 11 -> ItemList.Electric_Motor_UIV; - case 12 -> ItemList.Electric_Motor_UMV; - case 13 -> ItemList.Electric_Motor_UXV; - default -> ItemList.Electric_Motor_MAX; - }; - - case PISTON -> switch (this.mTier) { - case 0, 1 -> ItemList.Electric_Piston_LV; - case 2 -> ItemList.Electric_Piston_MV; - case 3 -> ItemList.Electric_Piston_HV; - case 4 -> ItemList.Electric_Piston_EV; - case 5 -> ItemList.Electric_Piston_IV; - case 6 -> ItemList.Electric_Piston_LuV; - case 7 -> ItemList.Electric_Piston_ZPM; - case 8 -> ItemList.Electric_Piston_UV; - case 9 -> ItemList.Electric_Piston_UHV; - case 10 -> ItemList.Electric_Piston_UEV; - case 11 -> ItemList.Electric_Piston_UIV; - case 12 -> ItemList.Electric_Piston_UMV; - case 13 -> ItemList.Electric_Piston_UXV; - default -> ItemList.Electric_Piston_MAX; - }; - - case CONVEYOR -> switch (this.mTier) { - case 0, 1 -> ItemList.Conveyor_Module_LV; - case 2 -> ItemList.Conveyor_Module_MV; - case 3 -> ItemList.Conveyor_Module_HV; - case 4 -> ItemList.Conveyor_Module_EV; - case 5 -> ItemList.Conveyor_Module_IV; - case 6 -> ItemList.Conveyor_Module_LuV; - case 7 -> ItemList.Conveyor_Module_ZPM; - case 8 -> ItemList.Conveyor_Module_UV; - case 9 -> ItemList.Conveyor_Module_UHV; - case 10 -> ItemList.Conveyor_Module_UEV; - case 11 -> ItemList.Conveyor_Module_UIV; - case 12 -> ItemList.Conveyor_Module_UMV; - case 13 -> ItemList.Conveyor_Module_UXV; - default -> ItemList.Conveyor_Module_MAX; - }; - - case EMITTER -> switch (this.mTier) { - case 0, 1 -> ItemList.Emitter_LV; - case 2 -> ItemList.Emitter_MV; - case 3 -> ItemList.Emitter_HV; - case 4 -> ItemList.Emitter_EV; - case 5 -> ItemList.Emitter_IV; - case 6 -> ItemList.Emitter_LuV; - case 7 -> ItemList.Emitter_ZPM; - case 8 -> ItemList.Emitter_UV; - case 9 -> ItemList.Emitter_UHV; - case 10 -> ItemList.Emitter_UEV; - case 11 -> ItemList.Emitter_UIV; - case 12 -> ItemList.Emitter_UMV; - case 13 -> ItemList.Emitter_UXV; - default -> ItemList.Emitter_MAX; - }; - - case SENSOR -> switch (this.mTier) { - case 0, 1 -> ItemList.Sensor_LV; - case 2 -> ItemList.Sensor_MV; - case 3 -> ItemList.Sensor_HV; - case 4 -> ItemList.Sensor_EV; - case 5 -> ItemList.Sensor_IV; - case 6 -> ItemList.Sensor_LuV; - case 7 -> ItemList.Sensor_ZPM; - case 8 -> ItemList.Sensor_UV; - case 9 -> ItemList.Sensor_UHV; - case 10 -> ItemList.Sensor_UEV; - case 11 -> ItemList.Sensor_UIV; - case 12 -> ItemList.Sensor_UMV; - case 13 -> ItemList.Sensor_UXV; - default -> ItemList.Sensor_MAX; - }; - - case FIELD_GENERATOR -> switch (this.mTier) { - case 0, 1 -> ItemList.Field_Generator_LV; - case 2 -> ItemList.Field_Generator_MV; - case 3 -> ItemList.Field_Generator_HV; - case 4 -> ItemList.Field_Generator_EV; - case 5 -> ItemList.Field_Generator_IV; - case 6 -> ItemList.Field_Generator_LuV; - case 7 -> ItemList.Field_Generator_ZPM; - case 8 -> ItemList.Field_Generator_UV; - case 9 -> ItemList.Field_Generator_UHV; - case 10 -> ItemList.Field_Generator_UEV; - case 11 -> ItemList.Field_Generator_UIV; - case 12 -> ItemList.Field_Generator_UMV; - case 13 -> ItemList.Field_Generator_UXV; - default -> ItemList.Field_Generator_MAX; - }; - - case ROTOR -> switch (this.mTier) { - case 0, 1 -> OrePrefixes.rotor.get(Materials.Tin); - case 2 -> OrePrefixes.rotor.get(Materials.Bronze); - case 3 -> OrePrefixes.rotor.get(Materials.Steel); - case 4 -> OrePrefixes.rotor.get(Materials.StainlessSteel); - case 5 -> OrePrefixes.rotor.get(Materials.TungstenSteel); - case 6 -> OrePrefixes.rotor.get(ExternalMaterials.getRhodiumPlatedPalladium()); - case 7 -> OrePrefixes.rotor.get(Materials.Iridium); - default -> OrePrefixes.rotor.get(Materials.Osmium); - }; - - default -> throw new IllegalArgumentException("MISSING TIER MAPPING FOR: " + aRecipe[i] + " AT TIER " + this.mTier); - }; - // spotless:on - } - - if (!GT_ModHandler.addCraftingRecipe( - getStackForm(1), - GT_ModHandler.RecipeBits.DISMANTLEABLE | GT_ModHandler.RecipeBits.BUFFERED - | GT_ModHandler.RecipeBits.NOT_REMOVABLE - | GT_ModHandler.RecipeBits.REVERSIBLE, - aRecipe)) { - throw new IllegalArgumentException("INVALID CRAFTING RECIPE FOR: " + getStackForm(1).getDisplayName()); - } - } - } - - /** - * Registers machine with single-line description, auto-scaled fluid tank, and sound specified by SoundResource. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(int aID, String aName, String aNameRegional, int aTier, - String aDescription, RecipeMap aRecipes, int aInputSlots, int aOutputSlots, boolean usesFluids, - SoundResource aSound, SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { - this( - aID, - aName, - aNameRegional, - aTier, - aDescription, - aRecipes, - aInputSlots, - aOutputSlots, - usesFluids ? getCapacityForTier(aTier) : 0, - aSound.resourceLocation, - aSpecialEffect, - aOverlays, - aRecipe); - } - - /** - * Registers machine with multi-line descriptions, auto-scaled fluid tank, and sound specified by SoundResource. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription, RecipeMap aRecipes, int aInputSlots, int aOutputSlots, boolean usesFluids, - SoundResource aSound, SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { - this( - aID, - aName, - aNameRegional, - aTier, - aDescription, - aRecipes, - aInputSlots, - aOutputSlots, - usesFluids ? getCapacityForTier(aTier) : 0, - aSound.resourceLocation, - aSpecialEffect, - aOverlays, - aRecipe); - } - - /** - * Registers machine with single-line description, specific tank capacity, and sound specified by SoundResource. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(int aID, String aName, String aNameRegional, int aTier, - String aDescription, RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, - SoundResource aSound, SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { - this( - aID, - aName, - aNameRegional, - aTier, - aDescription, - aRecipes, - aInputSlots, - aOutputSlots, - aTankCapacity, - aSound.resourceLocation, - aSpecialEffect, - aOverlays, - aRecipe); - } - - /** - * Registers machine with multi-line descriptions, specific tank capacity, and sound specified by SoundResource. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription, RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, - SoundResource aSound, SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { - this( - aID, - aName, - aNameRegional, - aTier, - aDescription, - aRecipes, - aInputSlots, - aOutputSlots, - aTankCapacity, - aSound.resourceLocation, - aSpecialEffect, - aOverlays, - aRecipe); - } - - /** - * For {@link #newMetaEntity}. - */ - public GT_MetaTileEntity_BasicMachine_GT_Recipe(String aName, int aTier, String[] aDescription, - RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, int aAmperage, - ITexture[][][] aTextures, ResourceLocation aSound, SpecialEffects aSpecialEffect) { - super(aName, aTier, aAmperage, aDescription, aTextures, aInputSlots, aOutputSlots); - this.mTankCapacity = aTankCapacity; - this.mSpecialEffect = aSpecialEffect; - this.mRecipes = aRecipes; - this.mSoundResourceLocation = aSound; - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_BasicMachine_GT_Recipe( - this.mName, - this.mTier, - this.mDescriptionArray, - this.mRecipes, - this.mInputSlotCount, - this.mOutputItems == null ? 0 : this.mOutputItems.length, - this.mTankCapacity, - this.mAmperage, - this.mTextures, - this.mSoundResourceLocation, - this.mSpecialEffect).setProgressBarTexture(this.progressBarTexture) - .setRecipeCatalystPriority(this.recipeCatalystPriority); - } - - public GT_MetaTileEntity_BasicMachine_GT_Recipe setProgressBarTexture(FallbackableUITexture progressBarTexture) { - this.progressBarTexture = progressBarTexture; - return this; - } - - public GT_MetaTileEntity_BasicMachine_GT_Recipe setProgressBarTextureName(String name, UITexture fallback) { - return setProgressBarTexture(GT_UITextures.fallbackableProgressbar(name, fallback)); - } - - public GT_MetaTileEntity_BasicMachine_GT_Recipe setProgressBarTextureName(String name) { - return setProgressBarTextureName(name, GT_UITextures.PROGRESSBAR_ARROW); - } - - @Override - protected boolean allowPutStackValidated(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (!super.allowPutStackValidated(aBaseMetaTileEntity, aIndex, side, aStack)) return false; - switch (this.mInputSlotCount) { - case 0 -> { - return false; - } - case 1 -> { - if (this.getFillableStack() == null) return this.getRecipeMap() - .containsInput(aStack); - else return this.getRecipeMap() - .findRecipe( - this.getBaseMetaTileEntity(), - this.mLastRecipe, - true, - true, - V[this.mTier], - new FluidStack[] { this.getFillableStack() }, - this.getSpecialSlot(), - appendSelectedCircuit(aStack)) - != null; - } - case 2 -> { - return ((this.getInputAt(0) != null && this.getInputAt(1) != null) - || (this.getInputAt(0) == null && this.getInputAt(1) == null ? this.getRecipeMap() - .containsInput(aStack) - : (this.getRecipeMap() - .containsInput(aStack) - && this.getRecipeMap() - .findRecipe( - this.getBaseMetaTileEntity(), - this.mLastRecipe, - true, - true, - V[this.mTier], - new FluidStack[] { this.getFillableStack() }, - this.getSpecialSlot(), - aIndex == this.getInputSlot() ? appendSelectedCircuit(aStack, this.getInputAt(1)) - : appendSelectedCircuit(this.getInputAt(0), aStack)) - != null))); - } - default -> { - int tID = this.getBaseMetaTileEntity() - .getMetaTileID(); - if (tID >= 211 && tID <= 218 || tID >= 1180 && tID <= 1187 || tID >= 10780 && tID <= 10786) { // assembler - // lv-iv; - // circuit - // asseblers - // lv - - // uv; - // assemblers - // luv-uev - if (GT_Utility.isStackValid(aStack)) for (int oreID : OreDictionary.getOreIDs(aStack)) { - if (OreDictionary.getOreName(oreID) - .startsWith("circuit")) return true; - } - } - return this.getRecipeMap() - .containsInput(aStack); - } - } - } - - @Override - public boolean allowSelectCircuit() { - return true; - } - - @Override - public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPreTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isClientSide() && aBaseMetaTileEntity.isActive()) { - // noinspection SwitchStatementWithTooFewBranches - switch (this.mSpecialEffect) { - case TOP_SMOKE -> { - if (aBaseMetaTileEntity.getFrontFacing() != UP && aBaseMetaTileEntity.getCoverIDAtSide(UP) == 0 - && !aBaseMetaTileEntity.getOpacityAtSide(UP)) { - - new ParticleEventBuilder().setMotion(0.0D, 0.0D, 0.0D) - .setIdentifier(ParticleFX.SMOKE) - .setPosition( - aBaseMetaTileEntity.getXCoord() + 0.8F - XSTR_INSTANCE.nextFloat() * 0.6F, - aBaseMetaTileEntity.getYCoord() + 0.9F + XSTR_INSTANCE.nextFloat() * 0.2F, - aBaseMetaTileEntity.getZCoord() + 0.8F - XSTR_INSTANCE.nextFloat() * 0.6F) - .setWorld(aBaseMetaTileEntity.getWorld()) - .run(); - } - } - default -> {} - } - } - } - - /** - * Handles {@link Block#randomDisplayTick} driven Special Effects - * - * @param aBaseMetaTileEntity The entity that will handle the {@see Block#randomDisplayTick} - */ - @SideOnly(Side.CLIENT) - @Override - public void onRandomDisplayTick(IGregTechTileEntity aBaseMetaTileEntity) { - - // noinspection SwitchStatementWithTooFewBranches - switch (this.mSpecialEffect) { - case MAIN_RANDOM_SPARKS -> { - // Random Sparkles at main face - if (aBaseMetaTileEntity.isActive() && XSTR_INSTANCE.nextInt(3) == 0) { - - final ForgeDirection mainFacing = this.mMainFacing; - - if ((mainFacing.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) == 0 - && aBaseMetaTileEntity.getCoverIDAtSide(mainFacing) == 0 - && !aBaseMetaTileEntity.getOpacityAtSide(mainFacing)) { - - final double oX = aBaseMetaTileEntity.getXCoord(); - final double oY = aBaseMetaTileEntity.getYCoord(); - final double oZ = aBaseMetaTileEntity.getZCoord(); - final double offset = 0.02D; - final double horizontal = 0.5D + XSTR_INSTANCE.nextFloat() * 8D / 16D - 4D / 16D; - - final double x, y, z, mX, mZ; - - y = oY + XSTR_INSTANCE.nextFloat() * 10D / 16D + 5D / 16D; - - if (mainFacing == ForgeDirection.WEST) { - x = oX - offset; - mX = -.05D; - z = oZ + horizontal; - mZ = 0D; - } else if (mainFacing == ForgeDirection.EAST) { - x = oX + offset; - mX = .05D; - z = oZ + horizontal; - mZ = 0D; - } else if (mainFacing == ForgeDirection.NORTH) { - x = oX + horizontal; - mX = 0D; - z = oZ - offset; - mZ = -.05D; - } else // if (frontFacing == ForgeDirection.SOUTH.ordinal()) - { - x = oX + horizontal; - mX = 0D; - z = oZ + offset; - mZ = .05D; - } - - ParticleEventBuilder particleEventBuilder = (new ParticleEventBuilder()).setMotion(mX, 0, mZ) - .setPosition(x, y, z) - .setWorld(getBaseMetaTileEntity().getWorld()); - particleEventBuilder.setIdentifier(ParticleFX.LAVA) - .run(); - } - } - } - default -> {} - } - } - - @Override - public RecipeMap getRecipeMap() { - return this.mRecipes; - } - - @Override - public int getRecipeCatalystPriority() { - return recipeCatalystPriority; - } - - public GT_MetaTileEntity_BasicMachine_GT_Recipe setRecipeCatalystPriority(int recipeCatalystPriority) { - this.recipeCatalystPriority = recipeCatalystPriority; - return this; - } - - @Override - public int getCapacity() { - return this.mTankCapacity; - } - - @Override - public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { - super.startSoundLoop(aIndex, aX, aY, aZ); - if (aIndex == 1 && this.mSoundResourceLocation != null - && GT_Utility.isStringValid(this.mSoundResourceLocation.getResourceDomain()) - && GT_Utility.isStringValid(this.mSoundResourceLocation.getResourcePath())) - GT_Utility.doSoundAtClient(this.mSoundResourceLocation, 100, 1.0F, aX, aY, aZ); - } - - @Override - public void startProcess() { - BaseMetaTileEntity myMetaTileEntity = ((BaseMetaTileEntity) this.getBaseMetaTileEntity()); - // Added to throttle sounds. To reduce lag, this is on the server side so BlockUpdate packets aren't sent. - if (myMetaTileEntity.mTickTimer > (myMetaTileEntity.mLastSoundTick + ticksBetweenSounds)) { - if (this.mSoundResourceLocation != null - && GT_Utility.isStringValid(this.mSoundResourceLocation.getResourceDomain()) - && GT_Utility.isStringValid(this.mSoundResourceLocation.getResourcePath())) - this.sendLoopStart((byte) 1); - // Does not have overflow protection, but they are longs. - myMetaTileEntity.mLastSoundTick = myMetaTileEntity.mTickTimer; - } - } - - @Override - protected BasicUIProperties getUIProperties() { - return super.getUIProperties().toBuilder() - .progressBarTexture(progressBarTexture) - .build(); - } - - public enum X { - PUMP, - WIRE, - WIRE4, - HULL, - PIPE, - GLASS, - PLATE, - MOTOR, - ROTOR, - SENSOR, - PISTON, - CIRCUIT, - EMITTER, - CONVEYOR, - ROBOT_ARM, - COIL_HEATING, - COIL_ELECTRIC, - STICK_MAGNETIC, - STICK_DISTILLATION, - BETTER_CIRCUIT, - FIELD_GENERATOR, - COIL_HEATING_DOUBLE, - STICK_ELECTROMAGNETIC - } - - /** - * Special Effects - */ - public enum SpecialEffects { - - NONE, - TOP_SMOKE, - MAIN_RANDOM_SPARKS; - - static final SpecialEffects[] VALID_SPECIAL_EFFECTS = { NONE, TOP_SMOKE, MAIN_RANDOM_SPARKS }; - - static SpecialEffects fromId(int id) { - return id >= 0 && id < VALID_SPECIAL_EFFECTS.length ? VALID_SPECIAL_EFFECTS[id] : NONE; - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Steel.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Steel.java deleted file mode 100644 index d6ae385430..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Steel.java +++ /dev/null @@ -1,150 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEELBRICKS_BOTTOM; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEELBRICKS_SIDE; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEELBRICKS_TOP; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEEL_BOTTOM; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEEL_SIDE; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEEL_TOP; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; - -import gregtech.api.enums.Dyes; -import gregtech.api.enums.SteamVariant; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IGetTitleColor; -import gregtech.api.objects.overclockdescriber.OverclockDescriber; -import gregtech.api.objects.overclockdescriber.SteamOverclockDescriber; -import gregtech.api.render.TextureFactory; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple - * Machine - */ -public abstract class GT_MetaTileEntity_BasicMachine_Steel extends GT_MetaTileEntity_BasicMachine_Bronze - implements IGetTitleColor { - - public GT_MetaTileEntity_BasicMachine_Steel(int aID, String aName, String aNameRegional, String aDescription, - int aInputSlotCount, int aOutputSlotCount, boolean aHighPressure) { - super(aID, aName, aNameRegional, aDescription, aInputSlotCount, aOutputSlotCount, aHighPressure); - } - - public GT_MetaTileEntity_BasicMachine_Steel(String aName, String[] aDescription, ITexture[][][] aTextures, - int aInputSlotCount, int aOutputSlotCount, boolean aHighPressure) { - super(aName, aDescription, aTextures, aInputSlotCount, aOutputSlotCount, aHighPressure); - } - - @Override - public OverclockDescriber createOverclockDescriber() { - return new SteamOverclockDescriber(SteamVariant.STEEL, 2, 1); - } - - @Override - public ITexture[] getSideFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getSideFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getFrontFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getFrontFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getTopFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getTopFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getBottomFacingActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getBottomFacingInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; - } - - @Override - public ITexture[] getBottomFacingPipeActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getBottomFacingPipeInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getTopFacingPipeActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getTopFacingPipeInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getSideFacingPipeActive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getSideFacingPipeInactive(byte aColor) { - return new ITexture[] { TextureFactory.of( - isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, - Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public SteamVariant getSteamVariant() { - return SteamVariant.STEEL; - } - - @Override - public int getTitleColor() { - return COLOR_TITLE_WHITE.get(); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java deleted file mode 100644 index 25fc7e7855..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicTank.java +++ /dev/null @@ -1,331 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; - -import com.gtnewhorizons.modularui.api.NumberFormatMUI; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.fluid.FluidStackTank; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; -import com.gtnewhorizons.modularui.common.widget.TextWidget; - -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_Utility; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my generic Tanks. Filling and emptying behavior have to be implemented manually - */ -public abstract class GT_MetaTileEntity_BasicTank extends GT_MetaTileEntity_TieredMachineBlock - implements IAddUIWidgets { - - public FluidStack mFluid; - // Due to class initializing order, getCapacity might not work properly at this time. - // So we pass supplier instead of current value here. - protected final FluidStackTank fluidTank = new FluidStackTank( - () -> mFluid, - fluidStack -> mFluid = fluidStack, - this::getRealCapacity); - - /** - * @param aInvSlotCount should be 3 - */ - public GT_MetaTileEntity_BasicTank(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicTank(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String[] aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicTank(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_BasicTank(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public boolean isSimpleMachine() { - return false; - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex != getStackDisplaySlot(); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - if (mFluid != null) aNBT.setTag("mFluid", mFluid.writeToNBT(new NBTTagCompound())); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - mFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid")); - } - - public abstract boolean doesFillContainers(); - - public abstract boolean doesEmptyContainers(); - - public abstract boolean canTankBeFilled(); - - public abstract boolean canTankBeEmptied(); - - public abstract boolean displaysItemStack(); - - /** - * @return If fluid amount is shown on FluidDisplayItem - */ - public abstract boolean displaysStackSize(); - - public int getInputSlot() { - return 0; - } - - public int getOutputSlot() { - return 1; - } - - public int getStackDisplaySlot() { - return 2; - } - - public boolean isFluidInputAllowed(FluidStack aFluid) { - return true; - } - - public boolean isFluidChangingAllowed() { - return true; - } - - public FluidStack getFillableStack() { - return mFluid; - } - - public FluidStack setFillableStack(FluidStack aFluid) { - mFluid = aFluid; - return mFluid; - } - - /** - * If you override this and change the field returned, be sure to override {@link #isDrainableStackSeparate()} as - * well! - */ - public FluidStack getDrainableStack() { - return mFluid; - } - - public FluidStack setDrainableStack(FluidStack aFluid) { - mFluid = aFluid; - return mFluid; - } - - public boolean isDrainableStackSeparate() { - return false; - } - - @Override - public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide()) { - if (isFluidChangingAllowed() && getFillableStack() != null && getFillableStack().amount <= 0) { - setFillableStack(null); - } - - final int inputSlot = getInputSlot(); - - if (doesEmptyContainers()) { - FluidStack tFluid = GT_Utility.getFluidForFilledItem(mInventory[inputSlot], true); - if (tFluid != null && isFluidInputAllowed(tFluid)) { - if (getFillableStack() == null) { - if (isFluidInputAllowed(tFluid) && tFluid.amount <= getCapacity()) { - if (aBaseMetaTileEntity.addStackToSlot( - getOutputSlot(), - GT_Utility.getContainerForFilledItem(mInventory[inputSlot], true), - 1)) { - setFillableStack(tFluid.copy()); - this.onEmptyingContainerWhenEmpty(); - aBaseMetaTileEntity.decrStackSize(inputSlot, 1); - } - } - } else { - if (tFluid.isFluidEqual(getFillableStack()) - && ((long) tFluid.amount + getFillableStack().amount) <= (long) getCapacity()) { - if (aBaseMetaTileEntity.addStackToSlot( - getOutputSlot(), - GT_Utility.getContainerForFilledItem(mInventory[inputSlot], true), - 1)) { - getFillableStack().amount += tFluid.amount; - aBaseMetaTileEntity.decrStackSize(inputSlot, 1); - } - } - } - } - } - - if (doesFillContainers()) { - ItemStack tOutput = GT_Utility - .fillFluidContainer(getDrainableStack(), mInventory[inputSlot], false, true); - if (tOutput != null && aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), tOutput, 1)) { - FluidStack tFluid = GT_Utility.getFluidForFilledItem(tOutput, true); - aBaseMetaTileEntity.decrStackSize(inputSlot, 1); - if (tFluid != null) getDrainableStack().amount -= tFluid.amount; - if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) setDrainableStack(null); - } - } - } - } - - @Override - public FluidStack getFluid() { - return getDrainableStack(); - } - - @Override - public int getFluidAmount() { - return getDrainableStack() != null ? getDrainableStack().amount : 0; - } - - @Override - public int fill(FluidStack aFluid, boolean doFill) { - if (aFluid == null || aFluid.getFluid() - .getID() <= 0 || aFluid.amount <= 0 || !canTankBeFilled() || !isFluidInputAllowed(aFluid)) return 0; - - if (getFillableStack() == null || getFillableStack().getFluid() - .getID() <= 0) { - if (aFluid.amount <= getCapacity()) { - if (doFill) { - setFillableStack(aFluid.copy()); - getBaseMetaTileEntity().markDirty(); - } - return aFluid.amount; - } - if (doFill) { - setFillableStack(aFluid.copy()); - getFillableStack().amount = getCapacity(); - getBaseMetaTileEntity().markDirty(); - } - return getCapacity(); - } - - if (!getFillableStack().isFluidEqual(aFluid)) return 0; - - int space = getCapacity() - getFillableStack().amount; - if (aFluid.amount <= space) { - if (doFill) { - getFillableStack().amount += aFluid.amount; - getBaseMetaTileEntity().markDirty(); - } - return aFluid.amount; - } - if (doFill) getFillableStack().amount = getCapacity(); - return space; - } - - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - if (getDrainableStack() == null || !canTankBeEmptied()) return null; - if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) { - setDrainableStack(null); - getBaseMetaTileEntity().markDirty(); - return null; - } - - int used = maxDrain; - if (getDrainableStack().amount < used) used = getDrainableStack().amount; - - if (doDrain) { - getDrainableStack().amount -= used; - getBaseMetaTileEntity().markDirty(); - } - - FluidStack drained = getDrainableStack().copy(); - drained.amount = used; - - if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) { - setDrainableStack(null); - getBaseMetaTileEntity().markDirty(); - } - - return drained; - } - - @Override - public FluidTankInfo[] getTankInfo(ForgeDirection side) { - if (getCapacity() <= 0 && !getBaseMetaTileEntity().hasSteamEngineUpgrade()) return new FluidTankInfo[] {}; - if (isDrainableStackSeparate()) { - return new FluidTankInfo[] { new FluidTankInfo(getFillableStack(), getCapacity()), - new FluidTankInfo(getDrainableStack(), getCapacity()) }; - } else { - return new FluidTankInfo[] { new FluidTankInfo(this) }; - } - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return aIndex == getOutputSlot(); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return aIndex == getInputSlot(); - } - - protected void onEmptyingContainerWhenEmpty() { - // Do nothing - } - - protected static final NumberFormatMUI numberFormat = new NumberFormatMUI(); - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(7, 16) - .setSize(71, 45)) - .widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_GAUGE) - .setPos(79, 34) - .setSize(18, 18)) - .widget( - new SlotWidget(inventoryHandler, getInputSlot()) - .setBackground(getGUITextureSet().getItemSlot(), GT_UITextures.OVERLAY_SLOT_IN) - .setPos(79, 16)) - .widget( - new SlotWidget(inventoryHandler, getOutputSlot()).setAccess(true, false) - .setBackground(getGUITextureSet().getItemSlot(), GT_UITextures.OVERLAY_SLOT_OUT) - .setPos(79, 52)) - .widget( - createFluidSlot().setBackground(GT_UITextures.TRANSPARENT) - .setPos(58, 41)) - .widget( - new TextWidget("Liquid Amount").setDefaultColor(COLOR_TEXT_WHITE.get()) - .setPos(10, 20)) - .widget( - new TextWidget().setStringSupplier(() -> numberFormat.format(mFluid != null ? mFluid.amount : 0)) - .setDefaultColor(COLOR_TEXT_WHITE.get()) - .setPos(10, 30)); - } - - protected FluidSlotWidget createFluidSlot() { - return new FluidSlotWidget(fluidTank); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java deleted file mode 100644 index ef64d99db8..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Buffer.java +++ /dev/null @@ -1,563 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_DOWN; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_DOWN_GLOW; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_LEFT; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_LEFT_GLOW; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_RIGHT; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_RIGHT_GLOW; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_UP; -import static gregtech.api.enums.Textures.BlockIcons.ARROW_UP_GLOW; -import static gregtech.api.enums.Textures.BlockIcons.MACHINE_CASINGS; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; -import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.IntStream; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.drawable.UITexture; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; -import com.gtnewhorizons.modularui.common.widget.SlotGroup; - -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_TooltipDataCache; -import gregtech.api.util.GT_Utility; - -public abstract class GT_MetaTileEntity_Buffer extends GT_MetaTileEntity_TieredMachineBlock implements IAddUIWidgets { - - private static final int OUTPUT_INDEX = 0; - private static final int ARROW_RIGHT_INDEX = 1; - private static final int ARROW_DOWN_INDEX = 2; - private static final int ARROW_LEFT_INDEX = 3; - private static final int ARROW_UP_INDEX = 4; - private static final int FRONT_INDEX = 5; - - private static final String EMIT_ENERGY_TOOLTIP = "GT5U.machines.emit_energy.tooltip"; - private static final String EMIT_REDSTONE_IF_FULL_TOOLTIP = "GT5U.machines.emit_redstone_if_full.tooltip"; - private static final String INVERT_REDSTONE_TOOLTIP = "GT5U.machines.invert_redstone.tooltip"; - private static final String STOCKING_MODE_TOOLTIP = "GT5U.machines.buffer_stocking_mode.tooltip"; - private static final String SORTING_MODE_TOOLTIP = "GT5U.machines.sorting_mode.tooltip"; - private static final int BUTTON_SIZE = 18; - - public int mMaxStackSize = 64; - public static int MAX = 8; - public boolean bOutput = false, bRedstoneIfFull = false, bInvert = false, bStockingMode = false, - bSortStacks = false; - public int mSuccess = 0, mTargetStackSize = 0; - private int uiButtonCount = 0; - - public GT_MetaTileEntity_Buffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_Buffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String[] aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_Buffer(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_Buffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[ForgeDirection.VALID_DIRECTIONS.length][17][]; - ITexture tIcon = getOverlayIcon(); - ITexture tOut = TextureFactory.of(OVERLAY_PIPE_OUT); - ITexture tUp = TextureFactory.of( - TextureFactory.of(ARROW_UP), - TextureFactory.builder() - .addIcon(ARROW_UP_GLOW) - .glow() - .build()); - ITexture tDown = TextureFactory.of( - TextureFactory.of(ARROW_DOWN), - TextureFactory.builder() - .addIcon(ARROW_DOWN_GLOW) - .glow() - .build()); - ITexture tLeft = TextureFactory.of( - TextureFactory.of(ARROW_LEFT), - TextureFactory.builder() - .addIcon(ARROW_LEFT_GLOW) - .glow() - .build()); - ITexture tRight = TextureFactory.of( - TextureFactory.of(ARROW_RIGHT), - TextureFactory.builder() - .addIcon(ARROW_RIGHT_GLOW) - .glow() - .build()); - for (int i = 0; i < rTextures[0].length; i++) { - rTextures[OUTPUT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tOut }; - rTextures[ARROW_RIGHT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tRight, tIcon }; - rTextures[ARROW_DOWN_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tDown, tIcon }; - rTextures[ARROW_LEFT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tLeft, tIcon }; - rTextures[ARROW_UP_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tUp, tIcon }; - rTextures[FRONT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tIcon }; - } - return rTextures; - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, - ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { - colorIndex = colorIndex + 1; - if (sideDirection == facingDirection) return mTextures[FRONT_INDEX][colorIndex]; - if (sideDirection.getOpposite() == facingDirection) return mTextures[OUTPUT_INDEX][colorIndex]; - switch (facingDirection) { - case DOWN -> { - return mTextures[ARROW_UP_INDEX][colorIndex]; // ARROW_UP - } - case UP -> { - return mTextures[ARROW_DOWN_INDEX][colorIndex]; // ARROW_DOWN - } - case NORTH -> { - switch (sideDirection) { - case DOWN, UP -> { - return mTextures[ARROW_DOWN_INDEX][colorIndex]; // ARROW_DOWN - } - case WEST -> { - return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT - } - case EAST -> { - return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT - } - default -> {} - } - } - case SOUTH -> { - switch (sideDirection) { - case DOWN, UP -> { - return mTextures[ARROW_UP_INDEX][colorIndex]; // ARROW_UP - } - case WEST -> { - return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT - } - case EAST -> { - return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT - } - default -> {} - } - } - case WEST -> { - switch (sideDirection) { - case UP, SOUTH -> { - return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT - } - case DOWN, NORTH -> { - return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT - } - default -> {} - } - } - case EAST -> { - switch (sideDirection) { - case UP, SOUTH -> { - return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT - } - case DOWN, NORTH -> { - return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT - } - default -> {} - } - } - default -> {} - } - return mTextures[FRONT_INDEX][colorIndex]; - } - - @Override - public boolean isSimpleMachine() { - return false; - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex < mInventory.length - 1; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isEnetInput() { - return true; - } - - @Override - public boolean isEnetOutput() { - return true; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return !isOutputFacing(side); - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return getBaseMetaTileEntity().getBackFacing() == side; - } - - @Override - public boolean isTeleporterCompatible() { - return false; - } - - @Override - public long getMinimumStoredEU() { - return 512L; - } - - @Override - public long maxEUStore() { - return 512L + V[mTier] * 50L; - } - - @Override - public long maxEUInput() { - return V[mTier]; - } - - @Override - public long maxEUOutput() { - // Return full value if we're an item and don't exist in the world for tooltip purposes - return getBaseMetaTileEntity().getWorld() == null || bOutput ? V[mTier] : 0L; - } - - @Override - public long maxAmperesIn() { - return 2; - } - - @Override - public long maxAmperesOut() { - return 2; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - public abstract ITexture getOverlayIcon(); - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - aNBT.setBoolean("bInvert", bInvert); - aNBT.setBoolean("bOutput", bOutput); - aNBT.setBoolean("bRedstoneIfFull", bRedstoneIfFull); - aNBT.setBoolean("bStockingMode", bStockingMode); - aNBT.setInteger("mTargetStackSize", mTargetStackSize); - aNBT.setBoolean("bSortStacks", bSortStacks); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - bInvert = aNBT.getBoolean("bInvert"); - bOutput = aNBT.getBoolean("bOutput"); - bRedstoneIfFull = aNBT.getBoolean("bRedstoneIfFull"); - bSortStacks = aNBT.getBoolean("bSortStacks"); - bStockingMode = aNBT.getBoolean("bStockingMode"); - mTargetStackSize = aNBT.getInteger("mTargetStackSize"); - } - - @Override - public void setItemNBT(NBTTagCompound aNBT) { - super.setItemNBT(aNBT); - if (mTargetStackSize > 0) aNBT.setInteger("mTargetStackSize", mTargetStackSize); - } - - @Override - public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { - if (side == getBaseMetaTileEntity().getBackFacing()) { - - mTargetStackSize = (byte) ((mTargetStackSize + (aPlayer.isSneaking() ? -1 : 1)) % 65); - if (mTargetStackSize < 0) { - mTargetStackSize = mMaxStackSize; - } - if (mTargetStackSize == 0) { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("098", "Do not regulate Item Stack Size")); - } else { - GT_Utility.sendChatToPlayer( - aPlayer, - GT_Utility.trans("099", "Regulate Item Stack Size to: ") + mTargetStackSize); - } - } - } - - @Override - public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, - float aX, float aY, float aZ) { - wrenchingSide = wrenchingSide.getOpposite(); - if (getBaseMetaTileEntity().isValidFacing(wrenchingSide)) { - getBaseMetaTileEntity().setFrontFacing(wrenchingSide); - return true; - } - return false; - } - - protected void handleRedstoneOutput(IGregTechTileEntity aBaseMetaTileEntity) { - int redstoneOutput = getRedstoneOutput(); - Arrays.stream(ForgeDirection.VALID_DIRECTIONS) - .forEach(side -> aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) redstoneOutput)); - } - - protected int getRedstoneOutput() { - return (!bRedstoneIfFull || (bInvert ^ hasEmptySlots())) ? 0 : 15; - } - - private boolean hasEmptySlots() { - return IntStream.range(0, mInventory.length) - .anyMatch(i -> isValidSlot(i) && mInventory[i] == null); - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - if (aBaseMetaTileEntity.isAllowedToWork() && aBaseMetaTileEntity.isServerSide() - && (aBaseMetaTileEntity.hasWorkJustBeenEnabled() || aBaseMetaTileEntity.hasInventoryBeenModified() - || aTimer % 200 == 0 - || mSuccess > 0)) { - mSuccess--; - updateSlots(); - moveItems(aBaseMetaTileEntity, aTimer); - handleRedstoneOutput(aBaseMetaTileEntity); - } - } - - @Override - public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { - for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) - aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) 0); - } - - protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - moveItems(aBaseMetaTileEntity, aTimer, 1); - } - - protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long ignoredTimer, int stacks) { - int tCost; - if (bStockingMode) tCost = GT_Utility.moveMultipleItemStacks( - aBaseMetaTileEntity, - aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getBackFacing()), - aBaseMetaTileEntity.getBackFacing(), - aBaseMetaTileEntity.getFrontFacing(), - null, - false, - mTargetStackSize == 0 ? 64 : (byte) mTargetStackSize, - mTargetStackSize == 0 ? 1 : (byte) mTargetStackSize, - (byte) 64, - (byte) 1, - stacks); - else tCost = GT_Utility.moveMultipleItemStacks( - aBaseMetaTileEntity, - aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getBackFacing()), - aBaseMetaTileEntity.getBackFacing(), - aBaseMetaTileEntity.getFrontFacing(), - null, - false, - (byte) 64, - (byte) 1, - mTargetStackSize == 0 ? 64 : (byte) mTargetStackSize, - mTargetStackSize == 0 ? 1 : (byte) mTargetStackSize, - stacks); - - if (tCost > 0 || aBaseMetaTileEntity.hasInventoryBeenModified()) { - mSuccess = 50; - } - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return true; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side != aBaseMetaTileEntity.getBackFacing(); - } - - @Override - public boolean allowGeneralRedstoneOutput() { - return true; - } - - public void updateSlots() { - for (int i = 0; i < mInventory.length; i++) - if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; - if (bSortStacks) fillStacksIntoFirstSlots(); - } - - protected void fillStacksIntoFirstSlots() { - HashMap slots = new HashMap<>(mInventory.length); - HashMap stacks = new HashMap<>(mInventory.length); - List order = new ArrayList<>(mInventory.length); - List validSlots = new ArrayList<>(mInventory.length); - for (int i = 0; i < mInventory.length - 1; i++) { - if (!isValidSlot(i)) continue; - validSlots.add(i); - ItemStack s = mInventory[i]; - if (s == null) continue; - GT_Utility.ItemId sID = GT_Utility.ItemId.createNoCopy(s); - slots.merge(sID, s.stackSize, Integer::sum); - if (!stacks.containsKey(sID)) stacks.put(sID, s); - order.add(sID); - mInventory[i] = null; - } - int slotindex = 0; - for (GT_Utility.ItemId sID : order) { - int toSet = slots.get(sID); - if (toSet == 0) continue; - int slot = validSlots.get(slotindex); - slotindex++; - mInventory[slot] = stacks.get(sID) - .copy(); - toSet = Math.min(toSet, mInventory[slot].getMaxStackSize()); - mInventory[slot].stackSize = toSet; - slots.merge(sID, toSet, (a, b) -> a - b); - } - } - - @Override - public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, - EntityPlayer entityPlayer, float aX, float aY, float aZ) { - if (entityPlayer.isSneaking()) { - // I was so proud of all this but I literally just copied code from OutputBus - bSortStacks = !bSortStacks; - GT_Utility.sendChatToPlayer( - entityPlayer, - GT_Utility.trans("200", "Sort mode: ") - + (bSortStacks ? GT_Utility.trans("088", "Enabled") : GT_Utility.trans("087", "Disabled"))); - return true; - } - return super.onSolderingToolRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); - } - - protected void addEmitEnergyButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> bOutput, - val -> bOutput = val, - GT_UITextures.OVERLAY_BUTTON_EMIT_ENERGY, - this::getEmitEnergyButtonTooltip)); - } - - private GT_TooltipDataCache.TooltipData getEmitEnergyButtonTooltip() { - return mTooltipCache.getData( - EMIT_ENERGY_TOOLTIP, - EnumChatFormatting.GREEN + GT_Utility.formatNumbers(V[mTier]) - + " (" - + GT_Utility.getColoredTierNameFromTier(mTier) - + EnumChatFormatting.GREEN - + ")" - + EnumChatFormatting.GRAY, - maxAmperesOut()); - } - - protected void addEmitRedstoneIfFullButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> bRedstoneIfFull, - val -> bRedstoneIfFull = val, - GT_UITextures.OVERLAY_BUTTON_EMIT_REDSTONE, - this::getEmitRedstoneIfFullButtonTooltip).setUpdateTooltipEveryTick(true)); - } - - private GT_TooltipDataCache.TooltipData getEmitRedstoneIfFullButtonTooltip() { - return mTooltipCache.getUncachedTooltipData( - EMIT_REDSTONE_IF_FULL_TOOLTIP, - StatCollector.translateToLocal(hasEmptySlots() ? "gui.yes" : "gui.no"), - getRedstoneOutput()); - } - - protected void addInvertRedstoneButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> bInvert, - val -> bInvert = val, - GT_UITextures.OVERLAY_BUTTON_INVERT_REDSTONE, - () -> mTooltipCache.getData(INVERT_REDSTONE_TOOLTIP))); - } - - protected void addStockingModeButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> bStockingMode, - val -> bStockingMode = val, - GT_UITextures.OVERLAY_BUTTON_STOCKING_MODE, - () -> mTooltipCache.getData(STOCKING_MODE_TOOLTIP))); - } - - protected void addSortStacksButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> bSortStacks, - val -> bSortStacks = val, - GT_UITextures.OVERLAY_BUTTON_SORTING_MODE, - () -> mTooltipCache.getData(SORTING_MODE_TOOLTIP))); - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - buildContext.addCloseListener(() -> uiButtonCount = 0); - addEmitEnergyButton(builder); - } - - protected Widget createToggleButton(Supplier getter, Consumer setter, UITexture picture, - Supplier tooltipDataSupplier) { - return new CycleButtonWidget().setToggle(getter, setter) - .setStaticTexture(picture) - .setVariableBackground(GT_UITextures.BUTTON_STANDARD_TOGGLE) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(7 + (uiButtonCount++ * BUTTON_SIZE), 62) - .setSize(BUTTON_SIZE, BUTTON_SIZE) - .setGTTooltip(tooltipDataSupplier); - } - - protected void addInventorySlots(ModularWindow.Builder builder) { - builder.widget( - SlotGroup.ofItemHandler(inventoryHandler, 9) - .endAtSlot(26) - .build() - .setPos(7, 4)); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java deleted file mode 100644 index efb91e3a26..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_CubicMultiBlockBase.java +++ /dev/null @@ -1,141 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static com.gtnewhorizon.structurelib.structure.StructureUtility.lazy; -import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; -import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; -import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; -import static gregtech.api.enums.GT_HatchElement.Energy; -import static gregtech.api.enums.GT_HatchElement.InputBus; -import static gregtech.api.enums.GT_HatchElement.InputHatch; -import static gregtech.api.enums.GT_HatchElement.Maintenance; -import static gregtech.api.enums.GT_HatchElement.Muffler; -import static gregtech.api.enums.GT_HatchElement.OutputBus; -import static gregtech.api.enums.GT_HatchElement.OutputHatch; - -import java.util.List; - -import net.minecraft.item.ItemStack; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; -import com.gtnewhorizon.structurelib.structure.IStructureDefinition; -import com.gtnewhorizon.structurelib.structure.IStructureElement; -import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; -import com.gtnewhorizon.structurelib.structure.StructureDefinition; - -import gregtech.api.interfaces.IHatchElement; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_StructureUtility; - -/** - * A simple 3x3x3 hollow cubic multiblock, that can be arbitrarily rotated, made of a single type of machine casing and - * accepts hatches everywhere. Controller will be placed in front center of the structure. - *

- * Note: You cannot use different casing for the same Class. Make a new subclass for it. You also should not change the - * casing dynamically, i.e. it should be a dumb method returning some sort of constant. - *

- * Implementation tips: 1. To restrict hatches, override {@link #addDynamoToMachineList(IGregTechTileEntity, int)} and - * its cousins instead of overriding the whole {@link #getStructureDefinition()} or change - * {@link #checkHatches(IGregTechTileEntity, ItemStack)}. The former is a total overkill, while the later cannot stop - * the structure check early. 2. To limit rotation, override {@link #getInitialAlignmentLimits()} - * - * @param - */ -public abstract class GT_MetaTileEntity_CubicMultiBlockBase> - extends GT_MetaTileEntity_EnhancedMultiBlockBase implements ISurvivalConstructable { - - protected static final String STRUCTURE_PIECE_MAIN = "main"; - protected static final ClassValue>> STRUCTURE_DEFINITION = new ClassValue<>() { - - @Override - protected IStructureDefinition> computeValue(Class type) { - return StructureDefinition.>builder() - .addShape( - STRUCTURE_PIECE_MAIN, - transpose( - new String[][] { { "hhh", "hhh", "hhh" }, { "h~h", "h-h", "hhh" }, { "hhh", "hhh", "hhh" }, })) - .addElement( - 'h', - ofChain( - lazy( - t -> GT_StructureUtility.>buildHatchAdder() - .atLeastList(t.getAllowedHatches()) - .casingIndex(t.getHatchTextureIndex()) - .dot(1) - .build()), - onElementPass( - GT_MetaTileEntity_CubicMultiBlockBase::onCorrectCasingAdded, - lazy(GT_MetaTileEntity_CubicMultiBlockBase::getCasingElement)))) - .build(); - } - }; - private int mCasingAmount = 0; - - protected GT_MetaTileEntity_CubicMultiBlockBase(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional); - } - - protected GT_MetaTileEntity_CubicMultiBlockBase(String aName) { - super(aName); - } - - /** - * Create a simple 3x3x3 hollow cubic structure made of a single type of machine casing and accepts hatches - * everywhere. - *

- * The created definition contains a single piece named {@link #STRUCTURE_PIECE_MAIN}. - */ - @Override - @SuppressWarnings("unchecked") - public IStructureDefinition getStructureDefinition() { - return (IStructureDefinition) STRUCTURE_DEFINITION.get(getClass()); - } - - @Override - public void construct(ItemStack aStack, boolean aHintsOnly) { - buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 1, 1, 0); - } - - @Override - public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { - if (mMachine) return -1; - return survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 1, 1, 0, elementBudget, env, false, true); - } - - @Override - public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { - mCasingAmount = 0; - return checkPiece(STRUCTURE_PIECE_MAIN, 1, 1, 0) && mCasingAmount >= getRequiredCasingCount() - && checkHatches(aBaseMetaTileEntity, aStack); - } - - /** - * Called by {@link #checkMachine(IGregTechTileEntity, ItemStack)} to check if all required hatches are present. - *

- * Default implementation requires EXACTLY ONE maintenance hatch to be present, and ignore all other conditions. - * - * @param aBaseMetaTileEntity the tile entity of self - * @param aStack The item stack inside the controller - * @return true if the test passes, false otherwise - */ - protected boolean checkHatches(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { - return mMaintenanceHatches.size() == 1; - } - - protected abstract IStructureElement> getCasingElement(); - - protected List>> getAllowedHatches() { - return ImmutableList.of(InputHatch, OutputHatch, InputBus, OutputBus, Muffler, Maintenance, Energy); - } - - /** - * The hatch's texture index. - */ - protected abstract int getHatchTextureIndex(); - - protected abstract int getRequiredCasingCount(); - - protected void onCorrectCasingAdded() { - mCasingAmount++; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java deleted file mode 100644 index 15ce78fae3..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java +++ /dev/null @@ -1,318 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; -import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; -import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable; -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.IItemSource; -import com.gtnewhorizon.structurelib.structure.IStructureDefinition; -import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; - -import cpw.mods.fml.common.network.NetworkRegistry; -import gregtech.api.GregTech_API; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_Multiblock_Tooltip_Builder; -import gregtech.api.util.shutdown.ShutDownReasonRegistry; - -/** - * Enhanced multiblock base class, featuring following improvement over {@link GT_MetaTileEntity_MultiBlockBase} - *

- * 1. TecTech style declarative structure check utilizing StructureLib. 2. Arbitrarily rotating the whole structure, if - * allowed to. - * - * @param type of this - */ -public abstract class GT_MetaTileEntity_EnhancedMultiBlockBase> - extends GT_MetaTileEntity_TooltipMultiBlockBase implements IAlignment, IConstructable { - - private ExtendedFacing mExtendedFacing = ExtendedFacing.DEFAULT; - private IAlignmentLimits mLimits = getInitialAlignmentLimits(); - - protected GT_MetaTileEntity_EnhancedMultiBlockBase(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional); - } - - protected GT_MetaTileEntity_EnhancedMultiBlockBase(String aName) { - super(aName); - } - - @Override - public ExtendedFacing getExtendedFacing() { - return mExtendedFacing; - } - - @Override - public void setExtendedFacing(ExtendedFacing newExtendedFacing) { - if (mExtendedFacing != newExtendedFacing) { - if (mMachine) stopMachine(ShutDownReasonRegistry.STRUCTURE_INCOMPLETE); - mExtendedFacing = newExtendedFacing; - final IGregTechTileEntity base = getBaseMetaTileEntity(); - mMachine = false; - mUpdated = false; - mUpdate = 50; - if (getBaseMetaTileEntity().isServerSide() - && !GregTech_API.isDummyWorld(getBaseMetaTileEntity().getWorld())) { - StructureLibAPI.sendAlignment( - (IAlignmentProvider) base, - new NetworkRegistry.TargetPoint( - base.getWorld().provider.dimensionId, - base.getXCoord(), - base.getYCoord(), - base.getZCoord(), - 512)); - } else { - base.issueTextureUpdate(); - } - } - } - - @Override - public final boolean isFacingValid(ForgeDirection facing) { - return canSetToDirectionAny(facing); - } - - @Override - public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, - float aX, float aY, float aZ) { - if (wrenchingSide != getBaseMetaTileEntity().getFrontFacing()) - return super.onWrenchRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); - if (entityPlayer.isSneaking()) { - if (isFlipChangeAllowed()) { - toolSetFlip(getFlip().isHorizontallyFlipped() ? Flip.NONE : Flip.HORIZONTAL); - } else { - return false; - } - } else { - if (isRotationChangeAllowed()) { - toolSetRotation(null); - } else { - return false; - } - } - return true; - } - - @Override - public void onFacingChange() { - toolSetDirection(getBaseMetaTileEntity().getFrontFacing()); - } - - @Override - public IAlignmentLimits getAlignmentLimits() { - return mLimits; - } - - protected void setAlignmentLimits(IAlignmentLimits mLimits) { - this.mLimits = mLimits; - } - - /** - * Due to limitation of Java type system, you might need to do an unchecked cast. HOWEVER, the returned - * IStructureDefinition is expected to be evaluated against current instance only, and should not be used against - * other instances, even for those of the same class. - */ - public abstract IStructureDefinition getStructureDefinition(); - - protected abstract GT_Multiblock_Tooltip_Builder createTooltip(); - - @Override - public String[] getStructureDescription(ItemStack stackSize) { - return getTooltip().getStructureHint(); - } - - protected IAlignmentLimits getInitialAlignmentLimits() { - return (d, r, f) -> !f.isVerticallyFliped(); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setByte( - "eRotation", - (byte) mExtendedFacing.getRotation() - .getIndex()); - aNBT.setByte( - "eFlip", - (byte) mExtendedFacing.getFlip() - .getIndex()); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - mExtendedFacing = ExtendedFacing.of( - getBaseMetaTileEntity().getFrontFacing(), - Rotation.byIndex(aNBT.getByte("eRotation")), - Flip.byIndex(aNBT.getByte("eFlip"))); - if (!getAlignmentLimits().isNewExtendedFacingValid(mExtendedFacing)) { - mExtendedFacing = getCorrectedAlignment(mExtendedFacing); - } - } - - /** - * When an old {@link ExtendedFacing} is loaded upon MTE deserialization, and the loaded facing cannot pass test of - * current {@link #getAlignmentLimits()}, this method will be called to retrieve a corrected version. This method - * is currently only intended to be used as a mean to migrate alignment limits, so if you never change the alignment - * limit then you can probably just use the default implementation. - * - * The returned new facing must be able to pass the test of {@link #isNewExtendedFacingValid(ExtendedFacing)} - */ - protected ExtendedFacing getCorrectedAlignment(ExtendedFacing aOldFacing) { - if (isNewExtendedFacingValid(ExtendedFacing.DEFAULT)) { - return ExtendedFacing.DEFAULT; - } - for (ExtendedFacing facing : ExtendedFacing.VALUES) { - if (facing.getFlip() - .isVerticallyFliped()) { - continue; - } - if (isNewExtendedFacingValid(facing)) { - return facing; - } - } - throw new AssertionError("No ExtendedFacing can pass the test of isNewExtendedFacingValid"); - } - - @SuppressWarnings("unchecked") - private IStructureDefinition> getCastedStructureDefinition() { - return (IStructureDefinition>) getStructureDefinition(); - } - - /** - * Explanation of the world coordinate these offset means: - *

- * Imagine you stand in front of the controller, with controller facing towards you not rotated or flipped. - *

- * The horizontalOffset would be the number of blocks on the left side of the controller, not counting controller - * itself. The verticalOffset would be the number of blocks on the top side of the controller, not counting - * controller itself. The depthOffset would be the number of blocks between you and controller, not counting - * controller itself. - *

- * All these offsets can be negative. - */ - protected final boolean checkPiece(String piece, int horizontalOffset, int verticalOffset, int depthOffset) { - final IGregTechTileEntity tTile = getBaseMetaTileEntity(); - return getCastedStructureDefinition().check( - this, - piece, - tTile.getWorld(), - getExtendedFacing(), - tTile.getXCoord(), - tTile.getYCoord(), - tTile.getZCoord(), - horizontalOffset, - verticalOffset, - depthOffset, - !mMachine); - } - - protected final boolean buildPiece(String piece, ItemStack trigger, boolean hintOnly, int horizontalOffset, - int verticalOffset, int depthOffset) { - final IGregTechTileEntity tTile = getBaseMetaTileEntity(); - return getCastedStructureDefinition().buildOrHints( - this, - trigger, - piece, - tTile.getWorld(), - getExtendedFacing(), - tTile.getXCoord(), - tTile.getYCoord(), - tTile.getZCoord(), - horizontalOffset, - verticalOffset, - depthOffset, - hintOnly); - } - - @Deprecated - protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, - int depthOffset, int elementsBudget, IItemSource source, EntityPlayerMP actor, boolean check) { - final IGregTechTileEntity tTile = getBaseMetaTileEntity(); - return getCastedStructureDefinition().survivalBuild( - this, - trigger, - piece, - tTile.getWorld(), - getExtendedFacing(), - tTile.getXCoord(), - tTile.getYCoord(), - tTile.getZCoord(), - horizontalOffset, - verticalOffset, - depthOffset, - elementsBudget, - source, - actor, - check); - } - - protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, - int depthOffset, int elementsBudget, ISurvivalBuildEnvironment env, boolean check) { - final IGregTechTileEntity tTile = getBaseMetaTileEntity(); - return getCastedStructureDefinition().survivalBuild( - this, - trigger, - piece, - tTile.getWorld(), - getExtendedFacing(), - tTile.getXCoord(), - tTile.getYCoord(), - tTile.getZCoord(), - horizontalOffset, - verticalOffset, - depthOffset, - elementsBudget, - env, - check); - } - - @Deprecated - protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, - int depthOffset, int elementsBudget, IItemSource source, EntityPlayerMP actor, boolean check, - boolean checkIfPlaced) { - int built = survivialBuildPiece( - piece, - trigger, - horizontalOffset, - verticalOffset, - depthOffset, - elementsBudget, - source, - actor, - check); - if (checkIfPlaced && built > 0) checkStructure(true, getBaseMetaTileEntity()); - return built; - } - - protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, - int depthOffset, int elementsBudget, ISurvivalBuildEnvironment env, boolean check, boolean checkIfPlaced) { - int built = survivialBuildPiece( - piece, - trigger, - horizontalOffset, - verticalOffset, - depthOffset, - elementsBudget, - env, - check); - if (checkIfPlaced && built > 0) checkStructure(true, getBaseMetaTileEntity()); - return built; - } - - @Override - public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { - super.onFirstTick(aBaseMetaTileEntity); - if (aBaseMetaTileEntity.isClientSide()) - StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java deleted file mode 100644 index f430114319..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java +++ /dev/null @@ -1,242 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.VN; -import static gregtech.api.util.GT_Utility.filterValidMTEs; - -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnull; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; - -import org.jetbrains.annotations.NotNull; - -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.logic.ProcessingLogic; -import gregtech.api.recipe.check.CheckRecipeResult; -import gregtech.api.util.GT_ExoticEnergyInputHelper; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.shutdown.ShutDownReason; -import gregtech.api.util.shutdown.ShutDownReasonRegistry; - -/** - * Multiblock base class that allows machine to use power over int. - */ -public abstract class GT_MetaTileEntity_ExtendedPowerMultiBlockBase> - extends GT_MetaTileEntity_EnhancedMultiBlockBase { - - public long lEUt; - - protected GT_MetaTileEntity_ExtendedPowerMultiBlockBase(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional); - } - - protected GT_MetaTileEntity_ExtendedPowerMultiBlockBase(String aName) { - super(aName); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - // NBT can be loaded as any primitive type, so we can load it as long. - this.lEUt = aNBT.getLong("mEUt"); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setLong("mEUt", this.lEUt); - } - - @Override - protected void calculateOverclockedNessMultiInternal(long aEUt, int aDuration, int mAmperage, long maxInputVoltage, - boolean perfectOC) { - GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(aEUt) - .setEUt(maxInputVoltage * mAmperage) - .setDuration(aDuration) - .setDurationDecreasePerOC(perfectOC ? 4.0 : 2.0) - .calculate(); - lEUt = calculator.getConsumption(); - mMaxProgresstime = calculator.getDuration(); - } - - @Override - public boolean onRunningTick(ItemStack aStack) { - if (this.lEUt > 0) { - addEnergyOutput((this.lEUt * mEfficiency) / 10000); - return true; - } - if (this.lEUt < 0) { - if (!drainEnergyInput(getActualEnergyUsage())) { - stopMachine(ShutDownReasonRegistry.POWER_LOSS); - return false; - } - } - return true; - } - - @Override - public void stopMachine(@NotNull ShutDownReason reason) { - this.lEUt = 0; - super.stopMachine(reason); - } - - @Override - protected long getActualEnergyUsage() { - return (-this.lEUt * 10000) / Math.max(1000, mEfficiency); - } - - public List getExoticAndNormalEnergyHatchList() { - List tHatches = new ArrayList<>(); - tHatches.addAll(filterValidMTEs(mExoticEnergyHatches)); - tHatches.addAll(filterValidMTEs(mEnergyHatches)); - return tHatches; - } - - @Override - public boolean drainEnergyInput(long aEU) { - return GT_ExoticEnergyInputHelper.drainEnergy(aEU, getExoticAndNormalEnergyHatchList()); - } - - @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); - - final IGregTechTileEntity tileEntity = getBaseMetaTileEntity(); - if (tileEntity != null) { - if (tileEntity.isActive()) { - if (lEUt < 0) tag.setLong("energyUsage", getActualEnergyUsage()); - else tag.setLong("energyUsage", -lEUt * mEfficiency / 10000); - } - } - } - - @Override - protected void setProcessingLogicPower(ProcessingLogic logic) { - logic.setAvailableVoltage(getAverageInputVoltage()); - logic.setAvailableAmperage(getMaxInputAmps()); - logic.setAmperageOC(true); - } - - @Nonnull - @Override - protected CheckRecipeResult postCheckRecipe(@Nonnull CheckRecipeResult result, - @Nonnull ProcessingLogic processingLogic) { - return result; - } - - @Override - protected void setEnergyUsage(ProcessingLogic processingLogic) { - lEUt = processingLogic.getCalculatedEut(); - if (lEUt > 0) { - lEUt = (-lEUt); - } - } - - @Override - public String[] getInfoData() { - int mPollutionReduction = 0; - for (GT_MetaTileEntity_Hatch_Muffler tHatch : filterValidMTEs(mMufflerHatches)) { - mPollutionReduction = Math.max(tHatch.calculatePollutionReduction(100), mPollutionReduction); - } - - long storedEnergy = 0; - long maxEnergy = 0; - for (GT_MetaTileEntity_Hatch tHatch : getExoticAndNormalEnergyHatchList()) { - storedEnergy += tHatch.getBaseMetaTileEntity() - .getStoredEU(); - maxEnergy += tHatch.getBaseMetaTileEntity() - .getEUCapacity(); - } - long voltage = getAverageInputVoltage(); - long amps = getMaxInputAmps(); - - return new String[] { - /* 1 */ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " - + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(mProgresstime / 20) - + EnumChatFormatting.RESET - + " s / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mMaxProgresstime / 20) - + EnumChatFormatting.RESET - + " s", - /* 2 */ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " - + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(storedEnergy) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(maxEnergy) - + EnumChatFormatting.RESET - + " EU", - /* 3 */ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " - + EnumChatFormatting.RED - + GT_Utility.formatNumbers(getActualEnergyUsage()) - + EnumChatFormatting.RESET - + " EU/t", - /* 4 */ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(voltage) - + EnumChatFormatting.RESET - + " EU/t(*" - + amps - + " A)" - + StatCollector.translateToLocal("GT5U.machines.tier") - + ": " - + EnumChatFormatting.YELLOW - + VN[GT_Utility.getTier(voltage)] - + EnumChatFormatting.RESET, - /* 5 */ StatCollector.translateToLocal("GT5U.multiblock.problems") + ": " - + EnumChatFormatting.RED - + (getIdealStatus() - getRepairStatus()) - + EnumChatFormatting.RESET - + " " - + StatCollector.translateToLocal("GT5U.multiblock.efficiency") - + ": " - + EnumChatFormatting.YELLOW - + mEfficiency / 100.0F - + EnumChatFormatting.RESET - + " %", - /* 6 */ StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": " - + EnumChatFormatting.GREEN - + mPollutionReduction - + EnumChatFormatting.RESET - + " %" }; - } - - @Override - public long getMaxInputVoltage() { - return GT_ExoticEnergyInputHelper.getMaxInputVoltageMulti(getExoticAndNormalEnergyHatchList()); - } - - @Override - public long getAverageInputVoltage() { - return GT_ExoticEnergyInputHelper.getAverageInputVoltageMulti(getExoticAndNormalEnergyHatchList()); - } - - @Override - public long getMaxInputAmps() { - return GT_ExoticEnergyInputHelper.getMaxWorkingInputAmpsMulti(getExoticAndNormalEnergyHatchList()); - } - - @Override - public long getMaxInputEu() { - return GT_ExoticEnergyInputHelper.getTotalEuMulti(getExoticAndNormalEnergyHatchList()); - } - - @Override - public void clearHatches() { - super.clearHatches(); - mExoticEnergyHatches.clear(); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_FilterBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_FilterBase.java deleted file mode 100644 index 896cb223f3..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_FilterBase.java +++ /dev/null @@ -1,106 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import net.minecraft.nbt.NBTTagCompound; - -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; - -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.util.GT_TooltipDataCache; - -public abstract class GT_MetaTileEntity_FilterBase extends GT_MetaTileEntity_Buffer { - - private static final String INVERT_FILTER_TOOLTIP = "GT5U.machines.invert_filter.tooltip"; - protected static final int FILTER_SLOT_INDEX = 9; - protected static final int NUM_INVENTORY_SLOTS = 9; - private static final String EMIT_REDSTONE_GRADUALLY_TOOLTIP = "GT5U" + ".machines.emit_redstone_gradually.tooltip"; - protected boolean invertFilter = false; - - public GT_MetaTileEntity_FilterBase(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_FilterBase(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String[] aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_FilterBase(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_FilterBase(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex < NUM_INVENTORY_SLOTS; - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setBoolean("bInvertFilter", this.invertFilter); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - this.invertFilter = aNBT.getBoolean("bInvertFilter"); - } - - @Override - protected int getRedstoneOutput() { - if (!bRedstoneIfFull) { - return 0; - } - int redstoneOutput = getEmptySlots(); - if (!bInvert) redstoneOutput = NUM_INVENTORY_SLOTS - redstoneOutput; - return redstoneOutput; - } - - private int getEmptySlots() { - int emptySlots = 0; - for (int i = 0; i < NUM_INVENTORY_SLOTS; i++) { - if (mInventory[i] == null) ++emptySlots; - } - return emptySlots; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - super.addUIWidgets(builder, buildContext); - addSortStacksButton(builder); - addEmitRedstoneGraduallyButton(builder); - addInvertRedstoneButton(builder); - addInvertFilterButton(builder); - } - - private void addEmitRedstoneGraduallyButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> bRedstoneIfFull, - val -> bRedstoneIfFull = val, - GT_UITextures.OVERLAY_BUTTON_EMIT_REDSTONE, - this::getEmitRedstoneGraduallyButtonTooltip).setUpdateTooltipEveryTick(true)); - } - - private GT_TooltipDataCache.TooltipData getEmitRedstoneGraduallyButtonTooltip() { - return mTooltipCache - .getUncachedTooltipData(EMIT_REDSTONE_GRADUALLY_TOOLTIP, getEmptySlots(), getRedstoneOutput()); - } - - private void addInvertFilterButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> invertFilter, - val -> invertFilter = val, - GT_UITextures.OVERLAY_BUTTON_INVERT_FILTER, - () -> mTooltipCache.getData(INVERT_FILTER_TOOLTIP))); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch.java deleted file mode 100644 index 1e974f5e9d..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch.java +++ /dev/null @@ -1,252 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; - -import appeng.api.crafting.ICraftingIconProvider; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -/** - * Handles texture changes internally. No special calls are necessary other than updateTexture in add***ToMachineList. - */ -public abstract class GT_MetaTileEntity_Hatch extends GT_MetaTileEntity_BasicTank implements ICraftingIconProvider { - - public enum ConnectionType { - CABLE, - WIRELESS, - LASER - } - - /** - * Uses new texture changing methods to avoid limitations of byte as texture index... - */ - @Deprecated - public byte mMachineBlock = 0; - - private byte mTexturePage = 0; - private byte actualTexture = 0; - - private ItemStack ae2CraftingIcon; - - public GT_MetaTileEntity_Hatch(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String[] aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public static int getSlots(int aTier) { - return aTier < 1 ? 1 : aTier == 1 ? 4 : aTier == 2 ? 9 : 16; - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - return new ITexture[0][0][0]; - } - - public abstract ITexture[] getTexturesActive(ITexture aBaseTexture); - - public abstract ITexture[] getTexturesInactive(ITexture aBaseTexture); - - @Override - public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, - int colorIndex, boolean aActive, boolean redstoneLevel) { - int texturePointer = (byte) (actualTexture & 0x7F); // just to be sure, from my testing the 8th bit cannot be - // set clientside - int textureIndex = texturePointer | (mTexturePage << 7); // Shift seven since one page is 128 textures! - try { - if (side != aFacing) { - if (textureIndex > 0) - return new ITexture[] { Textures.BlockIcons.casingTexturePages[mTexturePage][texturePointer] }; - else return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][colorIndex + 1] }; - } else { - if (textureIndex > 0) { - if (aActive) - return getTexturesActive(Textures.BlockIcons.casingTexturePages[mTexturePage][texturePointer]); - else return getTexturesInactive( - Textures.BlockIcons.casingTexturePages[mTexturePage][texturePointer]); - } else { - if (aActive) return getTexturesActive(Textures.BlockIcons.MACHINE_CASINGS[mTier][colorIndex + 1]); - else return getTexturesInactive(Textures.BlockIcons.MACHINE_CASINGS[mTier][colorIndex + 1]); - } - } - } catch (NullPointerException npe) { - return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[0][0] }; - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setByte("mMachineBlock", actualTexture); - aNBT.setByte("mTexturePage", mTexturePage); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - actualTexture = aNBT.getByte("mMachineBlock"); - mTexturePage = aNBT.getByte("mTexturePage"); - - if (mTexturePage != 0 && GT_Values.GT.isServerSide()) actualTexture |= 0x80; // <- lets just hope no one needs - // the correct value for that on - // server - mMachineBlock = actualTexture; - } - - /** - * Sets texture with page and index, called on add to machine list - * - * @param id (page<<7)+index of the texture - */ - public final void updateTexture(int id) { - onValueUpdate((byte) id); - onTexturePageUpdate((byte) (id >> 7)); - } - - /** - * Sets the icon for the owning multiblock used for AE2 crafting display of attached interfaces, called on add to - * machine list - */ - public final void updateCraftingIcon(ItemStack icon) { - this.ae2CraftingIcon = icon; - } - - @Override - public ItemStack getMachineCraftingIcon() { - return this.ae2CraftingIcon; - } - - /** - * Some multiblocks restrict hatches by tier. This method allows hatches to specify custom tier used for - * structure check, while keeping {@link #mTier} for other uses. - * - * @return Tier used for multiblock structure - */ - public byte getTierForStructure() { - return mTier; - } - - /** - * Sets texture with page and index, rather unusable, but kept FFS - * - * @param page page of texure - * @param index index of texure - */ - @Deprecated - public final void updateTexture(byte page, byte index) { - onValueUpdate(index); - onTexturePageUpdate(page); - } - - @Override - public final void onValueUpdate(byte aValue) { - actualTexture = (byte) (aValue & 0x7F); - mMachineBlock = actualTexture; - mTexturePage = 0; - } - - /** - * Get the maximum amount of amperes to work with, which excludes the additional amps in for loss - * - * @return Working amps - */ - public long maxWorkingAmperesIn() { - return maxAmperesIn(); - } - - /** - * Get the type of connection this hatch allows - * - * @return Connection type - */ - public ConnectionType getConnectionType() { - return ConnectionType.CABLE; - } - - @Override - public final byte getUpdateData() { - return (byte) (actualTexture & 0x7F); - } - - public final void onTexturePageUpdate(byte aValue) { - mTexturePage = (byte) (aValue & 0x7F); - if (mTexturePage != 0 && getBaseMetaTileEntity().isServerSide()) { // just to be sure - mMachineBlock |= 0x80; // <- lets just hope no one needs the correct value for that on server - actualTexture = mMachineBlock; - } - // set last bit to allow working of the page reset-er to 0 in rare case when texture id is the same but page - // changes to 0 - } - - public final byte getTexturePage() { - return (byte) (mTexturePage & 0x7F); - } - - @Override - public boolean doesFillContainers() { - return false; - } - - @Override - public boolean doesEmptyContainers() { - return false; - } - - @Override - public boolean canTankBeFilled() { - return false; - } - - @Override - public boolean canTankBeEmptied() { - return false; - } - - @Override - public boolean displaysItemStack() { - return false; - } - - @Override - public boolean displaysStackSize() { - return false; - } - - @Override - public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { // in that method since it is usually - // not overriden, especially for - // hatches. - if (actualTexture != mMachineBlock) { // revert to page 0 on edition of the field - old code way - actualTexture = (byte) (mMachineBlock & 0x7F); - mMachineBlock = actualTexture; // clear last bit in mMachineBlock since now we are at page 0 after the - // direct field - // change - mTexturePage = 0; // assuming old code only supports page 0 - } - super.onPreTick(aBaseMetaTileEntity, aTick); - } - - // To change to other page -> use the setter method -> updateTexture - - public int getCircuitSlot() { - return -1; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_DataAccess.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_DataAccess.java deleted file mode 100644 index 18344082ea..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_DataAccess.java +++ /dev/null @@ -1,170 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_DATA_ACCESS; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Predicate; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; - -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_AssemblyLineUtils; - -public class GT_MetaTileEntity_Hatch_DataAccess extends GT_MetaTileEntity_Hatch implements IAddUIWidgets { - - private int timeout = 4; - - public GT_MetaTileEntity_Hatch_DataAccess(int aID, String aName, String aNameRegional, int aTier) { - super( - aID, - aName, - aNameRegional, - aTier, - 16, - new String[] { "Data Access for Multiblocks", - "Adds " + (aTier == 4 ? 4 : 16) + " extra slots for Data Sticks" }); - } - - public GT_MetaTileEntity_Hatch_DataAccess(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aTier == 4 ? 4 : 16, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_DataAccess(String aName, int aTier, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aTier == 4 ? 4 : 16, aDescription, aTextures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_DATA_ACCESS) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_DATA_ACCESS) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return true; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_DataAccess(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return mTier >= 8 && !aBaseMetaTileEntity.isActive(); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return mTier >= 8 && !aBaseMetaTileEntity.isActive(); - } - - @Override - public int getInventoryStackLimit() { - return 1; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isActive()) { - timeout--; - if (timeout <= 0) { - aBaseMetaTileEntity.setActive(false); - } - } - } - - public void setActive(boolean mActive) { - getBaseMetaTileEntity().setActive(mActive); - timeout = mActive ? 4 : 0; - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - if (aNBT.getByte("mSticksUpdated") != 1) { - for (int i = 0; i < getSizeInventory(); i++) { - GT_AssemblyLineUtils.processDataStick(getStackInSlot(i)); - } - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - // reminder: remove this marker after many years - aNBT.setByte("mSticksUpdated", (byte) 1); - } - - @Override - public void setInventorySlotContents(int aIndex, ItemStack aStack) { - super.setInventorySlotContents(aIndex, aStack); - GT_AssemblyLineUtils.processDataStick(aStack); - } - - public List getInventoryItems(Predicate filter) { - ArrayList items = new ArrayList<>(); - IGregTechTileEntity te = getBaseMetaTileEntity(); - for (int i = 0; i < te.getSizeInventory(); ++i) { - ItemStack slot = te.getStackInSlot(i); - if (slot != null) { - if (filter != null && filter.test(slot)) { - items.add(slot); - } - } - } - return items; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - if (mTier == 4) { - getBaseMetaTileEntity() - .add2by2Slots(builder, getGUITextureSet().getItemSlot(), GT_UITextures.OVERLAY_SLOT_CIRCUIT); - } else { - getBaseMetaTileEntity() - .add4by4Slots(builder, getGUITextureSet().getItemSlot(), GT_UITextures.OVERLAY_SLOT_CIRCUIT); - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Dynamo.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Dynamo.java deleted file mode 100644 index 8e621434db..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Dynamo.java +++ /dev/null @@ -1,110 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; - -public class GT_MetaTileEntity_Hatch_Dynamo extends GT_MetaTileEntity_Hatch { - - public GT_MetaTileEntity_Hatch_Dynamo(int aID, String aName, String aNameRegional, int aTier) { - super( - aID, - aName, - aNameRegional, - aTier, - 0, - new String[] { "Generating electric Energy from Multiblocks", "Puts out up to 1 Amp" }); - } - - public GT_MetaTileEntity_Hatch_Dynamo(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription) { - super(aID, aName, aNameRegional, aTier, 0, aDescription); - } - - public GT_MetaTileEntity_Hatch_Dynamo(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Dynamo(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isEnetOutput() { - return true; - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public long getMinimumStoredEU() { - return 512; - } - - @Override - public long maxEUOutput() { - return V[mTier]; - } - - @Override - public long maxEUStore() { - return 512L + V[mTier + 1] * 2L; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_Dynamo(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy.java deleted file mode 100644 index d9be12671d..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy.java +++ /dev/null @@ -1,125 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; - -public class GT_MetaTileEntity_Hatch_Energy extends GT_MetaTileEntity_Hatch { - - public GT_MetaTileEntity_Hatch_Energy(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription) { - super(aID, aName, aNameRegional, aTier, 0, aDescription); - } - - public GT_MetaTileEntity_Hatch_Energy(int aID, String aName, String aNameRegional, int aTier) { - super( - aID, - aName, - aNameRegional, - aTier, - 0, - new String[] { "Energy Injector for Multiblocks", "Accepts up to 2 Amps" }); - } - - public GT_MetaTileEntity_Hatch_Energy(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String[] aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Energy(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Energy(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Energy(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isEnetInput() { - return true; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public long getMinimumStoredEU() { - return 512; - } - - @Override - public long maxEUInput() { - return V[mTier]; - } - - @Override - public long maxEUStore() { - return 512L + V[mTier] * 8L; - } - - @Override - public long maxAmperesIn() { - return 2; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_Energy(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java deleted file mode 100644 index 705a3e6248..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java +++ /dev/null @@ -1,196 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.FLUID_IN_SIGN; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_IN; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; - -import gregtech.GT_Mod; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_Utility; - -public class GT_MetaTileEntity_Hatch_Input extends GT_MetaTileEntity_Hatch { - - public RecipeMap mRecipeMap = null; - - public GT_MetaTileEntity_Hatch_Input(int aID, String aName, String aNameRegional, int aTier) { - this( - aID, - aName, - aNameRegional, - aTier, - new String[] { "Fluid Input for Multiblocks", - "Capacity: " + GT_Utility.formatNumbers(8000L * (1L << aTier)) + "L" }); - } - - public GT_MetaTileEntity_Hatch_Input(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription) { - this(aID, 3, aName, aNameRegional, aTier, aDescription); - } - - public GT_MetaTileEntity_Hatch_Input(int aID, int aSlot, String aName, String aNameRegional, int aTier) { - this( - aID, - aSlot, - aName, - aNameRegional, - aTier, - new String[] { "Fluid Input for Multiblocks", "", "Can hold " + aSlot + " types of fluid." }); - mDescriptionArray[1] = "Capacity: " + GT_Utility.formatNumbers(getCapacityPerTank(aTier, aSlot)) + "L"; - } - - public GT_MetaTileEntity_Hatch_Input(int aID, int aSlot, String aName, String aNameRegional, int aTier, - String[] aDescription) { - super(aID, aName, aNameRegional, aTier, aSlot, aDescription); - } - - public GT_MetaTileEntity_Hatch_Input(int aID, String aName, String aNameRegional, int aTier, int allSlotCount, - String[] strings) { - super(aID, aName, aNameRegional, aTier, allSlotCount, strings); - } - - public int getCapacityPerTank(int aTier, int aSlot) { - return (int) (8000L * (1L << aTier) / aSlot); - } - - public GT_MetaTileEntity_Hatch_Input(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 3, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Input(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 3, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Input(String aName, int aSlots, int aTier, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aSlots, aDescription, aTextures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(FLUID_IN_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(FLUID_IN_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_Input(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - if (mRecipeMap != null) { - aNBT.setString("recipeMap", mRecipeMap.unlocalizedName); - } - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - mRecipeMap = RecipeMap.getFromOldIdentifier(aNBT.getString("recipeMap")); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public boolean doesFillContainers() { - // return true; - return false; - } - - @Override - public boolean doesEmptyContainers() { - return true; - } - - @Override - public boolean canTankBeFilled() { - return true; - } - - @Override - public boolean canTankBeEmptied() { - return true; - } - - @Override - public boolean displaysItemStack() { - return true; - } - - @Override - public boolean displaysStackSize() { - return false; - } - - public void updateSlots() { - if (mInventory[getInputSlot()] != null && mInventory[getInputSlot()].stackSize <= 0) - mInventory[getInputSlot()] = null; - } - - @Override - public boolean isFluidInputAllowed(FluidStack aFluid) { - return mRecipeMap == null || mRecipeMap.containsInput(aFluid); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 1; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 0 - && (mRecipeMap == null || mRecipeMap.containsInput(aStack) - || mRecipeMap.containsInput(GT_Utility.getFluidForFilledItem(aStack, true))); - } - - @Override - public int getCapacity() { - return 8000 * (1 << mTier); - } - - @Override - public int getTankPressure() { - return -100; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java deleted file mode 100644 index 8c99e813e2..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java +++ /dev/null @@ -1,318 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.ITEM_IN_SIGN; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_IN; -import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.StatCollector; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.drawable.UITexture; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.api.widget.Widget; -import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; - -import gregtech.GT_Mod; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.IConfigurationCircuitSupport; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_ClientPreference; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_TooltipDataCache; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.extensions.ArrayExt; - -public class GT_MetaTileEntity_Hatch_InputBus extends GT_MetaTileEntity_Hatch - implements IConfigurationCircuitSupport, IAddUIWidgets { - - private static final String SORTING_MODE_TOOLTIP = "GT5U.machines.sorting_mode.tooltip"; - private static final String ONE_STACK_LIMIT_TOOLTIP = "GT5U.machines.one_stack_limit.tooltip"; - private static final int BUTTON_SIZE = 18; - - public RecipeMap mRecipeMap = null; - public boolean disableSort; - public boolean disableFilter = true; - public boolean disableLimited = true; - private int uiButtonCount = 0; - - public GT_MetaTileEntity_Hatch_InputBus(int id, String name, String nameRegional, int tier) { - this(id, name, nameRegional, tier, getSlots(tier) + 1); - } - - protected GT_MetaTileEntity_Hatch_InputBus(int id, String name, String nameRegional, int tier, int slots, - String[] description) { - super(id, name, nameRegional, tier, slots, description); - } - - public GT_MetaTileEntity_Hatch_InputBus(int id, String name, String nameRegional, int tier, int slots) { - super( - id, - name, - nameRegional, - tier, - slots, - ArrayExt.of( - "Item Input for Multiblocks", - "Shift + right click with screwdriver to turn Sort mode on/off", - "Capacity: " + getSlots(tier) + " stack" + (getSlots(tier) >= 2 ? "s" : ""))); - } - - public GT_MetaTileEntity_Hatch_InputBus(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - this(aName, aTier, getSlots(aTier) + 1, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_InputBus(String aName, int aTier, int aSlots, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aSlots, aDescription, aTextures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(ITEM_IN_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(ITEM_IN_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex != getCircuitSlot(); - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_InputBus(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public int getCircuitSlotX() { - return 153; - } - - @Override - public int getCircuitSlotY() { - return 63; - } - - @Override - public void initDefaultModes(NBTTagCompound aNBT) { - if (!getBaseMetaTileEntity().getWorld().isRemote) { - GT_ClientPreference tPreference = GT_Mod.gregtechproxy - .getClientPreference(getBaseMetaTileEntity().getOwnerUuid()); - if (tPreference != null) disableFilter = !tPreference.isInputBusInitialFilterEnabled(); - } - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.hasInventoryBeenModified()) { - updateSlots(); - } - } - - public void updateSlots() { - for (int i = 0; i < mInventory.length - 1; i++) - if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; - if (!disableSort) fillStacksIntoFirstSlots(); - } - - protected void fillStacksIntoFirstSlots() { - final int L = mInventory.length - 1; - HashMap slots = new HashMap<>(L); - HashMap stacks = new HashMap<>(L); - List order = new ArrayList<>(L); - List validSlots = new ArrayList<>(L); - for (int i = 0; i < L; i++) { - if (!isValidSlot(i)) continue; - validSlots.add(i); - ItemStack s = mInventory[i]; - if (s == null) continue; - GT_Utility.ItemId sID = GT_Utility.ItemId.createNoCopy(s); - slots.merge(sID, s.stackSize, Integer::sum); - if (!stacks.containsKey(sID)) stacks.put(sID, s); - order.add(sID); - mInventory[i] = null; - } - int slotindex = 0; - for (GT_Utility.ItemId sID : order) { - int toSet = slots.get(sID); - if (toSet == 0) continue; - int slot = validSlots.get(slotindex); - slotindex++; - mInventory[slot] = stacks.get(sID) - .copy(); - toSet = Math.min(toSet, mInventory[slot].getMaxStackSize()); - mInventory[slot].stackSize = toSet; - slots.merge(sID, toSet, (a, b) -> a - b); - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setBoolean("disableSort", disableSort); - aNBT.setBoolean("disableFilter", disableFilter); - aNBT.setBoolean("disableLimited", disableLimited); - if (mRecipeMap != null) { - aNBT.setString("recipeMap", mRecipeMap.unlocalizedName); - } - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - disableSort = aNBT.getBoolean("disableSort"); - disableFilter = aNBT.getBoolean("disableFilter"); - if (aNBT.hasKey("disableLimited")) { - disableLimited = aNBT.getBoolean("disableLimited"); - } - mRecipeMap = RecipeMap.getFromOldIdentifier(aNBT.getString("recipeMap")); - } - - @Override - public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { - if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) - .isGUIClickable()) return; - if (aPlayer.isSneaking()) { - if (disableSort) { - disableSort = false; - } else { - if (disableLimited) { - disableLimited = false; - } else { - disableSort = true; - disableLimited = true; - } - } - GT_Utility.sendChatToPlayer( - aPlayer, - StatCollector.translateToLocal("GT5U.hatch.disableSort." + disableSort) + " " - + StatCollector.translateToLocal("GT5U.hatch.disableLimited." + disableLimited)); - } else { - disableFilter = !disableFilter; - GT_Utility - .sendChatToPlayer(aPlayer, StatCollector.translateToLocal("GT5U.hatch.disableFilter." + disableFilter)); - } - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (aIndex == getCircuitSlot()) return false; - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side == getBaseMetaTileEntity().getFrontFacing() && aIndex != getCircuitSlot() - && (mRecipeMap == null || disableFilter || mRecipeMap.containsInput(aStack)) - && (disableLimited || limitedAllowPutStack(aIndex, aStack)); - } - - protected boolean limitedAllowPutStack(int aIndex, ItemStack aStack) { - for (int i = 0; i < getSizeInventory(); i++) - if (GT_Utility.areStacksEqual(GT_OreDictUnificator.get_nocopy(aStack), mInventory[i])) return i == aIndex; - return mInventory[aIndex] == null; - } - - @Override - public boolean allowSelectCircuit() { - return true; - } - - @Override - public int getCircuitSlot() { - return getSlots(mTier); - } - - private void addSortStacksButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> !disableSort, - val -> disableSort = !val, - GT_UITextures.OVERLAY_BUTTON_SORTING_MODE, - () -> mTooltipCache.getData(SORTING_MODE_TOOLTIP))); - } - - private void addOneStackLimitButton(ModularWindow.Builder builder) { - builder.widget(createToggleButton(() -> !disableLimited, val -> { - disableLimited = !val; - updateSlots(); - }, GT_UITextures.OVERLAY_BUTTON_ONE_STACK_LIMIT, () -> mTooltipCache.getData(ONE_STACK_LIMIT_TOOLTIP))); - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - buildContext.addCloseListener(() -> uiButtonCount = 0); - addSortStacksButton(builder); - addOneStackLimitButton(builder); - // Remove one for ghost circuit slot - int slotCount = getSizeInventory(); - if (allowSelectCircuit()) { - slotCount = slotCount - 1; - } - // We do this to decouple slot count from tier in here, since there is no reason to do so. - switch (slotCount) { - case 1 -> getBaseMetaTileEntity().add1by1Slot(builder); - case 4 -> getBaseMetaTileEntity().add2by2Slots(builder); - case 9 -> getBaseMetaTileEntity().add3by3Slots(builder); - case 16 -> getBaseMetaTileEntity().add4by4Slots(builder); - default -> {} - } - } - - private Widget createToggleButton(Supplier getter, Consumer setter, UITexture picture, - Supplier tooltipDataSupplier) { - return new CycleButtonWidget().setToggle(getter, setter) - .setStaticTexture(picture) - .setVariableBackground(GT_UITextures.BUTTON_STANDARD_TOGGLE) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setPos(7 + (uiButtonCount++ * BUTTON_SIZE), 62) - .setSize(BUTTON_SIZE, BUTTON_SIZE) - .setGTTooltip(tooltipDataSupplier); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Maintenance.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Maintenance.java deleted file mode 100644 index 8a4d718244..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Maintenance.java +++ /dev/null @@ -1,459 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE_GLOW; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE_IDLE; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE_IDLE_GLOW; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_DUCTTAPE; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_MAINTENANCE; - -import net.minecraft.entity.EntityLivingBase; -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.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; -import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; -import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; -import com.gtnewhorizons.modularui.common.widget.TextWidget; - -import cpw.mods.fml.common.network.NetworkRegistry; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Utility; -import ic2.core.IHasGui; -import ic2.core.item.ItemToolbox; - -public class GT_MetaTileEntity_Hatch_Maintenance extends GT_MetaTileEntity_Hatch implements IAddUIWidgets, IAlignment { - - private Rotation rotation = Rotation.NORMAL; - - private static ItemStack[] sAutoMaintenanceInputs; - public boolean mWrench = false, mScrewdriver = false, mSoftHammer = false, mHardHammer = false, - mSolderingTool = false, mCrowbar = false, mAuto; - - public GT_MetaTileEntity_Hatch_Maintenance(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, 1, "For maintaining Multiblocks"); - mAuto = false; - } - - public GT_MetaTileEntity_Hatch_Maintenance(int aID, String aName, String aNameRegional, int aTier, boolean aAuto) { - super(aID, aName, aNameRegional, aTier, 4, "For automatically maintaining Multiblocks"); - mAuto = aAuto; - } - - public GT_MetaTileEntity_Hatch_Maintenance(String aName, int aTier, String aDescription, ITexture[][][] aTextures, - boolean aAuto) { - super(aName, aTier, aAuto ? 4 : 1, aDescription, aTextures); - mAuto = aAuto; - } - - public GT_MetaTileEntity_Hatch_Maintenance(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures, - boolean aAuto) { - super(aName, aTier, aAuto ? 4 : 1, aDescription, aTextures); - mAuto = aAuto; - } - - private static ItemStack[] getAutoMaintenanceInputs() { - if (sAutoMaintenanceInputs == null) sAutoMaintenanceInputs = new ItemStack[] { ItemList.Duct_Tape.get(4), - GT_OreDictUnificator.get(OrePrefixes.cell, Materials.Lubricant, 2), - GT_OreDictUnificator.get(OrePrefixes.screw, Materials.Steel, 4), - GT_OreDictUnificator.get(OrePrefixes.circuit, Materials.HV, 2) }; - return sAutoMaintenanceInputs; - } - - @Override - public String[] getDescription() { - String[] desc; - if (mAuto) { - desc = new String[mDescriptionArray.length + 3]; - System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); - desc[mDescriptionArray.length] = "4 Ducttape, 2 Lubricant Cells"; - desc[mDescriptionArray.length + 1] = "4 Steel Screws, 2 HV Circuits"; - desc[mDescriptionArray.length + 2] = "For each autorepair"; - } else { - desc = new String[mDescriptionArray.length + 1]; - System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); - desc[mDescriptionArray.length] = "Cannot be shared between Multiblocks!"; - } - return desc; - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - if (mAuto) return new ITexture[] { aBaseTexture, TextureFactory.builder() - .addIcon(OVERLAY_AUTOMAINTENANCE_IDLE) - .extFacing() - .build(), - TextureFactory.builder() - .addIcon(OVERLAY_AUTOMAINTENANCE_IDLE_GLOW) - .extFacing() - .glow() - .build() }; - return new ITexture[] { aBaseTexture, TextureFactory.builder() - .addIcon(OVERLAY_MAINTENANCE) - .extFacing() - .build() }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - if (mAuto) return new ITexture[] { aBaseTexture, TextureFactory.builder() - .addIcon(OVERLAY_AUTOMAINTENANCE) - .extFacing() - .build(), - TextureFactory.builder() - .addIcon(OVERLAY_AUTOMAINTENANCE_GLOW) - .extFacing() - .glow() - .build() }; - return new ITexture[] { aBaseTexture, TextureFactory.builder() - .addIcon(OVERLAY_MAINTENANCE) - .extFacing() - .build(), - TextureFactory.builder() - .addIcon(OVERLAY_DUCTTAPE) - .extFacing() - .build() }; - } - - @Override - public void initDefaultModes(NBTTagCompound aNBT) { - getBaseMetaTileEntity().setActive(true); - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return mAuto && GT_Mod.gregtechproxy.mAMHInteraction; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - if (aTileEntity.getMetaTileID() == 111) - return new GT_MetaTileEntity_Hatch_Maintenance(mName, mTier, mDescriptionArray, mTextures, true); - return new GT_MetaTileEntity_Hatch_Maintenance(mName, mTier, mDescriptionArray, mTextures, false); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side, - float aX, float aY, float aZ) { - if (aBaseMetaTileEntity.isClientSide()) return true; - if (side == aBaseMetaTileEntity.getFrontFacing()) { - // only allow OC robot fake player - if (aPlayer instanceof FakePlayer && !aPlayer.getGameProfile() - .getName() - .endsWith(".robot")) return false; - ItemStack tStack = aPlayer.getCurrentEquippedItem(); - if (tStack != null) { - if (tStack.getItem() instanceof ItemToolbox) { - applyToolbox(tStack, aPlayer); - } else if (ItemList.Duct_Tape.isStackEqual(tStack)) { - mWrench = mScrewdriver = mSoftHammer = mHardHammer = mCrowbar = mSolderingTool = true; - getBaseMetaTileEntity().setActive(false); - if (--tStack.stackSize == 0) { - aPlayer.inventory.mainInventory[aPlayer.inventory.currentItem] = null; - } - } else GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - } else { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - } - return true; - } - return false; - } - - public void updateSlots() { - for (int i = 0; i < mInventory.length; i++) - if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; - } - - @Override - public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { - super.onFirstTick(aBaseMetaTileEntity); - if (aBaseMetaTileEntity.isClientSide()) - StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity); - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isServerSide() && mAuto && aTick % 100L == 0L) { - aBaseMetaTileEntity.setActive(!isRecipeInputEqual(false)); - } - } - - @Override - public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, - float aX, float aY, float aZ) { - if (wrenchingSide != getBaseMetaTileEntity().getFrontFacing()) - return super.onWrenchRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); - if (!entityPlayer.isSneaking() && isRotationChangeAllowed()) { - toolSetRotation(null); - return true; - } - return false; - } - - public boolean autoMaintainance() { - return isRecipeInputEqual(true); - } - - public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess) { - ItemStack[] mInputs = getAutoMaintenanceInputs(); - - int amt; - - for (ItemStack tStack : mInputs) { - if (tStack != null) { - amt = tStack.stackSize; - boolean temp = true; - for (ItemStack aStack : mInventory) { - if ((GT_Utility.areUnificationsEqual(aStack, tStack, true) - || GT_Utility.areUnificationsEqual(GT_OreDictUnificator.get(false, aStack), tStack, true))) { - amt -= aStack.stackSize; - if (amt < 1) { - temp = false; - break; - } - } - } - if (temp) return false; - } - } - - if (aDecreaseStacksizeBySuccess) { - for (ItemStack tStack : mInputs) { - if (tStack != null) { - amt = tStack.stackSize; - for (ItemStack aStack : mInventory) { - if ((GT_Utility.areUnificationsEqual(aStack, tStack, true) || GT_Utility - .areUnificationsEqual(GT_OreDictUnificator.get(false, aStack), tStack, true))) { - if (aStack.stackSize < amt) { - amt -= aStack.stackSize; - aStack.stackSize = 0; - } else { - aStack.stackSize -= amt; - amt = 0; - break; - } - } - } - } - } - mCrowbar = true; - mHardHammer = true; - mScrewdriver = true; - mSoftHammer = true; - mSolderingTool = true; - mWrench = true; - updateSlots(); - } - return true; - } - - public void onToolClick(ItemStack aStack, EntityLivingBase aPlayer, IInventory aToolboxInventory) { - if (aStack == null || aPlayer == null) return; - - // Allow IC2 Toolbox with tools to function for maint issues. - if (aStack.getItem() instanceof ItemToolbox && aPlayer instanceof EntityPlayer) { - applyToolbox(aStack, (EntityPlayer) aPlayer); - return; - } - - if (GT_Utility.isStackInList(aStack, GregTech_API.sWrenchList) && !mWrench - && GT_ModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mWrench = true; - if (GT_Utility.isStackInList(aStack, GregTech_API.sScrewdriverList) && !mScrewdriver - && GT_ModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mScrewdriver = true; - if (GT_Utility.isStackInList(aStack, GregTech_API.sSoftHammerList) && !mSoftHammer - && GT_ModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mSoftHammer = true; - if (GT_Utility.isStackInList(aStack, GregTech_API.sHardHammerList) && !mHardHammer - && GT_ModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mHardHammer = true; - if (GT_Utility.isStackInList(aStack, GregTech_API.sCrowbarList) && !mCrowbar - && GT_ModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mCrowbar = true; - if (!mSolderingTool && GT_ModHandler.useSolderingIron(aStack, aPlayer, aToolboxInventory)) - mSolderingTool = true; - if (GT_OreDictUnificator.isItemStackInstanceOf(aStack, "craftingDuctTape")) { - mWrench = mScrewdriver = mSoftHammer = mHardHammer = mCrowbar = mSolderingTool = true; - getBaseMetaTileEntity().setActive(false); - aStack.stackSize--; - } - if (mSolderingTool && aPlayer instanceof EntityPlayerMP tPlayer) { - try { - GT_Mod.achievements.issueAchievement(tPlayer, "maintainance"); - } catch (Exception ignored) {} - } - } - - public void onToolClick(ItemStack aStack, EntityLivingBase aPlayer) { - onToolClick(aStack, aPlayer, null); - } - - private void applyToolbox(ItemStack aStack, EntityPlayer aPlayer) { - final ItemToolbox aToolbox = (ItemToolbox) aStack.getItem(); - final IHasGui aToolboxGUI = aToolbox.getInventory(aPlayer, aStack); - for (int i = 0; i < aToolboxGUI.getSizeInventory(); i++) { - if (aToolboxGUI.getStackInSlot(i) != null) { - onToolClick(aToolboxGUI.getStackInSlot(i), aPlayer, aToolboxGUI); - if (aToolboxGUI.getStackInSlot(i) != null && aToolboxGUI.getStackInSlot(i).stackSize <= 0) - aToolboxGUI.setInventorySlotContents(i, null); - } - } - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return mAuto && GT_Mod.gregtechproxy.mAMHInteraction; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - if (mAuto && GT_Mod.gregtechproxy.mAMHInteraction) { - for (int i = 0; i < getSizeInventory(); i++) if (GT_Utility.areStacksEqual( - GT_OreDictUnificator.get(false, aStack), - GT_OreDictUnificator.get(false, getStackInSlot(i)))) return i == aIndex; - for (ItemStack tInput : getAutoMaintenanceInputs()) - if (GT_Utility.areUnificationsEqual(tInput, aStack, true) - || GT_Utility.areUnificationsEqual(GT_OreDictUnificator.get(false, aStack), tInput, true)) - return true; - } - return false; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - if (mAuto) { - getBaseMetaTileEntity().add2by2Slots(builder); - } else { - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.SLOT_MAINTENANCE) - .setPos(78, 33) - .setSize(20, 20)) - .widget(new SlotWidget(BaseSlot.empty()) { - - @Override - public boolean handleDragAndDrop(ItemStack draggedStack, int button) { - return false; - } - - @Override - protected void phantomClick(ClickData clickData, ItemStack cursorStack) { - if (cursorStack == null) return; - onToolClick(cursorStack, getContext().getPlayer()); - if (cursorStack.stackSize < 1) { - getContext().getPlayer().inventory.setItemStack(null); - } - if (getContext().getPlayer() instanceof EntityPlayerMP) { - ((EntityPlayerMP) getContext().getPlayer()).updateHeldItem(); - } - } - }.disableShiftInsert() - .setBackground(GT_UITextures.TRANSPARENT) - .setPos(79, 34)) - .widget( - new TextWidget("Click with Tool to repair.").setDefaultColor(COLOR_TEXT_GRAY.get()) - .setPos(8, 12)); - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setByte("mRotation", (byte) rotation.getIndex()); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - rotation = Rotation.byIndex(aNBT.getByte("mRotation")); - super.loadNBTData(aNBT); - } - - @Override - public ExtendedFacing getExtendedFacing() { - return ExtendedFacing.of(getBaseMetaTileEntity().getFrontFacing(), rotation, Flip.NONE); - } - - @Override - public void setExtendedFacing(ExtendedFacing alignment) { - boolean changed = false; - final IGregTechTileEntity base = getBaseMetaTileEntity(); - if (base.getFrontFacing() != alignment.getDirection()) { - base.setFrontFacing(alignment.getDirection()); - changed = true; - } - if (rotation != alignment.getRotation()) { - rotation = alignment.getRotation(); - changed = true; - } - if (changed) { - if (base.isServerSide() && !GregTech_API.isDummyWorld(base.getWorld())) { - StructureLibAPI.sendAlignment( - (IAlignmentProvider) base, - new NetworkRegistry.TargetPoint( - base.getWorld().provider.dimensionId, - base.getXCoord(), - base.getYCoord(), - base.getZCoord(), - 512)); - } else { - base.issueTextureUpdate(); - } - } - } - - @Override - public IAlignmentLimits getAlignmentLimits() { - return (d, r, f) -> f.isNotFlipped(); - } - - @Override - public boolean isFlipChangeAllowed() { - return false; - } - - @Override - public boolean isRotationChangeAllowed() { - return true; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Muffler.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Muffler.java deleted file mode 100644 index 8707d0f804..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Muffler.java +++ /dev/null @@ -1,208 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_MUFFLER; -import static gregtech.api.objects.XSTR.XSTR_INSTANCE; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.GT_Mod; -import gregtech.api.enums.ParticleFX; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.WorldSpawnedEventBuilder; -import gregtech.common.GT_Pollution; - -@SuppressWarnings("unused") // Unused API is expected within scope -public class GT_MetaTileEntity_Hatch_Muffler extends GT_MetaTileEntity_Hatch { - - private static final String localizedDescFormat = GT_LanguageManager.addStringLocalization( - "gt.blockmachines.hatch.muffler.desc.format", - "Outputs the Pollution (Might cause ... things)%n" + "DO NOT OBSTRUCT THE OUTPUT!%n" - + "Reduces Pollution to %d%%%n" - + "Recovers %d%% of CO2/CO/SO2"); - private final int pollutionReduction = calculatePollutionReduction(100); - private final int pollutionRecover = 100 - pollutionReduction; - private final String[] description = String.format(localizedDescFormat, pollutionReduction, pollutionRecover) - .split("\\R"); - - public GT_MetaTileEntity_Hatch_Muffler(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, 0, ""); - } - - public GT_MetaTileEntity_Hatch_Muffler(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, - String[] aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Muffler(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - this(aName, aTier, new String[] { aDescription }, aTextures); - } - - public GT_MetaTileEntity_Hatch_Muffler(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - this(aName, aTier, 0, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Muffler(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public String[] getDescription() { - return description; - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_MUFFLER) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_MUFFLER) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_Muffler(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isClientSide() && this.getBaseMetaTileEntity() - .isActive()) { - pollutionParticles( - this.getBaseMetaTileEntity() - .getWorld(), - ParticleFX.LARGE_SMOKE.toString()); - } - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @SideOnly(Side.CLIENT) - public void pollutionParticles(World aWorld, String name) { - boolean chk1, chk2, chk3; - float ran1 = XSTR_INSTANCE.nextFloat(), ran2, ran3; - chk1 = ran1 * 100 < calculatePollutionReduction(100); - if (GT_Pollution.getPollution(getBaseMetaTileEntity()) >= GT_Mod.gregtechproxy.mPollutionSmogLimit) { - ran2 = XSTR_INSTANCE.nextFloat(); - ran3 = XSTR_INSTANCE.nextFloat(); - chk2 = ran2 * 100 < calculatePollutionReduction(100); - chk3 = ran3 * 100 < calculatePollutionReduction(100); - if (!(chk1 || chk2 || chk3)) return; - } else { - if (!chk1) return; - ran2 = ran3 = 0.0F; - chk2 = chk3 = false; - } - - final IGregTechTileEntity aMuffler = this.getBaseMetaTileEntity(); - final ForgeDirection aDir = aMuffler.getFrontFacing(); - final float xPos = aDir.offsetX * 0.76F + aMuffler.getXCoord() + 0.25F; - final float yPos = aDir.offsetY * 0.76F + aMuffler.getYCoord() + 0.25F; - final float zPos = aDir.offsetZ * 0.76F + aMuffler.getZCoord() + 0.25F; - - final float ySpd = aDir.offsetY * 0.1F + 0.2F + 0.1F * XSTR_INSTANCE.nextFloat(); - final float xSpd; - final float zSpd; - - if (aDir.offsetY == -1) { - final float temp = XSTR_INSTANCE.nextFloat() * 2 * (float) Math.PI; - xSpd = (float) Math.sin(temp) * 0.1F; - zSpd = (float) Math.cos(temp) * 0.1F; - } else { - xSpd = aDir.offsetX * (0.1F + 0.2F * XSTR_INSTANCE.nextFloat()); - zSpd = aDir.offsetZ * (0.1F + 0.2F * XSTR_INSTANCE.nextFloat()); - } - - final WorldSpawnedEventBuilder.ParticleEventBuilder events = new WorldSpawnedEventBuilder.ParticleEventBuilder() - .setIdentifier(name) - .setWorld(aWorld) - .setMotion(xSpd, ySpd, zSpd); - - if (chk1) { - events - .setPosition( - xPos + ran1 * 0.5F, - yPos + XSTR_INSTANCE.nextFloat() * 0.5F, - zPos + XSTR_INSTANCE.nextFloat() * 0.5F) - .run(); - } - if (chk2) { - events - .setPosition( - xPos + ran2 * 0.5F, - yPos + XSTR_INSTANCE.nextFloat() * 0.5F, - zPos + XSTR_INSTANCE.nextFloat() * 0.5F) - .run(); - } - if (chk3) { - events - .setPosition( - xPos + ran3 * 0.5F, - yPos + XSTR_INSTANCE.nextFloat() * 0.5F, - zPos + XSTR_INSTANCE.nextFloat() * 0.5F) - .run(); - } - } - - public int calculatePollutionReduction(int aPollution) { - if (mTier < 2) { - return aPollution; - } - return (int) ((float) aPollution * ((100F - 12.5F * ((float) mTier - 1F)) / 100F)); - } - - /** - * @param mte The multi-block controller's {@link MetaTileEntity} MetaTileEntity is passed so newer muffler hatches - * can do wacky things with the multis - * @return pollution success - */ - public boolean polluteEnvironment(MetaTileEntity mte) { - if (getBaseMetaTileEntity().getAirAtSide(getBaseMetaTileEntity().getFrontFacing())) { - GT_Pollution.addPollution(getBaseMetaTileEntity(), calculatePollutionReduction(10000)); - return true; - } - return false; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java deleted file mode 100644 index 267c2d0f1c..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java +++ /dev/null @@ -1,300 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_INPUT_HATCH_2x2; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; - -import com.gtnewhorizons.modularui.api.ModularUITextures; -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.common.fluid.FluidStackTank; -import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; - -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.render.TextureFactory; - -public class GT_MetaTileEntity_Hatch_MultiInput extends GT_MetaTileEntity_Hatch_Input implements IAddUIWidgets { - - private final FluidStack[] mStoredFluid; - private final FluidStackTank[] fluidTanks; - public final int mCapacityPer; - - public GT_MetaTileEntity_Hatch_MultiInput(int aID, int aSlot, String aName, String aNameRegional, int aTier) { - super(aID, aSlot, aName, aNameRegional, aTier); - this.mStoredFluid = new FluidStack[aSlot]; - fluidTanks = new FluidStackTank[aSlot]; - mCapacityPer = getCapacityPerTank(aTier, aSlot); - } - - public GT_MetaTileEntity_Hatch_MultiInput(int aID, int aSlot, String aName, String aNameRegional, int aTier, - String[] aDescription) { - super(aID, aSlot, aName, aNameRegional, aTier, aDescription); - this.mStoredFluid = new FluidStack[aSlot]; - fluidTanks = new FluidStackTank[aSlot]; - mCapacityPer = getCapacityPerTank(aTier, aSlot); - } - - public GT_MetaTileEntity_Hatch_MultiInput(String aName, int aSlot, int aTier, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aSlot, aTier, aDescription, aTextures); - this.mStoredFluid = new FluidStack[aSlot]; - fluidTanks = new FluidStackTank[aSlot]; - mCapacityPer = getCapacityPerTank(aTier, aSlot); - for (int i = 0; i < aSlot; i++) { - final int index = i; - fluidTanks[i] = new FluidStackTank( - () -> mStoredFluid[index], - fluid -> mStoredFluid[index] = fluid, - mCapacityPer); - } - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_MultiInput(mName, getMaxType(), mTier, mDescriptionArray, mTextures); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - if (mStoredFluid != null) { - for (int i = 0; i < mStoredFluid.length; i++) { - if (mStoredFluid[i] != null) - aNBT.setTag("mFluid" + i, mStoredFluid[i].writeToNBT(new NBTTagCompound())); - } - } - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - if (mStoredFluid != null) { - for (int i = 0; i < mStoredFluid.length; i++) { - if (aNBT.hasKey("mFluid" + i)) { - mStoredFluid[i] = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid" + i)); - } - } - } - } - - @Override - public boolean displaysStackSize() { - return true; - } - - public FluidStack[] getStoredFluid() { - return mStoredFluid; - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_INPUT_HATCH_2x2) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_INPUT_HATCH_2x2) }; - } - - public int getMaxType() { - return mStoredFluid.length; - } - - @Override - public FluidStack getFluid() { - for (FluidStack tFluid : mStoredFluid) { - if (tFluid != null && tFluid.amount > 0) return tFluid; - } - return null; - } - - public FluidStack getFluid(int aSlot) { - if (mStoredFluid == null || aSlot < 0 || aSlot >= getMaxType()) return null; - return mStoredFluid[aSlot]; - } - - @Override - public int getFluidAmount() { - if (getFluid() != null) { - return getFluid().amount; - } - return 0; - } - - @Override - public int getCapacity() { - return mCapacityPer; - } - - public int getFirstEmptySlot() { - for (int i = 0; i < mStoredFluid.length; i++) { - if (mStoredFluid[i] == null) return i; - } - return -1; - } - - public boolean hasFluid(FluidStack aFluid) { - if (aFluid == null) return false; - for (FluidStack tFluid : mStoredFluid) { - if (aFluid.isFluidEqual(tFluid)) return true; - } - return false; - } - - public int getFluidSlot(FluidStack tFluid) { - if (tFluid == null) return -1; - for (int i = 0; i < mStoredFluid.length; i++) { - if (tFluid.equals(mStoredFluid[i])) return i; - } - return -1; - } - - public int getFluidAmount(FluidStack tFluid) { - int tSlot = getFluidSlot(tFluid); - if (tSlot != -1) { - return mStoredFluid[tSlot].amount; - } - return 0; - } - - public void setFluid(FluidStack aFluid, int aSlot) { - if (aSlot < 0 || aSlot >= getMaxType()) return; - mStoredFluid[aSlot] = aFluid; - } - - public void addFluid(FluidStack aFluid, int aSlot) { - if (aSlot < 0 || aSlot >= getMaxType()) return; - if (aFluid.equals(mStoredFluid[aSlot])) mStoredFluid[aSlot].amount += aFluid.amount; - if (mStoredFluid[aSlot] == null) mStoredFluid[aSlot] = aFluid.copy(); - } - - @Override - public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide()) { - mFluid = getFluid(); - } - super.onPreTick(aBaseMetaTileEntity, aTick); - } - - @Override - public int fill(FluidStack aFluid, boolean doFill) { - if (aFluid == null || aFluid.getFluid() - .getID() <= 0 || aFluid.amount <= 0 || !canTankBeFilled() || !isFluidInputAllowed(aFluid)) return 0; - if (!hasFluid(aFluid) && getFirstEmptySlot() != -1) { - int tFilled = Math.min(aFluid.amount, mCapacityPer); - if (doFill) { - FluidStack tFluid = aFluid.copy(); - tFluid.amount = tFilled; - addFluid(tFluid, getFirstEmptySlot()); - getBaseMetaTileEntity().markDirty(); - } - return tFilled; - } - if (hasFluid(aFluid)) { - int tLeft = mCapacityPer - getFluidAmount(aFluid); - int tFilled = Math.min(tLeft, aFluid.amount); - if (doFill) { - FluidStack tFluid = aFluid.copy(); - tFluid.amount = tFilled; - addFluid(tFluid, getFluidSlot(tFluid)); - getBaseMetaTileEntity().markDirty(); - } - return tFilled; - } - return 0; - } - - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - if (getFluid() == null || !canTankBeEmptied()) return null; - if (getFluid().amount <= 0 && isFluidChangingAllowed()) { - setFluid(null, getFluidSlot(getFluid())); - getBaseMetaTileEntity().markDirty(); - return null; - } - FluidStack tRemove = getFluid().copy(); - tRemove.amount = Math.min(maxDrain, tRemove.amount); - if (doDrain) { - getFluid().amount -= tRemove.amount; - getBaseMetaTileEntity().markDirty(); - } - if (getFluid() == null || getFluid().amount <= 0 && isFluidChangingAllowed()) { - setFluid(null, getFluidSlot(getFluid())); - getBaseMetaTileEntity().markDirty(); - } - return tRemove; - } - - @Override - public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { - return fill(resource, doFill); - } - - @Override - public FluidStack drain(ForgeDirection from, FluidStack aFluid, boolean doDrain) { - if (aFluid == null || !hasFluid(aFluid)) return null; - FluidStack tStored = mStoredFluid[getFluidSlot(aFluid)]; - if (tStored.amount <= 0 && isFluidChangingAllowed()) { - setFluid(null, getFluidSlot(tStored)); - getBaseMetaTileEntity().markDirty(); - return null; - } - FluidStack tRemove = tStored.copy(); - tRemove.amount = Math.min(aFluid.amount, tRemove.amount); - if (doDrain) { - tStored.amount -= tRemove.amount; - getBaseMetaTileEntity().markDirty(); - } - if (tStored.amount <= 0 && isFluidChangingAllowed()) { - setFluid(null, getFluidSlot(tStored)); - getBaseMetaTileEntity().markDirty(); - } - return tRemove; - } - - @Override - public FluidTankInfo[] getTankInfo(ForgeDirection from) { - FluidTankInfo[] FTI = new FluidTankInfo[getMaxType()]; - for (int i = 0; i < getMaxType(); i++) { - FTI[i] = new FluidTankInfo(mStoredFluid[i], mCapacityPer); - } - return FTI; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide() && mStoredFluid != null) { - for (int i = 0; i < getMaxType(); i++) { - if (mStoredFluid[i] != null && mStoredFluid[i].amount <= 0) { - mStoredFluid[i] = null; - } - } - } - super.onPostTick(aBaseMetaTileEntity, aTick); - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex >= 4; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - final int SLOT_NUMBER = 4; - final Pos2d[] positions = new Pos2d[] { new Pos2d(70, 25), new Pos2d(88, 25), new Pos2d(70, 43), - new Pos2d(88, 43), }; - - for (int i = 0; i < SLOT_NUMBER; i++) { - builder.widget( - new FluidSlotWidget(fluidTanks[i]).setBackground(ModularUITextures.FLUID_SLOT) - .setPos(positions[i])); - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java deleted file mode 100644 index 2aa2410bd1..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Output.java +++ /dev/null @@ -1,497 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.FLUID_OUT_SIGN; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; - -import java.lang.ref.WeakReference; - -import javax.annotation.Nonnull; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidContainerRegistry; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidContainerItem; -import net.minecraftforge.fluids.IFluidHandler; - -import com.gtnewhorizons.modularui.api.math.Alignment; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; -import com.gtnewhorizons.modularui.common.widget.TextWidget; - -import gregtech.GT_Mod; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.fluid.IFluidStore; -import gregtech.api.interfaces.metatileentity.IFluidLockable; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Utility; -import gregtech.common.gui.modularui.widget.FluidLockWidget; - -public class GT_MetaTileEntity_Hatch_Output extends GT_MetaTileEntity_Hatch - implements IFluidStore, IFluidLockable, IAddUIWidgets { - - private String lockedFluidName = null; - private WeakReference playerThatLockedfluid = null; - public byte mMode = 0; - - public GT_MetaTileEntity_Hatch_Output(int aID, String aName, String aNameRegional, int aTier) { - super( - aID, - aName, - aNameRegional, - aTier, - 4, - new String[] { "Fluid Output for Multiblocks", - "Capacity: " + GT_Utility.formatNumbers(8000L * (1L << aTier)) + "L", - "Right click with screwdriver to restrict output", - "Can be restricted to put out Items and/or Steam/No Steam/1 specific Fluid", - "Restricted Output Hatches are given priority for Multiblock Fluid output" }); - } - - public GT_MetaTileEntity_Hatch_Output(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 4, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Output(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 4, aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_Output(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, - int inventorySize) { - super(aID, aName, aNameRegional, aTier, inventorySize, aDescription); - } - - public GT_MetaTileEntity_Hatch_Output(String name, int tier, int slots, String[] description, - ITexture[][][] textures) { - super(name, tier, slots, description, textures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(FLUID_OUT_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(FLUID_OUT_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isLiquidInput(ForgeDirection side) { - return false; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_Output(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isAllowedToWork() && mFluid != null) { - IFluidHandler tTileEntity = aBaseMetaTileEntity - .getITankContainerAtSide(aBaseMetaTileEntity.getFrontFacing()); - if (tTileEntity != null) { - GT_Utility.moveFluid( - aBaseMetaTileEntity, - tTileEntity, - aBaseMetaTileEntity.getFrontFacing(), - Math.max(1, mFluid.amount), - null); - } - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setByte("mMode", mMode); - if (isFluidLocked() && lockedFluidName != null && lockedFluidName.length() != 0) - aNBT.setString("lockedFluidName", lockedFluidName); - else aNBT.removeTag("lockedFluidName"); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - mMode = aNBT.getByte("mMode"); - if (isFluidLocked()) { - lockedFluidName = aNBT.getString("lockedFluidName"); - } - lockedFluidName = GT_Utility.isStringInvalid(lockedFluidName) ? null : lockedFluidName; - } - - @Override - public boolean doesFillContainers() { - return true; - } - - @Override - public boolean doesEmptyContainers() { - return false; - } - - @Override - public boolean canTankBeFilled() { - return true; - } - - @Override - public boolean canTankBeEmptied() { - return true; - } - - @Override - public boolean displaysItemStack() { - return true; - } - - @Override - public boolean displaysStackSize() { - return false; - } - - public int getLockedDisplaySlot() { - return 3; - } - - @Override - public boolean isValidSlot(int aIndex) { - // Because getStackDisplaySlot() only allow return one int, this place I only can manually set. - return aIndex != getStackDisplaySlot() && aIndex != getLockedDisplaySlot(); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 1; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 0; - } - - @Override - public int getCapacity() { - return 8000 * (1 << mTier); - } - - @Override - public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { - if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) - .isGUIClickable()) return; - if (aPlayer.isSneaking()) { - mMode = (byte) ((mMode + 9) % 10); - } else { - mMode = (byte) ((mMode + 1) % 10); - } - final String inBrackets; - switch (mMode) { - case 0 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("108", "Outputs misc. Fluids, Steam and Items")); - this.setLockedFluidName(null); - } - case 1 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("109", "Outputs Steam and Items")); - this.setLockedFluidName(null); - } - case 2 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("110", "Outputs Steam and misc. Fluids")); - this.setLockedFluidName(null); - } - case 3 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("111", "Outputs Steam")); - this.setLockedFluidName(null); - } - case 4 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("112", "Outputs misc. Fluids and Items")); - this.setLockedFluidName(null); - } - case 5 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("113", "Outputs only Items")); - this.setLockedFluidName(null); - } - case 6 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("114", "Outputs only misc. Fluids")); - this.setLockedFluidName(null); - } - case 7 -> { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("115", "Outputs nothing")); - this.setLockedFluidName(null); - } - case 8 -> { - playerThatLockedfluid = new WeakReference<>(aPlayer); - if (mFluid == null) { - this.setLockedFluidName(null); - inBrackets = GT_Utility.trans( - "115.3", - "currently none, will be locked to the next that is put in (or use fluid cell to lock)"); - } else { - this.setLockedFluidName( - this.getDrainableStack() - .getFluid() - .getName()); - inBrackets = this.getDrainableStack() - .getLocalizedName(); - } - GT_Utility.sendChatToPlayer( - aPlayer, - String.format( - "%s (%s)", - GT_Utility.trans("151.1", "Outputs items and 1 specific Fluid"), - inBrackets)); - } - case 9 -> { - playerThatLockedfluid = new WeakReference<>(aPlayer); - if (mFluid == null) { - this.setLockedFluidName(null); - inBrackets = GT_Utility.trans( - "115.3", - "currently none, will be locked to the next that is put in (or use fluid cell to lock)"); - } else { - this.setLockedFluidName( - this.getDrainableStack() - .getFluid() - .getName()); - inBrackets = this.getDrainableStack() - .getLocalizedName(); - } - GT_Utility.sendChatToPlayer( - aPlayer, - String.format("%s (%s)", GT_Utility.trans("151.2", "Outputs 1 specific Fluid"), inBrackets)); - } - } - } - - private boolean tryToLockHatch(EntityPlayer aPlayer, ForgeDirection side) { - if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) - .isGUIClickable()) return false; - if (!isFluidLocked()) return false; - final ItemStack tCurrentItem = aPlayer.inventory.getCurrentItem(); - if (tCurrentItem == null) return false; - FluidStack tFluid = FluidContainerRegistry.getFluidForFilledItem(tCurrentItem); - if (tFluid == null && tCurrentItem.getItem() instanceof IFluidContainerItem) - tFluid = ((IFluidContainerItem) tCurrentItem.getItem()).getFluid(tCurrentItem); - if (tFluid != null) { - if (getLockedFluidName() != null && !getLockedFluidName().equals( - tFluid.getFluid() - .getName())) { - GT_Utility.sendChatToPlayer( - aPlayer, - String.format( - "%s %s", - GT_Utility.trans( - "151.3", - "Hatch is locked to a different fluid. To change the locking, empty it and made it locked to the next fluid with a screwdriver. Currently locked to"), - StatCollector.translateToLocal(getLockedFluidName()))); - } else { - setLockedFluidName( - tFluid.getFluid() - .getName()); - if (mMode == 8) GT_Utility.sendChatToPlayer( - aPlayer, - String.format( - "%s (%s)", - GT_Utility.trans("151.1", "Outputs items and 1 specific Fluid"), - tFluid.getLocalizedName())); - else GT_Utility.sendChatToPlayer( - aPlayer, - String.format( - "%s (%s)", - GT_Utility.trans("151.2", "Outputs 1 specific Fluid"), - tFluid.getLocalizedName())); - } - return true; - } - return false; - } - - public byte getMode() { - return mMode; - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side, - float aX, float aY, float aZ) { - if (tryToLockHatch(aPlayer, side)) return true; - return super.onRightclick(aBaseMetaTileEntity, aPlayer, side, aX, aY, aZ); - } - - public boolean outputsSteam() { - return mMode < 4; - } - - public boolean outputsLiquids() { - return mMode % 2 == 0 || mMode == 9; - } - - public boolean outputsItems() { - return mMode % 4 < 2 && mMode != 9; - } - - @Override - public String getLockedFluidName() { - return lockedFluidName; - } - - @Override - public void setLockedFluidName(String lockedFluidName) { - this.lockedFluidName = lockedFluidName; - markDirty(); - } - - @Override - public void lockFluid(boolean lock) { - if (lock) { - if (!isFluidLocked()) { - this.mMode = 9; - markDirty(); - } - } else { - this.mMode = 0; - setLockedFluidName(null); - markDirty(); - } - } - - @Override - public boolean isFluidLocked() { - return mMode == 8 || mMode == 9; - } - - @Override - public boolean acceptsFluidLock(String name) { - return true; - } - - @Override - public boolean isEmptyAndAcceptsAnyFluid() { - return mMode == 0 && getFluidAmount() == 0; - } - - @Override - public boolean canStoreFluid(@Nonnull FluidStack fluidStack) { - if (mFluid != null && !GT_Utility.areFluidsEqual(mFluid, fluidStack)) { - return false; - } - if (isFluidLocked()) { - if (lockedFluidName == null) { - return true; - } - return lockedFluidName.equals( - fluidStack.getFluid() - .getName()); - } - if (GT_ModHandler.isSteam(fluidStack)) { - return outputsSteam(); - } - return outputsLiquids(); - } - - @Override - public int getTankPressure() { - return +100; - } - - @Override - protected void onEmptyingContainerWhenEmpty() { - if (this.lockedFluidName == null && this.mFluid != null && isFluidLocked()) { - this.setLockedFluidName( - this.mFluid.getFluid() - .getName()); - final EntityPlayer player; - if (playerThatLockedfluid == null || (player = playerThatLockedfluid.get()) == null) return; - GT_Utility.sendChatToPlayer( - player, - String.format(GT_Utility.trans("151.4", "Successfully locked Fluid to %s"), mFluid.getLocalizedName())); - playerThatLockedfluid = null; - } - } - - @Override - public boolean isGivingInformation() { - return true; - } - - @Override - public String[] getInfoData() { - return new String[] { EnumChatFormatting.BLUE + "Output Hatch" + EnumChatFormatting.RESET, "Stored Fluid:", - EnumChatFormatting.GOLD + (mFluid == null ? "No Fluid" : mFluid.getLocalizedName()) - + EnumChatFormatting.RESET, - EnumChatFormatting.GREEN + GT_Utility.formatNumbers(mFluid == null ? 0 : mFluid.amount) - + " L" - + EnumChatFormatting.RESET - + " " - + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(getCapacity()) - + " L" - + EnumChatFormatting.RESET, - (!isFluidLocked() || lockedFluidName == null) ? "Not Locked" - : ("Locked to " + StatCollector.translateToLocal( - FluidRegistry.getFluidStack(lockedFluidName, 1) - .getUnlocalizedName())) }; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - super.addUIWidgets(builder, buildContext); - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(98, 16) - .setSize(71, 45)) - .widget(new FluidLockWidget(this).setPos(149, 41)) - .widget( - new TextWidget("Locked Fluid").setDefaultColor(COLOR_TEXT_WHITE.get()) - .setPos(101, 20)) - .widget(TextWidget.dynamicString(() -> { - FluidStack fluidStack = FluidRegistry.getFluidStack(lockedFluidName, 1); - return fluidStack != null ? fluidStack.getLocalizedName() : "None"; - }) - .setDefaultColor(COLOR_TEXT_WHITE.get()) - .setTextAlignment(Alignment.CenterLeft) - .setMaxWidth(65) - .setPos(101, 30)) - .widget(new FakeSyncWidget.ByteSyncer(() -> mMode, val -> mMode = val)); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java deleted file mode 100644 index 0bfe55cac1..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_OutputBus.java +++ /dev/null @@ -1,323 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.Textures.BlockIcons.ITEM_OUT_SIGN; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; -import static gregtech.api.util.GT_Utility.moveMultipleItemStacks; - -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.util.ChatComponentTranslation; -import net.minecraftforge.common.util.ForgeDirection; - -import org.jetbrains.annotations.Nullable; - -import com.gtnewhorizons.modularui.api.forge.ItemHandlerHelper; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; - -import gregtech.GT_Mod; -import gregtech.api.enums.ItemList; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.widgets.GT_PhantomItemButton; -import gregtech.api.interfaces.IDataCopyable; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IItemLockable; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.extensions.ArrayExt; - -public class GT_MetaTileEntity_Hatch_OutputBus extends GT_MetaTileEntity_Hatch - implements IAddUIWidgets, IItemLockable, IDataCopyable { - - private static final String DATA_STICK_DATA_TYPE = "outputBusFilter"; - private static final String LOCKED_ITEM_NBT_KEY = "lockedItem"; - - protected ItemStack lockedItem = null; - - public GT_MetaTileEntity_Hatch_OutputBus(int aID, String aName, String aNameRegional, int aTier) { - this(aID, aName, aNameRegional, aTier, getSlots(aTier)); - } - - public GT_MetaTileEntity_Hatch_OutputBus(int id, String name, String nameRegional, int tier, int slots) { - super( - id, - name, - nameRegional, - tier, - slots, - ArrayExt.of( - "Item Output for Multiblocks", - "Capacity: " + getSlots(tier) + " stack" + (getSlots(tier) >= 2 ? "s" : ""), - "Left click with data stick to save filter config", - "Right click with data stick to load filter config")); - } - - public GT_MetaTileEntity_Hatch_OutputBus(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription) { - super(aID, aName, aNameRegional, aTier, getSlots(aTier), aDescription); - } - - public GT_MetaTileEntity_Hatch_OutputBus(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription, int inventorySize) { - super(aID, aName, aNameRegional, aTier, inventorySize, aDescription); - } - - public GT_MetaTileEntity_Hatch_OutputBus(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, getSlots(aTier), aDescription, aTextures); - } - - public GT_MetaTileEntity_Hatch_OutputBus(String name, int tier, int slots, String[] description, - ITexture[][][] textures) { - super(name, tier, slots, description, textures); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(ITEM_OUT_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch - ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(ITEM_OUT_SIGN) } - : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return true; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_OutputBus(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - if (!acceptsItemLock() || !(aPlayer instanceof EntityPlayerMP)) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return super.onRightclick(aBaseMetaTileEntity, aPlayer); - } - - final ItemStack dataStick = aPlayer.inventory.getCurrentItem(); - if (!ItemList.Tool_DataStick.isStackEqual(dataStick, false, true)) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return super.onRightclick(aBaseMetaTileEntity, aPlayer); - } - - if (!pasteCopiedData(aPlayer, dataStick.stackTagCompound)) { - aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.output_bus.invalid")); - return false; - } - - aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.output_bus.loaded")); - return true; - - } - - @Override - public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - if (!acceptsItemLock() || !(aPlayer instanceof EntityPlayerMP)) { - return; - } - final ItemStack dataStick = aPlayer.inventory.getCurrentItem(); - if (!ItemList.Tool_DataStick.isStackEqual(dataStick, false, true)) { - return; - } - - dataStick.stackTagCompound = getCopiedData(aPlayer); - dataStick.setStackDisplayName("Output Bus Configuration"); - aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.output_bus.saved")); - } - - @Override - public NBTTagCompound getCopiedData(EntityPlayer player) { - final NBTTagCompound nbt = new NBTTagCompound(); - nbt.setString("type", DATA_STICK_DATA_TYPE); - if (lockedItem != null) { - nbt.setTag(LOCKED_ITEM_NBT_KEY, lockedItem.writeToNBT(new NBTTagCompound())); - } - return nbt; - } - - @Override - public boolean pasteCopiedData(EntityPlayer player, NBTTagCompound nbt) { - if (nbt == null || !DATA_STICK_DATA_TYPE.equals(nbt.getString("type"))) return false; - if (nbt.hasKey(LOCKED_ITEM_NBT_KEY)) { - lockedItem = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(LOCKED_ITEM_NBT_KEY)); - } else { - lockedItem = null; - } - return true; - } - - @Override - public String getCopiedDataIdentifier(EntityPlayer player) { - return DATA_STICK_DATA_TYPE; - } - - /** - * Attempt to store as many items as possible into the internal inventory of this output bus. If you need atomicity - * you should use {@link gregtech.api.interfaces.tileentity.IHasInventory#addStackToSlot(int, ItemStack)} - * - * @param aStack Assume valid. Will be mutated. Take over the ownership. Caller should not retain a reference to - * this stack if the call returns true. - * @return true if stack is fully accepted. false is stack is partially accepted or nothing is accepted - */ - public boolean storeAll(ItemStack aStack) { - markDirty(); - - if (lockedItem != null && !lockedItem.isItemEqual(aStack)) { - return false; - } - - for (int i = 0, mInventoryLength = mInventory.length; i < mInventoryLength && aStack.stackSize > 0; i++) { - ItemStack tSlot = mInventory[i]; - if (GT_Utility.isStackInvalid(tSlot)) { - int tRealStackLimit = Math.min(getInventoryStackLimit(), aStack.getMaxStackSize()); - if (aStack.stackSize <= tRealStackLimit) { - mInventory[i] = aStack; - return true; - } - mInventory[i] = aStack.splitStack(tRealStackLimit); - } else { - int tRealStackLimit = Math.min(getInventoryStackLimit(), tSlot.getMaxStackSize()); - if (tSlot.stackSize < tRealStackLimit && tSlot.isItemEqual(aStack) - && ItemStack.areItemStackTagsEqual(tSlot, aStack)) { - if (aStack.stackSize + tSlot.stackSize <= tRealStackLimit) { - mInventory[i].stackSize += aStack.stackSize; - return true; - } else { - // more to serve - aStack.stackSize -= tRealStackLimit - tSlot.stackSize; - mInventory[i].stackSize = tRealStackLimit; - } - } - } - } - return false; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return side == aBaseMetaTileEntity.getFrontFacing(); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPostTick(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isAllowedToWork() && (aTick & 0x7) == 0) { - final IInventory tTileEntity = aBaseMetaTileEntity - .getIInventoryAtSide(aBaseMetaTileEntity.getFrontFacing()); - if (tTileEntity != null) { - moveMultipleItemStacks( - aBaseMetaTileEntity, - tTileEntity, - aBaseMetaTileEntity.getFrontFacing(), - aBaseMetaTileEntity.getBackFacing(), - null, - false, - (byte) 64, - (byte) 1, - (byte) 64, - (byte) 1, - mInventory.length); - for (int i = 0; i < mInventory.length; i++) - if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; - } - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - if (lockedItem != null) { - aNBT.setTag(LOCKED_ITEM_NBT_KEY, lockedItem.writeToNBT(new NBTTagCompound())); - } - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - if (aNBT.hasKey(LOCKED_ITEM_NBT_KEY)) { - lockedItem = ItemStack.loadItemStackFromNBT(aNBT.getCompoundTag(LOCKED_ITEM_NBT_KEY)); - } - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - switch (mTier) { - case 0 -> getBaseMetaTileEntity().add1by1Slot(builder); - case 1 -> getBaseMetaTileEntity().add2by2Slots(builder); - case 2 -> getBaseMetaTileEntity().add3by3Slots(builder); - default -> getBaseMetaTileEntity().add4by4Slots(builder); - } - - if (acceptsItemLock()) { - builder.widget( - new GT_PhantomItemButton(this).setPos(getGUIWidth() - 25, 40) - .setBackground(GT_PhantomItemButton.FILTER_BACKGROUND)); - } - } - - @Override - public void setLockedItem(@Nullable ItemStack itemStack) { - if (itemStack == null) { - clearLock(); - } else { - lockedItem = ItemHandlerHelper.copyStackWithSize(itemStack, 1); - } - } - - @Nullable - @Override - public ItemStack getLockedItem() { - return lockedItem; - } - - @Override - public void clearLock() { - lockedItem = null; - } - - @Override - public boolean isLocked() { - return lockedItem != null; - } - - @Override - public boolean acceptsItemLock() { - return true; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_QuadrupleHumongous.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_QuadrupleHumongous.java deleted file mode 100644 index e0ab7acf95..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_QuadrupleHumongous.java +++ /dev/null @@ -1,27 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.MetaTileEntity; - -public class GT_MetaTileEntity_Hatch_QuadrupleHumongous extends GT_MetaTileEntity_Hatch_MultiInput { - - public GT_MetaTileEntity_Hatch_QuadrupleHumongous(int aID, int aSlot, String aName, String aNameRegional) { - super(aID, aSlot, aName, aNameRegional, 13); - } - - public GT_MetaTileEntity_Hatch_QuadrupleHumongous(String aName, int aSlot, int aTier, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aSlot, aTier, aDescription, aTextures); - } - - @Override - public int getCapacityPerTank(int aTier, int aSlot) { - return 500_000_000; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Hatch_QuadrupleHumongous(mName, getMaxType(), mTier, mDescriptionArray, mTextures); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MagHatch.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MagHatch.java deleted file mode 100644 index 8a462d12c6..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MagHatch.java +++ /dev/null @@ -1,103 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.AuthorFourIsTheNumber; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_EMS_HOUSING; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_EMS_HOUSING_GLOW; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.util.ForgeDirection; - -import org.apache.commons.lang3.ArrayUtils; - -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; - -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.render.TextureFactory; -import gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_IndustrialElectromagneticSeparator; - -public class GT_MetaTileEntity_MagHatch extends GT_MetaTileEntity_Hatch { - - public GT_MetaTileEntity_MagHatch(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional, 5, 1, "Holds electromagnet for the Magnetic Flux Exhibitor"); - } - - public GT_MetaTileEntity_MagHatch(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 1, aDescription[0], aTextures); - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public String[] getDescription() { - return ArrayUtils.addAll(this.mDescriptionArray, AuthorFourIsTheNumber); - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.widget( - new SlotWidget(inventoryHandler, 0) - .setFilter(GT_MetaTileEntity_IndustrialElectromagneticSeparator::isValidElectromagnet) - .setAccess(true, true) - .setPos(79, 34)); - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.builder() - .addIcon(OVERLAY_EMS_HOUSING) - .extFacing() - .build(), - TextureFactory.builder() - .addIcon(OVERLAY_EMS_HOUSING_GLOW) - .extFacing() - .glow() - .build() }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.builder() - .addIcon(OVERLAY_EMS_HOUSING) - .extFacing() - .build(), - TextureFactory.builder() - .addIcon(OVERLAY_EMS_HOUSING_GLOW) - .extFacing() - .glow() - .build() }; - } - - @Override - public int getInventoryStackLimit() { - return 1; - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_MagHatch(mName, mTier, mDescriptionArray, mTextures); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java deleted file mode 100644 index 6c2df9b082..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java +++ /dev/null @@ -1,2754 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.GT_Values.VN; -import static gregtech.api.util.GT_Utility.filterValidMTEs; -import static gregtech.api.util.GT_Utility.formatNumbers; -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 java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.IntConsumer; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.client.Minecraft; -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.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.ResourceLocation; -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 org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.TestOnly; - -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.gtnewhorizons.modularui.api.NumberFormatMUI; -import com.gtnewhorizons.modularui.api.drawable.UITexture; -import com.gtnewhorizons.modularui.api.math.Alignment; -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.common.internal.network.NetworkUtils; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; -import com.gtnewhorizons.modularui.common.widget.TextWidget; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.GT_Mod; -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.VoidingMode; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.fluid.IFluidStore; -import gregtech.api.interfaces.metatileentity.IItemLockable; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.modularui.ControllerWithOptionalFeatures; -import gregtech.api.interfaces.modularui.IAddGregtechLogo; -import gregtech.api.interfaces.modularui.IAddUIWidgets; -import gregtech.api.interfaces.modularui.IBindPlayerInventoryUI; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.items.GT_MetaGenerated_Tool; -import gregtech.api.logic.ProcessingLogic; -import gregtech.api.metatileentity.MetaTileEntity; -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.recipe.check.SingleRecipeCheck; -import gregtech.api.util.GT_ClientPreference; -import gregtech.api.util.GT_ExoticEnergyInputHelper; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_ParallelHelper; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Util; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.GT_Waila; -import gregtech.api.util.OutputHatchWrapper; -import gregtech.api.util.VoidProtectionHelper; -import gregtech.api.util.shutdown.ShutDownReason; -import gregtech.api.util.shutdown.ShutDownReasonRegistry; -import gregtech.client.GT_SoundLoop; -import gregtech.common.GT_Pollution; -import gregtech.common.config.machinestats.ConfigMachines; -import gregtech.common.gui.modularui.widget.CheckRecipeResultSyncer; -import gregtech.common.gui.modularui.widget.ShutDownReasonSyncer; -import gregtech.common.items.GT_MetaGenerated_Tool_01; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_CraftingInput_ME; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_InputBus_ME; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Input_ME; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_OutputBus_ME; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Output_ME; -import gregtech.common.tileentities.machines.IDualInputHatch; -import gregtech.common.tileentities.machines.IDualInputInventory; -import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch; -import gregtech.common.tileentities.machines.ISmartInputHatch; -import gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_LargeTurbine; -import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; -import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; -import mcp.mobius.waila.api.IWailaConfigHandler; -import mcp.mobius.waila.api.IWailaDataAccessor; - -public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity - implements ControllerWithOptionalFeatures, IAddGregtechLogo, IAddUIWidgets, IBindPlayerInventoryUI { - - public static boolean disableMaintenance; - public boolean hasMaintenanceChecks = getDefaultHasMaintenanceChecks(); - public boolean mMachine = false, mWrench = false, mScrewdriver = false, mSoftHammer = false, mHardHammer = false, - mSolderingTool = false, mCrowbar = false, mRunningOnLoad = false; - public boolean mStructureChanged = false; - public int mPollution = 0, mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mEfficiencyIncrease = 0, - mStartUpCheck = 100, mRuntime = 0, mEfficiency = 0; - public volatile boolean mUpdated = false; - public int mUpdate = 0; - public ItemStack[] mOutputItems = null; - public FluidStack[] mOutputFluids = null; - public String mNEI; - public int damageFactorLow = 5; - public float damageFactorHigh = 0.6f; - public int machineMode = 0; - public List machineModeIcons = new ArrayList(); - - public boolean mLockedToSingleRecipe = getDefaultRecipeLockingMode(); - protected boolean inputSeparation = getDefaultInputSeparationMode(); - protected VoidingMode voidingMode = getDefaultVoidingMode(); - protected boolean batchMode = getDefaultBatchMode(); - protected @Nonnull CheckRecipeResult checkRecipeResult = CheckRecipeResultRegistry.NONE; - - protected static final String INPUT_SEPARATION_NBT_KEY = "inputSeparation"; - protected static final String VOID_EXCESS_NBT_KEY = "voidExcess"; - protected static final String VOIDING_MODE_NBT_KEY = "voidingMode"; - protected static final String BATCH_MODE_NBT_KEY = "batchMode"; - protected SingleRecipeCheck mSingleRecipeCheck = null; - - public ArrayList mInputHatches = new ArrayList<>(); - public ArrayList mOutputHatches = new ArrayList<>(); - public ArrayList mInputBusses = new ArrayList<>(); - public ArrayList mOutputBusses = new ArrayList<>(); - public ArrayList mDualInputHatches = new ArrayList<>(); - public ArrayList mSmartInputHatches = new ArrayList<>(); - public ArrayList mDynamoHatches = new ArrayList<>(); - public ArrayList mMufflerHatches = new ArrayList<>(); - public ArrayList mEnergyHatches = new ArrayList<>(); - public ArrayList mMaintenanceHatches = new ArrayList<>(); - protected List mExoticEnergyHatches = new ArrayList<>(); - protected final ProcessingLogic processingLogic; - @SideOnly(Side.CLIENT) - protected GT_SoundLoop activitySoundLoop; - - protected long mLastWorkingTick = 0, mTotalRunTime = 0; - private static final int CHECK_INTERVAL = 100; // How often should we check for a new recipe on an idle machine? - private final int randomTickOffset = (int) (Math.random() * CHECK_INTERVAL + 1); - - protected static final byte INTERRUPT_SOUND_INDEX = 8; - protected static final byte PROCESS_START_SOUND_INDEX = 1; - - public GT_MetaTileEntity_MultiBlockBase(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional, 2); - this.processingLogic = null; - GT_MetaTileEntity_MultiBlockBase.disableMaintenance = ConfigMachines.disableMaintenanceChecks; - this.damageFactorLow = ConfigMachines.damageFactorLow; - this.damageFactorHigh = ConfigMachines.damageFactorHigh; - this.mNEI = ""; - if (!shouldCheckMaintenance()) fixAllIssues(); - } - - public GT_MetaTileEntity_MultiBlockBase(String aName) { - super(aName, 2); - this.processingLogic = createProcessingLogic(); - GT_MetaTileEntity_MultiBlockBase.disableMaintenance = ConfigMachines.disableMaintenanceChecks; - this.damageFactorLow = ConfigMachines.damageFactorLow; - this.damageFactorHigh = ConfigMachines.damageFactorHigh; - if (!shouldCheckMaintenance()) fixAllIssues(); - } - - @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { - return side != getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { - if (supportsSingleRecipeLocking()) { - mLockedToSingleRecipe = !mLockedToSingleRecipe; - if (mLockedToSingleRecipe) { - GT_Utility.sendChatToPlayer( - aPlayer, - GT_Utility.trans("223", "Single recipe locking enabled. Will lock to next recipe.")); - } else { - GT_Utility.sendChatToPlayer(aPlayer, GT_Utility.trans("220", "Single recipe locking disabled.")); - mSingleRecipeCheck = null; - } - } - } - - @Override - public boolean isSimpleMachine() { - return false; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isValidSlot(int aIndex) { - return aIndex > 0; - } - - @Override - public int getProgresstime() { - return mProgresstime; - } - - @Override - public int maxProgresstime() { - return mMaxProgresstime; - } - - public long getTotalRuntimeInTicks() { - return mTotalRunTime; - } - - @Override - public int increaseProgress(int aProgress) { - return aProgress; - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - aNBT.setInteger("mEUt", mEUt); - aNBT.setInteger("mProgresstime", mProgresstime); - aNBT.setInteger("mMaxProgresstime", mMaxProgresstime); - aNBT.setInteger("mEfficiencyIncrease", mEfficiencyIncrease); - aNBT.setInteger("mEfficiency", mEfficiency); - aNBT.setInteger("mPollution", mPollution); - aNBT.setInteger("mRuntime", mRuntime); - aNBT.setLong("mTotalRunTime", mTotalRunTime); - aNBT.setLong("mLastWorkingTick", mLastWorkingTick); - aNBT.setString("checkRecipeResultID", checkRecipeResult.getID()); - aNBT.setTag("checkRecipeResult", checkRecipeResult.writeToNBT(new NBTTagCompound())); - - if (supportsMachineModeSwitch()) { - aNBT.setInteger("machineMode", machineMode); - } - - if (supportsSingleRecipeLocking()) { - aNBT.setBoolean("mLockedToSingleRecipe", mLockedToSingleRecipe); - if (mLockedToSingleRecipe && mSingleRecipeCheck != null) - aNBT.setTag("mSingleRecipeCheck", mSingleRecipeCheck.writeToNBT()); - } - - if (mOutputItems != null) { - aNBT.setInteger("mOutputItemsLength", mOutputItems.length); - for (int i = 0; i < mOutputItems.length; i++) if (mOutputItems[i] != null) { - GT_Utility.saveItem(aNBT, "mOutputItem" + i, mOutputItems[i]); - } - } - if (mOutputFluids != null) { - aNBT.setInteger("mOutputFluidsLength", mOutputFluids.length); - for (int i = 0; i < mOutputFluids.length; i++) if (mOutputFluids[i] != null) { - NBTTagCompound tNBT = new NBTTagCompound(); - mOutputFluids[i].writeToNBT(tNBT); - aNBT.setTag("mOutputFluids" + i, tNBT); - } - } - aNBT.setBoolean("mWrench", mWrench); - aNBT.setBoolean("mScrewdriver", mScrewdriver); - aNBT.setBoolean("mSoftHammer", mSoftHammer); - aNBT.setBoolean("mHardHammer", mHardHammer); - aNBT.setBoolean("mSolderingTool", mSolderingTool); - aNBT.setBoolean("mCrowbar", mCrowbar); - aNBT.setBoolean(BATCH_MODE_NBT_KEY, batchMode); - aNBT.setBoolean(INPUT_SEPARATION_NBT_KEY, inputSeparation); - aNBT.setString(VOIDING_MODE_NBT_KEY, voidingMode.name); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - mEUt = aNBT.getInteger("mEUt"); - mProgresstime = aNBT.getInteger("mProgresstime"); - mMaxProgresstime = aNBT.getInteger("mMaxProgresstime"); - if (mMaxProgresstime > 0) mRunningOnLoad = true; - mEfficiencyIncrease = aNBT.getInteger("mEfficiencyIncrease"); - mEfficiency = aNBT.getInteger("mEfficiency"); - mPollution = aNBT.getInteger("mPollution"); - mRuntime = aNBT.getInteger("mRuntime"); - mTotalRunTime = aNBT.getLong("mTotalRunTime"); - mLastWorkingTick = aNBT.getLong("mLastWorkingTick"); - - String checkRecipeResultID = aNBT.getString("checkRecipeResultID"); - if (CheckRecipeResultRegistry.isRegistered(checkRecipeResultID)) { - CheckRecipeResult result = CheckRecipeResultRegistry.getSampleFromRegistry(checkRecipeResultID) - .newInstance(); - result.readFromNBT(aNBT.getCompoundTag("checkRecipeResult")); - checkRecipeResult = result; - } - - if (aNBT.hasKey("machineMode")) { - machineMode = aNBT.getInteger("machineMode"); - } - if (supportsSingleRecipeLocking()) { - mLockedToSingleRecipe = aNBT.getBoolean("mLockedToSingleRecipe"); - if (mLockedToSingleRecipe && aNBT.hasKey("mSingleRecipeCheck", Constants.NBT.TAG_COMPOUND)) { - SingleRecipeCheck c = loadSingleRecipeChecker(aNBT.getCompoundTag("mSingleRecipeCheck")); - if (c != null) mSingleRecipeCheck = c; - // the old recipe is gone. we disable the machine to prevent making garbage in case of shared inputs - // maybe use a better way to inform player in the future. - else getBaseMetaTileEntity().disableWorking(); - } - } - batchMode = aNBT.getBoolean(BATCH_MODE_NBT_KEY); - inputSeparation = aNBT.getBoolean(INPUT_SEPARATION_NBT_KEY); - if (aNBT.hasKey(VOIDING_MODE_NBT_KEY, Constants.NBT.TAG_STRING)) { - voidingMode = VoidingMode.fromName(aNBT.getString(VOIDING_MODE_NBT_KEY)); - } else if (aNBT.hasKey(VOID_EXCESS_NBT_KEY)) { - // backward compatibility - voidingMode = aNBT.getBoolean(VOID_EXCESS_NBT_KEY) ? VoidingMode.VOID_ALL : VoidingMode.VOID_NONE; - } - if (!getAllowedVoidingModes().contains(voidingMode)) voidingMode = getDefaultVoidingMode(); - - int aOutputItemsLength = aNBT.getInteger("mOutputItemsLength"); - if (aOutputItemsLength > 0) { - mOutputItems = new ItemStack[aOutputItemsLength]; - for (int i = 0; i < mOutputItems.length; i++) - mOutputItems[i] = GT_Utility.loadItem(aNBT, "mOutputItem" + i); - } - - int aOutputFluidsLength = aNBT.getInteger("mOutputFluidsLength"); - if (aOutputFluidsLength > 0) { - mOutputFluids = new FluidStack[aOutputFluidsLength]; - for (int i = 0; i < mOutputFluids.length; i++) - mOutputFluids[i] = GT_Utility.loadFluid(aNBT, "mOutputFluids" + i); - } - if (shouldCheckMaintenance()) { - mWrench = aNBT.getBoolean("mWrench"); - mScrewdriver = aNBT.getBoolean("mScrewdriver"); - mSoftHammer = aNBT.getBoolean("mSoftHammer"); - mHardHammer = aNBT.getBoolean("mHardHammer"); - mSolderingTool = aNBT.getBoolean("mSolderingTool"); - mCrowbar = aNBT.getBoolean("mCrowbar"); - } else fixAllIssues(); - } - - protected SingleRecipeCheck loadSingleRecipeChecker(NBTTagCompound aNBT) { - return SingleRecipeCheck.tryLoad(getRecipeMap(), aNBT); - } - - public boolean saveOtherHatchConfiguration(EntityPlayer player) { - return true; - } - - public boolean loadOtherHatchConfiguration(EntityPlayer player) { - return true; - } - - @Override - public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - if (aBaseMetaTileEntity.isServerSide() && GT_Util.saveMultiblockInputConfiguration(this, aPlayer)) { - aPlayer.addChatComponentMessage(new ChatComponentTranslation("GT5U.MULTI_MACHINE_CONFIG.SAVE")); - return; - } - super.onLeftclick(aBaseMetaTileEntity, aPlayer); - } - - @Override - public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { - if (GT_Util.hasMultiblockInputConfiguration(aPlayer.getHeldItem())) { - if (aBaseMetaTileEntity.isServerSide()) { - if (GT_Util.loadMultiblockInputConfiguration(this, aPlayer)) { - aPlayer.addChatComponentMessage(new ChatComponentTranslation("GT5U.MULTI_MACHINE_CONFIG.LOAD")); - } else { - aPlayer - .addChatComponentMessage(new ChatComponentTranslation("GT5U.MULTI_MACHINE_CONFIG.LOAD.FAIL")); - } - } - return true; - } - GT_UIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); - return true; - } - - @Override - public byte getTileEntityBaseType() { - return 2; - } - - /** - * Set the structure as having changed, and trigger an update. - */ - public void onStructureChange() { - mStructureChanged = true; - } - - @Override - public void onMachineBlockUpdate() { - mUpdated = true; - } - - /** - * ClearHatches as a part of structure check. If your multiblock has any hatches that need clearing override this - * method, call super, and clear your own hatches - */ - public void clearHatches() { - mInputHatches.clear(); - mInputBusses.clear(); - mOutputHatches.clear(); - mOutputBusses.clear(); - mDynamoHatches.clear(); - mEnergyHatches.clear(); - setMufflers(false); - mMufflerHatches.clear(); - mMaintenanceHatches.clear(); - mDualInputHatches.clear(); - mSmartInputHatches.clear(); - } - - public boolean checkStructure(boolean aForceReset) { - return checkStructure(aForceReset, getBaseMetaTileEntity()); - } - - public boolean checkStructure(boolean aForceReset, IGregTechTileEntity aBaseMetaTileEntity) { - if (!aBaseMetaTileEntity.isServerSide()) return mMachine; - // Only trigger an update if forced (from onPostTick, generally), or if the structure has changed - if ((mStructureChanged || aForceReset)) { - clearHatches(); - mMachine = checkMachine(aBaseMetaTileEntity, mInventory[1]); - } - mStructureChanged = false; - return mMachine; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide()) { - // Time Counter - mTotalRunTime++; - if (mEfficiency < 0) mEfficiency = 0; - if (mUpdated) { - // duct tape fix for too many updates on an overloaded server, causing the structure check to not run - if (mUpdate <= 0) mUpdate = 50; - mUpdated = false; - } - if (--mUpdate == 0 || --mStartUpCheck == 0) { - checkStructure(true, aBaseMetaTileEntity); - } - - if (mStartUpCheck < 0) { - if (mMachine) { - checkMaintenance(); - if (getRepairStatus() > 0) { - runMachine(aBaseMetaTileEntity, aTick); - } else if (aBaseMetaTileEntity.isAllowedToWork()) { - stopMachine(ShutDownReasonRegistry.NO_REPAIR); - } - } else if (aBaseMetaTileEntity.isAllowedToWork()) { - stopMachine(ShutDownReasonRegistry.STRUCTURE_INCOMPLETE); - } - } - aBaseMetaTileEntity.setErrorDisplayID( - (aBaseMetaTileEntity.getErrorDisplayID() & ~127) | (mWrench ? 0 : 1) - | (mScrewdriver ? 0 : 2) - | (mSoftHammer ? 0 : 4) - | (mHardHammer ? 0 : 8) - | (mSolderingTool ? 0 : 16) - | (mCrowbar ? 0 : 32) - | (mMachine ? 0 : 64)); - aBaseMetaTileEntity.setActive(mMaxProgresstime > 0); - boolean active = aBaseMetaTileEntity.isActive() && mPollution > 0; - setMufflers(active); - } else { - if (!aBaseMetaTileEntity.hasMufflerUpgrade()) { - doActivitySound(getActivitySoundLoop()); - } - } - } - - @Override - public void onTickFail(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onTickFail(aBaseMetaTileEntity, aTick); - if (aBaseMetaTileEntity.isServerSide()) { - aBaseMetaTileEntity.disableWorking(); - checkRecipeResult = CheckRecipeResultRegistry.CRASH; - } - } - - public void checkMaintenance() { - if (!shouldCheckMaintenance()) return; - - if (getRepairStatus() != getIdealStatus()) { - for (GT_MetaTileEntity_Hatch_Maintenance tHatch : filterValidMTEs(mMaintenanceHatches)) { - if (tHatch.mAuto) tHatch.autoMaintainance(); - if (tHatch.mWrench) mWrench = true; - if (tHatch.mScrewdriver) mScrewdriver = true; - if (tHatch.mSoftHammer) mSoftHammer = true; - if (tHatch.mHardHammer) mHardHammer = true; - if (tHatch.mSolderingTool) mSolderingTool = true; - if (tHatch.mCrowbar) mCrowbar = true; - - tHatch.mWrench = false; - tHatch.mScrewdriver = false; - tHatch.mSoftHammer = false; - tHatch.mHardHammer = false; - tHatch.mSolderingTool = false; - tHatch.mCrowbar = false; - } - } - } - - /** - * Starts checking recipe with some operations needed to actually run the check. Overriding this without due care - * may result in dupe of items, hence it's marked as final. - *

- * See {@link #createProcessingLogic()} or {@link #checkProcessing()} for what you want to override. - * - * @return If successfully found recipe and/or started processing - */ - protected final boolean checkRecipe() { - startRecipeProcessing(); - CheckRecipeResult result = checkProcessing(); - if (!CheckRecipeResultRegistry.isRegistered(result.getID())) { - throw new RuntimeException(String.format("Result %s is not registered for registry", result.getID())); - } - if (result.wasSuccessful()) { - sendStartMultiBlockSoundLoop(); - } - this.checkRecipeResult = result; - endRecipeProcessing(); - // Don't use `result` here because `endRecipeProcessing()` might mutate `this.checkRecipeResult` - return this.checkRecipeResult.wasSuccessful(); - } - - private boolean shouldCheckRecipeThisTick(long aTick) { - // do a recipe check if any crafting input hatch just got pushed in items - boolean shouldCheck = false; - // check all of them (i.e. do not return early) to reset the state of all of them. - for (IDualInputHatch craftingInputMe : mDualInputHatches) { - shouldCheck |= craftingInputMe.justUpdated(); - } - if (shouldCheck) return true; - // Do the same for Smart Input Hatches - for (ISmartInputHatch smartInputHatch : mSmartInputHatches) { - shouldCheck |= smartInputHatch.justUpdated(); - } - if (shouldCheck) return true; - - // Perform more frequent recipe change after the machine just shuts down. - long timeElapsed = mTotalRunTime - mLastWorkingTick; - - if (timeElapsed >= CHECK_INTERVAL) return (mTotalRunTime + randomTickOffset) % CHECK_INTERVAL == 0; - // Batch mode should be a lot less aggressive at recipe checking - if (!isBatchModeEnabled()) { - return timeElapsed == 5 || timeElapsed == 12 - || timeElapsed == 20 - || timeElapsed == 30 - || timeElapsed == 40 - || timeElapsed == 55 - || timeElapsed == 70 - || timeElapsed == 85; - } - return false; - } - - protected void runMachine(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (mMaxProgresstime > 0 && doRandomMaintenanceDamage()) { - if (onRunningTick(mInventory[1])) { - markDirty(); - if (!polluteEnvironment(getPollutionPerTick(mInventory[1]))) { - stopMachine(ShutDownReasonRegistry.POLLUTION_FAIL); - } - if (mMaxProgresstime > 0 && ++mProgresstime >= mMaxProgresstime) { - if (mOutputItems != null) { - for (ItemStack tStack : mOutputItems) { - if (tStack != null) { - try { - GT_Mod.achievements.issueAchivementHatch( - aBaseMetaTileEntity.getWorld() - .getPlayerEntityByName(aBaseMetaTileEntity.getOwnerName()), - tStack); - } catch (Exception ignored) {} - addOutput(tStack); - } - } - mOutputItems = null; - } - if (mOutputFluids != null) { - addFluidOutputs(mOutputFluids); - if (mOutputFluids.length > 1) { - try { - GT_Mod.achievements.issueAchievement( - aBaseMetaTileEntity.getWorld() - .getPlayerEntityByName(aBaseMetaTileEntity.getOwnerName()), - "oilplant"); - } catch (Exception ignored) {} - } - mOutputFluids = null; - } - mEfficiency = Math.max( - 0, - Math.min( - mEfficiency + mEfficiencyIncrease, - getMaxEfficiency(mInventory[1]) - ((getIdealStatus() - getRepairStatus()) * 1000))); - mOutputItems = null; - mProgresstime = 0; - mMaxProgresstime = 0; - mEfficiencyIncrease = 0; - mLastWorkingTick = mTotalRunTime; - if (aBaseMetaTileEntity.isAllowedToWork()) { - checkRecipe(); - } - } - } - } else { - // Check if the machine is enabled in the first place! - if (aBaseMetaTileEntity.isAllowedToWork()) { - - if (shouldCheckRecipeThisTick(aTick) || aBaseMetaTileEntity.hasWorkJustBeenEnabled() - || aBaseMetaTileEntity.hasInventoryBeenModified()) { - if (checkRecipe()) { - markDirty(); - } - } - if (mMaxProgresstime <= 0) mEfficiency = Math.max(0, mEfficiency - 1000); - } - } - } - - public boolean polluteEnvironment(int aPollutionLevel) { - mPollution += aPollutionLevel; - for (GT_MetaTileEntity_Hatch_Muffler tHatch : filterValidMTEs(mMufflerHatches)) { - if (mPollution >= 10000) { - if (tHatch.polluteEnvironment(this)) { - mPollution -= 10000; - } - } else { - break; - } - } - return mPollution < 10000; - } - - protected void sendStartMultiBlockSoundLoop() { - if (getProcessStartSound() != null) { - sendLoopStart(PROCESS_START_SOUND_INDEX); - } - } - - @Override - public void doSound(byte aIndex, double aX, double aY, double aZ) { - super.doSound(aIndex, aX, aY, aZ); - switch (aIndex) { - case PROCESS_START_SOUND_INDEX -> { - if (getProcessStartSound() != null) - GT_Utility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); - } - case INTERRUPT_SOUND_INDEX -> GT_Utility - .doSoundAtClient(SoundResource.IC2_MACHINES_INTERRUPT_ONE, 100, 1.0F, aX, aY, aZ); - } - } - - @Override - public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { - super.startSoundLoop(aIndex, aX, aY, aZ); - if (aIndex == PROCESS_START_SOUND_INDEX) { - if (getProcessStartSound() != null) - GT_Utility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); - } - } - - @SideOnly(Side.CLIENT) - protected void doActivitySound(ResourceLocation activitySound) { - if (getBaseMetaTileEntity().isActive() && activitySound != null) { - if (activitySoundLoop == null) { - activitySoundLoop = new GT_SoundLoop(activitySound, getBaseMetaTileEntity(), false, true); - Minecraft.getMinecraft() - .getSoundHandler() - .playSound(activitySoundLoop); - } - } else { - if (activitySoundLoop != null) { - activitySoundLoop = null; - } - } - } - - /** - * @return Time before the start process sound is played again - */ - protected int getTimeBetweenProcessSounds() { - return 100; - } - - /** - * @return Sound that will be played once, when the recipe check was valid - */ - protected SoundResource getProcessStartSound() { - return null; - } - - /** - * @return Sound that will be looped for as long as the machine is doing a recipe - */ - @SideOnly(Side.CLIENT) - protected ResourceLocation getActivitySoundLoop() { - return null; - } - - /** - * Called every tick the Machine runs - */ - public boolean onRunningTick(ItemStack aStack) { - if (mEUt > 0) { - addEnergyOutput(((long) mEUt * mEfficiency) / 10000); - return true; - } - if (mEUt < 0) { - if (!drainEnergyInput(getActualEnergyUsage())) { - stopMachine(ShutDownReasonRegistry.POWER_LOSS); - return false; - } - } - return true; - } - - protected long getActualEnergyUsage() { - return ((long) -mEUt * 10_000) / Math.max(1000, mEfficiency); - } - - /** - * Checks if this is a Correct Machine Part for this kind of Machine (Turbine Rotor for example) - */ - public abstract boolean isCorrectMachinePart(ItemStack aStack); - - /** - * @deprecated Use {@link #createProcessingLogic()} or {@link #checkProcessing()} - */ - @Deprecated - public boolean checkRecipe(ItemStack aStack) { - return false; - } - - /** - * Checks recipe and setup machine if it's successful. - *

- * For generic machine working with recipemap, use {@link #createProcessingLogic()} to make use of shared codebase. - */ - @Nonnull - public CheckRecipeResult checkProcessing() { - // If no logic is found, try legacy checkRecipe - if (processingLogic == null) { - return checkRecipe(mInventory[1]) ? CheckRecipeResultRegistry.SUCCESSFUL - : CheckRecipeResultRegistry.NO_RECIPE; - } - - setupProcessingLogic(processingLogic); - - CheckRecipeResult result = doCheckRecipe(); - result = postCheckRecipe(result, processingLogic); - // inputs are consumed at this point - updateSlots(); - if (!result.wasSuccessful()) return result; - - mEfficiency = (10000 - (getIdealStatus() - getRepairStatus()) * 1000); - mEfficiencyIncrease = 10000; - mMaxProgresstime = processingLogic.getDuration(); - setEnergyUsage(processingLogic); - - mOutputItems = processingLogic.getOutputItems(); - mOutputFluids = processingLogic.getOutputFluids(); - - return result; - } - - /** - * @return If controller slot should be considered as inputs for {@link #doCheckRecipe} - */ - protected boolean canUseControllerSlotForRecipe() { - return true; - } - - /** - * Initializes processing logic for use. Unlike {@link #createProcessingLogic}, this method is called - * every time checking for recipes. - */ - protected void setupProcessingLogic(ProcessingLogic logic) { - logic.clear(); - logic.setMachine(this); - logic.setRecipeMapSupplier(this::getRecipeMap); - logic.setVoidProtection(protectsExcessItem(), protectsExcessFluid()); - logic.setBatchSize(isBatchModeEnabled() ? getMaxBatchSize() : 1); - logic.setRecipeLocking(this, isRecipeLockingEnabled()); - setProcessingLogicPower(logic); - } - - /** - * Initializes processing logic for use, specifically for power-related parameters. - * Unlike {@link #createProcessingLogic}, this method is called every time checking for recipes. - */ - protected void setProcessingLogicPower(ProcessingLogic logic) { - logic.setAvailableVoltage(getAverageInputVoltage()); - logic.setAvailableAmperage(getMaxInputAmps()); - logic.setAmperageOC(mEnergyHatches.size() != 1); - } - - protected boolean supportsCraftingMEBuffer() { - return true; - } - - /** - * Iterates over hatches and tries to find recipe. Assume {@link #processingLogic} is already set up for use. - * If return value is successful, inputs are consumed. - */ - @Nonnull - protected CheckRecipeResult doCheckRecipe() { - CheckRecipeResult result = CheckRecipeResultRegistry.NO_RECIPE; - // check crafting input hatches first - if (supportsCraftingMEBuffer()) { - for (IDualInputHatch dualInputHatch : mDualInputHatches) { - for (var it = dualInputHatch.inventories(); it.hasNext();) { - IDualInputInventory slot = it.next(); - processingLogic.setInputItems(slot.getItemInputs()); - processingLogic.setInputFluids(slot.getFluidInputs()); - CheckRecipeResult foundResult = processingLogic.process(); - if (foundResult.wasSuccessful()) { - return foundResult; - } - if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { - // Recipe failed in interesting way, so remember that and continue searching - result = foundResult; - } - } - } - } - - processingLogic.setInputFluids(getStoredFluids()); - - if (isInputSeparationEnabled()) { - if (mInputBusses.isEmpty()) { - CheckRecipeResult foundResult = processingLogic.process(); - if (foundResult.wasSuccessful()) { - return foundResult; - } - if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { - // Recipe failed in interesting way, so remember that and continue searching - result = foundResult; - } - } else { - for (GT_MetaTileEntity_Hatch_InputBus bus : mInputBusses) { - if (bus instanceof GT_MetaTileEntity_Hatch_CraftingInput_ME) { - continue; - } - List inputItems = new ArrayList<>(); - for (int i = bus.getSizeInventory() - 1; i >= 0; i--) { - ItemStack stored = bus.getStackInSlot(i); - if (stored != null) { - inputItems.add(stored); - } - } - if (canUseControllerSlotForRecipe() && getControllerSlot() != null) { - inputItems.add(getControllerSlot()); - } - processingLogic.setInputItems(inputItems.toArray(new ItemStack[0])); - CheckRecipeResult foundResult = processingLogic.process(); - if (foundResult.wasSuccessful()) { - return foundResult; - } - if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { - // Recipe failed in interesting way, so remember that and continue searching - result = foundResult; - } - } - } - } else { - List inputItems = getStoredInputs(); - if (canUseControllerSlotForRecipe() && getControllerSlot() != null) { - inputItems.add(getControllerSlot()); - } - processingLogic.setInputItems(inputItems); - CheckRecipeResult foundResult = processingLogic.process(); - if (foundResult.wasSuccessful()) { - return foundResult; - } - if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { - // Recipe failed in interesting way, so remember that - result = foundResult; - } - } - return result; - } - - /** - * Performs additional check for {@link #processingLogic} after all the calculations are done. - * As many as checks should be done inside of custom {@link ProcessingLogic}, which you can specify with - * {@link #createProcessingLogic()}, because when this method is called, inputs might have been already consumed. - * However, certain checks cannot be done like that; Checking energy overflow should be suppressed for - * long-power machines for example. - * - * @return Modified (or not modified) result - */ - @Nonnull - protected CheckRecipeResult postCheckRecipe(@Nonnull CheckRecipeResult result, - @Nonnull ProcessingLogic processingLogic) { - if (result.wasSuccessful() && processingLogic.getCalculatedEut() > Integer.MAX_VALUE) { - return CheckRecipeResultRegistry.POWER_OVERFLOW; - } - return result; - } - - /** - * Called after {@link #doCheckRecipe} and {@link #postCheckRecipe} being successful. - * Override to set energy usage for this machine. - */ - protected void setEnergyUsage(ProcessingLogic processingLogic) { - // getCalculatedEut() is guaranteed to not exceed int by postCheckRecipe() - mEUt = (int) processingLogic.getCalculatedEut(); - if (mEUt > 0) { - mEUt = (-mEUt); - } - } - - protected int getMaxBatchSize() { - return 128; - } - - /** - * Checks the Machine. You have to assign the MetaTileEntities for the Hatches here. - */ - public abstract boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack); - - /** - * Gets the maximum Efficiency that spare Part can get (0 - 10000) - */ - public abstract int getMaxEfficiency(ItemStack aStack); - - /** - * Gets the pollution this Device outputs to a Muffler per tick (10000 = one Pullution Block) - */ - public int getPollutionPerTick(ItemStack aStack) { - return getPollutionPerSecond(aStack) / 20; - } - - /** - * Gets the pollution produced per second by this multiblock, default to 0. Override this with its actual value in - * the code of the multiblock. - */ - public int getPollutionPerSecond(ItemStack aStack) { - return 0; - } - - /** - * Gets the damage to the ItemStack, usually 0 or 1. - */ - public abstract int getDamageToComponent(ItemStack aStack); - - /** - * If it explodes when the Component has to be replaced. - */ - public abstract boolean explodesOnComponentBreak(ItemStack aStack); - - /** - * @deprecated Use {@link #stopMachine(ShutDownReason)} - */ - @Deprecated - public void stopMachine() { - stopMachine(ShutDownReasonRegistry.NONE); - } - - /** - * @deprecated Use {@link #stopMachine(ShutDownReason)} - */ - @Deprecated - public void criticalStopMachine() { - stopMachine(ShutDownReasonRegistry.CRITICAL_NONE); - } - - public void stopMachine(@Nonnull ShutDownReason reason) { - if (!ShutDownReasonRegistry.isRegistered(reason.getID())) { - throw new RuntimeException(String.format("Reason %s is not registered for registry", reason.getID())); - } - mLastWorkingTick = mTotalRunTime; - mOutputItems = null; - mOutputFluids = null; - mEUt = 0; - mEfficiency = 0; - mProgresstime = 0; - mMaxProgresstime = 0; - mEfficiencyIncrease = 0; - getBaseMetaTileEntity().disableWorking(); - getBaseMetaTileEntity().setShutDownReason(reason); - getBaseMetaTileEntity().setShutdownStatus(true); - if (reason.wasCritical()) { - sendSound(INTERRUPT_SOUND_INDEX); - } - } - - public int getRepairStatus() { - return (mWrench ? 1 : 0) + (mScrewdriver ? 1 : 0) - + (mSoftHammer ? 1 : 0) - + (mHardHammer ? 1 : 0) - + (mSolderingTool ? 1 : 0) - + (mCrowbar ? 1 : 0); - } - - public int getIdealStatus() { - return 6; - } - - public int getCurrentEfficiency(ItemStack itemStack) { - int maxEff = getMaxEfficiency(itemStack); - return maxEff - (getIdealStatus() - getRepairStatus()) * maxEff / 10; - } - - public boolean doRandomMaintenanceDamage() { - if (!isCorrectMachinePart(mInventory[1])) { - stopMachine(ShutDownReasonRegistry.NO_MACHINE_PART); - return false; - } - if (shouldCheckMaintenance() && getRepairStatus() == 0) { - stopMachine(ShutDownReasonRegistry.NO_REPAIR); - return false; - } - if (mRuntime++ > 1000) { - mRuntime = 0; - if (shouldCheckMaintenance() && getBaseMetaTileEntity().getRandomNumber(6000) == 0) { - causeMaintenanceIssue(); - } - if (mInventory[1] != null && getBaseMetaTileEntity().getRandomNumber(2) == 0 - && !mInventory[1].getUnlocalizedName() - .startsWith("gt.blockmachines.basicmachine.")) { - if (mInventory[1].getItem() instanceof GT_MetaGenerated_Tool_01) { - NBTTagCompound tNBT = mInventory[1].getTagCompound(); - ((GT_MetaGenerated_Tool) mInventory[1].getItem()).doDamage( - mInventory[1], - (long) getDamageToComponent(mInventory[1]) - * (long) Math.min(mEUt / this.damageFactorLow, Math.pow(mEUt, this.damageFactorHigh))); - if (mInventory[1].stackSize == 0) mInventory[1] = null; - } - } - } - return true; - } - - public void causeMaintenanceIssue() { - switch (getBaseMetaTileEntity().getRandomNumber(6)) { - case 0 -> mWrench = false; - case 1 -> mScrewdriver = false; - case 2 -> mSoftHammer = false; - case 3 -> mHardHammer = false; - case 4 -> mSolderingTool = false; - case 5 -> mCrowbar = false; - } - } - - public void explodeMultiblock() { - - GT_Log.exp.println( - "MultiBlockExplosion at: " + this.getBaseMetaTileEntity() - .getXCoord() - + " | " - + this.getBaseMetaTileEntity() - .getYCoord() - + " | " - + this.getBaseMetaTileEntity() - .getZCoord() - + " DIMID: " - + this.getBaseMetaTileEntity() - .getWorld().provider.dimensionId - + "."); - - GT_Pollution.addPollution(getBaseMetaTileEntity(), GT_Mod.gregtechproxy.mPollutionOnExplosion); - mInventory[1] = null; - // noinspection unchecked // In this case, the inspection only indicates that the array can be abused in runtime - Iterable allHatches = Iterables.concat( - mInputBusses, - mOutputBusses, - mInputHatches, - mOutputHatches, - mDynamoHatches, - mMufflerHatches, - mEnergyHatches, - mMaintenanceHatches); - for (MetaTileEntity tTileEntity : allHatches) { - if (tTileEntity != null && tTileEntity.getBaseMetaTileEntity() != null) { - tTileEntity.getBaseMetaTileEntity() - .doExplosion(V[8]); - } - } - getBaseMetaTileEntity().doExplosion(V[8]); - } - - public boolean addEnergyOutput(long aEU) { - if (aEU <= 0) { - return true; - } - if (mDynamoHatches.size() > 0) { - return addEnergyOutputMultipleDynamos(aEU, true); - } - return false; - } - - public boolean addEnergyOutputMultipleDynamos(long aEU, boolean aAllowMixedVoltageDynamos) { - int injected = 0; - long totalOutput = 0; - long aFirstVoltageFound = -1; - boolean aFoundMixedDynamos = false; - for (GT_MetaTileEntity_Hatch_Dynamo aDynamo : filterValidMTEs(mDynamoHatches)) { - long aVoltage = aDynamo.maxEUOutput(); - long aTotal = aDynamo.maxAmperesOut() * aVoltage; - // Check against voltage to check when hatch mixing - if (aFirstVoltageFound == -1) { - aFirstVoltageFound = aVoltage; - } else { - if (aFirstVoltageFound != aVoltage) { - aFoundMixedDynamos = true; - } - } - totalOutput += aTotal; - } - - if (totalOutput < aEU || (aFoundMixedDynamos && !aAllowMixedVoltageDynamos)) { - explodeMultiblock(); - return false; - } - - long leftToInject; - long aVoltage; - int aAmpsToInject; - int aRemainder; - int ampsOnCurrentHatch; - for (GT_MetaTileEntity_Hatch_Dynamo aDynamo : filterValidMTEs(mDynamoHatches)) { - leftToInject = aEU - injected; - aVoltage = aDynamo.maxEUOutput(); - aAmpsToInject = (int) (leftToInject / aVoltage); - aRemainder = (int) (leftToInject - (aAmpsToInject * aVoltage)); - ampsOnCurrentHatch = (int) Math.min(aDynamo.maxAmperesOut(), aAmpsToInject); - for (int i = 0; i < ampsOnCurrentHatch; i++) { - aDynamo.getBaseMetaTileEntity() - .increaseStoredEnergyUnits(aVoltage, false); - } - injected += aVoltage * ampsOnCurrentHatch; - if (aRemainder > 0 && ampsOnCurrentHatch < aDynamo.maxAmperesOut()) { - aDynamo.getBaseMetaTileEntity() - .increaseStoredEnergyUnits(aRemainder, false); - injected += aRemainder; - } - } - return injected > 0; - } - - /** - * Sums up voltage of energy hatches. Amperage does not matter. - */ - public long getMaxInputVoltage() { - long rVoltage = 0; - for (GT_MetaTileEntity_Hatch_Energy tHatch : filterValidMTEs(mEnergyHatches)) - rVoltage += tHatch.getBaseMetaTileEntity() - .getInputVoltage(); - return rVoltage; - } - - public long getAverageInputVoltage() { - return GT_ExoticEnergyInputHelper.getAverageInputVoltageMulti(mEnergyHatches); - } - - public long getMaxInputAmps() { - return GT_ExoticEnergyInputHelper.getMaxWorkingInputAmpsMulti(mEnergyHatches); - } - - public long getMaxInputEu() { - return GT_ExoticEnergyInputHelper.getTotalEuMulti(mEnergyHatches); - } - - /** - * Sums up max input EU/t of energy hatches, amperage included. - */ - public long getMaxInputPower() { - long eut = 0; - for (GT_MetaTileEntity_Hatch_Energy tHatch : filterValidMTEs(mEnergyHatches)) { - IGregTechTileEntity baseTile = tHatch.getBaseMetaTileEntity(); - eut += baseTile.getInputVoltage() * baseTile.getInputAmperage(); - } - return eut; - } - - /** - * Returns voltage tier of energy hatches. If multiple tiers are found, returns 0. - */ - public long getInputVoltageTier() { - long rTier = 0; - if (mEnergyHatches.size() > 0) { - rTier = mEnergyHatches.get(0) - .getInputTier(); - for (int i = 1; i < mEnergyHatches.size(); i++) { - if (mEnergyHatches.get(i) - .getInputTier() != rTier) return 0; - } - } - - return rTier; - } - - /** - * Calcualtes the overclockedness using long integers - * - * @param aEUt - recipe EUt - * @param aDuration - recipe Duration - * @param mAmperage - should be 1 ? - * @param maxInputVoltage - Multiblock Max input voltage. Voltage is rounded up to higher tier voltage. - * @param perfectOC - If the Multiblock OCs perfectly, i.e. the large Chemical Reactor - */ - protected void calculateOverclockedNessMultiInternal(long aEUt, int aDuration, int mAmperage, long maxInputVoltage, - boolean perfectOC) { - byte tier = (byte) Math.max(0, GT_Utility.getTier(maxInputVoltage)); - GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(aEUt) - .setEUt(V[tier] * mAmperage) - .setDuration(aDuration) - .setDurationDecreasePerOC(perfectOC ? 4.0 : 2.0) - .calculate(); - mEUt = (int) calculator.getConsumption(); - mMaxProgresstime = calculator.getDuration(); - } - - @Deprecated - protected void calculateOverclockedNessMulti(int aEUt, int aDuration, int mAmperage, long maxInputVoltage) { - calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, false); - } - - protected void calculateOverclockedNessMulti(long aEUt, int aDuration, int mAmperage, long maxInputVoltage) { - calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, false); - } - - @Deprecated - protected void calculatePerfectOverclockedNessMulti(int aEUt, int aDuration, int mAmperage, long maxInputVoltage) { - calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, true); - } - - protected void calculatePerfectOverclockedNessMulti(long aEUt, int aDuration, int mAmperage, long maxInputVoltage) { - calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, true); - } - - public boolean drainEnergyInput(long aEU) { - if (aEU <= 0) return true; - for (GT_MetaTileEntity_Hatch_Energy tHatch : filterValidMTEs(mEnergyHatches)) { - if (tHatch.getBaseMetaTileEntity() - .decreaseStoredEnergyUnits(aEU, false)) return true; - } - return false; - } - - protected static boolean dumpFluid(List aOutputHatches, FluidStack copiedFluidStack, - boolean restrictiveHatchesOnly) { - for (GT_MetaTileEntity_Hatch_Output tHatch : filterValidMTEs(aOutputHatches)) { - if (restrictiveHatchesOnly && tHatch.mMode == 0) { - continue; - } - if (!tHatch.canStoreFluid(copiedFluidStack)) continue; - int tAmount = tHatch.fill(copiedFluidStack, false); - if (tAmount >= copiedFluidStack.amount) { - boolean filled = tHatch.fill(copiedFluidStack, true) >= copiedFluidStack.amount; - tHatch.onEmptyingContainerWhenEmpty(); - return filled; - } else if (tAmount > 0) { - copiedFluidStack.amount = copiedFluidStack.amount - tHatch.fill(copiedFluidStack, true); - tHatch.onEmptyingContainerWhenEmpty(); - } - } - return false; - } - - public boolean addOutput(FluidStack aLiquid) { - if (aLiquid == null) return false; - FluidStack copiedFluidStack = aLiquid.copy(); - if (!dumpFluid(mOutputHatches, copiedFluidStack, true)) { - dumpFluid(mOutputHatches, copiedFluidStack, false); - } - return false; - } - - protected void addFluidOutputs(FluidStack[] mOutputFluids2) { - for (FluidStack outputFluidStack : mOutputFluids2) { - addOutput(outputFluidStack); - } - } - - public boolean depleteInput(FluidStack aLiquid) { - return depleteInput(aLiquid, false); - } - - public boolean depleteInput(FluidStack aLiquid, boolean simulate) { - if (aLiquid == null) return false; - for (GT_MetaTileEntity_Hatch_Input tHatch : filterValidMTEs(mInputHatches)) { - setHatchRecipeMap(tHatch); - FluidStack tLiquid = tHatch.drain(ForgeDirection.UNKNOWN, aLiquid, false); - if (tLiquid != null && tLiquid.amount >= aLiquid.amount) { - if (simulate) { - return true; - } - tLiquid = tHatch.drain(ForgeDirection.UNKNOWN, aLiquid, true); - return tLiquid != null && tLiquid.amount >= aLiquid.amount; - } - } - return false; - } - - public boolean addOutput(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return false; - aStack = GT_Utility.copyOrNull(aStack); - - final List filteredBuses = filterValidMTEs(mOutputBusses); - if (dumpItem(filteredBuses, aStack, true) || dumpItem(filteredBuses, aStack, false)) { - return true; - } - - boolean outputSuccess = true; - // noinspection DataFlowIssue - while (outputSuccess && aStack.stackSize > 0) { - outputSuccess = false; - ItemStack single = aStack.splitStack(1); - for (GT_MetaTileEntity_Hatch_Output tHatch : filterValidMTEs(mOutputHatches)) { - if (!outputSuccess && tHatch.outputsItems()) { - if (tHatch.getBaseMetaTileEntity() - .addStackToSlot(1, single)) outputSuccess = true; - } - } - } - return outputSuccess; - } - - private boolean dumpItem(List outputBuses, ItemStack itemStack, - boolean restrictiveBusesOnly) { - for (GT_MetaTileEntity_Hatch_OutputBus outputBus : outputBuses) { - if (restrictiveBusesOnly && !outputBus.isLocked()) { - continue; - } - - if (outputBus.storeAll(itemStack)) { - return true; - } - } - - return false; - } - - public boolean depleteInput(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return false; - FluidStack aLiquid = GT_Utility.getFluidForFilledItem(aStack, true); - if (aLiquid != null) return depleteInput(aLiquid); - for (GT_MetaTileEntity_Hatch_Input tHatch : filterValidMTEs(mInputHatches)) { - setHatchRecipeMap(tHatch); - if (GT_Utility.areStacksEqual( - aStack, - tHatch.getBaseMetaTileEntity() - .getStackInSlot(0))) { - if (tHatch.getBaseMetaTileEntity() - .getStackInSlot(0).stackSize >= aStack.stackSize) { - tHatch.getBaseMetaTileEntity() - .decrStackSize(0, aStack.stackSize); - return true; - } - } - } - for (GT_MetaTileEntity_Hatch_InputBus tHatch : filterValidMTEs(mInputBusses)) { - tHatch.mRecipeMap = getRecipeMap(); - for (int i = tHatch.getBaseMetaTileEntity() - .getSizeInventory() - 1; i >= 0; i--) { - if (GT_Utility.areStacksEqual( - aStack, - tHatch.getBaseMetaTileEntity() - .getStackInSlot(i))) { - if (tHatch.getBaseMetaTileEntity() - .getStackInSlot(i).stackSize >= aStack.stackSize) { - tHatch.getBaseMetaTileEntity() - .decrStackSize(i, aStack.stackSize); - return true; - } - } - } - } - return false; - } - - public ArrayList getStoredOutputs() { - ArrayList rList = new ArrayList<>(); - for (GT_MetaTileEntity_Hatch_OutputBus tHatch : filterValidMTEs(mOutputBusses)) { - for (int i = tHatch.getBaseMetaTileEntity() - .getSizeInventory() - 1; i >= 0; i--) { - rList.add( - tHatch.getBaseMetaTileEntity() - .getStackInSlot(i)); - } - } - return rList; - } - - public ArrayList getStoredFluids() { - ArrayList rList = new ArrayList<>(); - Map inputsFromME = new HashMap<>(); - for (GT_MetaTileEntity_Hatch_Input tHatch : filterValidMTEs(mInputHatches)) { - setHatchRecipeMap(tHatch); - if (tHatch instanceof GT_MetaTileEntity_Hatch_MultiInput multiInputHatch) { - for (FluidStack tFluid : multiInputHatch.getStoredFluid()) { - if (tFluid != null) { - rList.add(tFluid); - } - } - } else if (tHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { - for (FluidStack fluidStack : meHatch.getStoredFluids()) { - if (fluidStack != null) { - // Prevent the same fluid from different ME hatches from being recognized - inputsFromME.put(fluidStack.getFluid(), fluidStack); - } - } - } else { - if (tHatch.getFillableStack() != null) { - rList.add(tHatch.getFillableStack()); - } - } - } - - if (!inputsFromME.isEmpty()) { - rList.addAll(inputsFromME.values()); - } - return rList; - } - - /** - * Drains fluid from the given hatch, including {@link IDualInputHatch}. Should never be used during recipe check! - * - * @param doDrain If false, fluid will not actually be consumed - * @return Whether the hatch contains enough fluid to drain - */ - public boolean drain(GT_MetaTileEntity_Hatch hatch, FluidStack fluid, boolean doDrain) { - if (fluid == null || hatch == null) return false; - if (supportsCraftingMEBuffer() && hatch instanceof IDualInputHatch tHatch && tHatch.supportsFluids()) { - Optional inventory = tHatch.getFirstNonEmptyInventory(); - if (inventory.isPresent()) { - for (FluidStack storedFluid : Lists.newArrayList( - inventory.get() - .getFluidInputs())) { - if (fluid.isFluidEqual(storedFluid)) { - if (doDrain) storedFluid.amount = Math.max(storedFluid.amount - fluid.amount, 0); - return storedFluid.amount >= fluid.amount; - } - } - } - } - - if (hatch instanceof GT_MetaTileEntity_Hatch_Input tHatch && tHatch.isValid()) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { - meHatch.startRecipeProcessing(); - FluidStack tFluid = meHatch.drain(ForgeDirection.UNKNOWN, fluid, doDrain); - meHatch.endRecipeProcessing(this); - return tFluid != null && tFluid.amount >= fluid.amount; - } else { - FluidStack tFluid = tHatch.drain(ForgeDirection.UNKNOWN, fluid, doDrain); - return tFluid != null && tFluid.amount >= fluid.amount; - } - } - - return false; - } - - public ArrayList getStoredInputs() { - ArrayList rList = new ArrayList<>(); - Map inputsFromME = new HashMap<>(); - for (GT_MetaTileEntity_Hatch_InputBus tHatch : filterValidMTEs(mInputBusses)) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_CraftingInput_ME) { - continue; - } - tHatch.mRecipeMap = getRecipeMap(); - IGregTechTileEntity tileEntity = tHatch.getBaseMetaTileEntity(); - boolean isMEBus = tHatch instanceof GT_MetaTileEntity_Hatch_InputBus_ME; - for (int i = tileEntity.getSizeInventory() - 1; i >= 0; i--) { - ItemStack itemStack = tileEntity.getStackInSlot(i); - if (itemStack != null) { - if (isMEBus) { - // Prevent the same item from different ME buses from being recognized - inputsFromME.put(GT_Utility.ItemId.createNoCopy(itemStack), itemStack); - } else { - rList.add(itemStack); - } - } - } - } - - if (getStackInSlot(1) != null && getStackInSlot(1).getUnlocalizedName() - .startsWith("gt.integrated_circuit")) rList.add(getStackInSlot(1)); - if (!inputsFromME.isEmpty()) { - rList.addAll(inputsFromME.values()); - } - return rList; - } - - /** - * Anything that is usually separated off in {@link #getStoredInputs()} (like crafting input bus/buffer) is also - * included here. - */ - public ArrayList getAllStoredInputs() { - ArrayList rList = new ArrayList<>(); - - if (supportsCraftingMEBuffer()) { - for (IDualInputHatch dualInputHatch : mDualInputHatches) { - Iterator inventoryIterator = dualInputHatch.inventories(); - while (inventoryIterator.hasNext()) { - ItemStack[] items = inventoryIterator.next() - .getItemInputs(); - if (items == null) { - continue; - } - for (int i = 0; i < items.length; i++) { - ItemStack item = items[i]; - if (item != null) { - rList.add(item); - } - } - } - } - } - - Map inputsFromME = new HashMap<>(); - for (GT_MetaTileEntity_Hatch_InputBus tHatch : filterValidMTEs(mInputBusses)) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_CraftingInput_ME) { - continue; - } - tHatch.mRecipeMap = getRecipeMap(); - IGregTechTileEntity tileEntity = tHatch.getBaseMetaTileEntity(); - boolean isMEBus = tHatch instanceof GT_MetaTileEntity_Hatch_InputBus_ME; - for (int i = tileEntity.getSizeInventory() - 1; i >= 0; i--) { - ItemStack itemStack = tileEntity.getStackInSlot(i); - if (itemStack != null) { - if (isMEBus) { - // Prevent the same item from different ME buses from being recognized - inputsFromME.put(GT_Utility.ItemId.createNoCopy(itemStack), itemStack); - } else { - rList.add(itemStack); - } - } - } - } - - if (getStackInSlot(1) != null && getStackInSlot(1).getUnlocalizedName() - .startsWith("gt.integrated_circuit")) rList.add(getStackInSlot(1)); - if (!inputsFromME.isEmpty()) { - rList.addAll(inputsFromME.values()); - } - return rList; - } - - public Map getStoredInputsFromME() { - Map inputsFromME = new Object2ReferenceOpenHashMap<>(); - for (GT_MetaTileEntity_Hatch_InputBus tHatch : filterValidMTEs(mInputBusses)) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { - for (int i = meBus.getSizeInventory() - 1; i >= 0; i--) { - ItemStack itemStack = meBus.getStackInSlot(i); - if (itemStack != null) { - // Prevent the same item from different ME buses from being recognized - inputsFromME.put(GT_Utility.ItemId.createNoCopy(itemStack), itemStack); - } - } - } - } - return inputsFromME; - } - - public Map getStoredFluidsFromME() { - Map fluidsFromME = new Reference2ReferenceOpenHashMap<>(); - for (GT_MetaTileEntity_Hatch_Input tHatch : filterValidMTEs(mInputHatches)) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { - for (FluidStack fluid : meHatch.getStoredFluids()) { - if (fluid != null) { - // Prevent the same fluid from different ME hatches from being recognized - fluidsFromME.put(fluid.getFluid(), fluid); - } - } - } - } - return fluidsFromME; - } - - @Override - public RecipeMap getRecipeMap() { - return null; - } - - /** - * Creates logic to run recipe check based on recipemap. This runs only once, on class instantiation. - *

- * If this machine doesn't use recipemap or does some complex things, override {@link #checkProcessing()}. - */ - @ApiStatus.OverrideOnly - protected ProcessingLogic createProcessingLogic() { - return null; - } - - public void updateSlots() { - for (GT_MetaTileEntity_Hatch_Input tHatch : filterValidMTEs(mInputHatches)) tHatch.updateSlots(); - for (GT_MetaTileEntity_Hatch_InputBus tHatch : filterValidMTEs(mInputBusses)) tHatch.updateSlots(); - } - - protected void startRecipeProcessing() { - for (GT_MetaTileEntity_Hatch_InputBus hatch : filterValidMTEs(mInputBusses)) { - if (hatch instanceof IRecipeProcessingAwareHatch aware) { - aware.startRecipeProcessing(); - } - } - for (GT_MetaTileEntity_Hatch_Input hatch : filterValidMTEs(mInputHatches)) { - if (hatch instanceof IRecipeProcessingAwareHatch aware) { - aware.startRecipeProcessing(); - } - } - } - - public void setResultIfFailure(CheckRecipeResult result) { - if (!result.wasSuccessful()) { - this.checkRecipeResult = result; - } - } - - protected void endRecipeProcessing() { - for (GT_MetaTileEntity_Hatch_InputBus hatch : filterValidMTEs(mInputBusses)) { - if (hatch instanceof IRecipeProcessingAwareHatch aware) { - setResultIfFailure(aware.endRecipeProcessing(this)); - } - } - for (GT_MetaTileEntity_Hatch_Input hatch : filterValidMTEs(mInputHatches)) { - if (hatch instanceof IRecipeProcessingAwareHatch aware) { - setResultIfFailure(aware.endRecipeProcessing(this)); - } - } - } - - public boolean addToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - } - if (aMetaTileEntity instanceof IDualInputHatch hatch) { - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mDualInputHatches.add(hatch); - } - if (aMetaTileEntity instanceof ISmartInputHatch hatch) { - // Only add them to be iterated if enabled for performance reasons - if (hatch.doFastRecipeCheck()) { - mSmartInputHatches.add(hatch); - } - } - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Input) { - setHatchRecipeMap((GT_MetaTileEntity_Hatch_Input) aMetaTileEntity); - return mInputHatches.add((GT_MetaTileEntity_Hatch_Input) aMetaTileEntity); - } - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_InputBus) { - ((GT_MetaTileEntity_Hatch_InputBus) aMetaTileEntity).mRecipeMap = getRecipeMap(); - return mInputBusses.add((GT_MetaTileEntity_Hatch_InputBus) aMetaTileEntity); - } - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Output) - return mOutputHatches.add((GT_MetaTileEntity_Hatch_Output) aMetaTileEntity); - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_OutputBus) - return mOutputBusses.add((GT_MetaTileEntity_Hatch_OutputBus) aMetaTileEntity); - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Energy) - return mEnergyHatches.add((GT_MetaTileEntity_Hatch_Energy) aMetaTileEntity); - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Dynamo) - return mDynamoHatches.add((GT_MetaTileEntity_Hatch_Dynamo) aMetaTileEntity); - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Maintenance) - return mMaintenanceHatches.add((GT_MetaTileEntity_Hatch_Maintenance) aMetaTileEntity); - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Muffler) - return mMufflerHatches.add((GT_MetaTileEntity_Hatch_Muffler) aMetaTileEntity); - return false; - } - - public boolean addMaintenanceToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Maintenance hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mMaintenanceHatches.add(hatch); - } - return false; - } - - public boolean addEnergyInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) { - return false; - } - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Energy hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mEnergyHatches.add(hatch); - } - return false; - } - - public boolean addExoticEnergyInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch hatch - && GT_ExoticEnergyInputHelper.isExoticEnergyInput(aMetaTileEntity)) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mExoticEnergyHatches.add(hatch); - } - return false; - } - - public boolean addDynamoToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Dynamo hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mDynamoHatches.add(hatch); - } - return false; - } - - public boolean addMufflerToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Muffler hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mMufflerHatches.add(hatch); - } - return false; - } - - public boolean addInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - return addInputBusToMachineList(aTileEntity, aBaseCasingIndex) - || addInputHatchToMachineList(aTileEntity, aBaseCasingIndex); - } - - public boolean addOutputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - return addOutputBusToMachineList(aTileEntity, aBaseCasingIndex) - || addOutputHatchToMachineList(aTileEntity, aBaseCasingIndex); - } - - public boolean addInputBusToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof IDualInputHatch hatch) { - if (!supportsCraftingMEBuffer()) return false; - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mDualInputHatches.add(hatch); - } - if (aMetaTileEntity instanceof ISmartInputHatch hatch) { - mSmartInputHatches.add(hatch); - } - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_InputBus hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - hatch.mRecipeMap = getRecipeMap(); - return mInputBusses.add(hatch); - } - return false; - } - - public boolean addOutputBusToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_OutputBus hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mOutputBusses.add(hatch); - } - return false; - } - - public boolean addInputHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof ISmartInputHatch hatch) { - mSmartInputHatches.add(hatch); - } - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Input hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - setHatchRecipeMap(hatch); - return mInputHatches.add(hatch); - } - return false; - } - - public boolean addOutputHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { - if (aTileEntity == null) return false; - IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); - if (aMetaTileEntity == null) return false; - if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Output hatch) { - hatch.updateTexture(aBaseCasingIndex); - hatch.updateCraftingIcon(this.getMachineCraftingIcon()); - return mOutputHatches.add(hatch); - } - return false; - } - - protected void setHatchRecipeMap(GT_MetaTileEntity_Hatch_Input hatch) { - if (filtersFluid()) { - hatch.mRecipeMap = getRecipeMap(); - } - } - - /** - * @return If this multi filters fluid input for hatches based on recipemap. - */ - protected boolean filtersFluid() { - return true; - } - - @Override - public String[] getInfoData() { - int mPollutionReduction = 0; - for (GT_MetaTileEntity_Hatch_Muffler tHatch : filterValidMTEs(mMufflerHatches)) { - mPollutionReduction = Math.max(tHatch.calculatePollutionReduction(100), mPollutionReduction); - } - - long storedEnergy = 0; - long maxEnergy = 0; - for (GT_MetaTileEntity_Hatch_Energy tHatch : filterValidMTEs(mEnergyHatches)) { - storedEnergy += tHatch.getBaseMetaTileEntity() - .getStoredEU(); - maxEnergy += tHatch.getBaseMetaTileEntity() - .getEUCapacity(); - } - - return new String[] { - /* 1 */ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " - + EnumChatFormatting.GREEN - + formatNumbers(mProgresstime / 20) - + EnumChatFormatting.RESET - + " s / " - + EnumChatFormatting.YELLOW - + formatNumbers(mMaxProgresstime / 20) - + EnumChatFormatting.RESET - + " s", - /* 2 */ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " - + EnumChatFormatting.GREEN - + formatNumbers(storedEnergy) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + formatNumbers(maxEnergy) - + EnumChatFormatting.RESET - + " EU", - /* 3 */ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " - + EnumChatFormatting.RED - + formatNumbers(getActualEnergyUsage()) - + EnumChatFormatting.RESET - + " EU/t", - /* 4 */ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " - + EnumChatFormatting.YELLOW - + formatNumbers(getMaxInputVoltage()) - + EnumChatFormatting.RESET - + " EU/t(*2A) " - + StatCollector.translateToLocal("GT5U.machines.tier") - + ": " - + EnumChatFormatting.YELLOW - + VN[GT_Utility.getTier(getMaxInputVoltage())] - + EnumChatFormatting.RESET, - /* 5 */ StatCollector.translateToLocal("GT5U.multiblock.problems") + ": " - + EnumChatFormatting.RED - + (getIdealStatus() - getRepairStatus()) - + EnumChatFormatting.RESET - + " " - + StatCollector.translateToLocal("GT5U.multiblock.efficiency") - + ": " - + EnumChatFormatting.YELLOW - + mEfficiency / 100.0F - + EnumChatFormatting.RESET - + " %", - /* 6 */ StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": " - + EnumChatFormatting.GREEN - + mPollutionReduction - + EnumChatFormatting.RESET - + " %" }; - } - - @Override - public boolean isGivingInformation() { - return true; - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return supportsSlotAutomation(aIndex); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return supportsSlotAutomation(aIndex); - } - - protected ItemStack[] getCompactedInputs() { - // TODO: repalce method with a cleaner one - ArrayList tInputList = getStoredInputs(); - int tInputList_sS = tInputList.size(); - for (int i = 0; i < tInputList_sS - 1; i++) { - for (int j = i + 1; j < tInputList_sS; j++) { - if (!GT_Utility.areStacksEqual(tInputList.get(i), tInputList.get(j))) continue; - if (tInputList.get(i).stackSize >= tInputList.get(j).stackSize) { - tInputList.remove(j--); - tInputList_sS = tInputList.size(); - } else { - tInputList.remove(i--); - tInputList_sS = tInputList.size(); - break; - } - } - } - return tInputList.toArray(new ItemStack[0]); - } - - protected FluidStack[] getCompactedFluids() { - // TODO: repalce method with a cleaner one - ArrayList tFluidList = getStoredFluids(); - int tFluidList_sS = tFluidList.size(); - for (int i = 0; i < tFluidList_sS - 1; i++) { - for (int j = i + 1; j < tFluidList_sS; j++) { - if (!GT_Utility.areFluidsEqual(tFluidList.get(i), tFluidList.get(j))) continue; - - if (tFluidList.get(i).amount >= tFluidList.get(j).amount) { - tFluidList.remove(j--); - tFluidList_sS = tFluidList.size(); - } else { - tFluidList.remove(i--); - tFluidList_sS = tFluidList.size(); - break; - } - } - } - return tFluidList.toArray(new FluidStack[0]); - } - - @Override - public void getWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - final NBTTagCompound tag = accessor.getNBTData(); - - if (tag.getBoolean("incompleteStructure")) { - currentTip.add(RED + "** INCOMPLETE STRUCTURE **" + RESET); - } - String efficiency = RESET + " Efficiency: " + tag.getFloat("efficiency") + "%"; - if (tag.getBoolean("hasProblems")) { - currentTip.add(RED + "** HAS PROBLEMS **" + efficiency); - } else if (!tag.getBoolean("incompleteStructure")) { - currentTip.add(GREEN + "Running Fine" + efficiency); - } - - boolean isActive = tag.getBoolean("isActive"); - if (isActive) { - long energyTier = tag.getLong("energyTier"); - long actualEnergyUsage = tag.getLong("energyUsage"); - if (energyTier > 0) { - if (actualEnergyUsage > 0) { - currentTip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.use_with_amperage", - 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", - formatNumbers(-actualEnergyUsage), - GT_Utility.getAmperageForTier(-actualEnergyUsage, (byte) energyTier), - GT_Utility.getColoredTierNameFromTier((byte) energyTier))); - } - } else { - if (actualEnergyUsage > 0) { - currentTip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.use", - formatNumbers(actualEnergyUsage), - GT_Utility.getColoredTierNameFromVoltage(actualEnergyUsage))); - } else if (actualEnergyUsage < 0) { - currentTip.add( - StatCollector.translateToLocalFormatted( - "GT5U.waila.energy.produce", - formatNumbers(-actualEnergyUsage), - GT_Utility.getColoredTierNameFromVoltage(-actualEnergyUsage))); - } - } - } - currentTip.add( - GT_Waila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); - // Show ns on the tooltip - if (GT_Mod.gregtechproxy.wailaAverageNS && tag.hasKey("averageNS")) { - int tAverageTime = tag.getInteger("averageNS"); - currentTip.add("Average CPU load of ~" + formatNumbers(tAverageTime) + " ns"); - } - super.getWailaBody(itemStack, currentTip, accessor, config); - } - - public final void getMTEWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - super.getWailaBody(itemStack, currentTip, accessor, config); - } - - @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.setBoolean("hasProblems", (getIdealStatus() - getRepairStatus()) > 0); - tag.setFloat("efficiency", mEfficiency / 100.0F); - tag.setInteger("progress", mProgresstime); - tag.setInteger("maxProgress", mMaxProgresstime); - tag.setBoolean("incompleteStructure", (getBaseMetaTileEntity().getErrorDisplayID() & 64) != 0); - - final IGregTechTileEntity tileEntity = getBaseMetaTileEntity(); - if (tileEntity != null) { - tag.setBoolean("isActive", tileEntity.isActive()); - if (tileEntity.isActive()) { - if (mEUt < 0) tag.setLong("energyUsage", getActualEnergyUsage()); - else tag.setLong("energyUsage", (long) -mEUt * mEfficiency / 10000); - tag.setLong("energyTier", getInputVoltageTier()); - } - } - - final GT_ClientPreference preference = GT_Mod.gregtechproxy.getClientPreference(player.getUniqueID()); - if (preference != null && preference.isWailaAverageNSEnabled()) { - getBaseMetaTileEntity().startTimeStatistics(); - int tAverageTime = 0; - int amountOfZero = 0; - for (int tTime : this.getBaseMetaTileEntity() - .getTimeStatistics()) { - tAverageTime += tTime; - if (tTime == 0) { - amountOfZero += 1; - } - } - - // tick time zero means it has not been updated yet - int samples = getBaseMetaTileEntity().getTimeStatistics().length - amountOfZero; - if (samples > 0) { - tag.setInteger("averageNS", tAverageTime / samples); - } - } - } - - protected void setMufflers(boolean state) { - for (GT_MetaTileEntity_Hatch_Muffler aMuffler : mMufflerHatches) { - final IGregTechTileEntity iGTTileEntity = aMuffler.getBaseMetaTileEntity(); - if (iGTTileEntity != null && !iGTTileEntity.isDead()) { - iGTTileEntity.setActive(state); - } - } - } - - @Override - public void onRemoval() { - super.onRemoval(); - // Deactivate mufflers - setMufflers(false); - } - - public List getExoticEnergyHatches() { - return mExoticEnergyHatches; - } - - /** - * @return Returns true if there is 1 TT Energy Hatch OR up to 2 Energy Hatches - */ - 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; - } - - /** - * Checks if all the item / fluid outputs of the recipe can be outputted to the buses / hatches. - * If void protection is enabled, it also checks for {@link #protectsExcessItem()} and - * {@link #protectsExcessFluid()}, so you don't need to call them along with this method. - *

- * If you're using {@link GT_ParallelHelper}, it will handle void protection and return 0 parallel - * if all the output cannot be dumped into buses / hatches. In that case you won't use this method. - */ - protected boolean canOutputAll(@Nonnull GT_Recipe recipe) { - return canOutputAll(recipe.mOutputs, recipe.mFluidOutputs); - } - - /** - * Checks if all the items can be outputted to the output buses. - * If void protection is enabled, it also checks for {@link #protectsExcessItem()}, - * so you don't need to call it along with this method. - */ - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - protected boolean canOutputAll(ItemStack[] items) { - return canOutputAll(items, null); - } - - /** - * Checks if all the fluids can be outputted to the output hatches. - * If void protection is enabled, it also checks for {@link #protectsExcessFluid()}, - * so you don't need to call it along with this method. - */ - protected boolean canOutputAll(FluidStack[] fluids) { - return canOutputAll(null, fluids); - } - - /** - * Checks if all the items / fluids can be outputted to output buses / hatches. - * If void protection is enabled, it also checks for {@link #protectsExcessItem()} and - * {@link #protectsExcessFluid()}, so you don't need to call them along with this method. - */ - protected boolean canOutputAll(@Nullable ItemStack[] items, @Nullable FluidStack[] fluids) { - if (!protectsExcessItem() && !protectsExcessFluid()) { - return true; - } - - VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper().setMachine(this) - .setItemOutputs(items) - .setFluidOutputs(fluids) - .build(); - return voidProtectionHelper.getMaxParallel() > 0; - } - - @Override - public boolean isAllowedToWork() { - return getBaseMetaTileEntity() != null && getBaseMetaTileEntity().isAllowedToWork(); - } - - @Override - public void disableWorking() { - if (getBaseMetaTileEntity() != null) { - getBaseMetaTileEntity().disableWorking(); - } - } - - @Override - public void enableWorking() { - if (getBaseMetaTileEntity() != null) { - getBaseMetaTileEntity().enableWorking(); - } - } - - public ItemStack getControllerSlot() { - return mInventory[getControllerSlotIndex()]; - } - - public final int getControllerSlotIndex() { - return 1; - } - - // True if the slot with index aSlot may be interacted with through automation - protected boolean supportsSlotAutomation(int aSlot) { - return false; - } - - @Override - public Pos2d getPowerSwitchButtonPos() { - return new Pos2d(174, 148); - } - - @Override - public Pos2d getStructureUpdateButtonPos() { - return new Pos2d(174, 130); - } - - @Override - public int getStructureUpdateTime() { - return mUpdate; - } - - @Override - public void setStructureUpdateTime(int time) { - mUpdate = time; - } - - @Override - public boolean supportsVoidProtection() { - return false; - } - - @Override - public VoidingMode getVoidingMode() { - return voidingMode; - } - - @Override - public void setVoidingMode(VoidingMode mode) { - this.voidingMode = mode; - } - - @Override - public List getItemOutputSlots(ItemStack[] toOutput) { - List ret = new ArrayList<>(); - for (final GT_MetaTileEntity_Hatch tBus : filterValidMTEs(mOutputBusses)) { - if (!(tBus instanceof GT_MetaTileEntity_Hatch_OutputBus_ME)) { - final IInventory tBusInv = tBus.getBaseMetaTileEntity(); - for (int i = 0; i < tBusInv.getSizeInventory(); i++) { - final ItemStack stackInSlot = tBus.getStackInSlot(i); - - if (stackInSlot == null && tBus instanceof IItemLockable lockable && lockable.isLocked()) { - // getItemOutputSlots is only used to calculate free room for the purposes of parallels and - // void protection. We can use a fake item stack here without creating weirdness in the output - // bus' actual inventory. - assert lockable.getLockedItem() != null; - ItemStack fakeItemStack = lockable.getLockedItem() - .copy(); - fakeItemStack.stackSize = 0; - ret.add(fakeItemStack); - } else { - ret.add(stackInSlot); - } - } - } - } - return ret; - } - - @Override - public List getFluidOutputSlots(FluidStack[] toOutput) { - return filterValidMTEs(mOutputHatches); - } - - /** - * Util method for DT-like structure to collect list of output hatches. - */ - protected List getFluidOutputSlotsByLayer( - FluidStack[] toOutput, List> hatchesByLayer) { - List ret = new ArrayList<>(); - for (int i = 0; i < toOutput.length; i++) { - if (i >= hatchesByLayer.size()) { - break; - } - FluidStack fluidOutputForLayer = toOutput[i]; - for (GT_MetaTileEntity_Hatch_Output hatch : hatchesByLayer.get(i)) { - if (!hatch.isValid()) continue; - if (fluidOutputForLayer != null) { - ret.add(new OutputHatchWrapper(hatch, f -> GT_Utility.areFluidsEqual(f, fluidOutputForLayer))); - } else { - ret.add(hatch); - } - } - } - return ret; - } - - @Override - public boolean canDumpItemToME() { - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(mOutputBusses)) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_OutputBus_ME) { - if ((((GT_MetaTileEntity_Hatch_OutputBus_ME) tHatch).canAcceptItem())) { - return true; - } - } - } - return false; - } - - @Override - public boolean canDumpFluidToME() { - for (IFluidStore tHatch : getFluidOutputSlots(new FluidStack[0])) { - if (tHatch instanceof GT_MetaTileEntity_Hatch_Output_ME) { - if ((((GT_MetaTileEntity_Hatch_Output_ME) tHatch).canAcceptFluid())) { - return true; - } - } - } - return false; - } - - @Override - public Pos2d getVoidingModeButtonPos() { - return new Pos2d(8, 91); - } - - @Override - public boolean supportsInputSeparation() { - return false; - } - - @Override - public boolean isInputSeparationEnabled() { - return inputSeparation; - } - - @Override - public void setInputSeparation(boolean enabled) { - this.inputSeparation = enabled; - } - - @Override - public Pos2d getInputSeparationButtonPos() { - return new Pos2d(26, 91); - } - - /** - * Creates the icon list for this machine. Override this and add the overlays to machineModeIcons in order. - */ - public void setMachineModeIcons() { - machineModeIcons.add(GT_UITextures.OVERLAY_BUTTON_MACHINEMODE_DEFAULT); - machineModeIcons.add(GT_UITextures.OVERLAY_BUTTON_MACHINEMODE_DEFAULT); - } - - /** - * Override this if you are a multi-machine and want a GUI button. You will also want to override - * setMachineModeIcons(). - * Override nextMachineMode() if you have more than 2 modes. - */ - @Override - public boolean supportsMachineModeSwitch() { - return false; - } - - @Override - public int getMachineMode() { - return machineMode; - } - - @Override - public UITexture getMachineModeIcon(int index) { - return machineModeIcons.get(index); - } - - @Override - public void setMachineMode(int index) { - machineMode = index; - } - - @Override - public int nextMachineMode() { - if (machineMode == 0) return 1; - else return 0; - } - - @Override - public Pos2d getMachineModeSwitchButtonPos() { - return new Pos2d(80, 91); - } - - @Override - public boolean supportsBatchMode() { - return false; - } - - @Override - public boolean isBatchModeEnabled() { - return batchMode; - } - - @Override - public void setBatchMode(boolean enabled) { - this.batchMode = enabled; - } - - @Override - public Pos2d getBatchModeButtonPos() { - return new Pos2d(44, 91); - } - - @Override - public boolean supportsSingleRecipeLocking() { - return false; - } - - @Override - public boolean isRecipeLockingEnabled() { - return mLockedToSingleRecipe; - } - - @Override - public void setRecipeLocking(boolean enabled) { - mLockedToSingleRecipe = enabled; - if (!enabled) { - setSingleRecipeCheck(null); - } - } - - @Override - public void setSingleRecipeCheck(SingleRecipeCheck recipeCheck) { - mSingleRecipeCheck = recipeCheck; - } - - @Override - public SingleRecipeCheck getSingleRecipeCheck() { - return mSingleRecipeCheck; - } - - @Override - public Pos2d getRecipeLockingButtonPos() { - return new Pos2d(62, 91); - } - - @Override - public int getGUIWidth() { - return 198; - } - - @Override - public int getGUIHeight() { - return 192; - } - - @Override - public void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.bindPlayerInventory(buildContext.getPlayer(), new Pos2d(7, 109), getGUITextureSet().getItemSlot()); - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(4, 4) - .setSize(190, 85)); - final SlotWidget inventorySlot = new SlotWidget(inventoryHandler, 1); - builder.widget( - inventorySlot.setPos(173, 167) - .setBackground(GT_UITextures.SLOT_DARK_GRAY)); - - final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); - drawTexts(screenElements, inventorySlot); - builder.widget(screenElements); - - setMachineModeIcons(); - builder.widget(createPowerSwitchButton(builder)) - .widget(createVoidExcessButton(builder)) - .widget(createInputSeparationButton(builder)) - .widget(createModeSwitchButton(builder)) - .widget(createBatchModeButton(builder)) - .widget(createLockToSingleRecipeButton(builder)) - .widget(createStructureUpdateButton(builder)); - } - - @Override - public void addGregTechLogo(ModularWindow.Builder builder) {} - - protected boolean shouldDisplayCheckRecipeResult() { - return true; - } - - public boolean shouldDisplayShutDownReason() { - return true; - } - - protected final NumberFormatMUI numberFormat = new NumberFormatMUI(); - - protected String generateCurrentRecipeInfoString() { - StringBuffer ret = new StringBuffer(EnumChatFormatting.WHITE + "Progress: "); - - numberFormat.setMinimumFractionDigits(2); - numberFormat.setMaximumFractionDigits(2); - numberFormat.format((double) mProgresstime / 20, ret); - ret.append("s / "); - numberFormat.format((double) mMaxProgresstime / 20, ret); - ret.append("s ("); - numberFormat.setMinimumFractionDigits(1); - numberFormat.setMaximumFractionDigits(1); - numberFormat.format((double) mProgresstime / mMaxProgresstime * 100, ret); - ret.append("%)\n"); - numberFormat.setMinimumFractionDigits(0); - numberFormat.setMaximumFractionDigits(2); - - IntConsumer appendRate = (amount) -> { - double processPerTick = (double) amount / mMaxProgresstime * 20; - if (processPerTick > 1) { - ret.append(" ("); - numberFormat.format(Math.round(processPerTick * 10) / 10.0, ret); - ret.append("/s)"); - } else { - ret.append(" ("); - numberFormat.format(Math.round(1 / processPerTick * 10) / 10.0, ret); - ret.append("s/ea)"); - } - }; - - int lines = 0; - int MAX_LINES = 5; - - if (mOutputItems != null) { - for (var item : mOutputItems) { - if (item == null) continue; - if (lines >= MAX_LINES) { - ret.append("..."); - return ret.toString(); - } - lines++; - ret.append(EnumChatFormatting.AQUA) - .append(item.getDisplayName()) - .append(EnumChatFormatting.WHITE) - .append(" x ") - .append(EnumChatFormatting.GOLD); - numberFormat.format(item.stackSize, ret); - ret.append(EnumChatFormatting.WHITE); - appendRate.accept(item.stackSize); - ret.append('\n'); - } - } - if (mOutputFluids != null) { - for (var fluid : mOutputFluids) { - if (fluid == null) continue; - if (lines >= MAX_LINES) { - ret.append("..."); - return ret.toString(); - } - lines++; - ret.append(EnumChatFormatting.AQUA) - .append(fluid.getLocalizedName()) - .append(EnumChatFormatting.WHITE) - .append(" x ") - .append(EnumChatFormatting.GOLD); - numberFormat.format(fluid.amount, ret); - ret.append("L") - .append(EnumChatFormatting.WHITE); - appendRate.accept(fluid.amount); - ret.append('\n'); - } - } - return ret.toString(); - } - - protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { - screenElements.setSynced(false) - .setSpace(0) - .setPos(10, 7); - if (supportsMachineModeSwitch()) { - screenElements.widget( - TextWidget.dynamicString( - () -> EnumChatFormatting.WHITE + GT_Utility.trans("400", "Running mode: ") - + EnumChatFormatting.GOLD - + getMachineModeName())); - } - screenElements - .widget( - new TextWidget(GT_Utility.trans("132", "Pipe is loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mWrench)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mWrench, val -> mWrench = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("133", "Screws are loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mScrewdriver)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mScrewdriver, val -> mScrewdriver = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("134", "Something is stuck.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSoftHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSoftHammer, val -> mSoftHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("135", "Platings are dented.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mHardHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mHardHammer, val -> mHardHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("136", "Circuitry burned out.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSolderingTool)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSolderingTool, val -> mSolderingTool = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("137", "That doesn't belong there.")) - .setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mCrowbar)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mCrowbar, val -> mCrowbar = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("138", "Incomplete Structure.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mMachine)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mMachine, val -> mMachine = val)); - screenElements.widget( - new TextWidget("Too Uncertain.").setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> (getBaseMetaTileEntity().getErrorDisplayID() & 128) != 0)); - screenElements.widget( - new TextWidget("Invalid Parameters.").setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> (getBaseMetaTileEntity().getErrorDisplayID() & 256) != 0)); - - screenElements.widget( - new TextWidget(GT_Utility.trans("139", "Hit with Soft Mallet")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled( - widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && !getBaseMetaTileEntity().isActive())) - .widget( - new FakeSyncWidget.IntegerSyncer( - () -> getBaseMetaTileEntity().getErrorDisplayID(), - val -> getBaseMetaTileEntity().setErrorDisplayID(val))) - .widget( - new FakeSyncWidget.BooleanSyncer( - () -> getBaseMetaTileEntity().isActive(), - val -> getBaseMetaTileEntity().setActive(val))); - screenElements.widget( - new TextWidget(GT_Utility.trans("140", "to (re-)start the Machine")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled( - widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && !getBaseMetaTileEntity().isActive())); - screenElements.widget( - new TextWidget(GT_Utility.trans("141", "if it doesn't start.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled( - widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && !getBaseMetaTileEntity().isActive())); - screenElements.widget( - new TextWidget(GT_Utility.trans("142", "Running perfectly.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled( - widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && getBaseMetaTileEntity().isActive())); - - screenElements.widget(TextWidget.dynamicString(() -> { - Duration time = Duration.ofSeconds((mTotalRunTime - mLastWorkingTick) / 20); - return StatCollector.translateToLocalFormatted( - "GT5U.gui.text.shutdown_duration", - time.toHours(), - time.toMinutes() % 60, - time.getSeconds() % 60); - }) - .setEnabled( - widget -> shouldDisplayShutDownReason() && !getBaseMetaTileEntity().isActive() - && getBaseMetaTileEntity().wasShutdown())) - .widget(new FakeSyncWidget.LongSyncer(() -> mTotalRunTime, time -> mTotalRunTime = time)) - .widget(new FakeSyncWidget.LongSyncer(() -> mLastWorkingTick, time -> mLastWorkingTick = time)); - screenElements.widget( - TextWidget.dynamicString( - () -> getBaseMetaTileEntity().getLastShutDownReason() - .getDisplayString()) - .setSynced(false) - .setTextAlignment(Alignment.CenterLeft) - .setEnabled( - widget -> shouldDisplayShutDownReason() && !getBaseMetaTileEntity().isActive() - && GT_Utility.isStringValid( - getBaseMetaTileEntity().getLastShutDownReason() - .getDisplayString()) - && getBaseMetaTileEntity().wasShutdown())) - .widget( - new ShutDownReasonSyncer( - () -> getBaseMetaTileEntity().getLastShutDownReason(), - reason -> getBaseMetaTileEntity().setShutDownReason(reason))) - .widget( - new FakeSyncWidget.BooleanSyncer( - () -> getBaseMetaTileEntity().wasShutdown(), - wasShutDown -> getBaseMetaTileEntity().setShutdownStatus(wasShutDown))); - - screenElements.widget( - TextWidget.dynamicString(() -> checkRecipeResult.getDisplayString()) - .setSynced(false) - .setTextAlignment(Alignment.CenterLeft) - .setEnabled( - widget -> shouldDisplayCheckRecipeResult() - && GT_Utility.isStringValid(checkRecipeResult.getDisplayString()) - && (isAllowedToWork() || getBaseMetaTileEntity().isActive() - || checkRecipeResult.persistsOnShutdown()))) - .widget(new CheckRecipeResultSyncer(() -> checkRecipeResult, (result) -> checkRecipeResult = result)); - - if (showRecipeTextInGUI()) { - // Display current recipe - screenElements.widget( - TextWidget.dynamicString(this::generateCurrentRecipeInfoString) - .setSynced(false) - .setTextAlignment(Alignment.CenterLeft) - .setEnabled( - widget -> (mOutputFluids != null && mOutputFluids.length > 0) - || (mOutputItems != null && mOutputItems.length > 0))) - .widget( - new FakeSyncWidget.ListSyncer<>( - () -> mOutputFluids != null ? Arrays.asList(mOutputFluids) : Collections.emptyList(), - val -> mOutputFluids = val.toArray(new FluidStack[0]), - NetworkUtils::writeFluidStack, - NetworkUtils::readFluidStack)) - .widget( - new FakeSyncWidget.ListSyncer<>( - () -> mOutputItems != null ? Arrays.asList(mOutputItems) : Collections.emptyList(), - val -> mOutputItems = val.toArray(new ItemStack[0]), - NetworkUtils::writeItemStack, - NetworkUtils::readItemStack)) - .widget(new FakeSyncWidget.IntegerSyncer(() -> mProgresstime, val -> mProgresstime = val)) - .widget(new FakeSyncWidget.IntegerSyncer(() -> mMaxProgresstime, val -> mMaxProgresstime = val)); - } - - screenElements.widget( - new TextWidget(GT_Utility.trans("144", "Missing Turbine Rotor")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> { - if (getBaseMetaTileEntity().isAllowedToWork()) return false; - if (getBaseMetaTileEntity().getErrorDisplayID() == 0 - && this instanceof GT_MetaTileEntity_LargeTurbine) { - final ItemStack tItem = inventorySlot.getMcSlot() - .getStack(); - return tItem == null - || !(tItem.getItem() == GT_MetaGenerated_Tool_01.INSTANCE && tItem.getItemDamage() >= 170 - && tItem.getItemDamage() <= 177); - } - return false; - })); - } - - protected boolean showRecipeTextInGUI() { - return true; - } - - @TestOnly - protected void setEnergyHatches(ArrayList EnergyHatches) { - this.mEnergyHatches = EnergyHatches; - } - - @TestOnly - protected void setExoticEnergyHatches(List ExoticEnergyHatches) { - this.mExoticEnergyHatches = ExoticEnergyHatches; - } - - public void fixAllIssues() { - mWrench = true; - mScrewdriver = true; - mSoftHammer = true; - mHardHammer = true; - mSolderingTool = true; - mCrowbar = true; - } - - public boolean getDefaultHasMaintenanceChecks() { - return true; - } - - public boolean shouldCheckMaintenance() { - return !disableMaintenance && hasMaintenanceChecks; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java deleted file mode 100644 index 1a71f17ec8..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java +++ /dev/null @@ -1,134 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import java.util.List; -import java.util.function.Function; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizons.modularui.api.drawable.Text; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.api.screen.UIBuildContext; -import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import com.gtnewhorizons.modularui.common.widget.SlotGroup; -import com.gtnewhorizons.modularui.common.widget.SlotWidget; - -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -public abstract class GT_MetaTileEntity_SpecialFilter extends GT_MetaTileEntity_FilterBase { - - private static final String ALLOW_NBT_TOOLTIP = "GT5U.machines.allow_nbt.tooltip"; - private boolean allowNbt = false; - - public GT_MetaTileEntity_SpecialFilter(int aID, String aName, String aNameRegional, int aTier, - String[] aDescription) { - // 9 buffer slot, 1 representation slot, 1 holo slot. last seems not needed... - super(aID, aName, aNameRegional, aTier, 11, aDescription); - } - - public GT_MetaTileEntity_SpecialFilter(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_SpecialFilter(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - super.saveNBTData(aNBT); - aNBT.setBoolean("bNBTAllowed", this.allowNbt); - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - super.loadNBTData(aNBT); - this.allowNbt = aNBT.getBoolean("bNBTAllowed"); - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return (super.allowPutStack(aBaseMetaTileEntity, aIndex, side, aStack)) - && ((this.allowNbt) || (!aStack.hasTagCompound())) - && (this.isStackAllowed(aStack) != this.invertFilter); - } - - protected abstract boolean isStackAllowed(ItemStack aStack); - - protected List getEmptySlotTooltip() { - return null; - } - - protected Function, List> getItemStackReplacementTooltip() { - return list -> list; - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - super.addUIWidgets(builder, buildContext); - addAllowNbtButton(builder); - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_ARROW_24_WHITE.apply(27, false)) - .setPos(6, 19) - .setSize(27, 24)) - .widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_ARROW_24_BLUE.apply(42, true)) - .setPos(53, 19) - .setSize(42, 24)) - .widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_ARROW_24_RED.apply(19, true)) - .setPos(152, 19) - .setSize(19, 24)) - .widget( - createFilterIconSlot(BaseSlot.phantom(inventoryHandler, 9)).disableShiftInsert() - .setPos(34, 22) - .setBackground(GT_UITextures.BUTTON_STANDARD)) - .widget( - SlotGroup.ofItemHandler(inventoryHandler, 3) - .endAtSlot(8) - .build() - .setPos(97, 4)); - } - - private void addAllowNbtButton(ModularWindow.Builder builder) { - builder.widget( - createToggleButton( - () -> allowNbt, - val -> allowNbt = val, - GT_UITextures.OVERLAY_BUTTON_NBT, - () -> mTooltipCache.getData(ALLOW_NBT_TOOLTIP))); - } - - protected abstract SlotWidget createFilterIconSlot(BaseSlot slot); - - protected abstract class FilterIconSlotWidget extends SlotWidget { - - public FilterIconSlotWidget(BaseSlot slot) { - super(slot); - } - - @Override - protected abstract void phantomClick(ClickData clickData, ItemStack cursorStack); - - @Override - public void buildTooltip(List tooltip) { - super.buildTooltip(tooltip); - List emptySlotTooltip = getEmptySlotTooltip(); - if (emptySlotTooltip != null) { - tooltip.addAll(emptySlotTooltip); - } - } - - @Override - public Function, List> getOverwriteItemStackTooltip() { - return getItemStackReplacementTooltip(); - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlock.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlock.java deleted file mode 100644 index a08e49fd6c..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TieredMachineBlock.java +++ /dev/null @@ -1,119 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.GT; -import static gregtech.api.metatileentity.BaseTileEntity.BATTERY_SLOT_TOOLTIP; -import static gregtech.api.metatileentity.BaseTileEntity.BATTERY_SLOT_TOOLTIP_ALT; -import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; - -import com.gtnewhorizons.modularui.common.widget.SlotWidget; - -import gregtech.api.enums.GT_Values; -import gregtech.api.gui.modularui.GT_UITextures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.util.GT_Utility; - -public abstract class GT_MetaTileEntity_TieredMachineBlock extends MetaTileEntity { - - /** - * Value between [0 - 9] to describe the Tier of this Machine. PLZ [0-15] works - READ! GT_Values class. - */ - public final byte mTier; - - /** - * A simple Description. - */ - public final String[] mDescriptionArray; - - /** - * Contains all Textures used by this Block. - */ - public final ITexture[][][] mTextures; - - public GT_MetaTileEntity_TieredMachineBlock(int aID, String aName, String aNameRegional, int aTier, - int aInvSlotCount, String aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aInvSlotCount); - mTier = (byte) Math.max(0, Math.min(aTier, 14)); - mDescriptionArray = aDescription == null ? new String[0] : new String[] { aDescription }; - // must always be the last call! - if (GT.isClientSide()) mTextures = getTextureSet(aTextures); - else mTextures = null; - } - - public GT_MetaTileEntity_TieredMachineBlock(int aID, String aName, String aNameRegional, int aTier, - int aInvSlotCount, String[] aDescription, ITexture... aTextures) { - super(aID, aName, aNameRegional, aInvSlotCount); - mTier = (byte) Math.max(0, Math.min(aTier, 15)); - mDescriptionArray = aDescription == null ? new String[0] : aDescription; - - // must always be the last call! - if (GT.isClientSide()) mTextures = getTextureSet(aTextures); - else mTextures = null; - } - - public GT_MetaTileEntity_TieredMachineBlock(String aName, int aTier, int aInvSlotCount, String aDescription, - ITexture[][][] aTextures) { - super(aName, aInvSlotCount); - mTier = (byte) aTier; - mDescriptionArray = aDescription == null ? new String[0] : new String[] { aDescription }; - mTextures = aTextures; - } - - public GT_MetaTileEntity_TieredMachineBlock(String aName, int aTier, int aInvSlotCount, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aInvSlotCount); - mTier = (byte) aTier; - mDescriptionArray = aDescription == null ? new String[0] : aDescription; - mTextures = aTextures; - } - - @Override - public byte getTileEntityBaseType() { - return (byte) (Math.min(3, mTier <= 0 ? 0 : 1 + ((mTier - 1) / 4))); - } - - @Override - public long getInputTier() { - return mTier; - } - - @Override - public long getOutputTier() { - return mTier; - } - - @Override - public String[] getDescription() { - return mDescriptionArray; - } - - /** - * Used Client Side to get a Texture Set for this Block. Called after setting the Tier and the Description so that - * those two are accessible. - * - * @param aTextures is the optional Array you can give to the Constructor. - */ - public abstract ITexture[][][] getTextureSet(ITexture[] aTextures); - - protected SlotWidget createChargerSlot(int x, int y) { - final String batterySlotTooltipKey; - final Object[] batterySlotTooltipArgs; - final String pTier1 = GT_Utility.getColoredTierNameFromTier(mTier); - if (mTier == GT_Values.VN.length - 1) { - batterySlotTooltipKey = BATTERY_SLOT_TOOLTIP_ALT; - batterySlotTooltipArgs = new String[] { pTier1 }; - } else { - batterySlotTooltipKey = BATTERY_SLOT_TOOLTIP; - batterySlotTooltipArgs = new String[] { pTier1, GT_Utility.getColoredTierNameFromTier((byte) (mTier + 1)) }; - } - return createChargerSlot(x, y, batterySlotTooltipKey, batterySlotTooltipArgs); - } - - protected SlotWidget createChargerSlot(int x, int y, String tooltipKey, Object[] tooltipArgs) { - return (SlotWidget) new SlotWidget(inventoryHandler, rechargerSlotStartIndex()).disableShiftInsert() - .setGTTooltip(() -> mTooltipCache.getData(tooltipKey, tooltipArgs)) - .setTooltipShowUpDelay(TOOLTIP_DELAY) - .setBackground(getGUITextureSet().getItemSlot(), GT_UITextures.OVERLAY_SLOT_CHARGER) - .setPos(x, y); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TooltipMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TooltipMultiBlockBase.java deleted file mode 100644 index c12c7c1442..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_TooltipMultiBlockBase.java +++ /dev/null @@ -1,57 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import java.util.concurrent.atomic.AtomicReferenceArray; - -import org.lwjgl.input.Keyboard; - -import gregtech.api.GregTech_API; -import gregtech.api.interfaces.ISecondaryDescribable; -import gregtech.api.util.GT_Multiblock_Tooltip_Builder; - -/** - * A multiblock with tooltip {@link GT_Multiblock_Tooltip_Builder} - */ -public abstract class GT_MetaTileEntity_TooltipMultiBlockBase extends GT_MetaTileEntity_MultiBlockBase - implements ISecondaryDescribable { - - private static final AtomicReferenceArray tooltips = new AtomicReferenceArray<>( - GregTech_API.METATILEENTITIES.length); - - public GT_MetaTileEntity_TooltipMultiBlockBase(int aID, String aName, String aNameRegional) { - super(aID, aName, aNameRegional); - } - - public GT_MetaTileEntity_TooltipMultiBlockBase(String aName) { - super(aName); - } - - protected GT_Multiblock_Tooltip_Builder getTooltip() { - int tId = getBaseMetaTileEntity().getMetaTileID(); - GT_Multiblock_Tooltip_Builder tooltip = tooltips.get(tId); - if (tooltip == null) { - tooltip = createTooltip(); - tooltips.set(tId, tooltip); - } - return tooltip; - } - - protected abstract GT_Multiblock_Tooltip_Builder createTooltip(); - - @Override - public String[] getDescription() { - return getCurrentDescription(); - } - - @Override - public boolean isDisplaySecondaryDescription() { - return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT); - } - - public String[] getPrimaryDescription() { - return getTooltip().getInformation(); - } - - public String[] getSecondaryDescription() { - return getTooltip().getStructureInformation(); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java deleted file mode 100644 index de7019b292..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Transformer.java +++ /dev/null @@ -1,326 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.Mods.EnderIO; -import static mcp.mobius.waila.api.SpecialChars.BLUE; -import static mcp.mobius.waila.api.SpecialChars.GOLD; -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 java.util.List; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import cofh.api.energy.IEnergyProvider; -import cofh.api.energy.IEnergyStorage; -import crazypants.enderio.machine.capbank.TileCapBank; -import crazypants.enderio.machine.capbank.network.ICapBankNetwork; -import crazypants.enderio.power.IPowerContainer; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_Utility; -import mcp.mobius.waila.api.IWailaConfigHandler; -import mcp.mobius.waila.api.IWailaDataAccessor; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple - * Machine - */ -public class GT_MetaTileEntity_Transformer extends GT_MetaTileEntity_TieredMachineBlock { - - public GT_MetaTileEntity_Transformer(int aID, String aName, String aNameRegional, int aTier, String aDescription) { - super(aID, aName, aNameRegional, aTier, 0, aDescription); - } - - public GT_MetaTileEntity_Transformer(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - public GT_MetaTileEntity_Transformer(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[12][17][]; - for (byte i = -1; i < 16; i++) { - rTextures[0][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - rTextures[1][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - rTextures[2][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; - rTextures[3][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - rTextures[4][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - rTextures[5][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - rTextures[6][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN[mTier] }; - rTextures[7][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN[mTier] }; - rTextures[8][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN[mTier] }; - rTextures[9][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - rTextures[10][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - rTextures[11][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - } - return rTextures; - } - - @Override - public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, - ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { - return mTextures[Math.min(2, side.ordinal()) + (side == facingDirection ? 3 : 0) - + (baseMetaTileEntity.isAllowedToWork() ? 0 : 6)][colorIndex + 1]; - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Transformer(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isEnetInput() { - return true; - } - - @Override - public boolean isEnetOutput() { - return true; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - ForgeDirection blockFrontFacing = getBaseMetaTileEntity().getFrontFacing(); - - if (getBaseMetaTileEntity().isAllowedToWork()) { - return side == blockFrontFacing; - } else { - return side != blockFrontFacing; - } - } - - @Override - public boolean isOutputFacing(ForgeDirection side) { - return !isInputFacing(side); - } - - @Override - public boolean isTeleporterCompatible() { - return false; - } - - @Override - public long getMinimumStoredEU() { - return V[mTier + 1]; - } - - @Override - public long maxEUStore() { - return Math.max(512L, 1L << (mTier + 2)) + V[mTier + 1] * 4L; - } - - @Override - public long maxEUInput() { - return V[getBaseMetaTileEntity().isAllowedToWork() ? mTier + 1 : mTier]; - } - - @Override - public long maxEUOutput() { - return V[getBaseMetaTileEntity().isAllowedToWork() ? mTier : mTier + 1]; - } - - @Override - public long maxAmperesOut() { - return getBaseMetaTileEntity().isAllowedToWork() ? 4 : 1; - } - - @Override - public long maxAmperesIn() { - return getBaseMetaTileEntity().isAllowedToWork() ? 1 : 4; - } - - @Override - public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (aBaseMetaTileEntity.isServerSide() && GregTech_API.mInputRF) { - aBaseMetaTileEntity.setActive(aBaseMetaTileEntity.isAllowedToWork()); - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (aBaseMetaTileEntity.getStoredEU() >= aBaseMetaTileEntity.getEUCapacity()) break; - if (!aBaseMetaTileEntity.inputEnergyFrom(side)) continue; - final TileEntity tTileEntity = aBaseMetaTileEntity.getTileEntityAtSide(side); - if (tTileEntity instanceof IEnergyProvider energyProvider - && energyProvider.extractEnergy(side.getOpposite(), 1, true) == 1) { - long tEU = ((IEnergyProvider) tTileEntity).extractEnergy( - side.getOpposite(), - GT_Utility.safeInt(maxEUInput() * 100L / GregTech_API.mRFtoEU), - false); - tEU = tEU * GregTech_API.mRFtoEU / 100; - aBaseMetaTileEntity.injectEnergyUnits(ForgeDirection.UNKNOWN, Math.min(tEU, maxEUInput()), 1); - } else if (tTileEntity instanceof IEnergyStorage energyStorage - && energyStorage.extractEnergy(1, true) == 1) { - long tEU = ((IEnergyStorage) tTileEntity) - .extractEnergy(GT_Utility.safeInt(maxEUInput() * 100L / GregTech_API.mRFtoEU), false); - tEU = tEU * GregTech_API.mRFtoEU / 100; - aBaseMetaTileEntity.injectEnergyUnits(ForgeDirection.UNKNOWN, Math.min(tEU, maxEUInput()), 1); - } else if (EnderIO.isModLoaded() && tTileEntity instanceof IPowerContainer powerContainer - && powerContainer.getEnergyStored() > 0) { - final int storedRF = powerContainer.getEnergyStored(); - final int extractRF = GT_Utility.safeInt(maxEUInput() * 100L / GregTech_API.mRFtoEU); - long tEU = 0; - if (tTileEntity instanceof TileCapBank capBank) { - ICapBankNetwork network = capBank.getNetwork(); - if (network != null && network.getEnergyStoredL() > 0) { - tEU = Math.min( - (Math.min( - Math.min(network.getEnergyStoredL(), storedRF - extractRF), - network.getMaxOutput())) * (long) GregTech_API.mRFtoEU / 100L, - maxEUInput()); - network.addEnergy(GT_Utility.safeInt(-(tEU * 100 / GregTech_API.mRFtoEU))); - } - } else { - if (storedRF > extractRF) { - powerContainer.setEnergyStored(storedRF - extractRF); - tEU = maxEUInput(); - } else { - powerContainer.setEnergyStored(0); - tEU = storedRF * (long) GregTech_API.mRFtoEU / 100L; - } - } - aBaseMetaTileEntity - .injectEnergyUnits(ForgeDirection.UNKNOWN, Math.min(tEU, maxEUInput()), 1); - } - } - } - } - - @Override - public void saveNBTData(NBTTagCompound aNBT) { - // - } - - @Override - public void loadNBTData(NBTTagCompound aNBT) { - // - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean hasAlternativeModeText() { - return true; - } - - @Override - public String getAlternativeModeText() { - return (getBaseMetaTileEntity().isAllowedToWork() ? GT_Utility.trans("145", "Step Down, In: ") - : GT_Utility.trans("146", "Step Up, In: ")) + maxEUInput() - + GT_Utility.trans("148", "V ") - + maxAmperesIn() - + GT_Utility.trans("147", "A, Out: ") - + maxEUOutput() - + GT_Utility.trans("148", "V ") - + maxAmperesOut() - + GT_Utility.trans("149", "A"); - } - - @Override - public boolean shouldJoinIc2Enet() { - return true; - } - - @Override - public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, - IWailaConfigHandler config) { - final ForgeDirection facing = getBaseMetaTileEntity().getFrontFacing(); - final NBTTagCompound tag = accessor.getNBTData(); - final ForgeDirection side = accessor.getSide(); - final boolean allowedToWork = tag.getBoolean("isAllowedToWork"); - - final byte inputTier = GT_Utility.getTier(tag.getLong("maxEUInput")); - final byte outputTier = GT_Utility.getTier(tag.getLong("maxEUOutput")); - - currenttip.add( - String.format( - "%s %s(%dA) -> %s(%dA)", - (allowedToWork ? (GREEN + "Step Down") : (RED + "Step Up")) + RESET, - GT_Mod.gregtechproxy.mWailaTransformerVoltageTier ? GT_Utility.getColoredTierNameFromTier(inputTier) - : tag.getLong("maxEUInput"), - tag.getLong("maxAmperesIn"), - GT_Mod.gregtechproxy.mWailaTransformerVoltageTier ? GT_Utility.getColoredTierNameFromTier(outputTier) - : tag.getLong("maxEUOutput"), - tag.getLong("maxAmperesOut"))); - - if ((side == facing && allowedToWork) || (side != facing && !allowedToWork)) { - currenttip.add( - String.format( - GOLD + "Input:" + RESET + " %s(%dA)", - GT_Mod.gregtechproxy.mWailaTransformerVoltageTier ? GT_Utility.getColoredTierNameFromTier(inputTier) - : tag.getLong("maxEUInput"), - tag.getLong("maxAmperesIn"))); - } else { - currenttip.add( - String.format( - BLUE + "Output:" + RESET + " %s(%dA)", - GT_Mod.gregtechproxy.mWailaTransformerVoltageTier - ? GT_Utility.getColoredTierNameFromTier(outputTier) - : tag.getLong("maxEUOutput"), - tag.getLong("maxAmperesOut"))); - } - - super.getWailaBody(itemStack, currenttip, accessor, config); - } - - @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.setBoolean("isAllowedToWork", getBaseMetaTileEntity().isAllowedToWork()); - tag.setLong("maxEUInput", maxEUInput()); - tag.setLong("maxAmperesIn", maxAmperesIn()); - tag.setLong("maxEUOutput", maxEUOutput()); - tag.setLong("maxAmperesOut", maxAmperesOut()); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_WetTransformer.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_WetTransformer.java deleted file mode 100644 index f865a5ea8a..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_WetTransformer.java +++ /dev/null @@ -1,93 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.V; - -import net.minecraft.util.EnumChatFormatting; - -import org.apache.commons.lang3.ArrayUtils; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -public class GT_MetaTileEntity_WetTransformer extends GT_MetaTileEntity_Transformer { - - public GT_MetaTileEntity_WetTransformer(int aID, String aName, String aNameRegional, int aTier, - String aDescription) { - super(aID, aName, aNameRegional, aTier, aDescription); - } - - public GT_MetaTileEntity_WetTransformer(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aDescription, aTextures); - } - - @Override - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_WetTransformer(mName, mTier, mDescriptionArray, mTextures); - } - - @Override - public ITexture[][][] getTextureSet(ITexture[] aTextures) { - ITexture[][][] rTextures = new ITexture[12][17][]; - for (byte b = -1; b < 16; b++) { - rTextures[0][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - rTextures[1][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - rTextures[2][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; - rTextures[3][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_POWER[mTier + 1] }; - rTextures[4][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_POWER[mTier + 1] }; - rTextures[5][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_POWER[mTier + 1] }; - rTextures[6][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - rTextures[7][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - rTextures[8][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; - rTextures[9][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier + 1] }; - rTextures[10][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier + 1] }; - rTextures[11][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], - Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier + 1] }; - } - return rTextures; - } - - @Override - public String[] getDescription() { - return ArrayUtils.addAll( - mDescriptionArray, - "Accepts 16A and outputs 64A", - EnumChatFormatting.BLUE + "Tec" - + EnumChatFormatting.DARK_BLUE - + "Tech" - + EnumChatFormatting.BLUE - + ": Interdimensional"); - } - - @Override - public long getMinimumStoredEU() { - return V[mTier + 1]; - } - - @Override - public long maxEUStore() { - return 512L + V[mTier + 1] * 128L; - } - - @Override - public long maxAmperesOut() { - return getBaseMetaTileEntity().isAllowedToWork() ? 64 : 16; - } - - @Override - public long maxAmperesIn() { - return getBaseMetaTileEntity().isAllowedToWork() ? 16 : 64; - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java deleted file mode 100644 index a04f5cd986..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Dynamo.java +++ /dev/null @@ -1,146 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.AuthorColen; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; -import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; - -import java.util.UUID; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.interfaces.tileentity.IWirelessEnergyHatchInformation; -import gregtech.api.metatileentity.MetaTileEntity; - -public class GT_MetaTileEntity_Wireless_Dynamo extends GT_MetaTileEntity_Hatch_Dynamo - implements IWirelessEnergyHatchInformation { - - private UUID owner_uuid; - - public GT_MetaTileEntity_Wireless_Dynamo(String aName, byte aTier, String[] aDescription, - ITexture[][][] aTextures) { - super(aName, aTier, aDescription, aTextures); - } - - public GT_MetaTileEntity_Wireless_Dynamo(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, new String[] { "" }); - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isEnetOutput() { - return false; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public long getMinimumStoredEU() { - return 2 * V[mTier]; - } - - @Override - public long maxEUOutput() { - return V[mTier]; - } - - @Override - public long maxEUStore() { - return totalStorage(V[mTier]); - } - - @Override - public String[] getDescription() { - return new String[] { EnumChatFormatting.GRAY + "Stores energy globally in a network, up to 2^(2^31) EU.", - EnumChatFormatting.GRAY + "Does not connect to wires. This block accepts EU into the network.", - AuthorColen }; - } - - @Override - public long maxAmperesOut() { - return 2; - } - - @Override - public ConnectionType getConnectionType() { - return ConnectionType.WIRELESS; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Wireless_Dynamo(mName, mTier, new String[] { "" }, mTextures); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - super.onPreTick(aBaseMetaTileEntity, aTick); - - if (aBaseMetaTileEntity.isServerSide()) { - - // On first tick find the player name and attempt to add them to the map. - if (aTick == 1) { - - // UUID and username of the owner. - owner_uuid = aBaseMetaTileEntity.getOwnerUuid(); - - strongCheckOrAddUser(owner_uuid); - } - - // Every ticks_between_energy_addition ticks change the energy content of the machine. - if (aTick % ticks_between_energy_addition == 0L) { - addEUToGlobalEnergyMap(owner_uuid, getEUVar()); - setEUVar(0L); - } - } - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java deleted file mode 100644 index bf624eadd7..0000000000 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Wireless_Hatch.java +++ /dev/null @@ -1,168 +0,0 @@ -package gregtech.api.metatileentity.implementations; - -import static gregtech.api.enums.GT_Values.AuthorColen; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; -import static java.lang.Long.min; - -import java.math.BigInteger; -import java.util.UUID; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.interfaces.tileentity.IWirelessEnergyHatchInformation; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.common.misc.spaceprojects.SpaceProjectManager; - -public class GT_MetaTileEntity_Wireless_Hatch extends GT_MetaTileEntity_Hatch_Energy - implements IWirelessEnergyHatchInformation { - - private final BigInteger eu_transferred_per_operation = BigInteger - .valueOf(2 * V[mTier] * ticks_between_energy_addition); - private final long eu_transferred_per_operation_long = eu_transferred_per_operation.longValue(); - - private UUID owner_uuid; - - public GT_MetaTileEntity_Wireless_Hatch(String aName, byte aTier, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, 0, aDescription, aTextures); - } - - public GT_MetaTileEntity_Wireless_Hatch(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, new String[] { "" }); - } - - @Override - public String[] getDescription() { - return new String[] { EnumChatFormatting.GRAY + "Stores energy globally in a network, up to 2^(2^31) EU.", - EnumChatFormatting.GRAY + "Does not connect to wires. This block withdraws EU from the network.", - AuthorColen }; - } - - @Override - public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; - } - - @Override - public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; - } - - @Override - public boolean isSimpleMachine() { - return true; - } - - @Override - public boolean isFacingValid(ForgeDirection facing) { - return true; - } - - @Override - public boolean isAccessAllowed(EntityPlayer aPlayer) { - return true; - } - - @Override - public boolean isEnetInput() { - return false; - } - - @Override - public boolean isInputFacing(ForgeDirection side) { - return side == getBaseMetaTileEntity().getFrontFacing(); - } - - @Override - public boolean isValidSlot(int aIndex) { - return false; - } - - @Override - public long getMinimumStoredEU() { - return 2 * V[mTier]; - } - - @Override - public long maxEUInput() { - return V[mTier]; - } - - @Override - public long maxEUStore() { - return totalStorage(V[mTier]); - } - - @Override - public long maxAmperesIn() { - return 2; - } - - @Override - public ConnectionType getConnectionType() { - return ConnectionType.WIRELESS; - } - - @Override - public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_Wireless_Hatch(mName, mTier, new String[] { "" }, mTextures); - } - - @Override - public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, - ItemStack aStack) { - return false; - } - - @Override - public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { - super.onFirstTick(aBaseMetaTileEntity); - - if (!aBaseMetaTileEntity.isServerSide()) return; - - // UUID of the owner. - owner_uuid = aBaseMetaTileEntity.getOwnerUuid(); - - SpaceProjectManager.checkOrCreateTeam(owner_uuid);; - - tryFetchingEnergy(); - } - - @Override - public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - - super.onPreTick(aBaseMetaTileEntity, aTick); - - if (aBaseMetaTileEntity.isServerSide()) { - // This is set up in a way to be as optimised as possible. If a user has a relatively plentiful energy - // network - // it should make no difference to them. Minimising the number of operations on BigInteger is essential. - - // Every ticks_between_energy_addition add eu_transferred_per_operation to internal EU storage from network. - if (aTick % ticks_between_energy_addition == 0L) { - tryFetchingEnergy(); - } - } - } - - private void tryFetchingEnergy() { - long currentEU = getBaseMetaTileEntity().getStoredEU(); - long maxEU = maxEUStore(); - long euToTransfer = min(maxEU - currentEU, eu_transferred_per_operation_long); - if (euToTransfer <= 0) return; // nothing to transfer - if (!addEUToGlobalEnergyMap(owner_uuid, -euToTransfer)) return; - setEUVar(currentEU + euToTransfer); - } -} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicBatteryBuffer.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicBatteryBuffer.java new file mode 100644 index 0000000000..7ca8cce273 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicBatteryBuffer.java @@ -0,0 +1,435 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; +import com.gtnewhorizons.modularui.common.widget.SlotGroup; + +import gregtech.api.enums.Textures; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.MetaBaseItem; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; +import ic2.api.item.IElectricItem; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple + * Machine + */ +public class MTEBasicBatteryBuffer extends MTETieredMachineBlock implements IAddUIWidgets { + + public boolean mCharge = false, mDecharge = false; + public int mBatteryCount = 0, mChargeableCount = 0; + private long count = 0; + private long mStored = 0; + private long mMax = 0; + + public MTEBasicBatteryBuffer(int aID, String aName, String aNameRegional, int aTier, String aDescription, + int aSlotCount) { + super(aID, aName, aNameRegional, aTier, aSlotCount, aDescription); + } + + public MTEBasicBatteryBuffer(String aName, int aTier, String aDescription, ITexture[][][] aTextures, + int aSlotCount) { + super(aName, aTier, aSlotCount, aDescription, aTextures); + } + + public MTEBasicBatteryBuffer(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures, + int aSlotCount) { + super(aName, aTier, aSlotCount, aDescription, aTextures); + } + + @Override + public String[] getDescription() { + String[] desc = new String[mDescriptionArray.length + 1]; + System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); + desc[mDescriptionArray.length] = mInventory.length + " Slots"; + return desc; + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[2][17][]; + for (byte i = -1; i < 16; i++) { + rTextures[0][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; + rTextures[1][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + mInventory.length == 16 ? Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier] + : mInventory.length > 4 ? Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] + : Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + } + return rTextures; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, + int colorIndex, boolean aActive, boolean redstoneLevel) { + return mTextures[side == aFacing ? 1 : 0][colorIndex + 1]; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEBasicBatteryBuffer(mName, mTier, mDescriptionArray, mTextures, mInventory.length); + } + + @Override + public boolean isSimpleMachine() { + return false; + } + + @Override + public boolean isElectric() { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return side != getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean isTeleporterCompatible() { + return false; + } + + @Override + public long getMinimumStoredEU() { + return V[mTier] * 16L * mInventory.length; + } + + @Override + public long maxEUStore() { + return V[mTier] * 64L * mInventory.length; + } + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxEUOutput() { + return V[mTier]; + } + + @Override + public long maxAmperesIn() { + return mChargeableCount * 2L; + } + + @Override + public long maxAmperesOut() { + return mBatteryCount; + } + + @Override + public int rechargerSlotStartIndex() { + return 0; + } + + @Override + public int dechargerSlotStartIndex() { + return 0; + } + + @Override + public int rechargerSlotCount() { + return mCharge ? mInventory.length : 0; + } + + @Override + public int dechargerSlotCount() { + return mDecharge ? mInventory.length : 0; + } + + @Override + public int getProgresstime() { + return (int) getBaseMetaTileEntity().getUniversalEnergyStored(); + } + + @Override + public int maxProgresstime() { + return (int) getBaseMetaTileEntity().getUniversalEnergyCapacity(); + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + // + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + // + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + mCharge = aBaseMetaTileEntity.getStoredEU() / 2 > aBaseMetaTileEntity.getEUCapacity() / 3; + mDecharge = aBaseMetaTileEntity.getStoredEU() < aBaseMetaTileEntity.getEUCapacity() / 3; + mBatteryCount = 0; + mChargeableCount = 0; + for (ItemStack tStack : mInventory) if (GTModHandler.isElectricItem(tStack, mTier)) { + if (GTModHandler.isChargerItem(tStack)) mBatteryCount++; + mChargeableCount++; + } + } + count++; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (GTModHandler.isElectricItem(aStack) && aStack.getUnlocalizedName() + .startsWith("gt.metaitem.01.")) { + String name = aStack.getUnlocalizedName(); + if (name.equals("gt.metaitem.01.32510") || name.equals("gt.metaitem.01.32511") + || name.equals("gt.metaitem.01.32520") + || name.equals("gt.metaitem.01.32521") + || name.equals("gt.metaitem.01.32530") + || name.equals("gt.metaitem.01.32531")) { + return ic2.api.item.ElectricItem.manager.getCharge(aStack) == 0; + } + } + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (!GTUtility.isStackValid(aStack)) { + return false; + } + return mInventory[aIndex] == null && GTModHandler.isElectricItem(aStack, this.mTier); + } + + @Override + public int getInventoryStackLimit() { + return 1; + } + + public long[] getStoredEnergy() { + boolean scaleOverflow = false; + boolean storedOverflow = false; + long tScale = getBaseMetaTileEntity().getEUCapacity(); + long tStored = getBaseMetaTileEntity().getStoredEU(); + long tStep = 0; + if (mInventory != null) { + for (ItemStack aStack : mInventory) { + if (GTModHandler.isElectricItem(aStack)) { + + if (aStack.getItem() instanceof MetaBaseItem) { + Long[] stats = ((MetaBaseItem) aStack.getItem()).getElectricStats(aStack); + if (stats != null) { + if (stats[0] > Long.MAX_VALUE / 2) { + scaleOverflow = true; + } + tScale = tScale + stats[0]; + tStep = ((MetaBaseItem) aStack.getItem()).getRealCharge(aStack); + if (tStep > Long.MAX_VALUE / 2) { + storedOverflow = true; + } + tStored = tStored + tStep; + } + } else if (aStack.getItem() instanceof IElectricItem) { + tStored = tStored + (long) ic2.api.item.ElectricItem.manager.getCharge(aStack); + tScale = tScale + (long) ((IElectricItem) aStack.getItem()).getMaxCharge(aStack); + } + } + } + } + if (scaleOverflow) { + tScale = Long.MAX_VALUE; + } + if (storedOverflow) { + tStored = Long.MAX_VALUE; + } + return new long[] { tStored, tScale }; + } + + @Override + public String[] getInfoData() { + updateStorageInfo(); + + return new String[] { EnumChatFormatting.BLUE + getLocalName() + EnumChatFormatting.RESET, "Stored Items:", + EnumChatFormatting.GREEN + GTUtility.formatNumbers(mStored) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mMax) + + EnumChatFormatting.RESET + + " EU", + "Average input:", GTUtility.formatNumbers(getBaseMetaTileEntity().getAverageElectricInput()) + " EU/t", + "Average output:", GTUtility.formatNumbers(getBaseMetaTileEntity().getAverageElectricOutput()) + " EU/t" }; + } + + private void updateStorageInfo() { + if (mMax == 0 || (count > 20)) { + long[] tmp = getStoredEnergy(); + mStored = tmp[0]; + mMax = tmp[1]; + count = 0; + } + } + + @Override + public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + NBTTagCompound tag = accessor.getNBTData(); + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.stored", + GTUtility.formatNumbers(tag.getLong("mStored")), + GTUtility.formatNumbers(tag.getLong("mMax")))); + long avgIn = tag.getLong("AvgIn"); + long avgOut = tag.getLong("AvgOut"); + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.avg_in_with_amperage", + GTUtility.formatNumbers(avgIn), + GTUtility.getAmperageForTier(avgIn, (byte) getInputTier()), + GTUtility.getColoredTierNameFromTier((byte) getInputTier()))); + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.avg_out_with_amperage", + GTUtility.formatNumbers(avgOut), + GTUtility.getAmperageForTier(avgOut, (byte) getOutputTier()), + GTUtility.getColoredTierNameFromTier((byte) getOutputTier()))); + super.getWailaBody(itemStack, currenttip, accessor, config); + } + + @Override + public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, + int z) { + updateStorageInfo(); + super.getWailaNBTData(player, tile, tag, world, x, y, z); + tag.setLong("mStored", mStored); + tag.setLong("mMax", mMax); + tag.setLong("AvgIn", getBaseMetaTileEntity().getAverageElectricInput()); + tag.setLong("AvgOut", getBaseMetaTileEntity().getAverageElectricOutput()); + } + + @Override + public boolean isGivingInformation() { + return true; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + switch (mInventory.length) { + case 4 -> builder.widget( + SlotGroup.ofItemHandler(inventoryHandler, 2) + .startFromSlot(0) + .endAtSlot(3) + .slotCreator(index -> new BaseSlot(inventoryHandler, index) { + + @Override + public int getSlotStackLimit() { + return 1; + } + }) + .background(getGUITextureSet().getItemSlot()) + .build() + .setPos(70, 25)); + case 9 -> builder.widget( + SlotGroup.ofItemHandler(inventoryHandler, 3) + .startFromSlot(0) + .endAtSlot(8) + .slotCreator(index -> new BaseSlot(inventoryHandler, index) { + + @Override + public int getSlotStackLimit() { + return 1; + } + }) + .background(getGUITextureSet().getItemSlot()) + .build() + .setPos(61, 16)); + case 16 -> builder.widget( + SlotGroup.ofItemHandler(inventoryHandler, 4) + .startFromSlot(0) + .endAtSlot(15) + .slotCreator(index -> new BaseSlot(inventoryHandler, index) { + + @Override + public int getSlotStackLimit() { + return 1; + } + }) + .background(getGUITextureSet().getItemSlot()) + .build() + .setPos(52, 7)); + default -> builder.widget( + SlotGroup.ofItemHandler(inventoryHandler, 1) + .startFromSlot(0) + .endAtSlot(0) + .slotCreator(index -> new BaseSlot(inventoryHandler, index) { + + @Override + public int getSlotStackLimit() { + return 1; + } + }) + .background(getGUITextureSet().getItemSlot()) + .build() + .setPos(79, 34)); + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java new file mode 100644 index 0000000000..ac923bc699 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicGenerator.java @@ -0,0 +1,338 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; +import net.minecraftforge.fluids.IFluidHandler; + +import gregtech.api.enums.ItemList; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.Textures; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.RecipeMapWorkable; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.maps.FuelBackend; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.common.Pollution; + +public abstract class MTEBasicGenerator extends MTEBasicTank implements RecipeMapWorkable { + + public MTEBasicGenerator(int aID, String aName, String aNameRegional, int aTier, String aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, 3, aDescription, aTextures); + } + + public MTEBasicGenerator(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, 3, aDescription, aTextures); + } + + public MTEBasicGenerator(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 3, aDescription, aTextures); + } + + public MTEBasicGenerator(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 3, aDescription, aTextures); + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[10][17][]; + for (byte i = -1; i < 16; i++) { + rTextures[0][i + 1] = getFront(i); + rTextures[1][i + 1] = getBack(i); + rTextures[2][i + 1] = getBottom(i); + rTextures[3][i + 1] = getTop(i); + rTextures[4][i + 1] = getSides(i); + rTextures[5][i + 1] = getFrontActive(i); + rTextures[6][i + 1] = getBackActive(i); + rTextures[7][i + 1] = getBottomActive(i); + rTextures[8][i + 1] = getTopActive(i); + rTextures[9][i + 1] = getSidesActive(i); + } + return rTextures; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, + ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { + return mTextures[(active ? 5 : 0) + (side == facingDirection ? 0 + : side == facingDirection.getOpposite() ? 1 + : side == ForgeDirection.DOWN ? 2 : side == ForgeDirection.UP ? 3 : 4)][colorIndex + 1]; + } + + @Override + public String[] getDescription() { + String[] desc = new String[mDescriptionArray.length + 1]; + System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); + desc[mDescriptionArray.length] = "Fuel Efficiency: " + getEfficiency() + "%"; + return desc; + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + public ITexture[] getFront(byte aColor) { + return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getBack(byte aColor) { + return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getBottom(byte aColor) { + return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getTop(byte aColor) { + return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getSides(byte aColor) { + return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getFrontActive(byte aColor) { + return getFront(aColor); + } + + public ITexture[] getBackActive(byte aColor) { + return getBack(aColor); + } + + public ITexture[] getBottomActive(byte aColor) { + return getBottom(aColor); + } + + public ITexture[] getTopActive(byte aColor) { + return getTop(aColor); + } + + public ITexture[] getSidesActive(byte aColor) { + return getSides(aColor); + } + + @Override + public boolean isFacingValid(ForgeDirection side) { + return true; + } + + @Override + public boolean isSimpleMachine() { + return false; + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex < 2; + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public long maxEUOutput() { + return getBaseMetaTileEntity().isAllowedToWork() ? V[mTier] : 0L; + } + + @Override + public long maxEUStore() { + return Math.max(getEUVar(), V[mTier] * 80L + getMinimumStoredEU()); + } + + @Override + public boolean doesFillContainers() { + return getBaseMetaTileEntity().isAllowedToWork(); + // return false; + } + + @Override + public boolean doesEmptyContainers() { + return getBaseMetaTileEntity().isAllowedToWork(); + } + + @Override + public boolean canTankBeFilled() { + return getBaseMetaTileEntity().isAllowedToWork(); + } + + @Override + public boolean canTankBeEmptied() { + return getBaseMetaTileEntity().isAllowedToWork(); + } + + @Override + public boolean displaysItemStack() { + return true; + } + + @Override + public boolean displaysStackSize() { + return false; + } + + @Override + public boolean isFluidInputAllowed(FluidStack aFluid) { + return getFuelValue(aFluid) > 0; + } + + @Override + public boolean isLiquidOutput(ForgeDirection side) { + // return super.isLiquidOutput(aSide); + return false; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isAllowedToWork() && aTick % 10 == 0) { + if (mFluid != null) { + long tFuelValue = getFuelValue(mFluid), tConsumed = consumedFluidPerOperation(mFluid); + if (tFuelValue > 0 && tConsumed > 0 && mFluid.amount >= tConsumed) { + long tFluidAmountToUse = Math.min( + mFluid.amount / tConsumed, + (maxEUStore() - aBaseMetaTileEntity.getUniversalEnergyStored()) / tFuelValue); + if (tFluidAmountToUse > 0 + && aBaseMetaTileEntity.increaseStoredEnergyUnits(tFluidAmountToUse * tFuelValue, true)) { + // divided by two because this is called every 10 ticks, not 20 + Pollution.addPollution(getBaseMetaTileEntity(), getPollution() / 2); + mFluid.amount -= tFluidAmountToUse * tConsumed; + } + } + } + + if (mInventory[getInputSlot()] != null + && aBaseMetaTileEntity.getUniversalEnergyStored() < (maxEUOutput() * 20 + getMinimumStoredEU()) + && ((GTUtility.getFluidForFilledItem(mInventory[getInputSlot()], true) != null) + || solidFuelOverride(mInventory[getInputSlot()]))) { + long tFuelValue = getFuelValue(mInventory[getInputSlot()]); + if (tFuelValue <= 0) tFuelValue = getFuelValue(mInventory[getInputSlot()], true); + // System.out.println(" tFuelValue : " + tFuelValue ); + if (tFuelValue > 0) { + ItemStack tEmptyContainer = getEmptyContainer(mInventory[getInputSlot()]); + if (aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), tEmptyContainer)) { + aBaseMetaTileEntity.increaseStoredEnergyUnits(tFuelValue, true); + aBaseMetaTileEntity.decrStackSize(getInputSlot(), 1); + // divided by two because this is called every 10 ticks, not 20 + Pollution.addPollution(getBaseMetaTileEntity(), getPollution() / 2); + } + } + } + } + + if (aBaseMetaTileEntity.isServerSide()) aBaseMetaTileEntity.setActive( + aBaseMetaTileEntity.isAllowedToWork() + && aBaseMetaTileEntity.getUniversalEnergyStored() >= maxEUOutput() + getMinimumStoredEU()); + } + + /** + * @param stack the fuel stack + * @return if the stack is a solid fuel + */ + public boolean solidFuelOverride(ItemStack stack) { + // this could be used for a coal generator for example aswell... + ItemData association = GTOreDictUnificator.getAssociation(stack); + // if it is a gregtech Item, make sure its not a VOLUMETRIC_FLASK or any type of cell, else do vanilla checks + if (association != null) { + return !OrePrefixes.CELL_TYPES.contains(association.mPrefix) + && !GTUtility.areStacksEqual(ItemList.VOLUMETRIC_FLASK.get(1L), stack, true); + } else { + return stack != null && // when the stack is null its not a solid + stack.getItem() != null && // when the item in the stack is null its not a solid + !(stack.getItem() instanceof IFluidContainerItem) && // when the item is a fluid container its not a + // solid... + !(stack.getItem() instanceof IFluidHandler) && // when the item is a fluid handler its not a + // solid... + !stack.getItem() + .getUnlocalizedName() + .contains("bucket"); // since we cant really check for + // buckets... + } + } + + public abstract int getPollution(); + + @Override + public abstract RecipeMap getRecipeMap(); + + public abstract int getEfficiency(); + + public int consumedFluidPerOperation(FluidStack aLiquid) { + return 1; + } + + public int getFuelValue(FluidStack aLiquid) { + long value = getFuelValue(aLiquid, true); + return (value > Integer.MAX_VALUE) ? 0 : (int) value; + } + + public long getFuelValue(FluidStack aLiquid, boolean aLong) { + RecipeMap tRecipes = getRecipeMap(); + if (aLiquid == null || !(tRecipes.getBackend() instanceof FuelBackend tFuels)) return 0; + GTRecipe tFuel = tFuels.findFuel(aLiquid); + if (tFuel == null) return 0; + + return (long) tFuel.mSpecialValue * getEfficiency() * consumedFluidPerOperation(aLiquid) / 100; + } + + public int getFuelValue(ItemStack aStack) { + long value = getFuelValue(aStack, true); + return (value > Integer.MAX_VALUE) ? 0 : (int) value; + } + + public long getFuelValue(ItemStack aStack, boolean aLong) { + if (GTUtility.isStackInvalid(aStack) || getRecipeMap() == null) return 0; + GTRecipe tFuel = getRecipeMap().findRecipe(getBaseMetaTileEntity(), false, Long.MAX_VALUE, null, aStack); + if (tFuel == null) return 0; + + long liters = 10L; // 1000mb/100 + return (long) tFuel.mSpecialValue * liters * getEfficiency(); + } + + public ItemStack getEmptyContainer(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack) || getRecipeMap() == null) return null; + GTRecipe tFuel = getRecipeMap().findRecipe(getBaseMetaTileEntity(), false, Long.MAX_VALUE, null, aStack); + if (tFuel != null) return GTUtility.copyOrNull(tFuel.getOutput(0)); + return GTUtility.getContainerItem(aStack, true); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return super.allowPutStack(aBaseMetaTileEntity, aIndex, side, aStack) && (getFuelValue(aStack, true) > 0 + || getFuelValue(GTUtility.getFluidForFilledItem(aStack, true), true) > 0); + } + + @Override + public int getCapacity() { + return 16000; + } + + @Override + public int getTankPressure() { + return -100; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHull.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHull.java new file mode 100644 index 0000000000..35b6003c24 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHull.java @@ -0,0 +1,173 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public class MTEBasicHull extends MTEBasicTank { + + public MTEBasicHull(int aID, String aName, String aNameRegional, int aTier, String aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, 1, aDescription, aTextures); + } + + public MTEBasicHull(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEBasicHull(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEBasicHull(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEBasicHull(mName, mTier, mInventory.length, mDescriptionArray, mTextures); + } + + @Override + public boolean isElectric() { + return true; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return !isOutputFacing(side); + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public long getMinimumStoredEU() { + return 512; + } + + @Override + public long maxEUStore() { + return 512 + V[mTier] * 50; + } + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxEUOutput() { + return V[mTier]; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return true; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return true; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, + int colorIndex, boolean aConnected, boolean redstoneLevel) { + return mTextures[Math.min(2, side.ordinal()) + (side == aFacing ? 3 : 0)][colorIndex + 1]; + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[6][17][]; + for (byte i = -1; i < 16; i++) { + rTextures[0][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; + rTextures[1][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; + rTextures[2][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1] }; + rTextures[3][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + rTextures[4][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + rTextures[5][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + } + return rTextures; + } + + @Override + public boolean doesFillContainers() { + return false; + } + + @Override + public boolean doesEmptyContainers() { + return false; + } + + @Override + public boolean canTankBeFilled() { + return true; + } + + @Override + public boolean canTankBeEmptied() { + return true; + } + + @Override + public boolean displaysItemStack() { + return false; + } + + @Override + public boolean displaysStackSize() { + return false; + } + + @Override + public int getCapacity() { + return (mTier + 1) * 1000; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHullNonElectric.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHullNonElectric.java new file mode 100644 index 0000000000..ec01af0408 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicHullNonElectric.java @@ -0,0 +1,75 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public abstract class MTEBasicHullNonElectric extends MTEBasicHull { + + public MTEBasicHullNonElectric(int aID, String aName, String aNameRegional, int aTier, String aDescription) { + super(aID, aName, aNameRegional, aTier, aDescription); + } + + public MTEBasicHullNonElectric(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 1, aDescription, aTextures); + } + + public MTEBasicHullNonElectric(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 1, aDescription, aTextures); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, + ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { + return mTextures[Math.min(2, sideDirection.ordinal())][colorIndex + 1]; + } + + @Override + public boolean isElectric() { + return false; + } + + @Override + public boolean isEnetInput() { + return false; + } + + @Override + public boolean isEnetOutput() { + return false; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return false; + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return false; + } + + @Override + public long getMinimumStoredEU() { + return 0; + } + + @Override + public long maxEUStore() { + return 0; + } + + @Override + public long maxEUInput() { + return 0; + } + + @Override + public long maxEUOutput() { + return 0; + } + + @Override + public abstract ITexture[][][] getTextureSet(ITexture[] aTextures); +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachine.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachine.java new file mode 100644 index 0000000000..25dfb9b58b --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachine.java @@ -0,0 +1,1563 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.GTValues.debugCleanroom; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_CASINGS; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; +import static gregtech.api.metatileentity.BaseTileEntity.FLUID_TRANSFER_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.ITEM_TRANSFER_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.NEI_TRANSFER_STEAM_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.NEI_TRANSFER_VOLTAGE_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.POWER_SOURCE_KEY; +import static gregtech.api.metatileentity.BaseTileEntity.SPECIAL_SLOT_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.STALLED_STUTTERING_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.STALLED_VENT_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; +import static gregtech.api.metatileentity.BaseTileEntity.UNUSED_SLOT_TOOLTIP; +import static gregtech.api.util.GTRecipeConstants.EXPLODE; +import static gregtech.api.util.GTRecipeConstants.ON_FIRE; +import static gregtech.api.util.GTUtility.moveMultipleItemStacks; +import static net.minecraftforge.common.util.ForgeDirection.DOWN; +import static net.minecraftforge.common.util.ForgeDirection.UNKNOWN; +import static net.minecraftforge.common.util.ForgeDirection.UP; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidHandler; + +import org.apache.commons.lang3.tuple.Pair; + +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.math.Size; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.fluid.FluidStackTank; +import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; +import com.gtnewhorizons.modularui.common.widget.ProgressBar; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; + +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.SoundResource; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.gui.modularui.SteamTexture; +import gregtech.api.interfaces.ICleanroom; +import gregtech.api.interfaces.IConfigurationCircuitSupport; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddGregtechLogo; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.IOverclockDescriptionProvider; +import gregtech.api.interfaces.tileentity.RecipeMapWorkable; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.overclockdescriber.EUOverclockDescriber; +import gregtech.api.objects.overclockdescriber.OverclockDescriber; +import gregtech.api.recipe.BasicUIProperties; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTClientPreference; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GTWaila; +import gregtech.api.util.GT_TooltipDataCache; +import gregtech.api.util.OverclockCalculator; +import gregtech.common.gui.modularui.UIHelper; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple + * Machine + */ +public abstract class MTEBasicMachine extends MTEBasicTank implements RecipeMapWorkable, IConfigurationCircuitSupport, + IOverclockDescriptionProvider, IAddGregtechLogo, IAddUIWidgets { + + /** + * return values for checkRecipe() + */ + protected static final int DID_NOT_FIND_RECIPE = 0, FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS = 1, + FOUND_AND_SUCCESSFULLY_USED_RECIPE = 2; + + public static final int OTHER_SLOT_COUNT = 5; + public final ItemStack[] mOutputItems; + public final int mInputSlotCount, mAmperage; + public boolean mAllowInputFromOutputSide = false, mFluidTransfer = false, mItemTransfer = false, + mHasBeenUpdated = false, mStuttering = false, mCharge = false, mDecharge = false; + public boolean mDisableFilter = true; + public boolean mDisableMultiStack = true; + public int mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mOutputBlocked = 0; + public ForgeDirection mMainFacing = ForgeDirection.WEST; + public FluidStack mOutputFluid; + protected final OverclockDescriber overclockDescriber; + + /** + * Contains the Recipe which has been previously used, or null if there was no previous Recipe, which could have + * been buffered + */ + protected GTRecipe mLastRecipe = null; + + private FluidStack mFluidOut; + protected final FluidStackTank fluidOutputTank = new FluidStackTank( + () -> mFluidOut, + fluidStack -> mFluidOut = fluidStack, + this::getCapacity); + + /** + * Registers machine with single-line description. + * + * @param aOverlays 0 = SideFacingActive 1 = SideFacingInactive 2 = FrontFacingActive 3 = FrontFacingInactive 4 = + * TopFacingActive 5 = TopFacingInactive 6 = BottomFacingActive 7 = BottomFacingInactive ----- Not + * all Array Elements have to be initialised, you can also just use 8 Parameters for the Default + * Pipe Texture Overlays ----- 8 = BottomFacingPipeActive 9 = BottomFacingPipeInactive 10 = + * TopFacingPipeActive 11 = TopFacingPipeInactive 12 = SideFacingPipeActive 13 = + * SideFacingPipeInactive + */ + public MTEBasicMachine(int aID, String aName, String aNameRegional, int aTier, int aAmperage, String aDescription, + int aInputSlotCount, int aOutputSlotCount, ITexture... aOverlays) { + super( + aID, + aName, + aNameRegional, + aTier, + OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, + aDescription, + aOverlays); + mInputSlotCount = Math.max(0, aInputSlotCount); + mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)]; + mAmperage = aAmperage; + overclockDescriber = createOverclockDescriber(); + } + + /** + * Registers machine with multi-line descriptions. + */ + public MTEBasicMachine(int aID, String aName, String aNameRegional, int aTier, int aAmperage, String[] aDescription, + int aInputSlotCount, int aOutputSlotCount, ITexture... aOverlays) { + super( + aID, + aName, + aNameRegional, + aTier, + OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, + aDescription, + aOverlays); + mInputSlotCount = Math.max(0, aInputSlotCount); + mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)]; + mAmperage = aAmperage; + overclockDescriber = createOverclockDescriber(); + } + + /** + * For {@link #newMetaEntity}. + */ + public MTEBasicMachine(String aName, int aTier, int aAmperage, String[] aDescription, ITexture[][][] aTextures, + int aInputSlotCount, int aOutputSlotCount) { + super(aName, aTier, OTHER_SLOT_COUNT + aInputSlotCount + aOutputSlotCount + 1, aDescription, aTextures); + mInputSlotCount = Math.max(0, aInputSlotCount); + mOutputItems = new ItemStack[Math.max(0, aOutputSlotCount)]; + mAmperage = aAmperage; + overclockDescriber = createOverclockDescriber(); + } + + /** + * To be called by the constructor to initialize this instance's overclock behavior + */ + protected OverclockDescriber createOverclockDescriber() { + return new EUOverclockDescriber(mTier, mAmperage); + } + + protected boolean isValidMainFacing(ForgeDirection side) { + return (side.flag & (UP.flag | DOWN.flag | UNKNOWN.flag)) == 0; // Horizontal + } + + public boolean setMainFacing(ForgeDirection side) { + if (!isValidMainFacing(side)) return false; + mMainFacing = side; + if (getBaseMetaTileEntity().getFrontFacing() == mMainFacing) { + getBaseMetaTileEntity().setFrontFacing(side.getOpposite()); + } + onFacingChange(); + onMachineBlockUpdate(); + return true; + } + + @Override + public void onFacingChange() { + super.onFacingChange(); + // Set up the correct facing (front towards player, output opposite) client-side before the server packet + // arrives + if (mMainFacing == UNKNOWN) { + IGregTechTileEntity te = getBaseMetaTileEntity(); + if (te != null && te.getWorld().isRemote) { + mMainFacing = te.getFrontFacing(); + te.setFrontFacing(te.getBackFacing()); + } + } + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[14][17][]; + aTextures = Arrays.copyOf(aTextures, 14); + + for (int i = 0; i < aTextures.length; i++) if (aTextures[i] != null) for (byte c = -1; c < 16; c++) { + if (rTextures[i][c + 1] == null) + rTextures[i][c + 1] = new ITexture[] { MACHINE_CASINGS[mTier][c + 1], aTextures[i] }; + } + + for (byte c = -1; c < 16; c++) { + if (rTextures[0][c + 1] == null) rTextures[0][c + 1] = getSideFacingActive(c); + if (rTextures[1][c + 1] == null) rTextures[1][c + 1] = getSideFacingInactive(c); + if (rTextures[2][c + 1] == null) rTextures[2][c + 1] = getFrontFacingActive(c); + if (rTextures[3][c + 1] == null) rTextures[3][c + 1] = getFrontFacingInactive(c); + if (rTextures[4][c + 1] == null) rTextures[4][c + 1] = getTopFacingActive(c); + if (rTextures[5][c + 1] == null) rTextures[5][c + 1] = getTopFacingInactive(c); + if (rTextures[6][c + 1] == null) rTextures[6][c + 1] = getBottomFacingActive(c); + if (rTextures[7][c + 1] == null) rTextures[7][c + 1] = getBottomFacingInactive(c); + if (rTextures[8][c + 1] == null) rTextures[8][c + 1] = getBottomFacingPipeActive(c); + if (rTextures[9][c + 1] == null) rTextures[9][c + 1] = getBottomFacingPipeInactive(c); + if (rTextures[10][c + 1] == null) rTextures[10][c + 1] = getTopFacingPipeActive(c); + if (rTextures[11][c + 1] == null) rTextures[11][c + 1] = getTopFacingPipeInactive(c); + if (rTextures[12][c + 1] == null) rTextures[12][c + 1] = getSideFacingPipeActive(c); + if (rTextures[13][c + 1] == null) rTextures[13][c + 1] = getSideFacingPipeInactive(c); + } + return rTextures; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, + ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { + final int textureIndex; + if ((mMainFacing.flag & (UP.flag | DOWN.flag)) != 0) { // UP or DOWN + if (sideDirection == facingDirection) { + textureIndex = active ? 2 : 3; + } else { + textureIndex = switch (sideDirection) { + case DOWN -> active ? 6 : 7; + case UP -> active ? 4 : 5; + default -> active ? 0 : 1; + }; + } + } else { + if (sideDirection == mMainFacing) { + textureIndex = active ? 2 : 3; + } else { + if (showPipeFacing() && sideDirection == facingDirection) { + textureIndex = switch (sideDirection) { + case DOWN -> active ? 8 : 9; + case UP -> active ? 10 : 11; + default -> active ? 12 : 13; + }; + } else { + textureIndex = switch (sideDirection) { + case DOWN -> active ? 6 : 7; + case UP -> active ? 4 : 5; + default -> active ? 0 : 1; + }; + } + } + } + return mTextures[textureIndex][colorIndex + 1]; + } + + @Override + public boolean isSimpleMachine() { + return false; + } + + @Override + public boolean isOverclockerUpgradable() { + return false; + } + + @Override + public boolean isTransformerUpgradable() { + return false; + } + + @Override + public boolean isElectric() { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex > 0 && super.isValidSlot(aIndex) + && aIndex != getCircuitSlot() + && aIndex != OTHER_SLOT_COUNT + mInputSlotCount + mOutputItems.length; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + // Either mMainFacing or mMainFacing is horizontal + return ((facing.flag | mMainFacing.flag) & ~(UP.flag | DOWN.flag | UNKNOWN.flag)) != 0; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return side != mMainFacing; + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return false; + } + + @Override + public boolean isTeleporterCompatible() { + return false; + } + + @Override + public boolean isLiquidInput(ForgeDirection side) { + return side != mMainFacing && (mAllowInputFromOutputSide || side != getBaseMetaTileEntity().getFrontFacing()); + } + + @Override + public boolean isLiquidOutput(ForgeDirection side) { + return side != mMainFacing; + } + + @Override + public long getMinimumStoredEU() { + return V[mTier] * 16L; + } + + @Override + public long maxEUStore() { + return V[mTier] * 64L; + } + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxSteamStore() { + return maxEUStore(); + } + + @Override + public long maxAmperesIn() { + return ((long) mEUt * 2L) / V[mTier] + 1L; + } + + @Override + public int getInputSlot() { + return OTHER_SLOT_COUNT; + } + + @Override + public int getOutputSlot() { + return OTHER_SLOT_COUNT + mInputSlotCount; + } + + public int getSpecialSlotIndex() { + return 3; + } + + @Override + public int getStackDisplaySlot() { + return 2; + } + + @Override + public int rechargerSlotStartIndex() { + return 1; + } + + @Override + public int dechargerSlotStartIndex() { + return 1; + } + + @Override + public int rechargerSlotCount() { + return mCharge ? 1 : 0; + } + + @Override + public int dechargerSlotCount() { + return mDecharge ? 1 : 0; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public int getProgresstime() { + return mProgresstime; + } + + @Override + public int maxProgresstime() { + return mMaxProgresstime; + } + + @Override + public int increaseProgress(int aProgress) { + mProgresstime += aProgress; + return mMaxProgresstime - mProgresstime; + } + + @Override + public boolean isFluidInputAllowed(FluidStack aFluid) { + return getFillableStack() != null || (getRecipeMap() != null && getRecipeMap().containsInput(aFluid)); + } + + @Override + public boolean isFluidChangingAllowed() { + return true; + } + + @Override + public boolean doesFillContainers() { + return false; + } + + @Override + public boolean doesEmptyContainers() { + return false; + } + + @Override + public boolean canTankBeFilled() { + return true; + } + + @Override + public boolean canTankBeEmptied() { + return true; + } + + @Override + public boolean displaysItemStack() { + return true; + } + + @Override + public boolean displaysStackSize() { + return true; + } + + @Override + public FluidStack getDrainableStack() { + return mFluidOut; + } + + @Override + public FluidStack setDrainableStack(FluidStack aFluid) { + markDirty(); + mFluidOut = aFluid; + return mFluidOut; + } + + @Override + public boolean isDrainableStackSeparate() { + return true; + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + if (aBaseMetaTileEntity.isClientSide()) return true; + if (!GTMod.gregtechproxy.mForceFreeFace) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (aBaseMetaTileEntity.getAirAtSide(side)) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + } + GTUtility.sendChatToPlayer(aPlayer, "No free Side!"); + return true; + } + + @Override + public void initDefaultModes(NBTTagCompound aNBT) { + mMainFacing = ForgeDirection.UNKNOWN; + if (!getBaseMetaTileEntity().getWorld().isRemote) { + final GTClientPreference tPreference = GTMod.gregtechproxy + .getClientPreference(getBaseMetaTileEntity().getOwnerUuid()); + if (tPreference != null) { + mDisableFilter = !tPreference.isSingleBlockInitialFilterEnabled(); + mDisableMultiStack = !tPreference.isSingleBlockInitialMultiStackEnabled(); + } + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setBoolean("mFluidTransfer", mFluidTransfer); + aNBT.setBoolean("mItemTransfer", mItemTransfer); + aNBT.setBoolean("mHasBeenUpdated", mHasBeenUpdated); + aNBT.setBoolean("mAllowInputFromOutputSide", mAllowInputFromOutputSide); + aNBT.setBoolean("mDisableFilter", mDisableFilter); + aNBT.setBoolean("mDisableMultiStack", mDisableMultiStack); + aNBT.setInteger("mEUt", mEUt); + aNBT.setInteger("mMainFacing", mMainFacing.ordinal()); + aNBT.setInteger("mProgresstime", mProgresstime); + aNBT.setInteger("mMaxProgresstime", mMaxProgresstime); + if (mOutputFluid != null) aNBT.setTag("mOutputFluid", mOutputFluid.writeToNBT(new NBTTagCompound())); + if (mFluidOut != null) aNBT.setTag("mFluidOut", mFluidOut.writeToNBT(new NBTTagCompound())); + + for (int i = 0; i < mOutputItems.length; i++) + if (mOutputItems[i] != null) GTUtility.saveItem(aNBT, "mOutputItem" + i, mOutputItems[i]); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + mFluidTransfer = aNBT.getBoolean("mFluidTransfer"); + mItemTransfer = aNBT.getBoolean("mItemTransfer"); + mHasBeenUpdated = aNBT.getBoolean("mHasBeenUpdated"); + mAllowInputFromOutputSide = aNBT.getBoolean("mAllowInputFromOutputSide"); + mDisableFilter = aNBT.getBoolean("mDisableFilter"); + mDisableMultiStack = aNBT.getBoolean("mDisableMultiStack"); + mEUt = aNBT.getInteger("mEUt"); + mMainFacing = ForgeDirection.getOrientation(aNBT.getInteger("mMainFacing")); + mProgresstime = aNBT.getInteger("mProgresstime"); + mMaxProgresstime = aNBT.getInteger("mMaxProgresstime"); + mOutputFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mOutputFluid")); + mFluidOut = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluidOut")); + + for (int i = 0; i < mOutputItems.length; i++) mOutputItems[i] = GTUtility.loadItem(aNBT, "mOutputItem" + i); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + + if (aBaseMetaTileEntity.isServerSide()) { + mCharge = aBaseMetaTileEntity.getStoredEU() / 2 > aBaseMetaTileEntity.getEUCapacity() / 3; + mDecharge = aBaseMetaTileEntity.getStoredEU() < aBaseMetaTileEntity.getEUCapacity() / 3; + + doDisplayThings(); + + boolean tSucceeded = false; + + if (mMaxProgresstime > 0 && (mProgresstime >= 0 || aBaseMetaTileEntity.isAllowedToWork())) { + markDirty(); + aBaseMetaTileEntity.setActive(true); + if (mProgresstime < 0 || drainEnergyForProcess(mEUt)) { + if (++mProgresstime >= mMaxProgresstime) { + for (int i = 0; i < mOutputItems.length; i++) + for (int j = 0; j < mOutputItems.length; j++) if (aBaseMetaTileEntity + .addStackToSlot(getOutputSlot() + ((j + i) % mOutputItems.length), mOutputItems[i])) + break; + if (mOutputFluid != null) + if (getDrainableStack() == null) setDrainableStack(mOutputFluid.copy()); + else if (mOutputFluid.isFluidEqual(getDrainableStack())) + getDrainableStack().amount += mOutputFluid.amount; + Arrays.fill(mOutputItems, null); + mOutputFluid = null; + mEUt = 0; + mProgresstime = 0; + mMaxProgresstime = 0; + mStuttering = false; + tSucceeded = true; + endProcess(); + } + if (mProgresstime > 5) mStuttering = false; + } else { + if (!mStuttering) { + stutterProcess(); + if (canHaveInsufficientEnergy()) mProgresstime = -100; + mStuttering = true; + } + } + } else { + aBaseMetaTileEntity.setActive(false); + } + + boolean tRemovedOutputFluid = false; + + if (doesAutoOutputFluids() && getDrainableStack() != null + && aBaseMetaTileEntity.getFrontFacing() != mMainFacing + && (tSucceeded || aTick % 20 == 0)) { + IFluidHandler tTank = aBaseMetaTileEntity.getITankContainerAtSide(aBaseMetaTileEntity.getFrontFacing()); + if (tTank != null) { + FluidStack tDrained = drain(1000, false); + if (tDrained != null) { + final int tFilledAmount = tTank.fill(aBaseMetaTileEntity.getBackFacing(), tDrained, false); + if (tFilledAmount > 0) + tTank.fill(aBaseMetaTileEntity.getBackFacing(), drain(tFilledAmount, true), true); + } + } + if (getDrainableStack() == null) tRemovedOutputFluid = true; + } + + if (doesAutoOutput() && !isOutputEmpty() + && aBaseMetaTileEntity.getFrontFacing() != mMainFacing + && (tSucceeded || mOutputBlocked % 300 == 1 + || aBaseMetaTileEntity.hasInventoryBeenModified() + || aTick % 600 == 0)) { + TileEntity tTileEntity2 = aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getFrontFacing()); + long tStoredEnergy = aBaseMetaTileEntity.getUniversalEnergyStored(); + int tMaxStacks = (int) (tStoredEnergy / 64L); + if (tMaxStacks > mOutputItems.length) tMaxStacks = mOutputItems.length; + + moveMultipleItemStacks( + aBaseMetaTileEntity, + tTileEntity2, + aBaseMetaTileEntity.getFrontFacing(), + aBaseMetaTileEntity.getBackFacing(), + null, + false, + (byte) 64, + (byte) 1, + (byte) 64, + (byte) 1, + tMaxStacks); + } + + if (mOutputBlocked != 0) if (isOutputEmpty()) mOutputBlocked = 0; + else mOutputBlocked++; + + if (allowToCheckRecipe()) { + if (mMaxProgresstime <= 0 && aBaseMetaTileEntity.isAllowedToWork() + && (tRemovedOutputFluid || tSucceeded + || aBaseMetaTileEntity.hasInventoryBeenModified() + || aTick % 600 == 0 + || aBaseMetaTileEntity.hasWorkJustBeenEnabled()) + && hasEnoughEnergyToCheckRecipe()) { + if (checkRecipe() == FOUND_AND_SUCCESSFULLY_USED_RECIPE) { + if (getSpecialSlot() != null && getSpecialSlot().stackSize <= 0) + mInventory[getSpecialSlotIndex()] = null; + for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++) + if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; + for (int i = 0; i < mOutputItems.length; i++) { + mOutputItems[i] = GTUtility.copyOrNull(mOutputItems[i]); + if (mOutputItems[i] != null && mOutputItems[i].stackSize > 64) + mOutputItems[i].stackSize = 64; + mOutputItems[i] = GTOreDictUnificator.get(true, mOutputItems[i]); + } + if (mFluid != null && mFluid.amount <= 0) mFluid = null; + mMaxProgresstime = Math.max(1, mMaxProgresstime); + if (GTUtility.isDebugItem(mInventory[dechargerSlotStartIndex()])) { + mEUt = mMaxProgresstime = 1; + } + startProcess(); + } else { + mMaxProgresstime = 0; + Arrays.fill(mOutputItems, null); + mOutputFluid = null; + } + } + } else { + if (!mStuttering) { + stutterProcess(); + mStuttering = true; + } + } + } + // Only using mNeedsSteamVenting right now and assigning it to 64 to space in the range for more single block + // machine problems. + // Value | Class | Field + // 1 | GT_MetaTileEntity_BasicMachine | mStuttering + // 64 | GT_MetaTileEntity_BasicMachine_Bronze | mNeedsSteamVenting + aBaseMetaTileEntity.setErrorDisplayID((aBaseMetaTileEntity.getErrorDisplayID() & ~127)); // | (mStuttering ? 1 : + // 0)); + } + + protected void doDisplayThings() { + if (!isValidMainFacing(mMainFacing) && isValidMainFacing(getBaseMetaTileEntity().getFrontFacing())) { + mMainFacing = getBaseMetaTileEntity().getFrontFacing(); + } + if (isValidMainFacing(mMainFacing) && !mHasBeenUpdated) { + mHasBeenUpdated = true; + getBaseMetaTileEntity().setFrontFacing(getBaseMetaTileEntity().getBackFacing()); + } + } + + protected boolean hasEnoughEnergyToCheckRecipe() { + return getBaseMetaTileEntity().isUniversalEnergyStored(getMinimumStoredEU() / 2); + } + + protected boolean drainEnergyForProcess(long aEUt) { + return getBaseMetaTileEntity().decreaseStoredEnergyUnits(aEUt, false); + } + + /** + * Calculates overclock based on {@link #overclockDescriber}. + */ + protected void calculateCustomOverclock(GTRecipe recipe) { + OverclockCalculator calculator = overclockDescriber.createCalculator( + new OverclockCalculator().setRecipeEUt(recipe.mEUt) + .setDuration(recipe.mDuration) + .setOneTickDiscount(true), + recipe); + calculator.calculate(); + mEUt = (int) calculator.getConsumption(); + mMaxProgresstime = calculator.getDuration(); + } + + /** + * Helper method for calculating simple overclock. + */ + protected void calculateOverclockedNess(int eut, int duration) { + OverclockCalculator calculator = new OverclockCalculator().setRecipeEUt(eut) + .setEUt(V[mTier] * mAmperage) + .setDuration(duration) + .setOneTickDiscount(true) + .calculate(); + mEUt = (int) calculator.getConsumption(); + mMaxProgresstime = calculator.getDuration(); + } + + protected ItemStack getSpecialSlot() { + return mInventory[getSpecialSlotIndex()]; + } + + protected ItemStack getOutputAt(int aIndex) { + return mInventory[getOutputSlot() + aIndex]; + } + + protected ItemStack[] getAllOutputs() { + ItemStack[] rOutputs = new ItemStack[mOutputItems.length]; + for (int i = 0; i < mOutputItems.length; i++) rOutputs[i] = getOutputAt(i); + return rOutputs; + } + + protected boolean canOutput(GTRecipe aRecipe) { + return aRecipe != null && (aRecipe.mNeedsEmptyOutput ? isOutputEmpty() && getDrainableStack() == null + : canOutput(aRecipe.getFluidOutput(0)) && canOutput(aRecipe.mOutputs)); + } + + protected boolean canOutput(ItemStack... aOutputs) { + if (aOutputs == null) return true; + ItemStack[] tOutputSlots = getAllOutputs(); + for (int i = 0; i < tOutputSlots.length && i < aOutputs.length; i++) + if (tOutputSlots[i] != null && aOutputs[i] != null + && (!GTUtility.areStacksEqual(tOutputSlots[i], aOutputs[i], false) + || tOutputSlots[i].stackSize + aOutputs[i].stackSize > tOutputSlots[i].getMaxStackSize())) { + mOutputBlocked++; + return false; + } + return true; + } + + protected boolean canOutput(FluidStack aOutput) { + if (aOutput == null) return true; + FluidStack drainableStack = getDrainableStack(); + if (drainableStack != null && !drainableStack.isFluidEqual(aOutput)) return false; + return (drainableStack != null ? drainableStack.amount : 0) + aOutput.amount <= getCapacity(); + } + + protected ItemStack getInputAt(int aIndex) { + return mInventory[getInputSlot() + aIndex]; + } + + protected ItemStack[] getAllInputs() { + int tRealInputSlotCount = this.mInputSlotCount + (allowSelectCircuit() ? 1 : 0); + ItemStack[] rInputs = new ItemStack[tRealInputSlotCount]; + for (int i = 0; i < mInputSlotCount; i++) rInputs[i] = getInputAt(i); + if (allowSelectCircuit()) rInputs[mInputSlotCount] = getStackInSlot(getCircuitSlot()); + return rInputs; + } + + protected boolean isOutputEmpty() { + boolean rIsEmpty = true; + for (ItemStack tOutputSlotContent : getAllOutputs()) if (tOutputSlotContent != null) { + rIsEmpty = false; + break; + } + return rIsEmpty; + } + + @Override + public void onValueUpdate(byte aValue) { + mMainFacing = ForgeDirection.getOrientation(aValue); + } + + @Override + public byte getUpdateData() { + return (byte) mMainFacing.ordinal(); + } + + @Override + public void doSound(byte aIndex, double aX, double aY, double aZ) { + super.doSound(aIndex, aX, aY, aZ); + if (aIndex == 8) GTUtility.doSoundAtClient(SoundResource.IC2_MACHINES_INTERRUPT_ONE, 100, 1.0F, aX, aY, aZ); + } + + public boolean doesAutoOutput() { + return mItemTransfer; + } + + public boolean doesAutoOutputFluids() { + return mFluidTransfer; + } + + public boolean allowToCheckRecipe() { + return true; + } + + public boolean showPipeFacing() { + return true; + } + + /** + * Called whenever the Machine successfully started a Process, useful for Sound Effects + */ + public void startProcess() { + // + } + + /** + * Called whenever the Machine successfully finished a Process, useful for Sound Effects + */ + public void endProcess() { + // + } + + /** + * Called whenever the Machine aborted a Process, useful for Sound Effects + */ + public void abortProcess() { + // + } + + /** + * Called whenever the Machine aborted a Process but still works on it, useful for Sound Effects + */ + public void stutterProcess() { + if (useStandardStutterSound()) sendSound((byte) 8); + } + + /** + * If this Machine can have the Insufficient Energy Line Problem + */ + public boolean canHaveInsufficientEnergy() { + return true; + } + + public boolean useStandardStutterSound() { + return true; + } + + @Override + public String[] getInfoData() { + return new String[] { "Progress:", + EnumChatFormatting.GREEN + GTUtility.formatNumbers((mProgresstime / 20)) + + EnumChatFormatting.RESET + + " s / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mMaxProgresstime / 20) + + EnumChatFormatting.RESET + + " s", + "Stored Energy:", + EnumChatFormatting.GREEN + GTUtility.formatNumbers(getBaseMetaTileEntity().getStoredEU()) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(getBaseMetaTileEntity().getEUCapacity()) + + EnumChatFormatting.RESET + + " EU", + "Probably uses: " + EnumChatFormatting.RED + + GTUtility.formatNumbers(mEUt) + + EnumChatFormatting.RESET + + " EU/t at " + + EnumChatFormatting.RED + + GTUtility.formatNumbers(mEUt == 0 ? 0 : mAmperage) + + EnumChatFormatting.RESET + + " A" }; + } + + @Override + public boolean isGivingInformation() { + return true; + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (side == getBaseMetaTileEntity().getFrontFacing() || side == mMainFacing) { + if (aPlayer.isSneaking()) { + mDisableFilter = !mDisableFilter; + GTUtility.sendChatToPlayer( + aPlayer, + StatCollector.translateToLocal("GT5U.hatch.disableFilter." + mDisableFilter)); + } else { + mAllowInputFromOutputSide = !mAllowInputFromOutputSide; + GTUtility.sendChatToPlayer( + aPlayer, + mAllowInputFromOutputSide ? GTUtility.trans("095", "Input from Output Side allowed") + : GTUtility.trans("096", "Input from Output Side forbidden")); + } + } + } + + @Override + public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, + EntityPlayer entityPlayer, float aX, float aY, float aZ) { + if (!entityPlayer.isSneaking()) return false; + final boolean click = super.onSolderingToolRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); + if (click) return true; + if (wrenchingSide != mMainFacing) return false; + mDisableMultiStack = !mDisableMultiStack; + GTUtility.sendChatToPlayer( + entityPlayer, + StatCollector.translateToLocal("GT5U.hatch.disableMultiStack." + mDisableMultiStack)); + return true; + } + + @Override + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { + if (side != mMainFacing) return true; + CoverBehaviorBase tBehavior = GregTechAPI.getCoverBehaviorNew(aCoverID.toStack()); + return tBehavior.isGUIClickable( + side, + GTUtility.stackToInt(aCoverID.toStack()), + tBehavior.createDataObject(), + getBaseMetaTileEntity()); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side != mMainFacing && aIndex >= getOutputSlot() && aIndex < getOutputSlot() + mOutputItems.length; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (side == mMainFacing || aIndex < getInputSlot() + || aIndex >= getInputSlot() + mInputSlotCount + || (!mAllowInputFromOutputSide && side == aBaseMetaTileEntity.getFrontFacing())) return false; + for (int i = getInputSlot(), j = i + mInputSlotCount; i < j; i++) + if (GTUtility.areStacksEqual(GTOreDictUnificator.get(aStack), mInventory[i]) && mDisableMultiStack) + return i == aIndex; + return mDisableFilter || allowPutStackValidated(aBaseMetaTileEntity, aIndex, side, aStack); + } + + /** + * Test if given stack can be inserted into specified slot. If mDisableMultiStack is false, before execution of this + * method it is ensured there is no such kind of item inside any input slots already. Otherwise, you don't need to + * check for it anyway. + */ + protected boolean allowPutStackValidated(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return !mDisableMultiStack || mInventory[aIndex] == null; + } + + @Override + public boolean allowSelectCircuit() { + return false; + } + + protected final ItemStack[] appendSelectedCircuit(ItemStack... inputs) { + if (allowSelectCircuit()) { + ItemStack circuit = getStackInSlot(getCircuitSlot()); + if (circuit != null) { + ItemStack[] result = Arrays.copyOf(inputs, inputs.length + 1); + result[inputs.length] = circuit; + return result; + } + } + return inputs; + } + + @Override + public int getCircuitSlot() { + return 4; + } + + @Override + public int getCircuitGUISlot() { + return 3; + } + + @Override + public List getConfigurationCircuits() { + return GregTechAPI.getConfigurationCircuitList(mTier); + } + + @Override + public RecipeMap getRecipeMap() { + return null; + } + + /** + * Override this to check the Recipes yourself, super calls to this could be useful if you just want to add a + * special case + *

+ * I thought about Enum too, but Enum doesn't add support for people adding other return Systems. + *

+ * Funny how Eclipse marks the word Enum as not correctly spelled. + * + * @return see constants above + */ + public int checkRecipe() { + return checkRecipe(false); + } + + public static boolean isValidForLowGravity(GTRecipe tRecipe, int dimId) { + return // TODO check or get a better solution + DimensionManager.getProvider(dimId) + .getClass() + .getName() + .contains("Orbit") + || DimensionManager.getProvider(dimId) + .getClass() + .getName() + .endsWith("Space") + || DimensionManager.getProvider(dimId) + .getClass() + .getName() + .endsWith("Asteroids") + || DimensionManager.getProvider(dimId) + .getClass() + .getName() + .endsWith("SS") + || DimensionManager.getProvider(dimId) + .getClass() + .getName() + .contains("SpaceStation"); + } + + /** + * + * @param skipOC disables OverclockedNess calculation and check - if you do you must implement your own method... + * @return DID_NOT_FIND_RECIPE = 0, FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS = 1, + * FOUND_AND_SUCCESSFULLY_USED_RECIPE = 2; + */ + public int checkRecipe(boolean skipOC) { + RecipeMap tMap = getRecipeMap(); + if (tMap == null) return DID_NOT_FIND_RECIPE; + GTRecipe tRecipe = tMap.findRecipeQuery() + .items(getAllInputs()) + .fluids(getFillableStack()) + .specialSlot(getSpecialSlot()) + .voltage(V[mTier]) + .cachedRecipe(mLastRecipe) + .find(); + if (tRecipe == null) { + return DID_NOT_FIND_RECIPE; + } + if (tRecipe.getMetadataOrDefault(EXPLODE, false) && getBaseMetaTileEntity() != null) { + getBaseMetaTileEntity().doExplosion(V[mTier] * 4); + return DID_NOT_FIND_RECIPE; + } + if (tRecipe.getMetadataOrDefault(ON_FIRE, false) && getBaseMetaTileEntity() != null) { + getBaseMetaTileEntity().setOnFire(); + return DID_NOT_FIND_RECIPE; + } + + if (GTMod.gregtechproxy.mLowGravProcessing && (tRecipe.mSpecialValue == -100 || tRecipe.mSpecialValue == -300) + && !isValidForLowGravity(tRecipe, getBaseMetaTileEntity().getWorld().provider.dimensionId)) + return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + if (tRecipe.mCanBeBuffered) mLastRecipe = tRecipe; + if (!canOutput(tRecipe)) { + mOutputBlocked++; + return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + } + ICleanroom cleanroom = getCleanroom(); + if (tRecipe.mSpecialValue == -200 || tRecipe.mSpecialValue == -300) { + if (cleanroom == null || !cleanroom.isValidCleanroom() || cleanroom.getCleanness() == 0) { + return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + } + } + if (!tRecipe.isRecipeInputEqual(true, new FluidStack[] { getFillableStack() }, getAllInputs())) + return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + for (int i = 0; i < mOutputItems.length; i++) + if (getBaseMetaTileEntity().getRandomNumber(10000) < tRecipe.getOutputChance(i)) + mOutputItems[i] = tRecipe.getOutput(i); + if (tRecipe.mSpecialValue == -200 || tRecipe.mSpecialValue == -300) { + assert cleanroom != null; + for (int i = 0; i < mOutputItems.length; i++) if (mOutputItems[i] != null + && getBaseMetaTileEntity().getRandomNumber(10000) > cleanroom.getCleanness()) { + if (debugCleanroom) { + GTLog.out.println( + "BasicMachine: Voiding output due to cleanness failure. Cleanness = " + + cleanroom.getCleanness()); + } + mOutputItems[i] = null; + } + } + mOutputFluid = tRecipe.getFluidOutput(0); + if (!skipOC) { + calculateCustomOverclock(tRecipe); + // In case recipe is too OP for that machine + if (mMaxProgresstime == Integer.MAX_VALUE - 1 && mEUt == Integer.MAX_VALUE - 1) + return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + } + return FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + + public ITexture[] getSideFacingActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getSideFacingInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getFrontFacingActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getFrontFacingInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getTopFacingActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getTopFacingInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getBottomFacingActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getBottomFacingInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1] }; + } + + public ITexture[] getBottomFacingPipeActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + public ITexture[] getBottomFacingPipeInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + public ITexture[] getTopFacingPipeActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + public ITexture[] getTopFacingPipeInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + public ITexture[] getSideFacingPipeActive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + public ITexture[] getSideFacingPipeInactive(byte aColor) { + return new ITexture[] { MACHINE_CASINGS[mTier][aColor + 1], TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + final NBTTagCompound tag = accessor.getNBTData(); + + if (tag.getBoolean("stutteringSingleBlock")) { + currenttip.add("Status: insufficient energy"); + } else { + boolean isActive = tag.getBoolean("isActiveSingleBlock"); + if (isActive) { + int mEUt = tag.getInteger("eut"); + if (!isSteampowered()) { + if (mEUt > 0) { + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.use_with_amperage", + GTUtility.formatNumbers(mEUt), + GTUtility.getAmperageForTier(mEUt, (byte) getInputTier()), + GTUtility.getColoredTierNameFromTier((byte) getInputTier()))); + } else if (mEUt < 0) { + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.produce_with_amperage", + GTUtility.formatNumbers(-mEUt), + GTUtility.getAmperageForTier(-mEUt, (byte) getOutputTier()), + GTUtility.getColoredTierNameFromTier((byte) getOutputTier()))); + } + } else { + if (mEUt > 0) { + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.use", + GTUtility.formatNumbers(mEUt), + GTUtility.getColoredTierNameFromVoltage(mEUt))); + } else if (mEUt < 0) { + currenttip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.produce", + GTUtility.formatNumbers(-mEUt), + GTUtility.getColoredTierNameFromVoltage(-mEUt))); + } + } + } + currenttip.add( + GTWaila.getMachineProgressString( + isActive, + tag.getInteger("maxProgressSingleBlock"), + tag.getInteger("progressSingleBlock"))); + } + + currenttip.add( + String.format( + "Machine Facing: %s", + ForgeDirection.getOrientation(tag.getInteger("mainFacingSingleBlock")) + .name())); + + currenttip.add( + String.format( + "Output Facing: %s", + ForgeDirection.getOrientation(tag.getInteger("outputFacingSingleBlock")) + .name())); + } + + @Override + public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y, + int z) { + super.getWailaNBTData(player, tile, tag, world, x, y, z); + + tag.setInteger("progressSingleBlock", mProgresstime); + tag.setInteger("maxProgressSingleBlock", mMaxProgresstime); + tag.setInteger("mainFacingSingleBlock", mMainFacing.ordinal()); + tag.setBoolean("stutteringSingleBlock", mStuttering); + + final IGregTechTileEntity tileEntity = getBaseMetaTileEntity(); + if (tileEntity != null) { + tag.setBoolean("isActiveSingleBlock", tileEntity.isActive()); + tag.setInteger( + "outputFacingSingleBlock", + tileEntity.getFrontFacing() + .ordinal()); + if (tileEntity.isActive()) tag.setInteger("eut", mEUt); + } + } + + @Nonnull + @Override + public OverclockDescriber getOverclockDescriber() { + return overclockDescriber; + } + + // GUI stuff + + @Override + public int getCircuitSlotX() { + return 153; + } + + @Override + public int getCircuitSlotY() { + return 63; + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) { + if (getRecipeMap() != null) { + getRecipeMap().getFrontend() + .addGregTechLogo(builder, new Pos2d(0, 0)); + } else { + builder.widget( + new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo()) + .setSize(17, 17) + .setPos(152, 63)); + } + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + if (!isSteampowered()) { + builder.widget(createFluidAutoOutputButton()); + builder.widget(createItemAutoOutputButton()); + } + + BasicUIProperties uiProperties = getUIProperties(); + addIOSlots(builder, uiProperties); + + builder.widget(createChargerSlot(79, 62)); + + addProgressBar(builder, uiProperties); + + builder.widget( + createErrorStatusArea( + builder, + isSteampowered() ? GTUITextures.PICTURE_STALLED_STEAM : GTUITextures.PICTURE_STALLED_ELECTRICITY)); + } + + /** + * Override to specify UI properties if this machine doesn't work with recipemap. + */ + protected BasicUIProperties getUIProperties() { + if (getRecipeMap() != null) { + BasicUIProperties originalProperties = getRecipeMap().getFrontend() + .getUIProperties(); + return originalProperties.toBuilder() + .maxItemInputs(mInputSlotCount) + .maxItemOutputs(mOutputItems.length) + .maxFluidInputs(Math.min(originalProperties.maxFluidInputs, 1)) + .maxFluidOutputs(Math.min(originalProperties.maxFluidOutputs, 1)) + .build(); + } + return BasicUIProperties.builder() + .maxItemInputs(mInputSlotCount) + .maxItemOutputs(mOutputItems.length) + .maxFluidInputs(getCapacity() != 0 ? 1 : 0) + .maxFluidOutputs(0) + .build(); + } + + /** + * Adds item I/O, special item, and fluid I/O slots. + */ + protected void addIOSlots(ModularWindow.Builder builder, BasicUIProperties uiProperties) { + UIHelper.forEachSlots( + (i, backgrounds, pos) -> builder.widget(createItemInputSlot(i, backgrounds, pos)), + (i, backgrounds, pos) -> builder.widget(createItemOutputSlot(i, backgrounds, pos)), + (i, backgrounds, pos) -> builder.widget(createSpecialSlot(backgrounds, pos, uiProperties)), + (i, backgrounds, pos) -> builder.widget(createFluidInputSlot(backgrounds, pos)), + (i, backgrounds, pos) -> builder.widget(createFluidOutputSlot(backgrounds, pos)), + getGUITextureSet().getItemSlot(), + getGUITextureSet().getFluidSlot(), + uiProperties, + uiProperties.maxItemInputs, + uiProperties.maxItemOutputs, + uiProperties.maxFluidInputs, + uiProperties.maxFluidOutputs, + getSteamVariant(), + Pos2d.ZERO); + } + + protected void addProgressBar(ModularWindow.Builder builder, BasicUIProperties uiProperties) { + boolean isSteamPowered = isSteampowered(); + RecipeMap recipeMap = getRecipeMap(); + if (!isSteamPowered && uiProperties.progressBarTexture == null) { + if (recipeMap != null) { + // Require progress bar texture for machines working with recipemap, otherwise permit + throw new RuntimeException("Missing progressbar texture for " + recipeMap.unlocalizedName); + } else { + return; + } + } + if (isSteamPowered && uiProperties.progressBarTextureSteam == null) { + if (recipeMap != null) { + throw new RuntimeException("Missing steam progressbar texture for " + recipeMap.unlocalizedName); + } else { + return; + } + } + + builder.widget( + setNEITransferRect( + new ProgressBar() + .setProgress(() -> maxProgresstime() != 0 ? (float) getProgresstime() / maxProgresstime() : 0) + .setTexture( + isSteamPowered ? uiProperties.progressBarTextureSteam.get(getSteamVariant()) + : uiProperties.progressBarTexture.get(), + uiProperties.progressBarImageSize) + .setDirection(uiProperties.progressBarDirection) + .setPos(uiProperties.progressBarPos) + .setSize(uiProperties.progressBarSize), + uiProperties.neiTransferRectId)); + addProgressBarSpecialTextures(builder, uiProperties); + } + + /** + * Override this as needed instead of calling. + */ + protected SlotWidget createItemInputSlot(int index, IDrawable[] backgrounds, Pos2d pos) { + return (SlotWidget) new SlotWidget(inventoryHandler, getInputSlot() + index).setAccess(true, true) + .setBackground(backgrounds) + .setPos(pos); + } + + /** + * Override this as needed instead of calling. + */ + protected SlotWidget createItemOutputSlot(int index, IDrawable[] backgrounds, Pos2d pos) { + return (SlotWidget) new SlotWidget(inventoryHandler, getOutputSlot() + index).setAccess(true, false) + .setBackground(backgrounds) + .setPos(pos); + } + + /** + * Override this as needed instead of calling. + */ + protected SlotWidget createSpecialSlot(IDrawable[] backgrounds, Pos2d pos, BasicUIProperties uiProperties) { + return (SlotWidget) new SlotWidget(inventoryHandler, getSpecialSlotIndex()).setAccess(true, true) + .disableShiftInsert() + .setGTTooltip( + () -> mTooltipCache.getData(uiProperties.useSpecialSlot ? SPECIAL_SLOT_TOOLTIP : UNUSED_SLOT_TOOLTIP)) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setBackground(backgrounds) + .setPos(pos); + } + + protected FluidSlotWidget createFluidInputSlot(IDrawable[] backgrounds, Pos2d pos) { + return (FluidSlotWidget) new FluidSlotWidget(fluidTank).setBackground(backgrounds) + .setPos(pos); + } + + protected FluidSlotWidget createFluidOutputSlot(IDrawable[] backgrounds, Pos2d pos) { + return (FluidSlotWidget) new FluidSlotWidget(fluidOutputTank).setInteraction(true, false) + .setBackground(backgrounds) + .setPos(pos); + } + + @Override + protected SlotWidget createChargerSlot(int x, int y) { + if (isSteampowered()) { + return (SlotWidget) createChargerSlot(x, y, UNUSED_SLOT_TOOLTIP, new String[0]) + .setBackground(getGUITextureSet().getItemSlot()); + } else { + return super.createChargerSlot(x, y); + } + } + + protected CycleButtonWidget createItemAutoOutputButton() { + return (CycleButtonWidget) new CycleButtonWidget().setToggle(() -> mItemTransfer, val -> mItemTransfer = val) + .setStaticTexture(GTUITextures.OVERLAY_BUTTON_AUTOOUTPUT_ITEM) + .setVariableBackground(GTUITextures.BUTTON_STANDARD_TOGGLE) + .setGTTooltip(() -> mTooltipCache.getData(ITEM_TRANSFER_TOOLTIP)) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(25, 62) + .setSize(18, 18); + } + + protected CycleButtonWidget createFluidAutoOutputButton() { + return (CycleButtonWidget) new CycleButtonWidget().setToggle(() -> mFluidTransfer, val -> mFluidTransfer = val) + .setStaticTexture(GTUITextures.OVERLAY_BUTTON_AUTOOUTPUT_FLUID) + .setVariableBackground(GTUITextures.BUTTON_STANDARD_TOGGLE) + .setGTTooltip(() -> mTooltipCache.getData(FLUID_TRANSFER_TOOLTIP)) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(7, 62) + .setSize(18, 18); + } + + protected Widget setNEITransferRect(Widget widget, String transferRectID) { + if (GTUtility.isStringInvalid(transferRectID)) { + return widget; + } + final String transferRectTooltip; + if (isSteampowered()) { + transferRectTooltip = StatCollector + .translateToLocalFormatted(NEI_TRANSFER_STEAM_TOOLTIP, overclockDescriber.getTierString()); + } else { + transferRectTooltip = StatCollector + .translateToLocalFormatted(NEI_TRANSFER_VOLTAGE_TOOLTIP, overclockDescriber.getTierString()); + } + widget.setNEITransferRect(transferRectID, new Object[] { overclockDescriber }, transferRectTooltip); + return widget; + } + + protected void addProgressBarSpecialTextures(ModularWindow.Builder builder, BasicUIProperties uiProperties) { + if (isSteampowered()) { + for (Pair> specialTexture : uiProperties.specialTexturesSteam) { + builder.widget( + new DrawableWidget().setDrawable( + specialTexture.getLeft() + .get(getSteamVariant())) + .setSize( + specialTexture.getRight() + .getLeft()) + .setPos( + specialTexture.getRight() + .getRight())); + } + } else { + for (Pair> specialTexture : uiProperties.specialTextures) { + builder.widget( + new DrawableWidget().setDrawable(specialTexture.getLeft()) + .setSize( + specialTexture.getRight() + .getLeft()) + .setPos( + specialTexture.getRight() + .getRight())); + } + } + } + + protected DrawableWidget createErrorStatusArea(ModularWindow.Builder builder, IDrawable picture) { + return (DrawableWidget) new DrawableWidget().setDrawable(picture) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setEnabled( + widget -> !widget.getTooltip() + .isEmpty()) + .dynamicTooltip(this::getErrorDescriptions) + .dynamicTooltipShift(this::getErrorDescriptionsShift) + .setPos(79, 44) + .setSize(18, 18) + .attachSyncer( + new FakeSyncWidget.BooleanSyncer(() -> mStuttering, val -> mStuttering = val), + builder, + (widget, val) -> widget.notifyTooltipChange()) + .attachSyncer( + new FakeSyncWidget.IntegerSyncer( + () -> getBaseMetaTileEntity().getErrorDisplayID(), + val -> getBaseMetaTileEntity().setErrorDisplayID(val)), + builder, + (widget, val) -> widget.notifyTooltipChange()); + } + + protected List getErrorDescriptions() { + final GT_TooltipDataCache.TooltipData tooltip = getErrorTooltip(); + return tooltip != null ? tooltip.text : Collections.emptyList(); + } + + protected List getErrorDescriptionsShift() { + final GT_TooltipDataCache.TooltipData tooltip = getErrorTooltip(); + return tooltip != null ? tooltip.shiftText : Collections.emptyList(); + } + + protected GT_TooltipDataCache.TooltipData getErrorTooltip() { + if (isSteampowered()) { + if ((getBaseMetaTileEntity().getErrorDisplayID() & 64) != 0) { + return mTooltipCache.getData(STALLED_VENT_TOOLTIP); + } + } + if (mStuttering) { + return mTooltipCache.getData( + STALLED_STUTTERING_TOOLTIP, + StatCollector.translateToLocal(POWER_SOURCE_KEY + (isSteampowered() ? "steam" : "power"))); + } + return null; + } + + protected static int getCapacityForTier(int tier) { + return switch (tier) { + case 0 -> 8000; + case 1 -> 16000; + case 2 -> 32000; + case 3 -> 64000; + case 4 -> 128000; + default -> 256000; + }; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineBronze.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineBronze.java new file mode 100644 index 0000000000..507a807a76 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineBronze.java @@ -0,0 +1,387 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_BOTTOM; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_SIDE; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZEBRICKS_TOP; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZE_BOTTOM; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZE_SIDE; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_BRONZE_TOP; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; +import static gregtech.api.objects.XSTR.XSTR_INSTANCE; + +import java.util.Arrays; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; + +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.ParticleFX; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.SteamVariant; +import gregtech.api.enums.TierEU; +import gregtech.api.gui.modularui.GUITextureSet; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.overclockdescriber.OverclockDescriber; +import gregtech.api.objects.overclockdescriber.SteamOverclockDescriber; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple + * Machine + */ +public abstract class MTEBasicMachineBronze extends MTEBasicMachine { + + private static final String TT_machineType = "GT5U.MBTT.MachineType"; + private static final int NEEDS_STEAM_VENTING = 64; + public boolean mNeedsSteamVenting = false; + + public MTEBasicMachineBronze(int aID, String aName, String aNameRegional, String aDescription, int aInputSlotCount, + int aOutputSlotCount, boolean aHighPressure) { + super(aID, aName, aNameRegional, aHighPressure ? 2 : 1, 0, aDescription, aInputSlotCount, aOutputSlotCount); + } + + public MTEBasicMachineBronze(String aName, String[] aDescription, ITexture[][][] aTextures, int aInputSlotCount, + int aOutputSlotCount, boolean aHighPressure) { + super(aName, aHighPressure ? 2 : 1, 0, aDescription, aTextures, aInputSlotCount, aOutputSlotCount); + } + + protected boolean isBricked() { + return false; + } + + @Override + public OverclockDescriber createOverclockDescriber() { + return new SteamOverclockDescriber(SteamVariant.BRONZE, 1, 2); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setBoolean("mNeedsSteamVenting", mNeedsSteamVenting); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + mNeedsSteamVenting = aNBT.getBoolean("mNeedsSteamVenting"); + } + + @Override + public boolean isElectric() { + return false; + } + + @Override + public boolean isEnetInput() { + return false; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return false; + } + + @Override + public long maxEUStore() { + return 0; + } + + @Override + public long maxEUInput() { + return 0; + } + + @Override + public int rechargerSlotCount() { + return 0; + } + + @Override + public int dechargerSlotCount() { + return 0; + } + + @Override + public boolean isSteampowered() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return super.isFacingValid(facing) && facing != mMainFacing; + } + + @Override + public long getMinimumStoredEU() { + return 1000; + } + + @Override + public long maxSteamStore() { + return 16000; + } + + @Override + public boolean isLiquidInput(ForgeDirection side) { + return side != mMainFacing; + } + + @Override + public boolean isLiquidOutput(ForgeDirection side) { + return side != mMainFacing; + } + + @Override + public boolean doesAutoOutput() { + return false; + } + + @Override + public boolean allowToCheckRecipe() { + if (mNeedsSteamVenting + && getBaseMetaTileEntity().getCoverIDAtSide(getBaseMetaTileEntity().getFrontFacing()) == 0 + && !GTUtility.hasBlockHitBox( + getBaseMetaTileEntity().getWorld(), + getBaseMetaTileEntity().getOffsetX(getBaseMetaTileEntity().getFrontFacing(), 1), + getBaseMetaTileEntity().getOffsetY(getBaseMetaTileEntity().getFrontFacing(), 1), + getBaseMetaTileEntity().getOffsetZ(getBaseMetaTileEntity().getFrontFacing(), 1))) { + sendSound((byte) 9); + mNeedsSteamVenting = false; + try { + for (EntityLivingBase tLiving : getBaseMetaTileEntity().getWorld() + .getEntitiesWithinAABB( + EntityLivingBase.class, + AxisAlignedBB.getBoundingBox( + getBaseMetaTileEntity().getOffsetX(getBaseMetaTileEntity().getFrontFacing(), 1), + getBaseMetaTileEntity().getOffsetY(getBaseMetaTileEntity().getFrontFacing(), 1), + getBaseMetaTileEntity().getOffsetZ(getBaseMetaTileEntity().getFrontFacing(), 1), + getBaseMetaTileEntity().getOffsetX(getBaseMetaTileEntity().getFrontFacing(), 1) + 1, + getBaseMetaTileEntity().getOffsetY(getBaseMetaTileEntity().getFrontFacing(), 1) + 1, + getBaseMetaTileEntity().getOffsetZ(getBaseMetaTileEntity().getFrontFacing(), 1) + 1))) { + GTUtility.applyHeatDamage(tLiving, getSteamDamage()); + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + } + return !mNeedsSteamVenting; + } + + @Override + public int checkRecipe() { + GTRecipe tRecipe = getRecipeMap().findRecipe(getBaseMetaTileEntity(), false, TierEU.LV, null, getAllInputs()); + if ((tRecipe != null) && (canOutput(tRecipe.mOutputs)) + && (tRecipe.isRecipeInputEqual(true, null, getAllInputs()))) { + this.mOutputItems[0] = tRecipe.getOutput(0); + calculateCustomOverclock(tRecipe); + return FOUND_AND_SUCCESSFULLY_USED_RECIPE; + } + return DID_NOT_FIND_RECIPE; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + // Super already zeroed out setErrorDisplayID, add additional error codes here. + aBaseMetaTileEntity.setErrorDisplayID(aBaseMetaTileEntity.getErrorDisplayID() | (mNeedsSteamVenting ? 64 : 0)); + } + + @Override + public void endProcess() { + if (isSteampowered()) mNeedsSteamVenting = true; + } + + @Override + public void doSound(byte aIndex, double aX, double aY, double aZ) { + super.doSound(aIndex, aX, aY, aZ); + if (aIndex == 9) { + GTUtility.doSoundAtClient(SoundResource.RANDOM_FIZZ, 5, 1.0F, aX, aY, aZ); + + new ParticleEventBuilder().setIdentifier(ParticleFX.CLOUD) + .setWorld(getBaseMetaTileEntity().getWorld()) + .setMotion( + getBaseMetaTileEntity().getFrontFacing().offsetX / 5.0, + getBaseMetaTileEntity().getFrontFacing().offsetY / 5.0, + getBaseMetaTileEntity().getFrontFacing().offsetZ / 5.0) + .times( + 8, + x -> x + .setPosition( + aX - 0.5 + XSTR_INSTANCE.nextFloat(), + aY - 0.5 + XSTR_INSTANCE.nextFloat(), + aZ - 0.5 + XSTR_INSTANCE.nextFloat()) + .run()); + } + } + + @Override + public boolean isGivingInformation() { + return false; + } + + @Override + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { + return GregTechAPI.getCoverBehaviorNew(aCoverID.toStack()) + .isSimpleCover() && super.allowCoverOnSide(side, aCoverID); + } + + public float getSteamDamage() { + return 6.0F * mTier; + } + + @Override + public ITexture[] getSideFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getSideFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getFrontFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getFrontFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getTopFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getTopFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getBottomFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getBottomFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getBottomFacingPipeActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getBottomFacingPipeInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_BOTTOM : MACHINE_BRONZE_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getTopFacingPipeActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getTopFacingPipeInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_TOP : MACHINE_BRONZE_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getSideFacingPipeActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getSideFacingPipeInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_BRONZEBRICKS_SIDE : MACHINE_BRONZE_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public SteamVariant getSteamVariant() { + return SteamVariant.BRONZE; + } + + @Override + public GUITextureSet getGUITextureSet() { + return GUITextureSet.STEAM.apply(getSteamVariant()); + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) { + builder.widget( + new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo()) + .setSize(17, 17) + .setPos(152, 63)); + } + + @Override + protected FluidSlotWidget createFluidInputSlot(IDrawable[] backgrounds, Pos2d pos) { + return null; + } + + @Override + protected FluidSlotWidget createFluidOutputSlot(IDrawable[] backgrounds, Pos2d pos) { + return null; + } + + @Override + public String[] getDescription() { + String[] description = Arrays.copyOf(mDescriptionArray, mDescriptionArray.length + 1); + description[mDescriptionArray.length] = StatCollector.translateToLocal(TT_machineType) + ": " + + EnumChatFormatting.YELLOW + + StatCollector.translateToLocal(this.getRecipeMap().unlocalizedName) + + EnumChatFormatting.RESET; + return description; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineSteel.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineSteel.java new file mode 100644 index 0000000000..8d6f5568d5 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineSteel.java @@ -0,0 +1,149 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEELBRICKS_BOTTOM; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEELBRICKS_SIDE; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEELBRICKS_TOP; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEEL_BOTTOM; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEEL_SIDE; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_STEEL_TOP; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; + +import gregtech.api.enums.Dyes; +import gregtech.api.enums.SteamVariant; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IGetTitleColor; +import gregtech.api.objects.overclockdescriber.OverclockDescriber; +import gregtech.api.objects.overclockdescriber.SteamOverclockDescriber; +import gregtech.api.render.TextureFactory; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple + * Machine + */ +public abstract class MTEBasicMachineSteel extends MTEBasicMachineBronze implements IGetTitleColor { + + public MTEBasicMachineSteel(int aID, String aName, String aNameRegional, String aDescription, int aInputSlotCount, + int aOutputSlotCount, boolean aHighPressure) { + super(aID, aName, aNameRegional, aDescription, aInputSlotCount, aOutputSlotCount, aHighPressure); + } + + public MTEBasicMachineSteel(String aName, String[] aDescription, ITexture[][][] aTextures, int aInputSlotCount, + int aOutputSlotCount, boolean aHighPressure) { + super(aName, aDescription, aTextures, aInputSlotCount, aOutputSlotCount, aHighPressure); + } + + @Override + public OverclockDescriber createOverclockDescriber() { + return new SteamOverclockDescriber(SteamVariant.STEEL, 2, 1); + } + + @Override + public ITexture[] getSideFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getSideFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getFrontFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getFrontFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getTopFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getTopFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getBottomFacingActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getBottomFacingInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)) }; + } + + @Override + public ITexture[] getBottomFacingPipeActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getBottomFacingPipeInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_BOTTOM : MACHINE_STEEL_BOTTOM, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getTopFacingPipeActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getTopFacingPipeInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_TOP : MACHINE_STEEL_TOP, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getSideFacingPipeActive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getSideFacingPipeInactive(byte aColor) { + return new ITexture[] { TextureFactory.of( + isBricked() ? MACHINE_STEELBRICKS_SIDE : MACHINE_STEEL_SIDE, + Dyes.getModulation(aColor, Dyes._NULL.mRGBa)), TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public SteamVariant getSteamVariant() { + return SteamVariant.STEEL; + } + + @Override + public int getTitleColor() { + return COLOR_TITLE_WHITE.get(); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineWithRecipe.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineWithRecipe.java new file mode 100644 index 0000000000..b5bd3d77e1 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicMachineWithRecipe.java @@ -0,0 +1,817 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.GTValues.VN; +import static gregtech.api.enums.GTValues.W; +import static gregtech.api.enums.GTValues.ticksBetweenSounds; +import static gregtech.api.objects.XSTR.XSTR_INSTANCE; +import static net.minecraftforge.common.util.ForgeDirection.UP; + +import java.util.Locale; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.oredict.OreDictionary; + +import com.gtnewhorizons.modularui.api.drawable.FallbackableUITexture; +import com.gtnewhorizons.modularui.api.drawable.UITexture; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.ParticleFX; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.Textures.BlockIcons.CustomIcon; +import gregtech.api.enums.Tier; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.recipe.BasicUIProperties; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.ExternalMaterials; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; +import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple + * Machine + */ +public class MTEBasicMachineWithRecipe extends MTEBasicMachine { + + private final RecipeMap mRecipes; + private final int mTankCapacity; + private final SpecialEffects mSpecialEffect; + private final ResourceLocation mSoundResourceLocation; + private FallbackableUITexture progressBarTexture; + private int recipeCatalystPriority; + + /** + * Registers machine with single-line description, specific tank capacity, and sound specified by ResourceLocation. + */ + public MTEBasicMachineWithRecipe(int aID, String aName, String aNameRegional, int aTier, String aDescription, + RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, ResourceLocation aSound, + SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { + this( + aID, + aName, + aNameRegional, + aTier, + new String[] { aDescription }, + aRecipes, + aInputSlots, + aOutputSlots, + aTankCapacity, + aSound, + aSpecialEffect, + aOverlays, + aRecipe); + } + + /** + * Registers machine with multi-line descriptions, specific tank capacity, and sound specified by ResourceLocation. + */ + public MTEBasicMachineWithRecipe(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, + RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, ResourceLocation aSound, + SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { + super( + aID, + aName, + aNameRegional, + aTier, + aRecipes.getAmperage(), + aDescription, + aInputSlots, + aOutputSlots, + TextureFactory.of( + TextureFactory.of( + new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE_ACTIVE")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE_ACTIVE_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory + .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_SIDE_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of( + new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT_ACTIVE")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT_ACTIVE_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory + .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_FRONT_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of( + new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP_ACTIVE")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP_ACTIVE_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory + .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_TOP_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory.of( + new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM_ACTIVE")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM_ACTIVE_GLOW"))) + .glow() + .build()), + TextureFactory.of( + TextureFactory + .of(new CustomIcon("basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM")), + TextureFactory.builder() + .addIcon( + (new CustomIcon( + "basicmachines/" + aOverlays.toLowerCase(Locale.ENGLISH) + "/OVERLAY_BOTTOM_GLOW"))) + .glow() + .build())); + this.mTankCapacity = aTankCapacity; + this.mSpecialEffect = aSpecialEffect; + this.mRecipes = aRecipes; + this.mSoundResourceLocation = aSound; + this.progressBarTexture = mRecipes.getFrontend() + .getUIProperties().progressBarTexture; + + // TODO: CHECK + if (aRecipe != null) { + for (int i = 3; i < aRecipe.length; i++) { + if (!(aRecipe[i] instanceof X)) continue; + + // spotless:off + aRecipe[i] = switch ((X) aRecipe[i]) { + case CIRCUIT -> Tier.ELECTRIC[this.mTier].mManagingObject; + case BETTER_CIRCUIT -> Tier.ELECTRIC[this.mTier].mBetterManagingObject; + case HULL -> Tier.ELECTRIC[this.mTier].mHullObject; + case WIRE -> Tier.ELECTRIC[this.mTier].mConductingObject; + case WIRE4 -> Tier.ELECTRIC[this.mTier].mLargerConductingObject; + case STICK_DISTILLATION -> OrePrefixes.stick.get(Materials.Blaze); + + case GLASS -> switch (this.mTier) { + case 0, 1, 2, 3 -> new ItemStack(Blocks.glass, 1, W); + case 4, 5, 6, 7, 8 -> "blockGlass" + VN[aTier]; + default -> "blockGlass" + VN[8]; + }; + + case PLATE -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.plate.get(Materials.Steel); + case 2 -> OrePrefixes.plate.get(Materials.Aluminium); + case 3 -> OrePrefixes.plate.get(Materials.StainlessSteel); + case 4 -> OrePrefixes.plate.get(Materials.Titanium); + case 5 -> OrePrefixes.plate.get(Materials.TungstenSteel); + case 6 -> OrePrefixes.plate.get(Materials.HSSG); + case 7 -> OrePrefixes.plate.get(Materials.HSSE); + default -> OrePrefixes.plate.get(Materials.Neutronium); + }; + + case PIPE -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.pipeMedium.get(Materials.Bronze); + case 2 -> OrePrefixes.pipeMedium.get(Materials.Steel); + case 3 -> OrePrefixes.pipeMedium.get(Materials.StainlessSteel); + case 4 -> OrePrefixes.pipeMedium.get(Materials.Titanium); + case 5 -> OrePrefixes.pipeMedium.get(Materials.TungstenSteel); + case 6 -> OrePrefixes.pipeSmall.get(Materials.Ultimate); + case 7 -> OrePrefixes.pipeMedium.get(Materials.Ultimate); + case 8 -> OrePrefixes.pipeLarge.get(Materials.Ultimate); + default -> OrePrefixes.pipeHuge.get(Materials.Ultimate); + }; + + case COIL_HEATING -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); + case 2 -> OrePrefixes.wireGt02.get(Materials.Cupronickel); + case 3 -> OrePrefixes.wireGt02.get(Materials.Kanthal); + case 4 -> OrePrefixes.wireGt02.get(Materials.Nichrome); + case 5 -> OrePrefixes.wireGt02.get(Materials.TPV); + case 6 -> OrePrefixes.wireGt02.get(Materials.HSSG); + case 7 -> OrePrefixes.wireGt02.get(Materials.Naquadah); + case 8 -> OrePrefixes.wireGt02.get(Materials.NaquadahAlloy); + case 9 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); + default -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); + }; + + case COIL_HEATING_DOUBLE -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); + case 2 -> OrePrefixes.wireGt04.get(Materials.Cupronickel); + case 3 -> OrePrefixes.wireGt04.get(Materials.Kanthal); + case 4 -> OrePrefixes.wireGt04.get(Materials.Nichrome); + case 5 -> OrePrefixes.wireGt04.get(Materials.TPV); + case 6 -> OrePrefixes.wireGt04.get(Materials.HSSG); + case 7 -> OrePrefixes.wireGt04.get(Materials.Naquadah); + case 8 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); + case 9 -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); + default -> OrePrefixes.wireGt16.get(Materials.NaquadahAlloy); + }; + + case STICK_MAGNETIC -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.stick.get(Materials.IronMagnetic); + case 2, 3 -> OrePrefixes.stick.get(Materials.SteelMagnetic); + case 4, 5 -> OrePrefixes.stick.get(Materials.NeodymiumMagnetic); + case 6, 7, 8, 9 -> OrePrefixes.stick.get(Materials.SamariumMagnetic); + default -> OrePrefixes.stick.get(Materials.TengamAttuned); + }; + + case STICK_ELECTROMAGNETIC -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.stick.get(Materials.AnyIron); + case 2, 3 -> OrePrefixes.stick.get(Materials.Steel); + case 4 -> OrePrefixes.stick.get(Materials.Neodymium); + default -> OrePrefixes.stick.get(Materials.VanadiumGallium); + }; + + case COIL_ELECTRIC -> switch (this.mTier) { + case 0 -> OrePrefixes.wireGt01.get(Materials.Lead); + case 1 -> OrePrefixes.wireGt02.get(Materials.Tin); + case 2 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); + case 3 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); + case 4 -> OrePrefixes.wireGt08.get(Materials.AnnealedCopper); + case 5 -> OrePrefixes.wireGt16.get(Materials.AnnealedCopper); + case 6 -> OrePrefixes.wireGt04.get(Materials.YttriumBariumCuprate); + case 7 -> OrePrefixes.wireGt08.get(Materials.Iridium); + default -> OrePrefixes.wireGt16.get(Materials.Osmium); + }; + + case ROBOT_ARM -> switch (this.mTier) { + case 0, 1 -> ItemList.Robot_Arm_LV; + case 2 -> ItemList.Robot_Arm_MV; + case 3 -> ItemList.Robot_Arm_HV; + case 4 -> ItemList.Robot_Arm_EV; + case 5 -> ItemList.Robot_Arm_IV; + case 6 -> ItemList.Robot_Arm_LuV; + case 7 -> ItemList.Robot_Arm_ZPM; + case 8 -> ItemList.Robot_Arm_UV; + case 9 -> ItemList.Robot_Arm_UHV; + case 10 -> ItemList.Robot_Arm_UEV; + case 11 -> ItemList.Robot_Arm_UIV; + case 12 -> ItemList.Robot_Arm_UMV; + case 13 -> ItemList.Robot_Arm_UXV; + default -> ItemList.Robot_Arm_MAX; + }; + + case PUMP -> switch (this.mTier) { + case 0, 1 -> ItemList.Electric_Pump_LV; + case 2 -> ItemList.Electric_Pump_MV; + case 3 -> ItemList.Electric_Pump_HV; + case 4 -> ItemList.Electric_Pump_EV; + case 5 -> ItemList.Electric_Pump_IV; + case 6 -> ItemList.Electric_Pump_LuV; + case 7 -> ItemList.Electric_Pump_ZPM; + case 8 -> ItemList.Electric_Pump_UV; + case 9 -> ItemList.Electric_Pump_UHV; + case 10 -> ItemList.Electric_Pump_UEV; + case 11 -> ItemList.Electric_Pump_UIV; + case 12 -> ItemList.Electric_Pump_UMV; + case 13 -> ItemList.Electric_Pump_UXV; + default -> ItemList.Electric_Pump_MAX; + }; + + case MOTOR -> switch (this.mTier) { + case 0, 1 -> ItemList.Electric_Motor_LV; + case 2 -> ItemList.Electric_Motor_MV; + case 3 -> ItemList.Electric_Motor_HV; + case 4 -> ItemList.Electric_Motor_EV; + case 5 -> ItemList.Electric_Motor_IV; + case 6 -> ItemList.Electric_Motor_LuV; + case 7 -> ItemList.Electric_Motor_ZPM; + case 8 -> ItemList.Electric_Motor_UV; + case 9 -> ItemList.Electric_Motor_UHV; + case 10 -> ItemList.Electric_Motor_UEV; + case 11 -> ItemList.Electric_Motor_UIV; + case 12 -> ItemList.Electric_Motor_UMV; + case 13 -> ItemList.Electric_Motor_UXV; + default -> ItemList.Electric_Motor_MAX; + }; + + case PISTON -> switch (this.mTier) { + case 0, 1 -> ItemList.Electric_Piston_LV; + case 2 -> ItemList.Electric_Piston_MV; + case 3 -> ItemList.Electric_Piston_HV; + case 4 -> ItemList.Electric_Piston_EV; + case 5 -> ItemList.Electric_Piston_IV; + case 6 -> ItemList.Electric_Piston_LuV; + case 7 -> ItemList.Electric_Piston_ZPM; + case 8 -> ItemList.Electric_Piston_UV; + case 9 -> ItemList.Electric_Piston_UHV; + case 10 -> ItemList.Electric_Piston_UEV; + case 11 -> ItemList.Electric_Piston_UIV; + case 12 -> ItemList.Electric_Piston_UMV; + case 13 -> ItemList.Electric_Piston_UXV; + default -> ItemList.Electric_Piston_MAX; + }; + + case CONVEYOR -> switch (this.mTier) { + case 0, 1 -> ItemList.Conveyor_Module_LV; + case 2 -> ItemList.Conveyor_Module_MV; + case 3 -> ItemList.Conveyor_Module_HV; + case 4 -> ItemList.Conveyor_Module_EV; + case 5 -> ItemList.Conveyor_Module_IV; + case 6 -> ItemList.Conveyor_Module_LuV; + case 7 -> ItemList.Conveyor_Module_ZPM; + case 8 -> ItemList.Conveyor_Module_UV; + case 9 -> ItemList.Conveyor_Module_UHV; + case 10 -> ItemList.Conveyor_Module_UEV; + case 11 -> ItemList.Conveyor_Module_UIV; + case 12 -> ItemList.Conveyor_Module_UMV; + case 13 -> ItemList.Conveyor_Module_UXV; + default -> ItemList.Conveyor_Module_MAX; + }; + + case EMITTER -> switch (this.mTier) { + case 0, 1 -> ItemList.Emitter_LV; + case 2 -> ItemList.Emitter_MV; + case 3 -> ItemList.Emitter_HV; + case 4 -> ItemList.Emitter_EV; + case 5 -> ItemList.Emitter_IV; + case 6 -> ItemList.Emitter_LuV; + case 7 -> ItemList.Emitter_ZPM; + case 8 -> ItemList.Emitter_UV; + case 9 -> ItemList.Emitter_UHV; + case 10 -> ItemList.Emitter_UEV; + case 11 -> ItemList.Emitter_UIV; + case 12 -> ItemList.Emitter_UMV; + case 13 -> ItemList.Emitter_UXV; + default -> ItemList.Emitter_MAX; + }; + + case SENSOR -> switch (this.mTier) { + case 0, 1 -> ItemList.Sensor_LV; + case 2 -> ItemList.Sensor_MV; + case 3 -> ItemList.Sensor_HV; + case 4 -> ItemList.Sensor_EV; + case 5 -> ItemList.Sensor_IV; + case 6 -> ItemList.Sensor_LuV; + case 7 -> ItemList.Sensor_ZPM; + case 8 -> ItemList.Sensor_UV; + case 9 -> ItemList.Sensor_UHV; + case 10 -> ItemList.Sensor_UEV; + case 11 -> ItemList.Sensor_UIV; + case 12 -> ItemList.Sensor_UMV; + case 13 -> ItemList.Sensor_UXV; + default -> ItemList.Sensor_MAX; + }; + + case FIELD_GENERATOR -> switch (this.mTier) { + case 0, 1 -> ItemList.Field_Generator_LV; + case 2 -> ItemList.Field_Generator_MV; + case 3 -> ItemList.Field_Generator_HV; + case 4 -> ItemList.Field_Generator_EV; + case 5 -> ItemList.Field_Generator_IV; + case 6 -> ItemList.Field_Generator_LuV; + case 7 -> ItemList.Field_Generator_ZPM; + case 8 -> ItemList.Field_Generator_UV; + case 9 -> ItemList.Field_Generator_UHV; + case 10 -> ItemList.Field_Generator_UEV; + case 11 -> ItemList.Field_Generator_UIV; + case 12 -> ItemList.Field_Generator_UMV; + case 13 -> ItemList.Field_Generator_UXV; + default -> ItemList.Field_Generator_MAX; + }; + + case ROTOR -> switch (this.mTier) { + case 0, 1 -> OrePrefixes.rotor.get(Materials.Tin); + case 2 -> OrePrefixes.rotor.get(Materials.Bronze); + case 3 -> OrePrefixes.rotor.get(Materials.Steel); + case 4 -> OrePrefixes.rotor.get(Materials.StainlessSteel); + case 5 -> OrePrefixes.rotor.get(Materials.TungstenSteel); + case 6 -> OrePrefixes.rotor.get(ExternalMaterials.getRhodiumPlatedPalladium()); + case 7 -> OrePrefixes.rotor.get(Materials.Iridium); + default -> OrePrefixes.rotor.get(Materials.Osmium); + }; + + default -> throw new IllegalArgumentException("MISSING TIER MAPPING FOR: " + aRecipe[i] + " AT TIER " + this.mTier); + }; + // spotless:on + } + + if (!GTModHandler.addCraftingRecipe( + getStackForm(1), + GTModHandler.RecipeBits.DISMANTLEABLE | GTModHandler.RecipeBits.BUFFERED + | GTModHandler.RecipeBits.NOT_REMOVABLE + | GTModHandler.RecipeBits.REVERSIBLE, + aRecipe)) { + throw new IllegalArgumentException("INVALID CRAFTING RECIPE FOR: " + getStackForm(1).getDisplayName()); + } + } + } + + /** + * Registers machine with single-line description, auto-scaled fluid tank, and sound specified by SoundResource. + */ + public MTEBasicMachineWithRecipe(int aID, String aName, String aNameRegional, int aTier, String aDescription, + RecipeMap aRecipes, int aInputSlots, int aOutputSlots, boolean usesFluids, SoundResource aSound, + SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { + this( + aID, + aName, + aNameRegional, + aTier, + aDescription, + aRecipes, + aInputSlots, + aOutputSlots, + usesFluids ? getCapacityForTier(aTier) : 0, + aSound.resourceLocation, + aSpecialEffect, + aOverlays, + aRecipe); + } + + /** + * Registers machine with multi-line descriptions, auto-scaled fluid tank, and sound specified by SoundResource. + */ + public MTEBasicMachineWithRecipe(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, + RecipeMap aRecipes, int aInputSlots, int aOutputSlots, boolean usesFluids, SoundResource aSound, + SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { + this( + aID, + aName, + aNameRegional, + aTier, + aDescription, + aRecipes, + aInputSlots, + aOutputSlots, + usesFluids ? getCapacityForTier(aTier) : 0, + aSound.resourceLocation, + aSpecialEffect, + aOverlays, + aRecipe); + } + + /** + * Registers machine with single-line description, specific tank capacity, and sound specified by SoundResource. + */ + public MTEBasicMachineWithRecipe(int aID, String aName, String aNameRegional, int aTier, String aDescription, + RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, SoundResource aSound, + SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { + this( + aID, + aName, + aNameRegional, + aTier, + aDescription, + aRecipes, + aInputSlots, + aOutputSlots, + aTankCapacity, + aSound.resourceLocation, + aSpecialEffect, + aOverlays, + aRecipe); + } + + /** + * Registers machine with multi-line descriptions, specific tank capacity, and sound specified by SoundResource. + */ + public MTEBasicMachineWithRecipe(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, + RecipeMap aRecipes, int aInputSlots, int aOutputSlots, int aTankCapacity, SoundResource aSound, + SpecialEffects aSpecialEffect, String aOverlays, Object[] aRecipe) { + this( + aID, + aName, + aNameRegional, + aTier, + aDescription, + aRecipes, + aInputSlots, + aOutputSlots, + aTankCapacity, + aSound.resourceLocation, + aSpecialEffect, + aOverlays, + aRecipe); + } + + /** + * For {@link #newMetaEntity}. + */ + public MTEBasicMachineWithRecipe(String aName, int aTier, String[] aDescription, RecipeMap aRecipes, + int aInputSlots, int aOutputSlots, int aTankCapacity, int aAmperage, ITexture[][][] aTextures, + ResourceLocation aSound, SpecialEffects aSpecialEffect) { + super(aName, aTier, aAmperage, aDescription, aTextures, aInputSlots, aOutputSlots); + this.mTankCapacity = aTankCapacity; + this.mSpecialEffect = aSpecialEffect; + this.mRecipes = aRecipes; + this.mSoundResourceLocation = aSound; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEBasicMachineWithRecipe( + this.mName, + this.mTier, + this.mDescriptionArray, + this.mRecipes, + this.mInputSlotCount, + this.mOutputItems == null ? 0 : this.mOutputItems.length, + this.mTankCapacity, + this.mAmperage, + this.mTextures, + this.mSoundResourceLocation, + this.mSpecialEffect).setProgressBarTexture(this.progressBarTexture) + .setRecipeCatalystPriority(this.recipeCatalystPriority); + } + + public MTEBasicMachineWithRecipe setProgressBarTexture(FallbackableUITexture progressBarTexture) { + this.progressBarTexture = progressBarTexture; + return this; + } + + public MTEBasicMachineWithRecipe setProgressBarTextureName(String name, UITexture fallback) { + return setProgressBarTexture(GTUITextures.fallbackableProgressbar(name, fallback)); + } + + public MTEBasicMachineWithRecipe setProgressBarTextureName(String name) { + return setProgressBarTextureName(name, GTUITextures.PROGRESSBAR_ARROW); + } + + @Override + protected boolean allowPutStackValidated(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (!super.allowPutStackValidated(aBaseMetaTileEntity, aIndex, side, aStack)) return false; + switch (this.mInputSlotCount) { + case 0 -> { + return false; + } + case 1 -> { + if (this.getFillableStack() == null) return this.getRecipeMap() + .containsInput(aStack); + else return this.getRecipeMap() + .findRecipe( + this.getBaseMetaTileEntity(), + this.mLastRecipe, + true, + true, + V[this.mTier], + new FluidStack[] { this.getFillableStack() }, + this.getSpecialSlot(), + appendSelectedCircuit(aStack)) + != null; + } + case 2 -> { + return ((this.getInputAt(0) != null && this.getInputAt(1) != null) + || (this.getInputAt(0) == null && this.getInputAt(1) == null ? this.getRecipeMap() + .containsInput(aStack) + : (this.getRecipeMap() + .containsInput(aStack) + && this.getRecipeMap() + .findRecipe( + this.getBaseMetaTileEntity(), + this.mLastRecipe, + true, + true, + V[this.mTier], + new FluidStack[] { this.getFillableStack() }, + this.getSpecialSlot(), + aIndex == this.getInputSlot() ? appendSelectedCircuit(aStack, this.getInputAt(1)) + : appendSelectedCircuit(this.getInputAt(0), aStack)) + != null))); + } + default -> { + int tID = this.getBaseMetaTileEntity() + .getMetaTileID(); + if (tID >= 211 && tID <= 218 || tID >= 1180 && tID <= 1187 || tID >= 10780 && tID <= 10786) { // assembler + // lv-iv; + // circuit + // asseblers + // lv - + // uv; + // assemblers + // luv-uev + if (GTUtility.isStackValid(aStack)) for (int oreID : OreDictionary.getOreIDs(aStack)) { + if (OreDictionary.getOreName(oreID) + .startsWith("circuit")) return true; + } + } + return this.getRecipeMap() + .containsInput(aStack); + } + } + } + + @Override + public boolean allowSelectCircuit() { + return true; + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPreTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isClientSide() && aBaseMetaTileEntity.isActive()) { + // noinspection SwitchStatementWithTooFewBranches + switch (this.mSpecialEffect) { + case TOP_SMOKE -> { + if (aBaseMetaTileEntity.getFrontFacing() != UP && aBaseMetaTileEntity.getCoverIDAtSide(UP) == 0 + && !aBaseMetaTileEntity.getOpacityAtSide(UP)) { + + new ParticleEventBuilder().setMotion(0.0D, 0.0D, 0.0D) + .setIdentifier(ParticleFX.SMOKE) + .setPosition( + aBaseMetaTileEntity.getXCoord() + 0.8F - XSTR_INSTANCE.nextFloat() * 0.6F, + aBaseMetaTileEntity.getYCoord() + 0.9F + XSTR_INSTANCE.nextFloat() * 0.2F, + aBaseMetaTileEntity.getZCoord() + 0.8F - XSTR_INSTANCE.nextFloat() * 0.6F) + .setWorld(aBaseMetaTileEntity.getWorld()) + .run(); + } + } + default -> {} + } + } + } + + /** + * Handles {@link Block#randomDisplayTick} driven Special Effects + * + * @param aBaseMetaTileEntity The entity that will handle the {@see Block#randomDisplayTick} + */ + @SideOnly(Side.CLIENT) + @Override + public void onRandomDisplayTick(IGregTechTileEntity aBaseMetaTileEntity) { + + // noinspection SwitchStatementWithTooFewBranches + switch (this.mSpecialEffect) { + case MAIN_RANDOM_SPARKS -> { + // Random Sparkles at main face + if (aBaseMetaTileEntity.isActive() && XSTR_INSTANCE.nextInt(3) == 0) { + + final ForgeDirection mainFacing = this.mMainFacing; + + if ((mainFacing.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) == 0 + && aBaseMetaTileEntity.getCoverIDAtSide(mainFacing) == 0 + && !aBaseMetaTileEntity.getOpacityAtSide(mainFacing)) { + + final double oX = aBaseMetaTileEntity.getXCoord(); + final double oY = aBaseMetaTileEntity.getYCoord(); + final double oZ = aBaseMetaTileEntity.getZCoord(); + final double offset = 0.02D; + final double horizontal = 0.5D + XSTR_INSTANCE.nextFloat() * 8D / 16D - 4D / 16D; + + final double x, y, z, mX, mZ; + + y = oY + XSTR_INSTANCE.nextFloat() * 10D / 16D + 5D / 16D; + + if (mainFacing == ForgeDirection.WEST) { + x = oX - offset; + mX = -.05D; + z = oZ + horizontal; + mZ = 0D; + } else if (mainFacing == ForgeDirection.EAST) { + x = oX + offset; + mX = .05D; + z = oZ + horizontal; + mZ = 0D; + } else if (mainFacing == ForgeDirection.NORTH) { + x = oX + horizontal; + mX = 0D; + z = oZ - offset; + mZ = -.05D; + } else // if (frontFacing == ForgeDirection.SOUTH.ordinal()) + { + x = oX + horizontal; + mX = 0D; + z = oZ + offset; + mZ = .05D; + } + + ParticleEventBuilder particleEventBuilder = (new ParticleEventBuilder()).setMotion(mX, 0, mZ) + .setPosition(x, y, z) + .setWorld(getBaseMetaTileEntity().getWorld()); + particleEventBuilder.setIdentifier(ParticleFX.LAVA) + .run(); + } + } + } + default -> {} + } + } + + @Override + public RecipeMap getRecipeMap() { + return this.mRecipes; + } + + @Override + public int getRecipeCatalystPriority() { + return recipeCatalystPriority; + } + + public MTEBasicMachineWithRecipe setRecipeCatalystPriority(int recipeCatalystPriority) { + this.recipeCatalystPriority = recipeCatalystPriority; + return this; + } + + @Override + public int getCapacity() { + return this.mTankCapacity; + } + + @Override + public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { + super.startSoundLoop(aIndex, aX, aY, aZ); + if (aIndex == 1 && this.mSoundResourceLocation != null + && GTUtility.isStringValid(this.mSoundResourceLocation.getResourceDomain()) + && GTUtility.isStringValid(this.mSoundResourceLocation.getResourcePath())) + GTUtility.doSoundAtClient(this.mSoundResourceLocation, 100, 1.0F, aX, aY, aZ); + } + + @Override + public void startProcess() { + BaseMetaTileEntity myMetaTileEntity = ((BaseMetaTileEntity) this.getBaseMetaTileEntity()); + // Added to throttle sounds. To reduce lag, this is on the server side so BlockUpdate packets aren't sent. + if (myMetaTileEntity.mTickTimer > (myMetaTileEntity.mLastSoundTick + ticksBetweenSounds)) { + if (this.mSoundResourceLocation != null + && GTUtility.isStringValid(this.mSoundResourceLocation.getResourceDomain()) + && GTUtility.isStringValid(this.mSoundResourceLocation.getResourcePath())) this.sendLoopStart((byte) 1); + // Does not have overflow protection, but they are longs. + myMetaTileEntity.mLastSoundTick = myMetaTileEntity.mTickTimer; + } + } + + @Override + protected BasicUIProperties getUIProperties() { + return super.getUIProperties().toBuilder() + .progressBarTexture(progressBarTexture) + .build(); + } + + public enum X { + PUMP, + WIRE, + WIRE4, + HULL, + PIPE, + GLASS, + PLATE, + MOTOR, + ROTOR, + SENSOR, + PISTON, + CIRCUIT, + EMITTER, + CONVEYOR, + ROBOT_ARM, + COIL_HEATING, + COIL_ELECTRIC, + STICK_MAGNETIC, + STICK_DISTILLATION, + BETTER_CIRCUIT, + FIELD_GENERATOR, + COIL_HEATING_DOUBLE, + STICK_ELECTROMAGNETIC + } + + /** + * Special Effects + */ + public enum SpecialEffects { + + NONE, + TOP_SMOKE, + MAIN_RANDOM_SPARKS; + + static final SpecialEffects[] VALID_SPECIAL_EFFECTS = { NONE, TOP_SMOKE, MAIN_RANDOM_SPARKS }; + + static SpecialEffects fromId(int id) { + return id >= 0 && id < VALID_SPECIAL_EFFECTS.length ? VALID_SPECIAL_EFFECTS[id] : NONE; + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicTank.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicTank.java new file mode 100644 index 0000000000..003b8c893e --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBasicTank.java @@ -0,0 +1,328 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +import com.gtnewhorizons.modularui.api.NumberFormatMUI; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.fluid.FluidStackTank; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.GTUtility; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my generic Tanks. Filling and emptying behavior have to be implemented manually + */ +public abstract class MTEBasicTank extends MTETieredMachineBlock implements IAddUIWidgets { + + public FluidStack mFluid; + // Due to class initializing order, getCapacity might not work properly at this time. + // So we pass supplier instead of current value here. + protected final FluidStackTank fluidTank = new FluidStackTank( + () -> mFluid, + fluidStack -> mFluid = fluidStack, + this::getRealCapacity); + + /** + * @param aInvSlotCount should be 3 + */ + public MTEBasicTank(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEBasicTank(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String[] aDescription, ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEBasicTank(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEBasicTank(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public boolean isSimpleMachine() { + return false; + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex != getStackDisplaySlot(); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + if (mFluid != null) aNBT.setTag("mFluid", mFluid.writeToNBT(new NBTTagCompound())); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + mFluid = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid")); + } + + public abstract boolean doesFillContainers(); + + public abstract boolean doesEmptyContainers(); + + public abstract boolean canTankBeFilled(); + + public abstract boolean canTankBeEmptied(); + + public abstract boolean displaysItemStack(); + + /** + * @return If fluid amount is shown on FluidDisplayItem + */ + public abstract boolean displaysStackSize(); + + public int getInputSlot() { + return 0; + } + + public int getOutputSlot() { + return 1; + } + + public int getStackDisplaySlot() { + return 2; + } + + public boolean isFluidInputAllowed(FluidStack aFluid) { + return true; + } + + public boolean isFluidChangingAllowed() { + return true; + } + + public FluidStack getFillableStack() { + return mFluid; + } + + public FluidStack setFillableStack(FluidStack aFluid) { + mFluid = aFluid; + return mFluid; + } + + /** + * If you override this and change the field returned, be sure to override {@link #isDrainableStackSeparate()} as + * well! + */ + public FluidStack getDrainableStack() { + return mFluid; + } + + public FluidStack setDrainableStack(FluidStack aFluid) { + mFluid = aFluid; + return mFluid; + } + + public boolean isDrainableStackSeparate() { + return false; + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + if (isFluidChangingAllowed() && getFillableStack() != null && getFillableStack().amount <= 0) { + setFillableStack(null); + } + + final int inputSlot = getInputSlot(); + + if (doesEmptyContainers()) { + FluidStack tFluid = GTUtility.getFluidForFilledItem(mInventory[inputSlot], true); + if (tFluid != null && isFluidInputAllowed(tFluid)) { + if (getFillableStack() == null) { + if (isFluidInputAllowed(tFluid) && tFluid.amount <= getCapacity()) { + if (aBaseMetaTileEntity.addStackToSlot( + getOutputSlot(), + GTUtility.getContainerForFilledItem(mInventory[inputSlot], true), + 1)) { + setFillableStack(tFluid.copy()); + this.onEmptyingContainerWhenEmpty(); + aBaseMetaTileEntity.decrStackSize(inputSlot, 1); + } + } + } else { + if (tFluid.isFluidEqual(getFillableStack()) + && ((long) tFluid.amount + getFillableStack().amount) <= (long) getCapacity()) { + if (aBaseMetaTileEntity.addStackToSlot( + getOutputSlot(), + GTUtility.getContainerForFilledItem(mInventory[inputSlot], true), + 1)) { + getFillableStack().amount += tFluid.amount; + aBaseMetaTileEntity.decrStackSize(inputSlot, 1); + } + } + } + } + } + + if (doesFillContainers()) { + ItemStack tOutput = GTUtility + .fillFluidContainer(getDrainableStack(), mInventory[inputSlot], false, true); + if (tOutput != null && aBaseMetaTileEntity.addStackToSlot(getOutputSlot(), tOutput, 1)) { + FluidStack tFluid = GTUtility.getFluidForFilledItem(tOutput, true); + aBaseMetaTileEntity.decrStackSize(inputSlot, 1); + if (tFluid != null) getDrainableStack().amount -= tFluid.amount; + if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) setDrainableStack(null); + } + } + } + } + + @Override + public FluidStack getFluid() { + return getDrainableStack(); + } + + @Override + public int getFluidAmount() { + return getDrainableStack() != null ? getDrainableStack().amount : 0; + } + + @Override + public int fill(FluidStack aFluid, boolean doFill) { + if (aFluid == null || aFluid.getFluid() + .getID() <= 0 || aFluid.amount <= 0 || !canTankBeFilled() || !isFluidInputAllowed(aFluid)) return 0; + + if (getFillableStack() == null || getFillableStack().getFluid() + .getID() <= 0) { + if (aFluid.amount <= getCapacity()) { + if (doFill) { + setFillableStack(aFluid.copy()); + getBaseMetaTileEntity().markDirty(); + } + return aFluid.amount; + } + if (doFill) { + setFillableStack(aFluid.copy()); + getFillableStack().amount = getCapacity(); + getBaseMetaTileEntity().markDirty(); + } + return getCapacity(); + } + + if (!getFillableStack().isFluidEqual(aFluid)) return 0; + + int space = getCapacity() - getFillableStack().amount; + if (aFluid.amount <= space) { + if (doFill) { + getFillableStack().amount += aFluid.amount; + getBaseMetaTileEntity().markDirty(); + } + return aFluid.amount; + } + if (doFill) getFillableStack().amount = getCapacity(); + return space; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (getDrainableStack() == null || !canTankBeEmptied()) return null; + if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) { + setDrainableStack(null); + getBaseMetaTileEntity().markDirty(); + return null; + } + + int used = maxDrain; + if (getDrainableStack().amount < used) used = getDrainableStack().amount; + + if (doDrain) { + getDrainableStack().amount -= used; + getBaseMetaTileEntity().markDirty(); + } + + FluidStack drained = getDrainableStack().copy(); + drained.amount = used; + + if (getDrainableStack().amount <= 0 && isFluidChangingAllowed()) { + setDrainableStack(null); + getBaseMetaTileEntity().markDirty(); + } + + return drained; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection side) { + if (getCapacity() <= 0 && !getBaseMetaTileEntity().hasSteamEngineUpgrade()) return new FluidTankInfo[] {}; + if (isDrainableStackSeparate()) { + return new FluidTankInfo[] { new FluidTankInfo(getFillableStack(), getCapacity()), + new FluidTankInfo(getDrainableStack(), getCapacity()) }; + } else { + return new FluidTankInfo[] { new FluidTankInfo(this) }; + } + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return aIndex == getOutputSlot(); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return aIndex == getInputSlot(); + } + + protected void onEmptyingContainerWhenEmpty() { + // Do nothing + } + + protected static final NumberFormatMUI numberFormat = new NumberFormatMUI(); + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_SCREEN_BLACK) + .setPos(7, 16) + .setSize(71, 45)) + .widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_GAUGE) + .setPos(79, 34) + .setSize(18, 18)) + .widget( + new SlotWidget(inventoryHandler, getInputSlot()) + .setBackground(getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_IN) + .setPos(79, 16)) + .widget( + new SlotWidget(inventoryHandler, getOutputSlot()).setAccess(true, false) + .setBackground(getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_OUT) + .setPos(79, 52)) + .widget( + createFluidSlot().setBackground(GTUITextures.TRANSPARENT) + .setPos(58, 41)) + .widget( + new TextWidget("Liquid Amount").setDefaultColor(COLOR_TEXT_WHITE.get()) + .setPos(10, 20)) + .widget( + new TextWidget().setStringSupplier(() -> numberFormat.format(mFluid != null ? mFluid.amount : 0)) + .setDefaultColor(COLOR_TEXT_WHITE.get()) + .setPos(10, 30)); + } + + protected FluidSlotWidget createFluidSlot() { + return new FluidSlotWidget(fluidTank); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java new file mode 100644 index 0000000000..c8b4e6bfca --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java @@ -0,0 +1,559 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_DOWN; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_DOWN_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_LEFT; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_LEFT_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_RIGHT; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_RIGHT_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_UP; +import static gregtech.api.enums.Textures.BlockIcons.ARROW_UP_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.MACHINE_CASINGS; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; +import com.gtnewhorizons.modularui.common.widget.SlotGroup; + +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GT_TooltipDataCache; + +public abstract class MTEBuffer extends MTETieredMachineBlock implements IAddUIWidgets { + + private static final int OUTPUT_INDEX = 0; + private static final int ARROW_RIGHT_INDEX = 1; + private static final int ARROW_DOWN_INDEX = 2; + private static final int ARROW_LEFT_INDEX = 3; + private static final int ARROW_UP_INDEX = 4; + private static final int FRONT_INDEX = 5; + + private static final String EMIT_ENERGY_TOOLTIP = "GT5U.machines.emit_energy.tooltip"; + private static final String EMIT_REDSTONE_IF_FULL_TOOLTIP = "GT5U.machines.emit_redstone_if_full.tooltip"; + private static final String INVERT_REDSTONE_TOOLTIP = "GT5U.machines.invert_redstone.tooltip"; + private static final String STOCKING_MODE_TOOLTIP = "GT5U.machines.buffer_stocking_mode.tooltip"; + private static final String SORTING_MODE_TOOLTIP = "GT5U.machines.sorting_mode.tooltip"; + private static final int BUTTON_SIZE = 18; + + public int mMaxStackSize = 64; + public static int MAX = 8; + public boolean bOutput = false, bRedstoneIfFull = false, bInvert = false, bStockingMode = false, + bSortStacks = false; + public int mSuccess = 0, mTargetStackSize = 0; + private int uiButtonCount = 0; + + public MTEBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public MTEBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public MTEBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[ForgeDirection.VALID_DIRECTIONS.length][17][]; + ITexture tIcon = getOverlayIcon(); + ITexture tOut = TextureFactory.of(OVERLAY_PIPE_OUT); + ITexture tUp = TextureFactory.of( + TextureFactory.of(ARROW_UP), + TextureFactory.builder() + .addIcon(ARROW_UP_GLOW) + .glow() + .build()); + ITexture tDown = TextureFactory.of( + TextureFactory.of(ARROW_DOWN), + TextureFactory.builder() + .addIcon(ARROW_DOWN_GLOW) + .glow() + .build()); + ITexture tLeft = TextureFactory.of( + TextureFactory.of(ARROW_LEFT), + TextureFactory.builder() + .addIcon(ARROW_LEFT_GLOW) + .glow() + .build()); + ITexture tRight = TextureFactory.of( + TextureFactory.of(ARROW_RIGHT), + TextureFactory.builder() + .addIcon(ARROW_RIGHT_GLOW) + .glow() + .build()); + for (int i = 0; i < rTextures[0].length; i++) { + rTextures[OUTPUT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tOut }; + rTextures[ARROW_RIGHT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tRight, tIcon }; + rTextures[ARROW_DOWN_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tDown, tIcon }; + rTextures[ARROW_LEFT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tLeft, tIcon }; + rTextures[ARROW_UP_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tUp, tIcon }; + rTextures[FRONT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tIcon }; + } + return rTextures; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, + ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { + colorIndex = colorIndex + 1; + if (sideDirection == facingDirection) return mTextures[FRONT_INDEX][colorIndex]; + if (sideDirection.getOpposite() == facingDirection) return mTextures[OUTPUT_INDEX][colorIndex]; + switch (facingDirection) { + case DOWN -> { + return mTextures[ARROW_UP_INDEX][colorIndex]; // ARROW_UP + } + case UP -> { + return mTextures[ARROW_DOWN_INDEX][colorIndex]; // ARROW_DOWN + } + case NORTH -> { + switch (sideDirection) { + case DOWN, UP -> { + return mTextures[ARROW_DOWN_INDEX][colorIndex]; // ARROW_DOWN + } + case WEST -> { + return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT + } + case EAST -> { + return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT + } + default -> {} + } + } + case SOUTH -> { + switch (sideDirection) { + case DOWN, UP -> { + return mTextures[ARROW_UP_INDEX][colorIndex]; // ARROW_UP + } + case WEST -> { + return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT + } + case EAST -> { + return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT + } + default -> {} + } + } + case WEST -> { + switch (sideDirection) { + case UP, SOUTH -> { + return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT + } + case DOWN, NORTH -> { + return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT + } + default -> {} + } + } + case EAST -> { + switch (sideDirection) { + case UP, SOUTH -> { + return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT + } + case DOWN, NORTH -> { + return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT + } + default -> {} + } + } + default -> {} + } + return mTextures[FRONT_INDEX][colorIndex]; + } + + @Override + public boolean isSimpleMachine() { + return false; + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex < mInventory.length - 1; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return !isOutputFacing(side); + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return getBaseMetaTileEntity().getBackFacing() == side; + } + + @Override + public boolean isTeleporterCompatible() { + return false; + } + + @Override + public long getMinimumStoredEU() { + return 512L; + } + + @Override + public long maxEUStore() { + return 512L + V[mTier] * 50L; + } + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxEUOutput() { + // Return full value if we're an item and don't exist in the world for tooltip purposes + return getBaseMetaTileEntity().getWorld() == null || bOutput ? V[mTier] : 0L; + } + + @Override + public long maxAmperesIn() { + return 2; + } + + @Override + public long maxAmperesOut() { + return 2; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + public abstract ITexture getOverlayIcon(); + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setBoolean("bInvert", bInvert); + aNBT.setBoolean("bOutput", bOutput); + aNBT.setBoolean("bRedstoneIfFull", bRedstoneIfFull); + aNBT.setBoolean("bStockingMode", bStockingMode); + aNBT.setInteger("mTargetStackSize", mTargetStackSize); + aNBT.setBoolean("bSortStacks", bSortStacks); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + bInvert = aNBT.getBoolean("bInvert"); + bOutput = aNBT.getBoolean("bOutput"); + bRedstoneIfFull = aNBT.getBoolean("bRedstoneIfFull"); + bSortStacks = aNBT.getBoolean("bSortStacks"); + bStockingMode = aNBT.getBoolean("bStockingMode"); + mTargetStackSize = aNBT.getInteger("mTargetStackSize"); + } + + @Override + public void setItemNBT(NBTTagCompound aNBT) { + super.setItemNBT(aNBT); + if (mTargetStackSize > 0) aNBT.setInteger("mTargetStackSize", mTargetStackSize); + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (side == getBaseMetaTileEntity().getBackFacing()) { + + mTargetStackSize = (byte) ((mTargetStackSize + (aPlayer.isSneaking() ? -1 : 1)) % 65); + if (mTargetStackSize < 0) { + mTargetStackSize = mMaxStackSize; + } + if (mTargetStackSize == 0) { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("098", "Do not regulate Item Stack Size")); + } else { + GTUtility.sendChatToPlayer( + aPlayer, + GTUtility.trans("099", "Regulate Item Stack Size to: ") + mTargetStackSize); + } + } + } + + @Override + public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, + float aX, float aY, float aZ) { + wrenchingSide = wrenchingSide.getOpposite(); + if (getBaseMetaTileEntity().isValidFacing(wrenchingSide)) { + getBaseMetaTileEntity().setFrontFacing(wrenchingSide); + return true; + } + return false; + } + + protected void handleRedstoneOutput(IGregTechTileEntity aBaseMetaTileEntity) { + int redstoneOutput = getRedstoneOutput(); + Arrays.stream(ForgeDirection.VALID_DIRECTIONS) + .forEach(side -> aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) redstoneOutput)); + } + + protected int getRedstoneOutput() { + return (!bRedstoneIfFull || (bInvert ^ hasEmptySlots())) ? 0 : 15; + } + + private boolean hasEmptySlots() { + return IntStream.range(0, mInventory.length) + .anyMatch(i -> isValidSlot(i) && mInventory[i] == null); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + if (aBaseMetaTileEntity.isAllowedToWork() && aBaseMetaTileEntity.isServerSide() + && (aBaseMetaTileEntity.hasWorkJustBeenEnabled() || aBaseMetaTileEntity.hasInventoryBeenModified() + || aTimer % 200 == 0 + || mSuccess > 0)) { + mSuccess--; + updateSlots(); + moveItems(aBaseMetaTileEntity, aTimer); + handleRedstoneOutput(aBaseMetaTileEntity); + } + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) + aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) 0); + } + + protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + moveItems(aBaseMetaTileEntity, aTimer, 1); + } + + protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long ignoredTimer, int stacks) { + int tCost; + if (bStockingMode) tCost = GTUtility.moveMultipleItemStacks( + aBaseMetaTileEntity, + aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getBackFacing()), + aBaseMetaTileEntity.getBackFacing(), + aBaseMetaTileEntity.getFrontFacing(), + null, + false, + mTargetStackSize == 0 ? 64 : (byte) mTargetStackSize, + mTargetStackSize == 0 ? 1 : (byte) mTargetStackSize, + (byte) 64, + (byte) 1, + stacks); + else tCost = GTUtility.moveMultipleItemStacks( + aBaseMetaTileEntity, + aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getBackFacing()), + aBaseMetaTileEntity.getBackFacing(), + aBaseMetaTileEntity.getFrontFacing(), + null, + false, + (byte) 64, + (byte) 1, + mTargetStackSize == 0 ? 64 : (byte) mTargetStackSize, + mTargetStackSize == 0 ? 1 : (byte) mTargetStackSize, + stacks); + + if (tCost > 0 || aBaseMetaTileEntity.hasInventoryBeenModified()) { + mSuccess = 50; + } + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return true; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side != aBaseMetaTileEntity.getBackFacing(); + } + + @Override + public boolean allowGeneralRedstoneOutput() { + return true; + } + + public void updateSlots() { + for (int i = 0; i < mInventory.length; i++) + if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; + if (bSortStacks) fillStacksIntoFirstSlots(); + } + + protected void fillStacksIntoFirstSlots() { + HashMap slots = new HashMap<>(mInventory.length); + HashMap stacks = new HashMap<>(mInventory.length); + List order = new ArrayList<>(mInventory.length); + List validSlots = new ArrayList<>(mInventory.length); + for (int i = 0; i < mInventory.length - 1; i++) { + if (!isValidSlot(i)) continue; + validSlots.add(i); + ItemStack s = mInventory[i]; + if (s == null) continue; + GTUtility.ItemId sID = GTUtility.ItemId.createNoCopy(s); + slots.merge(sID, s.stackSize, Integer::sum); + if (!stacks.containsKey(sID)) stacks.put(sID, s); + order.add(sID); + mInventory[i] = null; + } + int slotindex = 0; + for (GTUtility.ItemId sID : order) { + int toSet = slots.get(sID); + if (toSet == 0) continue; + int slot = validSlots.get(slotindex); + slotindex++; + mInventory[slot] = stacks.get(sID) + .copy(); + toSet = Math.min(toSet, mInventory[slot].getMaxStackSize()); + mInventory[slot].stackSize = toSet; + slots.merge(sID, toSet, (a, b) -> a - b); + } + } + + @Override + public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, + EntityPlayer entityPlayer, float aX, float aY, float aZ) { + if (entityPlayer.isSneaking()) { + // I was so proud of all this but I literally just copied code from OutputBus + bSortStacks = !bSortStacks; + GTUtility.sendChatToPlayer( + entityPlayer, + GTUtility.trans("200", "Sort mode: ") + + (bSortStacks ? GTUtility.trans("088", "Enabled") : GTUtility.trans("087", "Disabled"))); + return true; + } + return super.onSolderingToolRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); + } + + protected void addEmitEnergyButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> bOutput, + val -> bOutput = val, + GTUITextures.OVERLAY_BUTTON_EMIT_ENERGY, + this::getEmitEnergyButtonTooltip)); + } + + private GT_TooltipDataCache.TooltipData getEmitEnergyButtonTooltip() { + return mTooltipCache.getData( + EMIT_ENERGY_TOOLTIP, + EnumChatFormatting.GREEN + GTUtility.formatNumbers(V[mTier]) + + " (" + + GTUtility.getColoredTierNameFromTier(mTier) + + EnumChatFormatting.GREEN + + ")" + + EnumChatFormatting.GRAY, + maxAmperesOut()); + } + + protected void addEmitRedstoneIfFullButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> bRedstoneIfFull, + val -> bRedstoneIfFull = val, + GTUITextures.OVERLAY_BUTTON_EMIT_REDSTONE, + this::getEmitRedstoneIfFullButtonTooltip).setUpdateTooltipEveryTick(true)); + } + + private GT_TooltipDataCache.TooltipData getEmitRedstoneIfFullButtonTooltip() { + return mTooltipCache.getUncachedTooltipData( + EMIT_REDSTONE_IF_FULL_TOOLTIP, + StatCollector.translateToLocal(hasEmptySlots() ? "gui.yes" : "gui.no"), + getRedstoneOutput()); + } + + protected void addInvertRedstoneButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> bInvert, + val -> bInvert = val, + GTUITextures.OVERLAY_BUTTON_INVERT_REDSTONE, + () -> mTooltipCache.getData(INVERT_REDSTONE_TOOLTIP))); + } + + protected void addStockingModeButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> bStockingMode, + val -> bStockingMode = val, + GTUITextures.OVERLAY_BUTTON_STOCKING_MODE, + () -> mTooltipCache.getData(STOCKING_MODE_TOOLTIP))); + } + + protected void addSortStacksButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> bSortStacks, + val -> bSortStacks = val, + GTUITextures.OVERLAY_BUTTON_SORTING_MODE, + () -> mTooltipCache.getData(SORTING_MODE_TOOLTIP))); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + buildContext.addCloseListener(() -> uiButtonCount = 0); + addEmitEnergyButton(builder); + } + + protected Widget createToggleButton(Supplier getter, Consumer setter, UITexture picture, + Supplier tooltipDataSupplier) { + return new CycleButtonWidget().setToggle(getter, setter) + .setStaticTexture(picture) + .setVariableBackground(GTUITextures.BUTTON_STANDARD_TOGGLE) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(7 + (uiButtonCount++ * BUTTON_SIZE), 62) + .setSize(BUTTON_SIZE, BUTTON_SIZE) + .setGTTooltip(tooltipDataSupplier); + } + + protected void addInventorySlots(ModularWindow.Builder builder) { + builder.widget( + SlotGroup.ofItemHandler(inventoryHandler, 9) + .endAtSlot(26) + .build() + .setPos(7, 4)); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTECable.java b/src/main/java/gregtech/api/metatileentity/implementations/MTECable.java new file mode 100644 index 0000000000..b56769c59b --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTECable.java @@ -0,0 +1,649 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Mods.GalacticraftCore; +import static net.minecraftforge.common.util.ForgeDirection.DOWN; +import static net.minecraftforge.common.util.ForgeDirection.EAST; +import static net.minecraftforge.common.util.ForgeDirection.NORTH; +import static net.minecraftforge.common.util.ForgeDirection.SOUTH; +import static net.minecraftforge.common.util.ForgeDirection.UP; +import static net.minecraftforge.common.util.ForgeDirection.WEST; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import cofh.api.energy.IEnergyReceiver; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.Materials; +import gregtech.api.enums.TextureSet; +import gregtech.api.enums.Textures; +import gregtech.api.graphs.Node; +import gregtech.api.graphs.NodeList; +import gregtech.api.graphs.PowerNode; +import gregtech.api.graphs.PowerNodes; +import gregtech.api.graphs.consumers.ConsumerNode; +import gregtech.api.graphs.paths.PowerNodePath; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IConnectable; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.metatileentity.IMetaTileEntityCable; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IEnergyConnected; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.logic.interfaces.PowerLogicHost; +import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gregtech.api.metatileentity.MetaPipeEntity; +import gregtech.api.objects.GTCoverNone; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTGCCompat; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; +import gregtech.api.util.ISerializableObject; +import gregtech.common.GTClient; +import gregtech.common.covers.CoverInfo; +import gregtech.common.covers.CoverSolarPanel; +import ic2.api.energy.EnergyNet; +import ic2.api.energy.tile.IEnergyEmitter; +import ic2.api.energy.tile.IEnergySink; +import ic2.api.energy.tile.IEnergySource; +import ic2.api.energy.tile.IEnergyTile; +import ic2.api.reactor.IReactorChamber; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +public class MTECable extends MetaPipeEntity implements IMetaTileEntityCable { + + public final float mThickNess; + public final Materials mMaterial; + public final long mCableLossPerMeter, mAmperage, mVoltage; + public final boolean mInsulated, mCanShock; + + public int mTransferredAmperage = 0; + + public MTECable(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, + long aCableLossPerMeter, long aAmperage, long aVoltage, boolean aInsulated, boolean aCanShock) { + super(aID, aName, aNameRegional, 0); + mThickNess = aThickNess; + mMaterial = aMaterial; + mAmperage = aAmperage; + mVoltage = aVoltage; + mInsulated = aInsulated; + mCanShock = aCanShock; + mCableLossPerMeter = aCableLossPerMeter; + } + + public MTECable(String aName, float aThickNess, Materials aMaterial, long aCableLossPerMeter, long aAmperage, + long aVoltage, boolean aInsulated, boolean aCanShock) { + super(aName, 0); + mThickNess = aThickNess; + mMaterial = aMaterial; + mAmperage = aAmperage; + mVoltage = aVoltage; + mInsulated = aInsulated; + mCanShock = aCanShock; + mCableLossPerMeter = aCableLossPerMeter; + } + + @Override + public byte getTileEntityBaseType() { + return (byte) (mInsulated ? 9 : 8); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTECable( + mName, + mThickNess, + mMaterial, + mCableLossPerMeter, + mAmperage, + mVoltage, + mInsulated, + mCanShock); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, + int facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { + if (!mInsulated) return new ITexture[] { TextureFactory + .of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], Dyes.getModulation(colorIndex, mMaterial.mRGBa)) }; + if (active) { + float tThickNess = getThickNess(); + if (tThickNess < 0.124F) return new ITexture[] { TextureFactory + .of(Textures.BlockIcons.INSULATION_FULL, Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + if (tThickNess < 0.374F) // 0.375 x1 + return new ITexture[] { + TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), + TextureFactory.of( + Textures.BlockIcons.INSULATION_TINY, + Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + if (tThickNess < 0.499F) // 0.500 x2 + return new ITexture[] { + TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), + TextureFactory.of( + Textures.BlockIcons.INSULATION_SMALL, + Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + if (tThickNess < 0.624F) // 0.625 x4 + return new ITexture[] { + TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), + TextureFactory.of( + Textures.BlockIcons.INSULATION_MEDIUM, + Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + if (tThickNess < 0.749F) // 0.750 x8 + return new ITexture[] { + TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), + TextureFactory.of( + Textures.BlockIcons.INSULATION_MEDIUM_PLUS, + Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + if (tThickNess < 0.874F) // 0.825 x12 + return new ITexture[] { + TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), + TextureFactory.of( + Textures.BlockIcons.INSULATION_LARGE, + Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + return new ITexture[] { + TextureFactory.of(mMaterial.mIconSet.mTextures[TextureSet.INDEX_wire], mMaterial.mRGBa), + TextureFactory.of( + Textures.BlockIcons.INSULATION_HUGE, + Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + } + return new ITexture[] { TextureFactory + .of(Textures.BlockIcons.INSULATION_FULL, Dyes.getModulation(colorIndex, Dyes.CABLE_INSULATION.mRGBa)) }; + } + + @Override + public void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity aEntity) { + + if (!mCanShock) return; + + final BaseMetaPipeEntity baseEntity = (BaseMetaPipeEntity) getBaseMetaTileEntity(); + + if (!(aEntity instanceof EntityLivingBase livingEntity)) return; + if (!(baseEntity.getNodePath() instanceof PowerNodePath powerPath)) return; + + if (isCoverOnSide(baseEntity, livingEntity)) return; + if ((baseEntity.mConnections & IConnectable.HAS_HARDENEDFOAM) == 1) return; + + final long amperage = powerPath.getAmperage(); + final long voltage = powerPath.getVoltage(); + + if (amperage == 0L) return; + + GTUtility.applyElectricityDamage(livingEntity, voltage, amperage); + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return false; + } + + @Override + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public final boolean renderInside(ForgeDirection side) { + return false; + } + + @Override + public int getProgresstime() { + return (int) mTransferredAmperage * 64; + } + + @Override + public int maxProgresstime() { + return (int) mAmperage * 64; + } + + @Override + public long injectEnergyUnits(ForgeDirection side, long voltage, long amperage) { + if (!isConnectedAtSide(side) && side != ForgeDirection.UNKNOWN) return 0; + if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) + .letsEnergyIn()) return 0; + return transferElectricity(side, voltage, amperage, (HashSet) null); + } + + @Override + @Deprecated + public long transferElectricity(ForgeDirection side, long aVoltage, long aAmperage, + ArrayList aAlreadyPassedTileEntityList) { + return transferElectricity(side, aVoltage, aAmperage, new HashSet<>(aAlreadyPassedTileEntityList)); + } + + @Override + public long transferElectricity(ForgeDirection side, long voltage, long amperage, + HashSet alreadyPassedSet) { + if (!getBaseMetaTileEntity().isServerSide() || !isConnectedAtSide(side) && side != ForgeDirection.UNKNOWN) + return 0; + final BaseMetaPipeEntity tBase = (BaseMetaPipeEntity) getBaseMetaTileEntity(); + if (!(tBase.getNode() instanceof PowerNode tNode)) return 0; + int tPlace = 0; + final Node[] tToPower = new Node[tNode.mConsumers.size()]; + if (tNode.mHadVoltage) { + for (ConsumerNode consumer : tNode.mConsumers) { + if (consumer.needsEnergy()) tToPower[tPlace++] = consumer; + } + } else { + tNode.mHadVoltage = true; + for (ConsumerNode consumer : tNode.mConsumers) { + tToPower[tPlace++] = consumer; + } + } + return PowerNodes.powerNode(tNode, null, new NodeList(tToPower), (int) voltage, (int) amperage); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aTick % 20 == 0 && aBaseMetaTileEntity.isServerSide() + && (!GTMod.gregtechproxy.gt6Cable || mCheckConnections)) { + checkConnections(); + } + } + + @Override + public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (GTMod.gregtechproxy.gt6Cable + && GTModHandler.damageOrDechargeItem(aPlayer.inventory.getCurrentItem(), 1, 500, aPlayer)) { + if (isConnectedAtSide(wrenchingSide)) { + disconnect(wrenchingSide); + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("215", "Disconnected")); + } else if (!GTMod.gregtechproxy.costlyCableConnection) { + if (connect(wrenchingSide) > 0) + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("214", "Connected")); + } + return true; + } + return false; + } + + @Override + public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer, + float aX, float aY, float aZ) { + if (GTMod.gregtechproxy.gt6Cable + && GTModHandler.damageOrDechargeItem(aPlayer.inventory.getCurrentItem(), 1, 500, aPlayer)) { + if (isConnectedAtSide(wrenchingSide)) { + disconnect(wrenchingSide); + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("215", "Disconnected")); + } else if (!GTMod.gregtechproxy.costlyCableConnection || GTModHandler.consumeSolderingMaterial(aPlayer)) { + if (connect(wrenchingSide) > 0) + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("214", "Connected")); + } + return true; + } + return false; + } + + @Override + public boolean letsIn(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return coverBehavior.letsEnergyIn(side, aCoverID, aCoverVariable, aTileEntity); + } + + @Override + public boolean letsOut(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return coverBehavior.letsEnergyOut(side, aCoverID, aCoverVariable, aTileEntity); + } + + @Override + public boolean letsIn(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return coverBehavior.letsEnergyIn(side, aCoverID, aCoverVariable, aTileEntity); + } + + @Override + public boolean letsOut(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return coverBehavior.letsEnergyOut(side, aCoverID, aCoverVariable, aTileEntity); + } + + @Override + public boolean letsIn(CoverInfo coverInfo) { + return coverInfo.letsEnergyIn(); + } + + @Override + public boolean letsOut(CoverInfo coverInfo) { + return coverInfo.letsEnergyOut(); + } + + @Override + public boolean canConnect(ForgeDirection side, TileEntity tileEntity) { + final IGregTechTileEntity baseMetaTile = getBaseMetaTileEntity(); + final CoverBehaviorBase coverBehavior = baseMetaTile.getCoverBehaviorAtSideNew(side); + final ForgeDirection oppositeSide = side.getOpposite(); + + // GT Machine handling + if ((tileEntity instanceof PowerLogicHost powerLogic && powerLogic.getPowerLogic(oppositeSide) != null) + || ((tileEntity instanceof IEnergyConnected energyConnected) + && (energyConnected.inputEnergyFrom(oppositeSide, false) + || energyConnected.outputsEnergyTo(oppositeSide, false)))) + return true; + + // Solar Panel Compat + if (coverBehavior instanceof CoverSolarPanel) return true; + + // ((tIsGregTechTileEntity && tIsTileEntityCable) && (tAlwaysLookConnected || tLetEnergyIn || tLetEnergyOut) ) + // --> Not needed + if (GalacticraftCore.isModLoaded() && GTGCCompat.canConnect(tileEntity, oppositeSide)) return true; + + // AE2-p2p Compat + if (tileEntity instanceof appeng.tile.powersink.IC2 ic2sink + && ic2sink.acceptsEnergyFrom((TileEntity) baseMetaTile, oppositeSide)) return true; + + // IC2 Compat + { + final TileEntity ic2Energy; + + if (tileEntity instanceof IReactorChamber) + ic2Energy = (TileEntity) ((IReactorChamber) tileEntity).getReactor(); + else ic2Energy = (tileEntity == null || tileEntity instanceof IEnergyTile || EnergyNet.instance == null) + ? tileEntity + : EnergyNet.instance + .getTileEntity(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord); + + // IC2 Sink Compat + if ((ic2Energy instanceof IEnergySink) + && ((IEnergySink) ic2Energy).acceptsEnergyFrom((TileEntity) baseMetaTile, oppositeSide)) return true; + + // IC2 Source Compat + if (GTMod.gregtechproxy.ic2EnergySourceCompat && (ic2Energy instanceof IEnergySource)) { + if (((IEnergySource) ic2Energy).emitsEnergyTo((TileEntity) baseMetaTile, oppositeSide)) { + return true; + } + } + } + // RF Output Compat + if (GregTechAPI.mOutputRF && tileEntity instanceof IEnergyReceiver + && ((IEnergyReceiver) tileEntity).canConnectEnergy(oppositeSide)) return true; + + // RF Input Compat + return GregTechAPI.mInputRF && (tileEntity instanceof IEnergyEmitter + && ((IEnergyEmitter) tileEntity).emitsEnergyTo((TileEntity) baseMetaTile, oppositeSide)); + } + + @Override + public boolean getGT6StyleConnection() { + // Yes if GT6 Cables are enabled + return GTMod.gregtechproxy.gt6Cable; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public String[] getDescription() { + return new String[] { + StatCollector.translateToLocal("GT5U.item.cable.max_voltage") + ": %%%" + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(mVoltage) + + " (" + + GTUtility.getColoredTierNameFromVoltage(mVoltage) + + EnumChatFormatting.GREEN + + ")" + + EnumChatFormatting.GRAY, + StatCollector.translateToLocal("GT5U.item.cable.max_amperage") + ": %%%" + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mAmperage) + + EnumChatFormatting.GRAY, + StatCollector.translateToLocal("GT5U.item.cable.loss") + ": %%%" + + EnumChatFormatting.RED + + GTUtility.formatNumbers(mCableLossPerMeter) + + EnumChatFormatting.GRAY + + "%%% " + + StatCollector.translateToLocal("GT5U.item.cable.eu_volt") }; + } + + @Override + public float getThickNess() { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x1) != 0) return 0.0625F; + return mThickNess; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + if (GTMod.gregtechproxy.gt6Cable) aNBT.setByte("mConnections", mConnections); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + if (GTMod.gregtechproxy.gt6Cable) { + mConnections = aNBT.getByte("mConnections"); + } + } + + @Override + public boolean isGivingInformation() { + return true; + } + + @Override + public String[] getInfoData() { + final BaseMetaPipeEntity base = (BaseMetaPipeEntity) getBaseMetaTileEntity(); + final PowerNodePath path = (PowerNodePath) base.getNodePath(); + + if (path == null) + return new String[] { EnumChatFormatting.RED + "Failed to get Power Node info" + EnumChatFormatting.RESET }; + + final long currAmp = path.getAmperage(); + final long currVoltage = path.getVoltage(); + + final double avgAmp = path.getAvgAmperage(); + final double avgVoltage = path.getAvgVoltage(); + + final long maxVoltageOut = (mVoltage - mCableLossPerMeter) * mAmperage; + + return new String[] { + "Amperage: " + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(currAmp) + + EnumChatFormatting.RESET + + " / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mAmperage) + + EnumChatFormatting.RESET + + " A", + "Voltage Out: " + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(currVoltage) + + EnumChatFormatting.RESET + + " / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(maxVoltageOut) + + EnumChatFormatting.RESET + + " EU/t", + "Avg Amperage (20t): " + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(avgAmp) + + EnumChatFormatting.RESET + + " A", + "Avg Output (20t): " + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(avgVoltage) + + EnumChatFormatting.RESET + + " EU/t" }; + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x2) != 0) + return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1); + else return getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); + } + + private AxisAlignedBB getActualCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { + float tSpace = (1f - mThickNess) / 2; + float spaceDown = tSpace; + float spaceUp = 1f - tSpace; + float spaceNorth = tSpace; + float spaceSouth = 1f - tSpace; + float spaceWest = tSpace; + float spaceEast = 1f - tSpace; + + if (getBaseMetaTileEntity().getCoverIDAtSide(DOWN) != 0) { + spaceDown = spaceNorth = spaceWest = 0; + spaceSouth = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(UP) != 0) { + spaceNorth = spaceWest = 0; + spaceUp = spaceSouth = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(NORTH) != 0) { + spaceDown = spaceNorth = spaceWest = 0; + spaceUp = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(SOUTH) != 0) { + spaceDown = spaceWest = 0; + spaceUp = spaceSouth = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(WEST) != 0) { + spaceDown = spaceNorth = spaceWest = 0; + spaceUp = spaceSouth = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(EAST) != 0) { + spaceDown = spaceNorth = 0; + spaceUp = spaceSouth = spaceEast = 1; + } + + byte tConn = ((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections; + if ((tConn & DOWN.flag) != 0) spaceDown = 0f; + if ((tConn & UP.flag) != 0) spaceUp = 1f; + if ((tConn & NORTH.flag) != 0) spaceNorth = 0f; + if ((tConn & SOUTH.flag) != 0) spaceSouth = 1f; + if ((tConn & WEST.flag) != 0) spaceWest = 0f; + if ((tConn & EAST.flag) != 0) spaceEast = 1f; + + return AxisAlignedBB.getBoundingBox( + aX + spaceWest, + aY + spaceDown, + aZ + spaceNorth, + aX + spaceEast, + aY + spaceUp, + aZ + spaceSouth); + } + + @Override + public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, + List outputAABB, Entity collider) { + super.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider); + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x2) != 0) { + final AxisAlignedBB aabb = getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); + if (inputAABB.intersectsWith(aabb)) outputAABB.add(aabb); + } + } + + @Override + public boolean shouldJoinIc2Enet() { + if (!GTMod.gregtechproxy.ic2EnergySourceCompat) return false; + + if (mConnections != 0) { + final IGregTechTileEntity baseMeta = getBaseMetaTileEntity(); + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (isConnectedAtSide(side)) { + final TileEntity tTileEntity = baseMeta.getTileEntityAtSide(side); + final TileEntity tEmitter = (tTileEntity == null || tTileEntity instanceof IEnergyTile + || EnergyNet.instance == null) + ? tTileEntity + : EnergyNet.instance.getTileEntity( + tTileEntity.getWorldObj(), + tTileEntity.xCoord, + tTileEntity.yCoord, + tTileEntity.zCoord); + + if (tEmitter instanceof IEnergyEmitter) return true; + } + } + } + return false; + } + + @Override + public void reloadLocks() { + final BaseMetaPipeEntity pipe = (BaseMetaPipeEntity) getBaseMetaTileEntity(); + if (pipe.getNode() != null) { + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (isConnectedAtSide(side)) { + final CoverInfo coverInfo = pipe.getCoverInfoAtSide(side); + if (coverInfo.getCoverBehavior() instanceof GTCoverNone) continue; + if (!letsIn(coverInfo) || !letsOut(coverInfo)) { + pipe.addToLock(pipe, side); + } else { + pipe.removeFromLock(pipe, side); + } + } + } + } else { + boolean dontAllow = false; + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (isConnectedAtSide(side)) { + final CoverInfo coverInfo = pipe.getCoverInfoAtSide(side); + if (coverInfo.getCoverBehavior() instanceof GTCoverNone) continue; + + if (!letsIn(coverInfo) || !letsOut(coverInfo)) { + dontAllow = true; + } + } + } + if (dontAllow) { + pipe.addToLock(pipe, DOWN); + } else { + pipe.removeFromLock(pipe, DOWN); + } + } + } + + @Override + public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + + currenttip.add( + StatCollector.translateToLocal("GT5U.item.cable.max_voltage") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(mVoltage) + + " (" + + GTUtility.getColoredTierNameFromVoltage(mVoltage) + + EnumChatFormatting.GREEN + + ")"); + currenttip.add( + StatCollector.translateToLocal("GT5U.item.cable.max_amperage") + ": " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mAmperage)); + currenttip.add( + StatCollector.translateToLocal("GT5U.item.cable.loss") + ": " + + EnumChatFormatting.RED + + GTUtility.formatNumbers(mCableLossPerMeter) + + EnumChatFormatting.RESET + + " " + + StatCollector.translateToLocal("GT5U.item.cable.eu_volt")); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTECubicMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTECubicMultiBlockBase.java new file mode 100644 index 0000000000..c8b0c8ce3f --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTECubicMultiBlockBase.java @@ -0,0 +1,141 @@ +package gregtech.api.metatileentity.implementations; + +import static com.gtnewhorizon.structurelib.structure.StructureUtility.lazy; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; +import static gregtech.api.enums.HatchElement.Energy; +import static gregtech.api.enums.HatchElement.InputBus; +import static gregtech.api.enums.HatchElement.InputHatch; +import static gregtech.api.enums.HatchElement.Maintenance; +import static gregtech.api.enums.HatchElement.Muffler; +import static gregtech.api.enums.HatchElement.OutputBus; +import static gregtech.api.enums.HatchElement.OutputHatch; + +import java.util.List; + +import net.minecraft.item.ItemStack; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import gregtech.api.interfaces.IHatchElement; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.GTStructureUtility; + +/** + * A simple 3x3x3 hollow cubic multiblock, that can be arbitrarily rotated, made of a single type of machine casing and + * accepts hatches everywhere. Controller will be placed in front center of the structure. + *

+ * Note: You cannot use different casing for the same Class. Make a new subclass for it. You also should not change the + * casing dynamically, i.e. it should be a dumb method returning some sort of constant. + *

+ * Implementation tips: 1. To restrict hatches, override {@link #addDynamoToMachineList(IGregTechTileEntity, int)} and + * its cousins instead of overriding the whole {@link #getStructureDefinition()} or change + * {@link #checkHatches(IGregTechTileEntity, ItemStack)}. The former is a total overkill, while the later cannot stop + * the structure check early. 2. To limit rotation, override {@link #getInitialAlignmentLimits()} + * + * @param + */ +public abstract class MTECubicMultiBlockBase> extends MTEEnhancedMultiBlockBase + implements ISurvivalConstructable { + + protected static final String STRUCTURE_PIECE_MAIN = "main"; + protected static final ClassValue>> STRUCTURE_DEFINITION = new ClassValue<>() { + + @Override + protected IStructureDefinition> computeValue(Class type) { + return StructureDefinition.>builder() + .addShape( + STRUCTURE_PIECE_MAIN, + transpose( + new String[][] { { "hhh", "hhh", "hhh" }, { "h~h", "h-h", "hhh" }, { "hhh", "hhh", "hhh" }, })) + .addElement( + 'h', + ofChain( + lazy( + t -> GTStructureUtility.>buildHatchAdder() + .atLeastList(t.getAllowedHatches()) + .casingIndex(t.getHatchTextureIndex()) + .dot(1) + .build()), + onElementPass( + MTECubicMultiBlockBase::onCorrectCasingAdded, + lazy(MTECubicMultiBlockBase::getCasingElement)))) + .build(); + } + }; + private int mCasingAmount = 0; + + protected MTECubicMultiBlockBase(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + protected MTECubicMultiBlockBase(String aName) { + super(aName); + } + + /** + * Create a simple 3x3x3 hollow cubic structure made of a single type of machine casing and accepts hatches + * everywhere. + *

+ * The created definition contains a single piece named {@link #STRUCTURE_PIECE_MAIN}. + */ + @Override + @SuppressWarnings("unchecked") + public IStructureDefinition getStructureDefinition() { + return (IStructureDefinition) STRUCTURE_DEFINITION.get(getClass()); + } + + @Override + public void construct(ItemStack aStack, boolean aHintsOnly) { + buildPiece(STRUCTURE_PIECE_MAIN, aStack, aHintsOnly, 1, 1, 0); + } + + @Override + public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { + if (mMachine) return -1; + return survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 1, 1, 0, elementBudget, env, false, true); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + mCasingAmount = 0; + return checkPiece(STRUCTURE_PIECE_MAIN, 1, 1, 0) && mCasingAmount >= getRequiredCasingCount() + && checkHatches(aBaseMetaTileEntity, aStack); + } + + /** + * Called by {@link #checkMachine(IGregTechTileEntity, ItemStack)} to check if all required hatches are present. + *

+ * Default implementation requires EXACTLY ONE maintenance hatch to be present, and ignore all other conditions. + * + * @param aBaseMetaTileEntity the tile entity of self + * @param aStack The item stack inside the controller + * @return true if the test passes, false otherwise + */ + protected boolean checkHatches(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + return mMaintenanceHatches.size() == 1; + } + + protected abstract IStructureElement> getCasingElement(); + + protected List>> getAllowedHatches() { + return ImmutableList.of(InputHatch, OutputHatch, InputBus, OutputBus, Muffler, Maintenance, Energy); + } + + /** + * The hatch's texture index. + */ + protected abstract int getHatchTextureIndex(); + + protected abstract int getRequiredCasingCount(); + + protected void onCorrectCasingAdded() { + mCasingAmount++; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEEnhancedMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEEnhancedMultiBlockBase.java new file mode 100644 index 0000000000..2cf4398e87 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEEnhancedMultiBlockBase.java @@ -0,0 +1,318 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; +import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable; +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.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; + +import cpw.mods.fml.common.network.NetworkRegistry; +import gregtech.api.GregTechAPI; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.shutdown.ShutDownReasonRegistry; + +/** + * Enhanced multiblock base class, featuring following improvement over {@link MTEMultiBlockBase} + *

+ * 1. TecTech style declarative structure check utilizing StructureLib. 2. Arbitrarily rotating the whole structure, if + * allowed to. + * + * @param type of this + */ +public abstract class MTEEnhancedMultiBlockBase> extends MTETooltipMultiBlockBase + implements IAlignment, IConstructable { + + private ExtendedFacing mExtendedFacing = ExtendedFacing.DEFAULT; + private IAlignmentLimits mLimits = getInitialAlignmentLimits(); + + protected MTEEnhancedMultiBlockBase(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + protected MTEEnhancedMultiBlockBase(String aName) { + super(aName); + } + + @Override + public ExtendedFacing getExtendedFacing() { + return mExtendedFacing; + } + + @Override + public void setExtendedFacing(ExtendedFacing newExtendedFacing) { + if (mExtendedFacing != newExtendedFacing) { + if (mMachine) stopMachine(ShutDownReasonRegistry.STRUCTURE_INCOMPLETE); + mExtendedFacing = newExtendedFacing; + final IGregTechTileEntity base = getBaseMetaTileEntity(); + mMachine = false; + mUpdated = false; + mUpdate = 50; + if (getBaseMetaTileEntity().isServerSide() + && !GregTechAPI.isDummyWorld(getBaseMetaTileEntity().getWorld())) { + StructureLibAPI.sendAlignment( + (IAlignmentProvider) base, + new NetworkRegistry.TargetPoint( + base.getWorld().provider.dimensionId, + base.getXCoord(), + base.getYCoord(), + base.getZCoord(), + 512)); + } else { + base.issueTextureUpdate(); + } + } + } + + @Override + public final boolean isFacingValid(ForgeDirection facing) { + return canSetToDirectionAny(facing); + } + + @Override + public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, + float aX, float aY, float aZ) { + if (wrenchingSide != getBaseMetaTileEntity().getFrontFacing()) + return super.onWrenchRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); + if (entityPlayer.isSneaking()) { + if (isFlipChangeAllowed()) { + toolSetFlip(getFlip().isHorizontallyFlipped() ? Flip.NONE : Flip.HORIZONTAL); + } else { + return false; + } + } else { + if (isRotationChangeAllowed()) { + toolSetRotation(null); + } else { + return false; + } + } + return true; + } + + @Override + public void onFacingChange() { + toolSetDirection(getBaseMetaTileEntity().getFrontFacing()); + } + + @Override + public IAlignmentLimits getAlignmentLimits() { + return mLimits; + } + + protected void setAlignmentLimits(IAlignmentLimits mLimits) { + this.mLimits = mLimits; + } + + /** + * Due to limitation of Java type system, you might need to do an unchecked cast. HOWEVER, the returned + * IStructureDefinition is expected to be evaluated against current instance only, and should not be used against + * other instances, even for those of the same class. + */ + public abstract IStructureDefinition getStructureDefinition(); + + protected abstract MultiblockTooltipBuilder createTooltip(); + + @Override + public String[] getStructureDescription(ItemStack stackSize) { + return getTooltip().getStructureHint(); + } + + protected IAlignmentLimits getInitialAlignmentLimits() { + return (d, r, f) -> !f.isVerticallyFliped(); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setByte( + "eRotation", + (byte) mExtendedFacing.getRotation() + .getIndex()); + aNBT.setByte( + "eFlip", + (byte) mExtendedFacing.getFlip() + .getIndex()); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + mExtendedFacing = ExtendedFacing.of( + getBaseMetaTileEntity().getFrontFacing(), + Rotation.byIndex(aNBT.getByte("eRotation")), + Flip.byIndex(aNBT.getByte("eFlip"))); + if (!getAlignmentLimits().isNewExtendedFacingValid(mExtendedFacing)) { + mExtendedFacing = getCorrectedAlignment(mExtendedFacing); + } + } + + /** + * When an old {@link ExtendedFacing} is loaded upon MTE deserialization, and the loaded facing cannot pass test of + * current {@link #getAlignmentLimits()}, this method will be called to retrieve a corrected version. This method + * is currently only intended to be used as a mean to migrate alignment limits, so if you never change the alignment + * limit then you can probably just use the default implementation. + * + * The returned new facing must be able to pass the test of {@link #isNewExtendedFacingValid(ExtendedFacing)} + */ + protected ExtendedFacing getCorrectedAlignment(ExtendedFacing aOldFacing) { + if (isNewExtendedFacingValid(ExtendedFacing.DEFAULT)) { + return ExtendedFacing.DEFAULT; + } + for (ExtendedFacing facing : ExtendedFacing.VALUES) { + if (facing.getFlip() + .isVerticallyFliped()) { + continue; + } + if (isNewExtendedFacingValid(facing)) { + return facing; + } + } + throw new AssertionError("No ExtendedFacing can pass the test of isNewExtendedFacingValid"); + } + + @SuppressWarnings("unchecked") + private IStructureDefinition> getCastedStructureDefinition() { + return (IStructureDefinition>) getStructureDefinition(); + } + + /** + * Explanation of the world coordinate these offset means: + *

+ * Imagine you stand in front of the controller, with controller facing towards you not rotated or flipped. + *

+ * The horizontalOffset would be the number of blocks on the left side of the controller, not counting controller + * itself. The verticalOffset would be the number of blocks on the top side of the controller, not counting + * controller itself. The depthOffset would be the number of blocks between you and controller, not counting + * controller itself. + *

+ * All these offsets can be negative. + */ + protected final boolean checkPiece(String piece, int horizontalOffset, int verticalOffset, int depthOffset) { + final IGregTechTileEntity tTile = getBaseMetaTileEntity(); + return getCastedStructureDefinition().check( + this, + piece, + tTile.getWorld(), + getExtendedFacing(), + tTile.getXCoord(), + tTile.getYCoord(), + tTile.getZCoord(), + horizontalOffset, + verticalOffset, + depthOffset, + !mMachine); + } + + protected final boolean buildPiece(String piece, ItemStack trigger, boolean hintOnly, int horizontalOffset, + int verticalOffset, int depthOffset) { + final IGregTechTileEntity tTile = getBaseMetaTileEntity(); + return getCastedStructureDefinition().buildOrHints( + this, + trigger, + piece, + tTile.getWorld(), + getExtendedFacing(), + tTile.getXCoord(), + tTile.getYCoord(), + tTile.getZCoord(), + horizontalOffset, + verticalOffset, + depthOffset, + hintOnly); + } + + @Deprecated + protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, + int depthOffset, int elementsBudget, IItemSource source, EntityPlayerMP actor, boolean check) { + final IGregTechTileEntity tTile = getBaseMetaTileEntity(); + return getCastedStructureDefinition().survivalBuild( + this, + trigger, + piece, + tTile.getWorld(), + getExtendedFacing(), + tTile.getXCoord(), + tTile.getYCoord(), + tTile.getZCoord(), + horizontalOffset, + verticalOffset, + depthOffset, + elementsBudget, + source, + actor, + check); + } + + protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, + int depthOffset, int elementsBudget, ISurvivalBuildEnvironment env, boolean check) { + final IGregTechTileEntity tTile = getBaseMetaTileEntity(); + return getCastedStructureDefinition().survivalBuild( + this, + trigger, + piece, + tTile.getWorld(), + getExtendedFacing(), + tTile.getXCoord(), + tTile.getYCoord(), + tTile.getZCoord(), + horizontalOffset, + verticalOffset, + depthOffset, + elementsBudget, + env, + check); + } + + @Deprecated + protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, + int depthOffset, int elementsBudget, IItemSource source, EntityPlayerMP actor, boolean check, + boolean checkIfPlaced) { + int built = survivialBuildPiece( + piece, + trigger, + horizontalOffset, + verticalOffset, + depthOffset, + elementsBudget, + source, + actor, + check); + if (checkIfPlaced && built > 0) checkStructure(true, getBaseMetaTileEntity()); + return built; + } + + protected final int survivialBuildPiece(String piece, ItemStack trigger, int horizontalOffset, int verticalOffset, + int depthOffset, int elementsBudget, ISurvivalBuildEnvironment env, boolean check, boolean checkIfPlaced) { + int built = survivialBuildPiece( + piece, + trigger, + horizontalOffset, + verticalOffset, + depthOffset, + elementsBudget, + env, + check); + if (checkIfPlaced && built > 0) checkStructure(true, getBaseMetaTileEntity()); + return built; + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + super.onFirstTick(aBaseMetaTileEntity); + if (aBaseMetaTileEntity.isClientSide()) + StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEExtendedPowerMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEExtendedPowerMultiBlockBase.java new file mode 100644 index 0000000000..64bade97e8 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEExtendedPowerMultiBlockBase.java @@ -0,0 +1,242 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.VN; +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.logic.ProcessingLogic; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.util.ExoticEnergyInputHelper; +import gregtech.api.util.GTUtility; +import gregtech.api.util.OverclockCalculator; +import gregtech.api.util.shutdown.ShutDownReason; +import gregtech.api.util.shutdown.ShutDownReasonRegistry; + +/** + * Multiblock base class that allows machine to use power over int. + */ +public abstract class MTEExtendedPowerMultiBlockBase> + extends MTEEnhancedMultiBlockBase { + + public long lEUt; + + protected MTEExtendedPowerMultiBlockBase(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + protected MTEExtendedPowerMultiBlockBase(String aName) { + super(aName); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + // NBT can be loaded as any primitive type, so we can load it as long. + this.lEUt = aNBT.getLong("mEUt"); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setLong("mEUt", this.lEUt); + } + + @Override + protected void calculateOverclockedNessMultiInternal(long aEUt, int aDuration, int mAmperage, long maxInputVoltage, + boolean perfectOC) { + OverclockCalculator calculator = new OverclockCalculator().setRecipeEUt(aEUt) + .setEUt(maxInputVoltage * mAmperage) + .setDuration(aDuration) + .setDurationDecreasePerOC(perfectOC ? 4.0 : 2.0) + .calculate(); + lEUt = calculator.getConsumption(); + mMaxProgresstime = calculator.getDuration(); + } + + @Override + public boolean onRunningTick(ItemStack aStack) { + if (this.lEUt > 0) { + addEnergyOutput((this.lEUt * mEfficiency) / 10000); + return true; + } + if (this.lEUt < 0) { + if (!drainEnergyInput(getActualEnergyUsage())) { + stopMachine(ShutDownReasonRegistry.POWER_LOSS); + return false; + } + } + return true; + } + + @Override + public void stopMachine(@NotNull ShutDownReason reason) { + this.lEUt = 0; + super.stopMachine(reason); + } + + @Override + protected long getActualEnergyUsage() { + return (-this.lEUt * 10000) / Math.max(1000, mEfficiency); + } + + public List getExoticAndNormalEnergyHatchList() { + List tHatches = new ArrayList<>(); + tHatches.addAll(filterValidMTEs(mExoticEnergyHatches)); + tHatches.addAll(filterValidMTEs(mEnergyHatches)); + return tHatches; + } + + @Override + public boolean drainEnergyInput(long aEU) { + return ExoticEnergyInputHelper.drainEnergy(aEU, getExoticAndNormalEnergyHatchList()); + } + + @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); + + final IGregTechTileEntity tileEntity = getBaseMetaTileEntity(); + if (tileEntity != null) { + if (tileEntity.isActive()) { + if (lEUt < 0) tag.setLong("energyUsage", getActualEnergyUsage()); + else tag.setLong("energyUsage", -lEUt * mEfficiency / 10000); + } + } + } + + @Override + protected void setProcessingLogicPower(ProcessingLogic logic) { + logic.setAvailableVoltage(getAverageInputVoltage()); + logic.setAvailableAmperage(getMaxInputAmps()); + logic.setAmperageOC(true); + } + + @Nonnull + @Override + protected CheckRecipeResult postCheckRecipe(@Nonnull CheckRecipeResult result, + @Nonnull ProcessingLogic processingLogic) { + return result; + } + + @Override + protected void setEnergyUsage(ProcessingLogic processingLogic) { + lEUt = processingLogic.getCalculatedEut(); + if (lEUt > 0) { + lEUt = (-lEUt); + } + } + + @Override + public String[] getInfoData() { + int mPollutionReduction = 0; + for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) { + mPollutionReduction = Math.max(tHatch.calculatePollutionReduction(100), mPollutionReduction); + } + + long storedEnergy = 0; + long maxEnergy = 0; + for (MTEHatch tHatch : getExoticAndNormalEnergyHatchList()) { + storedEnergy += tHatch.getBaseMetaTileEntity() + .getStoredEU(); + maxEnergy += tHatch.getBaseMetaTileEntity() + .getEUCapacity(); + } + long voltage = getAverageInputVoltage(); + long amps = getMaxInputAmps(); + + return new String[] { + /* 1 */ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(mProgresstime / 20) + + EnumChatFormatting.RESET + + " s / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(mMaxProgresstime / 20) + + EnumChatFormatting.RESET + + " s", + /* 2 */ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(storedEnergy) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(maxEnergy) + + EnumChatFormatting.RESET + + " EU", + /* 3 */ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " + + EnumChatFormatting.RED + + GTUtility.formatNumbers(getActualEnergyUsage()) + + EnumChatFormatting.RESET + + " EU/t", + /* 4 */ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(voltage) + + EnumChatFormatting.RESET + + " EU/t(*" + + amps + + " A)" + + StatCollector.translateToLocal("GT5U.machines.tier") + + ": " + + EnumChatFormatting.YELLOW + + VN[GTUtility.getTier(voltage)] + + EnumChatFormatting.RESET, + /* 5 */ StatCollector.translateToLocal("GT5U.multiblock.problems") + ": " + + EnumChatFormatting.RED + + (getIdealStatus() - getRepairStatus()) + + EnumChatFormatting.RESET + + " " + + StatCollector.translateToLocal("GT5U.multiblock.efficiency") + + ": " + + EnumChatFormatting.YELLOW + + mEfficiency / 100.0F + + EnumChatFormatting.RESET + + " %", + /* 6 */ StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": " + + EnumChatFormatting.GREEN + + mPollutionReduction + + EnumChatFormatting.RESET + + " %" }; + } + + @Override + public long getMaxInputVoltage() { + return ExoticEnergyInputHelper.getMaxInputVoltageMulti(getExoticAndNormalEnergyHatchList()); + } + + @Override + public long getAverageInputVoltage() { + return ExoticEnergyInputHelper.getAverageInputVoltageMulti(getExoticAndNormalEnergyHatchList()); + } + + @Override + public long getMaxInputAmps() { + return ExoticEnergyInputHelper.getMaxWorkingInputAmpsMulti(getExoticAndNormalEnergyHatchList()); + } + + @Override + public long getMaxInputEu() { + return ExoticEnergyInputHelper.getTotalEuMulti(getExoticAndNormalEnergyHatchList()); + } + + @Override + public void clearHatches() { + super.clearHatches(); + mExoticEnergyHatches.clear(); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEFilterBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEFilterBase.java new file mode 100644 index 0000000000..32e224e50f --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEFilterBase.java @@ -0,0 +1,104 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.nbt.NBTTagCompound; + +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; + +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.util.GT_TooltipDataCache; + +public abstract class MTEFilterBase extends MTEBuffer { + + private static final String INVERT_FILTER_TOOLTIP = "GT5U.machines.invert_filter.tooltip"; + protected static final int FILTER_SLOT_INDEX = 9; + protected static final int NUM_INVENTORY_SLOTS = 9; + private static final String EMIT_REDSTONE_GRADUALLY_TOOLTIP = "GT5U" + ".machines.emit_redstone_gradually.tooltip"; + protected boolean invertFilter = false; + + public MTEFilterBase(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public MTEFilterBase(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String[] aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public MTEFilterBase(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEFilterBase(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex < NUM_INVENTORY_SLOTS; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setBoolean("bInvertFilter", this.invertFilter); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + this.invertFilter = aNBT.getBoolean("bInvertFilter"); + } + + @Override + protected int getRedstoneOutput() { + if (!bRedstoneIfFull) { + return 0; + } + int redstoneOutput = getEmptySlots(); + if (!bInvert) redstoneOutput = NUM_INVENTORY_SLOTS - redstoneOutput; + return redstoneOutput; + } + + private int getEmptySlots() { + int emptySlots = 0; + for (int i = 0; i < NUM_INVENTORY_SLOTS; i++) { + if (mInventory[i] == null) ++emptySlots; + } + return emptySlots; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + super.addUIWidgets(builder, buildContext); + addSortStacksButton(builder); + addEmitRedstoneGraduallyButton(builder); + addInvertRedstoneButton(builder); + addInvertFilterButton(builder); + } + + private void addEmitRedstoneGraduallyButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> bRedstoneIfFull, + val -> bRedstoneIfFull = val, + GTUITextures.OVERLAY_BUTTON_EMIT_REDSTONE, + this::getEmitRedstoneGraduallyButtonTooltip).setUpdateTooltipEveryTick(true)); + } + + private GT_TooltipDataCache.TooltipData getEmitRedstoneGraduallyButtonTooltip() { + return mTooltipCache + .getUncachedTooltipData(EMIT_REDSTONE_GRADUALLY_TOOLTIP, getEmptySlots(), getRedstoneOutput()); + } + + private void addInvertFilterButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> invertFilter, + val -> invertFilter = val, + GTUITextures.OVERLAY_BUTTON_INVERT_FILTER, + () -> mTooltipCache.getData(INVERT_FILTER_TOOLTIP))); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEFluid.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEFluid.java new file mode 100644 index 0000000000..ddc0e28723 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEFluid.java @@ -0,0 +1,971 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.ALL_VALID_SIDES; +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.Mods.TinkerConstruct; +import static gregtech.api.enums.Mods.Translocator; +import static gregtech.api.metatileentity.implementations.MTEFluid.Border.BOTTOM; +import static gregtech.api.metatileentity.implementations.MTEFluid.Border.LEFT; +import static gregtech.api.metatileentity.implementations.MTEFluid.Border.RIGHT; +import static gregtech.api.metatileentity.implementations.MTEFluid.Border.TOP; +import static gregtech.api.objects.XSTR.XSTR_INSTANCE; +import static net.minecraftforge.common.util.ForgeDirection.DOWN; +import static net.minecraftforge.common.util.ForgeDirection.EAST; +import static net.minecraftforge.common.util.ForgeDirection.NORTH; +import static net.minecraftforge.common.util.ForgeDirection.SOUTH; +import static net.minecraftforge.common.util.ForgeDirection.UP; +import static net.minecraftforge.common.util.ForgeDirection.WEST; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; + +import org.apache.commons.lang3.tuple.MutableTriple; + +import cpw.mods.fml.common.Optional; +import gregtech.GTMod; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.Materials; +import gregtech.api.enums.Mods; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.ParticleFX; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.Textures; +import gregtech.api.enums.ToolModes; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.MetaGeneratedTool; +import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gregtech.api.metatileentity.MetaPipeEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtility; +import gregtech.api.util.ISerializableObject; +import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder; +import gregtech.common.GTClient; +import gregtech.common.config.other.ConfigGeneral; +import gregtech.common.covers.CoverDrain; +import gregtech.common.covers.CoverFluidRegulator; +import gregtech.common.covers.CoverInfo; + +public class MTEFluid extends MetaPipeEntity { + + protected static final EnumMap> FACE_BORDER_MAP = new EnumMap<>( + ForgeDirection.class); + + static { + FACE_BORDER_MAP.put(DOWN, borderMap(NORTH, SOUTH, EAST, WEST)); + FACE_BORDER_MAP.put(UP, borderMap(NORTH, SOUTH, WEST, EAST)); + FACE_BORDER_MAP.put(NORTH, borderMap(UP, DOWN, EAST, WEST)); + FACE_BORDER_MAP.put(SOUTH, borderMap(UP, DOWN, WEST, EAST)); + FACE_BORDER_MAP.put(WEST, borderMap(UP, DOWN, NORTH, SOUTH)); + FACE_BORDER_MAP.put(EAST, borderMap(UP, DOWN, SOUTH, NORTH)); + } + + protected static final Map RESTR_TEXTURE_MAP = new HashMap<>(); + + static { + RESTR_TEXTURE_MAP.put(TOP.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UP); + RESTR_TEXTURE_MAP.put(BOTTOM.mask, Textures.BlockIcons.PIPE_RESTRICTOR_DOWN); + RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UD); + RESTR_TEXTURE_MAP.put(LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_LEFT); + RESTR_TEXTURE_MAP.put(TOP.mask | LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UL); + RESTR_TEXTURE_MAP.put(BOTTOM.mask | LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_DL); + RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask | LEFT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_NR); + RESTR_TEXTURE_MAP.put(RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_RIGHT); + RESTR_TEXTURE_MAP.put(TOP.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_UR); + RESTR_TEXTURE_MAP.put(BOTTOM.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_DR); + RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_NL); + RESTR_TEXTURE_MAP.put(LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_LR); + RESTR_TEXTURE_MAP.put(TOP.mask | LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_ND); + RESTR_TEXTURE_MAP.put(BOTTOM.mask | LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR_NU); + RESTR_TEXTURE_MAP.put(TOP.mask | BOTTOM.mask | LEFT.mask | RIGHT.mask, Textures.BlockIcons.PIPE_RESTRICTOR); + } + + public final float mThickNess; + public final Materials mMaterial; + public final int mCapacity, mHeatResistance, mPipeAmount; + public final boolean mGasProof; + public final FluidStack[] mFluids; + public byte mLastReceivedFrom = 0, oLastReceivedFrom = 0; + /** + * Bitmask for whether disable fluid input form each side. + */ + public byte mDisableInput = 0; + + public MTEFluid(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, int aCapacity, + int aHeatResistance, boolean aGasProof) { + this(aID, aName, aNameRegional, aThickNess, aMaterial, aCapacity, aHeatResistance, aGasProof, 1); + } + + public MTEFluid(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, int aCapacity, + int aHeatResistance, boolean aGasProof, int aFluidTypes) { + super(aID, aName, aNameRegional, 0, false); + mThickNess = aThickNess; + mMaterial = aMaterial; + mCapacity = aCapacity; + mGasProof = aGasProof; + mHeatResistance = aHeatResistance; + mPipeAmount = aFluidTypes; + mFluids = new FluidStack[mPipeAmount]; + addInfo(aID); + } + + public MTEFluid(String aName, float aThickNess, Materials aMaterial, int aCapacity, int aHeatResistance, + boolean aGasProof, int aFluidTypes) { + super(aName, 0); + mThickNess = aThickNess; + mMaterial = aMaterial; + mCapacity = aCapacity; + mGasProof = aGasProof; + mHeatResistance = aHeatResistance; + mPipeAmount = aFluidTypes; + mFluids = new FluidStack[mPipeAmount]; + } + + @Override + public byte getTileEntityBaseType() { + return (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEFluid(mName, mThickNess, mMaterial, mCapacity, mHeatResistance, mGasProof, mPipeAmount); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, int aConnections, + int colorIndex, boolean aConnected, boolean redstoneLevel) { + if (side == ForgeDirection.UNKNOWN) return Textures.BlockIcons.ERROR_RENDERING; + final float tThickNess = getThickNess(); + if (mDisableInput == 0) + return new ITexture[] { aConnected ? getBaseTexture(tThickNess, mPipeAmount, mMaterial, colorIndex) + : TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(colorIndex, mMaterial.mRGBa)) }; + int borderMask = 0; + for (Border border : Border.values()) { + if (isInputDisabledAtSide(getSideAtBorder(side, border))) borderMask |= border.mask; + } + + return new ITexture[] { aConnected ? getBaseTexture(tThickNess, mPipeAmount, mMaterial, colorIndex) + : TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(colorIndex, mMaterial.mRGBa)), + getRestrictorTexture(borderMask) }; + } + + protected static ITexture getBaseTexture(float aThickNess, int aPipeAmount, Materials aMaterial, int colorIndex) { + if (aPipeAmount >= 9) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeNonuple.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + if (aPipeAmount >= 4) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeQuadruple.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + if (aThickNess < 0.124F) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + if (aThickNess < 0.374F) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeTiny.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + if (aThickNess < 0.499F) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeSmall.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + if (aThickNess < 0.749F) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeMedium.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + if (aThickNess < 0.874F) return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeLarge.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + return TextureFactory.of( + aMaterial.mIconSet.mTextures[OrePrefixes.pipeHuge.mTextureIndex], + Dyes.getModulation(colorIndex, aMaterial.mRGBa)); + } + + protected static ITexture getRestrictorTexture(int borderMask) { + final IIconContainer restrictorIcon = RESTR_TEXTURE_MAP.get(borderMask); + return restrictorIcon != null ? TextureFactory.of(restrictorIcon) : null; + } + + @Override + public void onValueUpdate(byte aValue) { + mDisableInput = aValue; + } + + @Override + public byte getUpdateData() { + return mDisableInput; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return false; + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public final boolean renderInside(ForgeDirection side) { + return false; + } + + @Override + public int getProgresstime() { + return getFluidAmount(); + } + + @Override + public int maxProgresstime() { + return getCapacity(); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + for (int i = 0; i < mPipeAmount; i++) if (mFluids[i] != null) + aNBT.setTag("mFluid" + (i == 0 ? "" : i), mFluids[i].writeToNBT(new NBTTagCompound())); + aNBT.setByte("mLastReceivedFrom", mLastReceivedFrom); + if (GTMod.gregtechproxy.gt6Pipe) { + aNBT.setByte("mConnections", mConnections); + aNBT.setByte("mDisableInput", mDisableInput); + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + for (int i = 0; i < mPipeAmount; i++) + mFluids[i] = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid" + (i == 0 ? "" : i))); + mLastReceivedFrom = aNBT.getByte("mLastReceivedFrom"); + if (GTMod.gregtechproxy.gt6Pipe) { + mConnections = aNBT.getByte("mConnections"); + mDisableInput = aNBT.getByte("mDisableInput"); + } + } + + @Override + public void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity aEntity) { + if ((((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections & -128) == 0 + && aEntity instanceof EntityLivingBase) { + for (FluidStack tFluid : mFluids) { + if (tFluid != null) { + final int tTemperature = tFluid.getFluid() + .getTemperature(tFluid); + if (tTemperature > 320 + && !isCoverOnSide((BaseMetaPipeEntity) getBaseMetaTileEntity(), (EntityLivingBase) aEntity)) { + GTUtility.applyHeatDamage((EntityLivingBase) aEntity, (tTemperature - 300) / 50.0F); + break; + } else if (tTemperature < 260 + && !isCoverOnSide((BaseMetaPipeEntity) getBaseMetaTileEntity(), (EntityLivingBase) aEntity)) { + GTUtility.applyFrostDamage((EntityLivingBase) aEntity, (270 - tTemperature) / 25.0F); + break; + } + } + } + } + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && aTick % 5 == 0) { + mLastReceivedFrom &= 63; + if (mLastReceivedFrom == 63) { + mLastReceivedFrom = 0; + } + + if (!GTMod.gregtechproxy.gt6Pipe || mCheckConnections) checkConnections(); + + final boolean shouldDistribute = (oLastReceivedFrom == mLastReceivedFrom); + for (int i = 0, j = aBaseMetaTileEntity.getRandomNumber(mPipeAmount); i < mPipeAmount; i++) { + final int index = (i + j) % mPipeAmount; + if (mFluids[index] != null && mFluids[index].amount <= 0) mFluids[index] = null; + if (mFluids[index] == null) continue; + + if (checkEnvironment(index, aBaseMetaTileEntity)) return; + + if (shouldDistribute) { + distributeFluid(index, aBaseMetaTileEntity); + mLastReceivedFrom = 0; + } + } + + oLastReceivedFrom = mLastReceivedFrom; + } + } + + private boolean checkEnvironment(int index, IGregTechTileEntity aBaseMetaTileEntity) { + // Check for hot liquids that melt the pipe or gasses that escape and burn/freeze people + final FluidStack tFluid = mFluids[index]; + + if (tFluid != null && tFluid.amount > 0) { + final int tTemperature = tFluid.getFluid() + .getTemperature(tFluid); + if (tTemperature > mHeatResistance) { + if (aBaseMetaTileEntity.getRandomNumber(100) == 0) { + // Poof + GTLog.exp.println( + "Set Pipe to Fire due to to low heat resistance at " + aBaseMetaTileEntity.getXCoord() + + " | " + + aBaseMetaTileEntity.getYCoord() + + " | " + + aBaseMetaTileEntity.getZCoord() + + " DIMID: " + + aBaseMetaTileEntity.getWorld().provider.dimensionId); + aBaseMetaTileEntity.setToFire(); + return true; + } + // Mmhmm, Fire + aBaseMetaTileEntity.setOnFire(); + GTLog.exp.println( + "Set Blocks around Pipe to Fire due to to low heat resistance at " + aBaseMetaTileEntity.getXCoord() + + " | " + + aBaseMetaTileEntity.getYCoord() + + " | " + + aBaseMetaTileEntity.getZCoord() + + " DIMID: " + + aBaseMetaTileEntity.getWorld().provider.dimensionId); + } + if (!mGasProof && tFluid.getFluid() + .isGaseous(tFluid)) { + tFluid.amount -= 5; + sendSound((byte) 9); + if (tTemperature > 320) { + try { + for (EntityLivingBase tLiving : getBaseMetaTileEntity().getWorld() + .getEntitiesWithinAABB( + EntityLivingBase.class, + AxisAlignedBB.getBoundingBox( + getBaseMetaTileEntity().getXCoord() - 2, + getBaseMetaTileEntity().getYCoord() - 2, + getBaseMetaTileEntity().getZCoord() - 2, + getBaseMetaTileEntity().getXCoord() + 3, + getBaseMetaTileEntity().getYCoord() + 3, + getBaseMetaTileEntity().getZCoord() + 3))) { + GTUtility.applyHeatDamage(tLiving, (tTemperature - 300) / 25.0F); + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + } else if (tTemperature < 260) { + try { + for (EntityLivingBase tLiving : getBaseMetaTileEntity().getWorld() + .getEntitiesWithinAABB( + EntityLivingBase.class, + AxisAlignedBB.getBoundingBox( + getBaseMetaTileEntity().getXCoord() - 2, + getBaseMetaTileEntity().getYCoord() - 2, + getBaseMetaTileEntity().getZCoord() - 2, + getBaseMetaTileEntity().getXCoord() + 3, + getBaseMetaTileEntity().getYCoord() + 3, + getBaseMetaTileEntity().getZCoord() + 3))) { + GTUtility.applyFrostDamage(tLiving, (270 - tTemperature) / 12.5F); + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + } + } + if (tFluid.amount <= 0) mFluids[index] = null; + } + return false; + } + + private void distributeFluid(int index, IGregTechTileEntity aBaseMetaTileEntity) { + final FluidStack tFluid = mFluids[index]; + if (tFluid == null) return; + + // Tank, From, Amount to receive + final List> tTanks = new ArrayList<>(); + final int amount = tFluid.amount; + final byte tOffset = (byte) getBaseMetaTileEntity().getRandomNumber(6); + for (final byte i : ALL_VALID_SIDES) { + // Get a list of tanks accepting fluids, and what side they're on + final ForgeDirection side = ForgeDirection.getOrientation((i + tOffset) % 6); + final ForgeDirection oppositeSide = side.getOpposite(); + final IFluidHandler tTank = aBaseMetaTileEntity.getITankContainerAtSide(side); + final IGregTechTileEntity gTank = tTank instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTank : null; + + if (isConnectedAtSide(side) && tTank != null + && (mLastReceivedFrom & side.flag) == 0 + && getBaseMetaTileEntity().getCoverInfoAtSide(side) + .letsFluidOut(tFluid.getFluid()) + && (gTank == null || gTank.getCoverInfoAtSide(oppositeSide) + .letsFluidIn(tFluid.getFluid()))) { + if (tTank.fill(oppositeSide, tFluid, false) > 0) { + tTanks.add(new MutableTriple<>(tTank, oppositeSide, 0)); + } + tFluid.amount = amount; // Because some mods do actually modify input fluid stack + } + } + + // How much of this fluid is available for distribution? + final double tAmount = Math.max(1, Math.min(mCapacity * 10, tFluid.amount)); + + final FluidStack maxFluid = tFluid.copy(); + maxFluid.amount = Integer.MAX_VALUE; + + double availableCapacity = 0; + // Calculate available capacity for distribution from all tanks + for (final MutableTriple tEntry : tTanks) { + tEntry.right = tEntry.left.fill(tEntry.middle, maxFluid, false); + availableCapacity += tEntry.right; + } + + // Now distribute + for (final MutableTriple tEntry : tTanks) { + // Distribue fluids based on percentage available space at destination + if (availableCapacity > tAmount) + tEntry.right = (int) Math.floor(tEntry.right * tAmount / availableCapacity); + + // If the percent is not enough to give at least 1L, try to give 1L + if (tEntry.right == 0) tEntry.right = (int) Math.min(1, tAmount); + + if (tEntry.right <= 0) continue; + + final int tFilledAmount = tEntry.left + .fill(tEntry.middle, drainFromIndex(tEntry.right, false, index), false); + + if (tFilledAmount > 0) tEntry.left.fill(tEntry.middle, drainFromIndex(tFilledAmount, true, index), true); + + if (mFluids[index] == null || mFluids[index].amount <= 0) return; + } + } + + public void connectPipeOnSide(ForgeDirection side, EntityPlayer entityPlayer) { + if (!isConnectedAtSide(side)) { + if (connect(side) > 0) GTUtility.sendChatToPlayer(entityPlayer, GTUtility.trans("214", "Connected")); + } else { + disconnect(side); + GTUtility.sendChatToPlayer(entityPlayer, GTUtility.trans("215", "Disconnected")); + } + } + + public void blockPipeOnSide(ForgeDirection side, EntityPlayer entityPlayer, byte mask) { + if (isInputDisabledAtSide(side)) { + mDisableInput &= ~mask; + GTUtility.sendChatToPlayer(entityPlayer, GTUtility.trans("212", "Input enabled")); + if (!isConnectedAtSide(side)) connect(side); + } else { + mDisableInput |= mask; + GTUtility.sendChatToPlayer(entityPlayer, GTUtility.trans("213", "Input disabled")); + } + } + + @Override + public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, + float aX, float aY, float aZ, ItemStack aTool) { + + if (GTMod.gregtechproxy.gt6Pipe) { + final int mode = MetaGeneratedTool.getToolMode(aTool); + IGregTechTileEntity currentPipeBase = getBaseMetaTileEntity(); + MTEFluid currentPipe = (MTEFluid) currentPipeBase.getMetaTileEntity(); + final ForgeDirection tSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); + final byte tMask = (byte) (tSide.flag); + + if (mode == ToolModes.REGULAR.get()) { + if (entityPlayer.isSneaking()) { + currentPipe.blockPipeOnSide(tSide, entityPlayer, tMask); + } else currentPipe.connectPipeOnSide(tSide, entityPlayer); + return true; + } + + if (mode == ToolModes.WRENCH_LINE.get()) { + + boolean initialState = entityPlayer.isSneaking() ? currentPipe.isInputDisabledAtSide(tSide) + : currentPipe.isConnectedAtSide(tSide); + + boolean wasActionPerformed = false; + + int limit = ConfigGeneral.pipeWrenchingChainRange; + for (int connected = 0; connected < limit; connected++) { + + TileEntity nextPipeBaseTile = currentPipeBase.getTileEntityAtSide(tSide); + + // if next tile doesn't exist or if next tile is not GT tile + if (!(nextPipeBaseTile instanceof IGregTechTileEntity nextPipeBase)) { + return wasActionPerformed; + } + + // if next tile is wrong color + if (!currentPipe.connectableColor(nextPipeBaseTile)) { + return wasActionPerformed; + } + + MTEFluid nextPipe = nextPipeBase.getMetaTileEntity() instanceof MTEFluid + ? (MTEFluid) nextPipeBase.getMetaTileEntity() + : null; + + // if next tile entity is not a pipe + if (nextPipe == null) { + return wasActionPerformed; + } + + // if pipes are same size + if (mPipeAmount != nextPipe.mPipeAmount) { + return wasActionPerformed; + } + + // making sure next pipe has same fluid + for (int i = 0; i < mPipeAmount; i++) { + if (mFluids[i] != null && nextPipe.mFluids[i] != null) { + if (!mFluids[i].isFluidEqual(nextPipe.mFluids[i])) { + return wasActionPerformed; + } + } else if (mFluids[i] != nextPipe.mFluids[i]) { + return wasActionPerformed; + } + } + + boolean currentState = entityPlayer.isSneaking() ? currentPipe.isInputDisabledAtSide(tSide) + : currentPipe.isConnectedAtSide(tSide); + + /* + * Making sure next pipe will have same action applied to it + * e.g. Connecting pipe won`t trigger disconnect if next pipe is already connected + */ + if (currentState != initialState) { + return wasActionPerformed; + } + + if (entityPlayer.isSneaking()) { + currentPipe.blockPipeOnSide(tSide, entityPlayer, tMask); + } else currentPipe.connectPipeOnSide(tSide, entityPlayer); + + wasActionPerformed = true; + + currentPipeBase = (IGregTechTileEntity) nextPipeBase; + currentPipe = nextPipe; + + } + return wasActionPerformed; + } + } + return false; + } + + @Override + public boolean letsIn(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return coverBehavior.letsFluidIn(side, aCoverID, aCoverVariable, null, aTileEntity); + } + + @Override + public boolean letsOut(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return coverBehavior.letsFluidOut(side, aCoverID, aCoverVariable, null, aTileEntity); + } + + @Override + public boolean letsIn(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return coverBehavior.letsFluidIn(side, aCoverID, aCoverVariable, null, aTileEntity); + } + + @Override + public boolean letsOut(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return coverBehavior.letsFluidOut(side, aCoverID, aCoverVariable, null, aTileEntity); + } + + @Override + public boolean letsIn(CoverInfo coverInfo) { + return coverInfo.letsFluidIn(null); + } + + @Override + public boolean letsOut(CoverInfo coverInfo) { + return coverInfo.letsFluidOut(null); + } + + @Override + public boolean canConnect(ForgeDirection side, TileEntity tileEntity) { + if (tileEntity == null) return false; + + final ForgeDirection tSide = side.getOpposite(); + final IGregTechTileEntity baseMetaTile = getBaseMetaTileEntity(); + if (baseMetaTile == null) return false; + + final CoverBehaviorBase coverBehavior = baseMetaTile.getCoverBehaviorAtSideNew(side); + final IGregTechTileEntity gTileEntity = (tileEntity instanceof IGregTechTileEntity) + ? (IGregTechTileEntity) tileEntity + : null; + + if (coverBehavior instanceof CoverDrain || (TinkerConstruct.isModLoaded() && isTConstructFaucet(tileEntity))) + return true; + + final IFluidHandler fTileEntity = (tileEntity instanceof IFluidHandler) ? (IFluidHandler) tileEntity : null; + + if (fTileEntity != null) { + final FluidTankInfo[] tInfo = fTileEntity.getTankInfo(tSide); + if (tInfo != null) { + return tInfo.length > 0 || (Translocator.isModLoaded() && isTranslocator(tileEntity)) + || gTileEntity != null + && gTileEntity.getCoverBehaviorAtSideNew(tSide) instanceof CoverFluidRegulator; + } + } + return false; + } + + @Optional.Method(modid = Mods.Names.TINKER_CONSTRUCT) + private boolean isTConstructFaucet(TileEntity tTileEntity) { + // Tinker Construct Faucets return a null tank info, so check the class + return tTileEntity instanceof tconstruct.smeltery.logic.FaucetLogic; + } + + @Optional.Method(modid = Mods.Names.TRANSLOCATOR) + private boolean isTranslocator(TileEntity tTileEntity) { + // Translocators return a TankInfo, but it's of 0 length - so check the class if we see this pattern + return tTileEntity instanceof codechicken.translocator.TileLiquidTranslocator; + } + + @Override + public boolean getGT6StyleConnection() { + // Yes if GT6 pipes are enabled + return GTMod.gregtechproxy.gt6Pipe; + } + + @Override + public void doSound(byte aIndex, double aX, double aY, double aZ) { + super.doSound(aIndex, aX, aY, aZ); + if (aIndex == 9) { + GTUtility.doSoundAtClient(SoundResource.RANDOM_FIZZ, 5, 1.0F, aX, aY, aZ); + + new ParticleEventBuilder().setIdentifier(ParticleFX.CLOUD) + .setWorld(getBaseMetaTileEntity().getWorld()) + .times( + 6, + (x, i) -> x + .setMotion( + ForgeDirection.getOrientation(i).offsetX / 5.0, + ForgeDirection.getOrientation(i).offsetY / 5.0, + ForgeDirection.getOrientation(i).offsetZ / 5.0) + .setPosition( + aX - 0.5 + XSTR_INSTANCE.nextFloat(), + aY - 0.5 + XSTR_INSTANCE.nextFloat(), + aZ - 0.5 + XSTR_INSTANCE.nextFloat()) + .run()); + } + } + + @Override + public final int getCapacity() { + return mCapacity * 20 * mPipeAmount; + } + + @Override + public FluidTankInfo getInfo() { + for (FluidStack tFluid : mFluids) { + if (tFluid != null) return new FluidTankInfo(tFluid, mCapacity * 20); + } + return new FluidTankInfo(null, mCapacity * 20); + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection side) { + if (getCapacity() <= 0 && !getBaseMetaTileEntity().hasSteamEngineUpgrade()) return new FluidTankInfo[] {}; + ArrayList tList = new ArrayList<>(); + for (FluidStack tFluid : mFluids) tList.add(new FluidTankInfo(tFluid, mCapacity * 20)); + return tList.toArray(new FluidTankInfo[mPipeAmount]); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public final FluidStack getFluid() { + for (FluidStack tFluid : mFluids) { + if (tFluid != null) return tFluid; + } + return null; + } + + @Override + public final int getFluidAmount() { + int rAmount = 0; + for (FluidStack tFluid : mFluids) { + if (tFluid != null) rAmount += tFluid.amount; + } + return rAmount; + } + + @Override + public final int fill_default(ForgeDirection side, FluidStack aFluid, boolean doFill) { + if (aFluid == null || aFluid.getFluid() + .getID() <= 0) return 0; + + int index = -1; + for (int i = 0; i < mPipeAmount; i++) { + if (mFluids[i] != null && mFluids[i].isFluidEqual(aFluid)) { + index = i; + break; + } else if ((mFluids[i] == null || mFluids[i].getFluid() + .getID() <= 0) && index < 0) { + index = i; + } + } + + return fill_default_intoIndex(side, aFluid, doFill, index); + } + + private int fill_default_intoIndex(ForgeDirection side, FluidStack aFluid, boolean doFill, int index) { + if (index < 0 || index >= mPipeAmount) return 0; + if (aFluid == null || aFluid.getFluid() + .getID() <= 0) return 0; + + final int ordinalSide = side.ordinal(); + + if (mFluids[index] == null || mFluids[index].getFluid() + .getID() <= 0) { + if (aFluid.amount * mPipeAmount <= getCapacity()) { + if (doFill) { + mFluids[index] = aFluid.copy(); + mLastReceivedFrom |= (1 << ordinalSide); + } + return aFluid.amount; + } + if (doFill) { + mFluids[index] = aFluid.copy(); + mLastReceivedFrom |= (1 << ordinalSide); + mFluids[index].amount = getCapacity() / mPipeAmount; + } + return getCapacity() / mPipeAmount; + } + + if (!mFluids[index].isFluidEqual(aFluid)) return 0; + + final int space = getCapacity() / mPipeAmount - mFluids[index].amount; + if (aFluid.amount <= space) { + if (doFill) { + mFluids[index].amount += aFluid.amount; + mLastReceivedFrom |= (1 << ordinalSide); + } + return aFluid.amount; + } + if (doFill) { + mFluids[index].amount = getCapacity() / mPipeAmount; + mLastReceivedFrom |= (1 << ordinalSide); + } + return space; + } + + @Override + public final FluidStack drain(int maxDrain, boolean doDrain) { + FluidStack drained; + for (int i = 0; i < mPipeAmount; i++) { + if ((drained = drainFromIndex(maxDrain, doDrain, i)) != null) return drained; + } + return null; + } + + private FluidStack drainFromIndex(int maxDrain, boolean doDrain, int index) { + if (index < 0 || index >= mPipeAmount) return null; + if (mFluids[index] == null) return null; + if (mFluids[index].amount <= 0) { + mFluids[index] = null; + return null; + } + + int used = maxDrain; + if (mFluids[index].amount < used) used = mFluids[index].amount; + + if (doDrain) { + mFluids[index].amount -= used; + } + + final FluidStack drained = mFluids[index].copy(); + drained.amount = used; + + if (mFluids[index].amount <= 0) { + mFluids[index] = null; + } + + return drained; + } + + @Override + public int getTankPressure() { + return getFluidAmount() - (getCapacity() / 2); + } + + @Override + public String[] getDescription() { + List descriptions = new ArrayList<>(); + descriptions.add( + EnumChatFormatting.BLUE + "Fluid Capacity: %%%" + + GTUtility.formatNumbers(mCapacity * 20L) + + "%%% L/sec" + + EnumChatFormatting.GRAY); + descriptions.add( + EnumChatFormatting.RED + "Heat Limit: %%%" + + GTUtility.formatNumbers(mHeatResistance) + + "%%% K" + + EnumChatFormatting.GRAY); + if (!mGasProof) { + descriptions.add(EnumChatFormatting.DARK_GREEN + "Cannot handle gas" + EnumChatFormatting.GRAY); + } + if (mPipeAmount != 1) { + descriptions.add(EnumChatFormatting.AQUA + "Pipe Amount: %%%" + mPipeAmount + EnumChatFormatting.GRAY); + } + return descriptions.toArray(new String[0]); + } + + @Override + public float getThickNess() { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x1) != 0) return 0.0625F; + return mThickNess; + } + + @Override + public boolean isLiquidInput(ForgeDirection side) { + return !isInputDisabledAtSide(side); + } + + @Override + public boolean isLiquidOutput(ForgeDirection side) { + return true; + } + + public boolean isInputDisabledAtSide(ForgeDirection side) { + return (mDisableInput & side.flag) != 0; + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x2) != 0) + return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1); + else return getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); + } + + private AxisAlignedBB getActualCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { + final float tSpace = (1f - mThickNess) / 2; + float tSide0 = tSpace; + float tSide1 = 1f - tSpace; + float tSide2 = tSpace; + float tSide3 = 1f - tSpace; + float tSide4 = tSpace; + float tSide5 = 1f - tSpace; + + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.DOWN) != 0) { + tSide0 = tSide2 = tSide4 = 0; + tSide3 = tSide5 = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.UP) != 0) { + tSide2 = tSide4 = 0; + tSide1 = tSide3 = tSide5 = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.NORTH) != 0) { + tSide0 = tSide2 = tSide4 = 0; + tSide1 = tSide5 = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.SOUTH) != 0) { + tSide0 = tSide4 = 0; + tSide1 = tSide3 = tSide5 = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.WEST) != 0) { + tSide0 = tSide2 = tSide4 = 0; + tSide1 = tSide3 = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.EAST) != 0) { + tSide0 = tSide2 = 0; + tSide1 = tSide3 = tSide5 = 1; + } + + final byte tConn = ((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections; + if ((tConn & ForgeDirection.DOWN.flag) != 0) tSide0 = 0f; + if ((tConn & ForgeDirection.UP.flag) != 0) tSide1 = 1f; + if ((tConn & ForgeDirection.NORTH.flag) != 0) tSide2 = 0f; + if ((tConn & ForgeDirection.SOUTH.flag) != 0) tSide3 = 1f; + if ((tConn & ForgeDirection.WEST.flag) != 0) tSide4 = 0f; + if ((tConn & ForgeDirection.EAST.flag) != 0) tSide5 = 1f; + + return AxisAlignedBB + .getBoundingBox(aX + tSide4, aY + tSide0, aZ + tSide2, aX + tSide5, aY + tSide1, aZ + tSide3); + } + + @Override + public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, + List outputAABB, Entity collider) { + super.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider); + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x2) != 0) { + final AxisAlignedBB aabb = getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); + if (inputAABB.intersectsWith(aabb)) outputAABB.add(aabb); + } + } + + @Override + public FluidStack drain(ForgeDirection side, FluidStack aFluid, boolean doDrain) { + if (aFluid == null) return null; + for (int i = 0; i < mFluids.length; ++i) { + final FluidStack f = mFluids[i]; + if (f == null || !f.isFluidEqual(aFluid)) continue; + return drainFromIndex(aFluid.amount, doDrain, i); + } + return null; + } + + private static EnumMap borderMap(ForgeDirection topSide, ForgeDirection bottomSide, + ForgeDirection leftSide, ForgeDirection rightSide) { + final EnumMap sideMap = new EnumMap<>(Border.class); + sideMap.put(TOP, topSide); + sideMap.put(BOTTOM, bottomSide); + sideMap.put(LEFT, leftSide); + sideMap.put(RIGHT, rightSide); + return sideMap; + } + + protected static ForgeDirection getSideAtBorder(ForgeDirection side, Border border) { + return FACE_BORDER_MAP.get(side) + .get(border); + } + + protected enum Border { + + TOP(), + BOTTOM(), + LEFT(), + RIGHT(); + + public final int mask; + + Border() { + mask = 1 << this.ordinal(); + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEFrame.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEFrame.java new file mode 100644 index 0000000000..ec000b6e9c --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEFrame.java @@ -0,0 +1,119 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Dyes; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaPipeEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTLanguageManager; + +public class MTEFrame extends MetaPipeEntity { + + private static final String localizedDescFormat = GTLanguageManager + .addStringLocalization("gt.blockmachines.gt_frame.desc.format", "Just something you can put covers on."); + public final Materials mMaterial; + + public MTEFrame(int aID, String aName, String aNameRegional, Materials aMaterial) { + super(aID, aName, aNameRegional, 0); + mMaterial = aMaterial; + // Hide TileEntity frame in NEI, since we have the block version now that should always be used + codechicken.nei.api.API.hideItem(this.getStackForm(1)); + } + + public MTEFrame(String aName, Materials aMaterial) { + super(aName, 0); + mMaterial = aMaterial; + } + + @Override + public byte getTileEntityBaseType() { + return (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEFrame(mName, mMaterial); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection, int connections, + int colorIndex, boolean active, boolean redstoneLevel) { + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.frameGt.mTextureIndex], + Dyes.getModulation(colorIndex, mMaterial.mRGBa)) }; + } + + @Override + public String[] getDescription() { + return localizedDescFormat.split("\\R"); + } + + @Override + public final boolean isSimpleMachine() { + return true; + } + + @Override + public final boolean isFacingValid(ForgeDirection facing) { + return false; + } + + @Override + public final boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public final boolean renderInside(ForgeDirection side) { + return true; + } + + @Override + public final float getThickNess() { + return 1.0F; + } + + @Override + public final void saveNBTData(NBTTagCompound aNBT) { + /* Do nothing */ + } + + @Override + public final void loadNBTData(NBTTagCompound aNBT) { + /* Do nothing */ + } + + @Override + public final boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public final boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public int connect(ForgeDirection side) { + return 0; + } + + @Override + public void disconnect(ForgeDirection side) { + /* Do nothing */ + } + + @Override + public boolean isMachineBlockUpdateRecursive() { + return true; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatch.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatch.java new file mode 100644 index 0000000000..bd0b3b6f61 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatch.java @@ -0,0 +1,250 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import appeng.api.crafting.ICraftingIconProvider; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +/** + * Handles texture changes internally. No special calls are necessary other than updateTexture in add***ToMachineList. + */ +public abstract class MTEHatch extends MTEBasicTank implements ICraftingIconProvider { + + public enum ConnectionType { + CABLE, + WIRELESS, + LASER + } + + /** + * Uses new texture changing methods to avoid limitations of byte as texture index... + */ + @Deprecated + public byte mMachineBlock = 0; + + private byte mTexturePage = 0; + private byte actualTexture = 0; + + private ItemStack ae2CraftingIcon; + + public MTEHatch(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEHatch(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription, + ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEHatch(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEHatch(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public static int getSlots(int aTier) { + return aTier < 1 ? 1 : aTier == 1 ? 4 : aTier == 2 ? 9 : 16; + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + return new ITexture[0][0][0]; + } + + public abstract ITexture[] getTexturesActive(ITexture aBaseTexture); + + public abstract ITexture[] getTexturesInactive(ITexture aBaseTexture); + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, + int colorIndex, boolean aActive, boolean redstoneLevel) { + int texturePointer = (byte) (actualTexture & 0x7F); // just to be sure, from my testing the 8th bit cannot be + // set clientside + int textureIndex = texturePointer | (mTexturePage << 7); // Shift seven since one page is 128 textures! + try { + if (side != aFacing) { + if (textureIndex > 0) + return new ITexture[] { Textures.BlockIcons.casingTexturePages[mTexturePage][texturePointer] }; + else return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][colorIndex + 1] }; + } else { + if (textureIndex > 0) { + if (aActive) + return getTexturesActive(Textures.BlockIcons.casingTexturePages[mTexturePage][texturePointer]); + else return getTexturesInactive( + Textures.BlockIcons.casingTexturePages[mTexturePage][texturePointer]); + } else { + if (aActive) return getTexturesActive(Textures.BlockIcons.MACHINE_CASINGS[mTier][colorIndex + 1]); + else return getTexturesInactive(Textures.BlockIcons.MACHINE_CASINGS[mTier][colorIndex + 1]); + } + } + } catch (NullPointerException npe) { + return new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[0][0] }; + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setByte("mMachineBlock", actualTexture); + aNBT.setByte("mTexturePage", mTexturePage); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + actualTexture = aNBT.getByte("mMachineBlock"); + mTexturePage = aNBT.getByte("mTexturePage"); + + if (mTexturePage != 0 && GTValues.GT.isServerSide()) actualTexture |= 0x80; // <- lets just hope no one needs + // the correct value for that on + // server + mMachineBlock = actualTexture; + } + + /** + * Sets texture with page and index, called on add to machine list + * + * @param id (page<<7)+index of the texture + */ + public final void updateTexture(int id) { + onValueUpdate((byte) id); + onTexturePageUpdate((byte) (id >> 7)); + } + + /** + * Sets the icon for the owning multiblock used for AE2 crafting display of attached interfaces, called on add to + * machine list + */ + public final void updateCraftingIcon(ItemStack icon) { + this.ae2CraftingIcon = icon; + } + + @Override + public ItemStack getMachineCraftingIcon() { + return this.ae2CraftingIcon; + } + + /** + * Some multiblocks restrict hatches by tier. This method allows hatches to specify custom tier used for + * structure check, while keeping {@link #mTier} for other uses. + * + * @return Tier used for multiblock structure + */ + public byte getTierForStructure() { + return mTier; + } + + /** + * Sets texture with page and index, rather unusable, but kept FFS + * + * @param page page of texure + * @param index index of texure + */ + @Deprecated + public final void updateTexture(byte page, byte index) { + onValueUpdate(index); + onTexturePageUpdate(page); + } + + @Override + public final void onValueUpdate(byte aValue) { + actualTexture = (byte) (aValue & 0x7F); + mMachineBlock = actualTexture; + mTexturePage = 0; + } + + /** + * Get the maximum amount of amperes to work with, which excludes the additional amps in for loss + * + * @return Working amps + */ + public long maxWorkingAmperesIn() { + return maxAmperesIn(); + } + + /** + * Get the type of connection this hatch allows + * + * @return Connection type + */ + public ConnectionType getConnectionType() { + return ConnectionType.CABLE; + } + + @Override + public final byte getUpdateData() { + return (byte) (actualTexture & 0x7F); + } + + public final void onTexturePageUpdate(byte aValue) { + mTexturePage = (byte) (aValue & 0x7F); + if (mTexturePage != 0 && getBaseMetaTileEntity().isServerSide()) { // just to be sure + mMachineBlock |= 0x80; // <- lets just hope no one needs the correct value for that on server + actualTexture = mMachineBlock; + } + // set last bit to allow working of the page reset-er to 0 in rare case when texture id is the same but page + // changes to 0 + } + + public final byte getTexturePage() { + return (byte) (mTexturePage & 0x7F); + } + + @Override + public boolean doesFillContainers() { + return false; + } + + @Override + public boolean doesEmptyContainers() { + return false; + } + + @Override + public boolean canTankBeFilled() { + return false; + } + + @Override + public boolean canTankBeEmptied() { + return false; + } + + @Override + public boolean displaysItemStack() { + return false; + } + + @Override + public boolean displaysStackSize() { + return false; + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { // in that method since it is usually + // not overriden, especially for + // hatches. + if (actualTexture != mMachineBlock) { // revert to page 0 on edition of the field - old code way + actualTexture = (byte) (mMachineBlock & 0x7F); + mMachineBlock = actualTexture; // clear last bit in mMachineBlock since now we are at page 0 after the + // direct field + // change + mTexturePage = 0; // assuming old code only supports page 0 + } + super.onPreTick(aBaseMetaTileEntity, aTick); + } + + // To change to other page -> use the setter method -> updateTexture + + public int getCircuitSlot() { + return -1; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDataAccess.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDataAccess.java new file mode 100644 index 0000000000..38c3102ff2 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDataAccess.java @@ -0,0 +1,169 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_DATA_ACCESS; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; + +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.AssemblyLineUtils; + +public class MTEHatchDataAccess extends MTEHatch implements IAddUIWidgets { + + private int timeout = 4; + + public MTEHatchDataAccess(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 16, + new String[] { "Data Access for Multiblocks", + "Adds " + (aTier == 4 ? 4 : 16) + " extra slots for Data Sticks" }); + } + + public MTEHatchDataAccess(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aTier == 4 ? 4 : 16, aDescription, aTextures); + } + + public MTEHatchDataAccess(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aTier == 4 ? 4 : 16, aDescription, aTextures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_DATA_ACCESS) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_DATA_ACCESS) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchDataAccess(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return mTier >= 8 && !aBaseMetaTileEntity.isActive(); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return mTier >= 8 && !aBaseMetaTileEntity.isActive(); + } + + @Override + public int getInventoryStackLimit() { + return 1; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isActive()) { + timeout--; + if (timeout <= 0) { + aBaseMetaTileEntity.setActive(false); + } + } + } + + public void setActive(boolean mActive) { + getBaseMetaTileEntity().setActive(mActive); + timeout = mActive ? 4 : 0; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (aNBT.getByte("mSticksUpdated") != 1) { + for (int i = 0; i < getSizeInventory(); i++) { + AssemblyLineUtils.processDataStick(getStackInSlot(i)); + } + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + // reminder: remove this marker after many years + aNBT.setByte("mSticksUpdated", (byte) 1); + } + + @Override + public void setInventorySlotContents(int aIndex, ItemStack aStack) { + super.setInventorySlotContents(aIndex, aStack); + AssemblyLineUtils.processDataStick(aStack); + } + + public List getInventoryItems(Predicate filter) { + ArrayList items = new ArrayList<>(); + IGregTechTileEntity te = getBaseMetaTileEntity(); + for (int i = 0; i < te.getSizeInventory(); ++i) { + ItemStack slot = te.getStackInSlot(i); + if (slot != null) { + if (filter != null && filter.test(slot)) { + items.add(slot); + } + } + } + return items; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + if (mTier == 4) { + getBaseMetaTileEntity() + .add2by2Slots(builder, getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_CIRCUIT); + } else { + getBaseMetaTileEntity() + .add4by4Slots(builder, getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_CIRCUIT); + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDynamo.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDynamo.java new file mode 100644 index 0000000000..00f46fe9eb --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchDynamo.java @@ -0,0 +1,109 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; + +public class MTEHatchDynamo extends MTEHatch { + + public MTEHatchDynamo(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 0, + new String[] { "Generating electric Energy from Multiblocks", "Puts out up to 1 Amp" }); + } + + public MTEHatchDynamo(int aID, String aName, String aNameRegional, int aTier, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, 0, aDescription); + } + + public MTEHatchDynamo(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + public MTEHatchDynamo(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public long getMinimumStoredEU() { + return 512; + } + + @Override + public long maxEUOutput() { + return V[mTier]; + } + + @Override + public long maxEUStore() { + return 512L + V[mTier + 1] * 2L; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchDynamo(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchEnergy.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchEnergy.java new file mode 100644 index 0000000000..12d22d3bc7 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchEnergy.java @@ -0,0 +1,123 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; + +public class MTEHatchEnergy extends MTEHatch { + + public MTEHatchEnergy(int aID, String aName, String aNameRegional, int aTier, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, 0, aDescription); + } + + public MTEHatchEnergy(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 0, + new String[] { "Energy Injector for Multiblocks", "Accepts up to 2 Amps" }); + } + + public MTEHatchEnergy(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String[] aDescription, ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEHatchEnergy(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + public MTEHatchEnergy(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + public MTEHatchEnergy(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public long getMinimumStoredEU() { + return 512; + } + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxEUStore() { + return 512L + V[mTier] * 8L; + } + + @Override + public long maxAmperesIn() { + return 2; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchEnergy(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInput.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInput.java new file mode 100644 index 0000000000..c660bcc8f8 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInput.java @@ -0,0 +1,192 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.FLUID_IN_SIGN; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_IN; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.GTMod; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; + +public class MTEHatchInput extends MTEHatch { + + public RecipeMap mRecipeMap = null; + + public MTEHatchInput(int aID, String aName, String aNameRegional, int aTier) { + this( + aID, + aName, + aNameRegional, + aTier, + new String[] { "Fluid Input for Multiblocks", + "Capacity: " + GTUtility.formatNumbers(8000L * (1L << aTier)) + "L" }); + } + + public MTEHatchInput(int aID, String aName, String aNameRegional, int aTier, String[] aDescription) { + this(aID, 3, aName, aNameRegional, aTier, aDescription); + } + + public MTEHatchInput(int aID, int aSlot, String aName, String aNameRegional, int aTier) { + this( + aID, + aSlot, + aName, + aNameRegional, + aTier, + new String[] { "Fluid Input for Multiblocks", "", "Can hold " + aSlot + " types of fluid." }); + mDescriptionArray[1] = "Capacity: " + GTUtility.formatNumbers(getCapacityPerTank(aTier, aSlot)) + "L"; + } + + public MTEHatchInput(int aID, int aSlot, String aName, String aNameRegional, int aTier, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, aSlot, aDescription); + } + + public MTEHatchInput(int aID, String aName, String aNameRegional, int aTier, int allSlotCount, String[] strings) { + super(aID, aName, aNameRegional, aTier, allSlotCount, strings); + } + + public int getCapacityPerTank(int aTier, int aSlot) { + return (int) (8000L * (1L << aTier) / aSlot); + } + + public MTEHatchInput(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 3, aDescription, aTextures); + } + + public MTEHatchInput(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 3, aDescription, aTextures); + } + + public MTEHatchInput(String aName, int aSlots, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aSlots, aDescription, aTextures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(FLUID_IN_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(FLUID_IN_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchInput(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + if (mRecipeMap != null) { + aNBT.setString("recipeMap", mRecipeMap.unlocalizedName); + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + mRecipeMap = RecipeMap.getFromOldIdentifier(aNBT.getString("recipeMap")); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public boolean doesFillContainers() { + // return true; + return false; + } + + @Override + public boolean doesEmptyContainers() { + return true; + } + + @Override + public boolean canTankBeFilled() { + return true; + } + + @Override + public boolean canTankBeEmptied() { + return true; + } + + @Override + public boolean displaysItemStack() { + return true; + } + + @Override + public boolean displaysStackSize() { + return false; + } + + public void updateSlots() { + if (mInventory[getInputSlot()] != null && mInventory[getInputSlot()].stackSize <= 0) + mInventory[getInputSlot()] = null; + } + + @Override + public boolean isFluidInputAllowed(FluidStack aFluid) { + return mRecipeMap == null || mRecipeMap.containsInput(aFluid); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 1; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 0 + && (mRecipeMap == null || mRecipeMap.containsInput(aStack) + || mRecipeMap.containsInput(GTUtility.getFluidForFilledItem(aStack, true))); + } + + @Override + public int getCapacity() { + return 8000 * (1 << mTier); + } + + @Override + public int getTankPressure() { + return -100; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInputBus.java new file mode 100644 index 0000000000..f4f04c38a3 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchInputBus.java @@ -0,0 +1,315 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.ITEM_IN_SIGN; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_IN; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; + +import gregtech.GTMod; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.IConfigurationCircuitSupport; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTClientPreference; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GT_TooltipDataCache; +import gregtech.api.util.extensions.ArrayExt; + +public class MTEHatchInputBus extends MTEHatch implements IConfigurationCircuitSupport, IAddUIWidgets { + + private static final String SORTING_MODE_TOOLTIP = "GT5U.machines.sorting_mode.tooltip"; + private static final String ONE_STACK_LIMIT_TOOLTIP = "GT5U.machines.one_stack_limit.tooltip"; + private static final int BUTTON_SIZE = 18; + + public RecipeMap mRecipeMap = null; + public boolean disableSort; + public boolean disableFilter = true; + public boolean disableLimited = true; + private int uiButtonCount = 0; + + public MTEHatchInputBus(int id, String name, String nameRegional, int tier) { + this(id, name, nameRegional, tier, getSlots(tier) + 1); + } + + protected MTEHatchInputBus(int id, String name, String nameRegional, int tier, int slots, String[] description) { + super(id, name, nameRegional, tier, slots, description); + } + + public MTEHatchInputBus(int id, String name, String nameRegional, int tier, int slots) { + super( + id, + name, + nameRegional, + tier, + slots, + ArrayExt.of( + "Item Input for Multiblocks", + "Shift + right click with screwdriver to turn Sort mode on/off", + "Capacity: " + getSlots(tier) + " stack" + (getSlots(tier) >= 2 ? "s" : ""))); + } + + public MTEHatchInputBus(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + this(aName, aTier, getSlots(aTier) + 1, aDescription, aTextures); + } + + public MTEHatchInputBus(String aName, int aTier, int aSlots, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aSlots, aDescription, aTextures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(ITEM_IN_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(ITEM_IN_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_IN) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex != getCircuitSlot(); + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchInputBus(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public int getCircuitSlotX() { + return 153; + } + + @Override + public int getCircuitSlotY() { + return 63; + } + + @Override + public void initDefaultModes(NBTTagCompound aNBT) { + if (!getBaseMetaTileEntity().getWorld().isRemote) { + GTClientPreference tPreference = GTMod.gregtechproxy + .getClientPreference(getBaseMetaTileEntity().getOwnerUuid()); + if (tPreference != null) disableFilter = !tPreference.isInputBusInitialFilterEnabled(); + } + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.hasInventoryBeenModified()) { + updateSlots(); + } + } + + public void updateSlots() { + for (int i = 0; i < mInventory.length - 1; i++) + if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; + if (!disableSort) fillStacksIntoFirstSlots(); + } + + protected void fillStacksIntoFirstSlots() { + final int L = mInventory.length - 1; + HashMap slots = new HashMap<>(L); + HashMap stacks = new HashMap<>(L); + List order = new ArrayList<>(L); + List validSlots = new ArrayList<>(L); + for (int i = 0; i < L; i++) { + if (!isValidSlot(i)) continue; + validSlots.add(i); + ItemStack s = mInventory[i]; + if (s == null) continue; + GTUtility.ItemId sID = GTUtility.ItemId.createNoCopy(s); + slots.merge(sID, s.stackSize, Integer::sum); + if (!stacks.containsKey(sID)) stacks.put(sID, s); + order.add(sID); + mInventory[i] = null; + } + int slotindex = 0; + for (GTUtility.ItemId sID : order) { + int toSet = slots.get(sID); + if (toSet == 0) continue; + int slot = validSlots.get(slotindex); + slotindex++; + mInventory[slot] = stacks.get(sID) + .copy(); + toSet = Math.min(toSet, mInventory[slot].getMaxStackSize()); + mInventory[slot].stackSize = toSet; + slots.merge(sID, toSet, (a, b) -> a - b); + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setBoolean("disableSort", disableSort); + aNBT.setBoolean("disableFilter", disableFilter); + aNBT.setBoolean("disableLimited", disableLimited); + if (mRecipeMap != null) { + aNBT.setString("recipeMap", mRecipeMap.unlocalizedName); + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + disableSort = aNBT.getBoolean("disableSort"); + disableFilter = aNBT.getBoolean("disableFilter"); + if (aNBT.hasKey("disableLimited")) { + disableLimited = aNBT.getBoolean("disableLimited"); + } + mRecipeMap = RecipeMap.getFromOldIdentifier(aNBT.getString("recipeMap")); + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) + .isGUIClickable()) return; + if (aPlayer.isSneaking()) { + if (disableSort) { + disableSort = false; + } else { + if (disableLimited) { + disableLimited = false; + } else { + disableSort = true; + disableLimited = true; + } + } + GTUtility.sendChatToPlayer( + aPlayer, + StatCollector.translateToLocal("GT5U.hatch.disableSort." + disableSort) + " " + + StatCollector.translateToLocal("GT5U.hatch.disableLimited." + disableLimited)); + } else { + disableFilter = !disableFilter; + GTUtility + .sendChatToPlayer(aPlayer, StatCollector.translateToLocal("GT5U.hatch.disableFilter." + disableFilter)); + } + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (aIndex == getCircuitSlot()) return false; + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == getBaseMetaTileEntity().getFrontFacing() && aIndex != getCircuitSlot() + && (mRecipeMap == null || disableFilter || mRecipeMap.containsInput(aStack)) + && (disableLimited || limitedAllowPutStack(aIndex, aStack)); + } + + protected boolean limitedAllowPutStack(int aIndex, ItemStack aStack) { + for (int i = 0; i < getSizeInventory(); i++) + if (GTUtility.areStacksEqual(GTOreDictUnificator.get_nocopy(aStack), mInventory[i])) return i == aIndex; + return mInventory[aIndex] == null; + } + + @Override + public boolean allowSelectCircuit() { + return true; + } + + @Override + public int getCircuitSlot() { + return getSlots(mTier); + } + + private void addSortStacksButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> !disableSort, + val -> disableSort = !val, + GTUITextures.OVERLAY_BUTTON_SORTING_MODE, + () -> mTooltipCache.getData(SORTING_MODE_TOOLTIP))); + } + + private void addOneStackLimitButton(ModularWindow.Builder builder) { + builder.widget(createToggleButton(() -> !disableLimited, val -> { + disableLimited = !val; + updateSlots(); + }, GTUITextures.OVERLAY_BUTTON_ONE_STACK_LIMIT, () -> mTooltipCache.getData(ONE_STACK_LIMIT_TOOLTIP))); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + buildContext.addCloseListener(() -> uiButtonCount = 0); + addSortStacksButton(builder); + addOneStackLimitButton(builder); + // Remove one for ghost circuit slot + int slotCount = getSizeInventory(); + if (allowSelectCircuit()) { + slotCount = slotCount - 1; + } + // We do this to decouple slot count from tier in here, since there is no reason to do so. + switch (slotCount) { + case 1 -> getBaseMetaTileEntity().add1by1Slot(builder); + case 4 -> getBaseMetaTileEntity().add2by2Slots(builder); + case 9 -> getBaseMetaTileEntity().add3by3Slots(builder); + case 16 -> getBaseMetaTileEntity().add4by4Slots(builder); + default -> {} + } + } + + private Widget createToggleButton(Supplier getter, Consumer setter, UITexture picture, + Supplier tooltipDataSupplier) { + return new CycleButtonWidget().setToggle(getter, setter) + .setStaticTexture(picture) + .setVariableBackground(GTUITextures.BUTTON_STANDARD_TOGGLE) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(7 + (uiButtonCount++ * BUTTON_SIZE), 62) + .setSize(BUTTON_SIZE, BUTTON_SIZE) + .setGTTooltip(tooltipDataSupplier); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMagnet.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMagnet.java new file mode 100644 index 0000000000..660894d0df --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMagnet.java @@ -0,0 +1,102 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.AuthorFourIsTheNumber; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_EMS_HOUSING; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_EMS_HOUSING_GLOW; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.util.ForgeDirection; + +import org.apache.commons.lang3.ArrayUtils; + +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; + +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.common.tileentities.machines.multi.MTEIndustrialElectromagneticSeparator; + +public class MTEHatchMagnet extends MTEHatch { + + public MTEHatchMagnet(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional, 5, 1, "Holds electromagnet for the Magnetic Flux Exhibitor"); + } + + public MTEHatchMagnet(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 1, aDescription[0], aTextures); + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public String[] getDescription() { + return ArrayUtils.addAll(this.mDescriptionArray, AuthorFourIsTheNumber); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new SlotWidget(inventoryHandler, 0).setFilter(MTEIndustrialElectromagneticSeparator::isValidElectromagnet) + .setAccess(true, true) + .setPos(79, 34)); + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(OVERLAY_EMS_HOUSING) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_EMS_HOUSING_GLOW) + .extFacing() + .glow() + .build() }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(OVERLAY_EMS_HOUSING) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_EMS_HOUSING_GLOW) + .extFacing() + .glow() + .build() }; + } + + @Override + public int getInventoryStackLimit() { + return 1; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchMagnet(mName, mTier, mDescriptionArray, mTextures); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMaintenance.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMaintenance.java new file mode 100644 index 0000000000..3a715a541a --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMaintenance.java @@ -0,0 +1,455 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE_IDLE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_AUTOMAINTENANCE_IDLE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_DUCTTAPE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_MAINTENANCE; + +import net.minecraft.entity.EntityLivingBase; +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.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; +import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; +import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import cpw.mods.fml.common.network.NetworkRegistry; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTUtility; +import ic2.core.IHasGui; +import ic2.core.item.ItemToolbox; + +public class MTEHatchMaintenance extends MTEHatch implements IAddUIWidgets, IAlignment { + + private Rotation rotation = Rotation.NORMAL; + + private static ItemStack[] sAutoMaintenanceInputs; + public boolean mWrench = false, mScrewdriver = false, mSoftHammer = false, mHardHammer = false, + mSolderingTool = false, mCrowbar = false, mAuto; + + public MTEHatchMaintenance(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, 1, "For maintaining Multiblocks"); + mAuto = false; + } + + public MTEHatchMaintenance(int aID, String aName, String aNameRegional, int aTier, boolean aAuto) { + super(aID, aName, aNameRegional, aTier, 4, "For automatically maintaining Multiblocks"); + mAuto = aAuto; + } + + public MTEHatchMaintenance(String aName, int aTier, String aDescription, ITexture[][][] aTextures, boolean aAuto) { + super(aName, aTier, aAuto ? 4 : 1, aDescription, aTextures); + mAuto = aAuto; + } + + public MTEHatchMaintenance(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures, + boolean aAuto) { + super(aName, aTier, aAuto ? 4 : 1, aDescription, aTextures); + mAuto = aAuto; + } + + private static ItemStack[] getAutoMaintenanceInputs() { + if (sAutoMaintenanceInputs == null) sAutoMaintenanceInputs = new ItemStack[] { ItemList.Duct_Tape.get(4), + GTOreDictUnificator.get(OrePrefixes.cell, Materials.Lubricant, 2), + GTOreDictUnificator.get(OrePrefixes.screw, Materials.Steel, 4), + GTOreDictUnificator.get(OrePrefixes.circuit, Materials.HV, 2) }; + return sAutoMaintenanceInputs; + } + + @Override + public String[] getDescription() { + String[] desc; + if (mAuto) { + desc = new String[mDescriptionArray.length + 3]; + System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); + desc[mDescriptionArray.length] = "4 Ducttape, 2 Lubricant Cells"; + desc[mDescriptionArray.length + 1] = "4 Steel Screws, 2 HV Circuits"; + desc[mDescriptionArray.length + 2] = "For each autorepair"; + } else { + desc = new String[mDescriptionArray.length + 1]; + System.arraycopy(mDescriptionArray, 0, desc, 0, mDescriptionArray.length); + desc[mDescriptionArray.length] = "Cannot be shared between Multiblocks!"; + } + return desc; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + if (mAuto) return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(OVERLAY_AUTOMAINTENANCE_IDLE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_AUTOMAINTENANCE_IDLE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(OVERLAY_MAINTENANCE) + .extFacing() + .build() }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + if (mAuto) return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(OVERLAY_AUTOMAINTENANCE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_AUTOMAINTENANCE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(OVERLAY_MAINTENANCE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_DUCTTAPE) + .extFacing() + .build() }; + } + + @Override + public void initDefaultModes(NBTTagCompound aNBT) { + getBaseMetaTileEntity().setActive(true); + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return mAuto && GTMod.gregtechproxy.mAMHInteraction; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + if (aTileEntity.getMetaTileID() == 111) + return new MTEHatchMaintenance(mName, mTier, mDescriptionArray, mTextures, true); + return new MTEHatchMaintenance(mName, mTier, mDescriptionArray, mTextures, false); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side, + float aX, float aY, float aZ) { + if (aBaseMetaTileEntity.isClientSide()) return true; + if (side == aBaseMetaTileEntity.getFrontFacing()) { + // only allow OC robot fake player + if (aPlayer instanceof FakePlayer && !aPlayer.getGameProfile() + .getName() + .endsWith(".robot")) return false; + ItemStack tStack = aPlayer.getCurrentEquippedItem(); + if (tStack != null) { + if (tStack.getItem() instanceof ItemToolbox) { + applyToolbox(tStack, aPlayer); + } else if (ItemList.Duct_Tape.isStackEqual(tStack)) { + mWrench = mScrewdriver = mSoftHammer = mHardHammer = mCrowbar = mSolderingTool = true; + getBaseMetaTileEntity().setActive(false); + if (--tStack.stackSize == 0) { + aPlayer.inventory.mainInventory[aPlayer.inventory.currentItem] = null; + } + } else GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + } else { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + } + return true; + } + return false; + } + + public void updateSlots() { + for (int i = 0; i < mInventory.length; i++) + if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + super.onFirstTick(aBaseMetaTileEntity); + if (aBaseMetaTileEntity.isClientSide()) + StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && mAuto && aTick % 100L == 0L) { + aBaseMetaTileEntity.setActive(!isRecipeInputEqual(false)); + } + } + + @Override + public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, + float aX, float aY, float aZ) { + if (wrenchingSide != getBaseMetaTileEntity().getFrontFacing()) + return super.onWrenchRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ); + if (!entityPlayer.isSneaking() && isRotationChangeAllowed()) { + toolSetRotation(null); + return true; + } + return false; + } + + public boolean autoMaintainance() { + return isRecipeInputEqual(true); + } + + public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess) { + ItemStack[] mInputs = getAutoMaintenanceInputs(); + + int amt; + + for (ItemStack tStack : mInputs) { + if (tStack != null) { + amt = tStack.stackSize; + boolean temp = true; + for (ItemStack aStack : mInventory) { + if ((GTUtility.areUnificationsEqual(aStack, tStack, true) + || GTUtility.areUnificationsEqual(GTOreDictUnificator.get(false, aStack), tStack, true))) { + amt -= aStack.stackSize; + if (amt < 1) { + temp = false; + break; + } + } + } + if (temp) return false; + } + } + + if (aDecreaseStacksizeBySuccess) { + for (ItemStack tStack : mInputs) { + if (tStack != null) { + amt = tStack.stackSize; + for (ItemStack aStack : mInventory) { + if ((GTUtility.areUnificationsEqual(aStack, tStack, true) + || GTUtility.areUnificationsEqual(GTOreDictUnificator.get(false, aStack), tStack, true))) { + if (aStack.stackSize < amt) { + amt -= aStack.stackSize; + aStack.stackSize = 0; + } else { + aStack.stackSize -= amt; + amt = 0; + break; + } + } + } + } + } + mCrowbar = true; + mHardHammer = true; + mScrewdriver = true; + mSoftHammer = true; + mSolderingTool = true; + mWrench = true; + updateSlots(); + } + return true; + } + + public void onToolClick(ItemStack aStack, EntityLivingBase aPlayer, IInventory aToolboxInventory) { + if (aStack == null || aPlayer == null) return; + + // Allow IC2 Toolbox with tools to function for maint issues. + if (aStack.getItem() instanceof ItemToolbox && aPlayer instanceof EntityPlayer) { + applyToolbox(aStack, (EntityPlayer) aPlayer); + return; + } + + if (GTUtility.isStackInList(aStack, GregTechAPI.sWrenchList) && !mWrench + && GTModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mWrench = true; + if (GTUtility.isStackInList(aStack, GregTechAPI.sScrewdriverList) && !mScrewdriver + && GTModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mScrewdriver = true; + if (GTUtility.isStackInList(aStack, GregTechAPI.sSoftHammerList) && !mSoftHammer + && GTModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mSoftHammer = true; + if (GTUtility.isStackInList(aStack, GregTechAPI.sHardHammerList) && !mHardHammer + && GTModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mHardHammer = true; + if (GTUtility.isStackInList(aStack, GregTechAPI.sCrowbarList) && !mCrowbar + && GTModHandler.damageOrDechargeItem(aStack, 1, 1000, aPlayer)) mCrowbar = true; + if (!mSolderingTool && GTModHandler.useSolderingIron(aStack, aPlayer, aToolboxInventory)) mSolderingTool = true; + if (GTOreDictUnificator.isItemStackInstanceOf(aStack, "craftingDuctTape")) { + mWrench = mScrewdriver = mSoftHammer = mHardHammer = mCrowbar = mSolderingTool = true; + getBaseMetaTileEntity().setActive(false); + aStack.stackSize--; + } + if (mSolderingTool && aPlayer instanceof EntityPlayerMP tPlayer) { + try { + GTMod.achievements.issueAchievement(tPlayer, "maintainance"); + } catch (Exception ignored) {} + } + } + + public void onToolClick(ItemStack aStack, EntityLivingBase aPlayer) { + onToolClick(aStack, aPlayer, null); + } + + private void applyToolbox(ItemStack aStack, EntityPlayer aPlayer) { + final ItemToolbox aToolbox = (ItemToolbox) aStack.getItem(); + final IHasGui aToolboxGUI = aToolbox.getInventory(aPlayer, aStack); + for (int i = 0; i < aToolboxGUI.getSizeInventory(); i++) { + if (aToolboxGUI.getStackInSlot(i) != null) { + onToolClick(aToolboxGUI.getStackInSlot(i), aPlayer, aToolboxGUI); + if (aToolboxGUI.getStackInSlot(i) != null && aToolboxGUI.getStackInSlot(i).stackSize <= 0) + aToolboxGUI.setInventorySlotContents(i, null); + } + } + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return mAuto && GTMod.gregtechproxy.mAMHInteraction; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (mAuto && GTMod.gregtechproxy.mAMHInteraction) { + for (int i = 0; i < getSizeInventory(); i++) if (GTUtility.areStacksEqual( + GTOreDictUnificator.get(false, aStack), + GTOreDictUnificator.get(false, getStackInSlot(i)))) return i == aIndex; + for (ItemStack tInput : getAutoMaintenanceInputs()) if (GTUtility.areUnificationsEqual(tInput, aStack, true) + || GTUtility.areUnificationsEqual(GTOreDictUnificator.get(false, aStack), tInput, true)) return true; + } + return false; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + if (mAuto) { + getBaseMetaTileEntity().add2by2Slots(builder); + } else { + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.SLOT_MAINTENANCE) + .setPos(78, 33) + .setSize(20, 20)) + .widget(new SlotWidget(BaseSlot.empty()) { + + @Override + public boolean handleDragAndDrop(ItemStack draggedStack, int button) { + return false; + } + + @Override + protected void phantomClick(ClickData clickData, ItemStack cursorStack) { + if (cursorStack == null) return; + onToolClick(cursorStack, getContext().getPlayer()); + if (cursorStack.stackSize < 1) { + getContext().getPlayer().inventory.setItemStack(null); + } + if (getContext().getPlayer() instanceof EntityPlayerMP) { + ((EntityPlayerMP) getContext().getPlayer()).updateHeldItem(); + } + } + }.disableShiftInsert() + .setBackground(GTUITextures.TRANSPARENT) + .setPos(79, 34)) + .widget( + new TextWidget("Click with Tool to repair.").setDefaultColor(COLOR_TEXT_GRAY.get()) + .setPos(8, 12)); + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setByte("mRotation", (byte) rotation.getIndex()); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + rotation = Rotation.byIndex(aNBT.getByte("mRotation")); + super.loadNBTData(aNBT); + } + + @Override + public ExtendedFacing getExtendedFacing() { + return ExtendedFacing.of(getBaseMetaTileEntity().getFrontFacing(), rotation, Flip.NONE); + } + + @Override + public void setExtendedFacing(ExtendedFacing alignment) { + boolean changed = false; + final IGregTechTileEntity base = getBaseMetaTileEntity(); + if (base.getFrontFacing() != alignment.getDirection()) { + base.setFrontFacing(alignment.getDirection()); + changed = true; + } + if (rotation != alignment.getRotation()) { + rotation = alignment.getRotation(); + changed = true; + } + if (changed) { + if (base.isServerSide() && !GregTechAPI.isDummyWorld(base.getWorld())) { + StructureLibAPI.sendAlignment( + (IAlignmentProvider) base, + new NetworkRegistry.TargetPoint( + base.getWorld().provider.dimensionId, + base.getXCoord(), + base.getYCoord(), + base.getZCoord(), + 512)); + } else { + base.issueTextureUpdate(); + } + } + } + + @Override + public IAlignmentLimits getAlignmentLimits() { + return (d, r, f) -> f.isNotFlipped(); + } + + @Override + public boolean isFlipChangeAllowed() { + return false; + } + + @Override + public boolean isRotationChangeAllowed() { + return true; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java new file mode 100644 index 0000000000..179ba56254 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMuffler.java @@ -0,0 +1,208 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_MUFFLER; +import static gregtech.api.objects.XSTR.XSTR_INSTANCE; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.GTMod; +import gregtech.api.enums.ParticleFX; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.WorldSpawnedEventBuilder; +import gregtech.common.Pollution; + +@SuppressWarnings("unused") // Unused API is expected within scope +public class MTEHatchMuffler extends MTEHatch { + + private static final String localizedDescFormat = GTLanguageManager.addStringLocalization( + "gt.blockmachines.hatch.muffler.desc.format", + "Outputs the Pollution (Might cause ... things)%n" + "DO NOT OBSTRUCT THE OUTPUT!%n" + + "Reduces Pollution to %d%%%n" + + "Recovers %d%% of CO2/CO/SO2"); + private final int pollutionReduction = calculatePollutionReduction(100); + private final int pollutionRecover = 100 - pollutionReduction; + private final String[] description = String.format(localizedDescFormat, pollutionReduction, pollutionRecover) + .split("\\R"); + + public MTEHatchMuffler(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, 0, ""); + } + + public MTEHatchMuffler(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String[] aDescription, ITexture... aTextures) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTEHatchMuffler(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + this(aName, aTier, new String[] { aDescription }, aTextures); + } + + public MTEHatchMuffler(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + this(aName, aTier, 0, aDescription, aTextures); + } + + public MTEHatchMuffler(String aName, int aTier, int aInvSlotCount, String[] aDescription, + ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public String[] getDescription() { + return description; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_MUFFLER) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_MUFFLER) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchMuffler(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isClientSide() && this.getBaseMetaTileEntity() + .isActive()) { + pollutionParticles( + this.getBaseMetaTileEntity() + .getWorld(), + ParticleFX.LARGE_SMOKE.toString()); + } + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @SideOnly(Side.CLIENT) + public void pollutionParticles(World aWorld, String name) { + boolean chk1, chk2, chk3; + float ran1 = XSTR_INSTANCE.nextFloat(), ran2, ran3; + chk1 = ran1 * 100 < calculatePollutionReduction(100); + if (Pollution.getPollution(getBaseMetaTileEntity()) >= GTMod.gregtechproxy.mPollutionSmogLimit) { + ran2 = XSTR_INSTANCE.nextFloat(); + ran3 = XSTR_INSTANCE.nextFloat(); + chk2 = ran2 * 100 < calculatePollutionReduction(100); + chk3 = ran3 * 100 < calculatePollutionReduction(100); + if (!(chk1 || chk2 || chk3)) return; + } else { + if (!chk1) return; + ran2 = ran3 = 0.0F; + chk2 = chk3 = false; + } + + final IGregTechTileEntity aMuffler = this.getBaseMetaTileEntity(); + final ForgeDirection aDir = aMuffler.getFrontFacing(); + final float xPos = aDir.offsetX * 0.76F + aMuffler.getXCoord() + 0.25F; + final float yPos = aDir.offsetY * 0.76F + aMuffler.getYCoord() + 0.25F; + final float zPos = aDir.offsetZ * 0.76F + aMuffler.getZCoord() + 0.25F; + + final float ySpd = aDir.offsetY * 0.1F + 0.2F + 0.1F * XSTR_INSTANCE.nextFloat(); + final float xSpd; + final float zSpd; + + if (aDir.offsetY == -1) { + final float temp = XSTR_INSTANCE.nextFloat() * 2 * (float) Math.PI; + xSpd = (float) Math.sin(temp) * 0.1F; + zSpd = (float) Math.cos(temp) * 0.1F; + } else { + xSpd = aDir.offsetX * (0.1F + 0.2F * XSTR_INSTANCE.nextFloat()); + zSpd = aDir.offsetZ * (0.1F + 0.2F * XSTR_INSTANCE.nextFloat()); + } + + final WorldSpawnedEventBuilder.ParticleEventBuilder events = new WorldSpawnedEventBuilder.ParticleEventBuilder() + .setIdentifier(name) + .setWorld(aWorld) + .setMotion(xSpd, ySpd, zSpd); + + if (chk1) { + events + .setPosition( + xPos + ran1 * 0.5F, + yPos + XSTR_INSTANCE.nextFloat() * 0.5F, + zPos + XSTR_INSTANCE.nextFloat() * 0.5F) + .run(); + } + if (chk2) { + events + .setPosition( + xPos + ran2 * 0.5F, + yPos + XSTR_INSTANCE.nextFloat() * 0.5F, + zPos + XSTR_INSTANCE.nextFloat() * 0.5F) + .run(); + } + if (chk3) { + events + .setPosition( + xPos + ran3 * 0.5F, + yPos + XSTR_INSTANCE.nextFloat() * 0.5F, + zPos + XSTR_INSTANCE.nextFloat() * 0.5F) + .run(); + } + } + + public int calculatePollutionReduction(int aPollution) { + if (mTier < 2) { + return aPollution; + } + return (int) ((float) aPollution * ((100F - 12.5F * ((float) mTier - 1F)) / 100F)); + } + + /** + * @param mte The multi-block controller's {@link MetaTileEntity} MetaTileEntity is passed so newer muffler hatches + * can do wacky things with the multis + * @return pollution success + */ + public boolean polluteEnvironment(MetaTileEntity mte) { + if (getBaseMetaTileEntity().getAirAtSide(getBaseMetaTileEntity().getFrontFacing())) { + Pollution.addPollution(getBaseMetaTileEntity(), calculatePollutionReduction(10000)); + return true; + } + return false; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMultiInput.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMultiInput.java new file mode 100644 index 0000000000..9bf061573b --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchMultiInput.java @@ -0,0 +1,299 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_INPUT_HATCH_2x2; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +import com.gtnewhorizons.modularui.api.ModularUITextures; +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.common.fluid.FluidStackTank; +import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; + +public class MTEHatchMultiInput extends MTEHatchInput implements IAddUIWidgets { + + private final FluidStack[] mStoredFluid; + private final FluidStackTank[] fluidTanks; + public final int mCapacityPer; + + public MTEHatchMultiInput(int aID, int aSlot, String aName, String aNameRegional, int aTier) { + super(aID, aSlot, aName, aNameRegional, aTier); + this.mStoredFluid = new FluidStack[aSlot]; + fluidTanks = new FluidStackTank[aSlot]; + mCapacityPer = getCapacityPerTank(aTier, aSlot); + } + + public MTEHatchMultiInput(int aID, int aSlot, String aName, String aNameRegional, int aTier, + String[] aDescription) { + super(aID, aSlot, aName, aNameRegional, aTier, aDescription); + this.mStoredFluid = new FluidStack[aSlot]; + fluidTanks = new FluidStackTank[aSlot]; + mCapacityPer = getCapacityPerTank(aTier, aSlot); + } + + public MTEHatchMultiInput(String aName, int aSlot, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aSlot, aTier, aDescription, aTextures); + this.mStoredFluid = new FluidStack[aSlot]; + fluidTanks = new FluidStackTank[aSlot]; + mCapacityPer = getCapacityPerTank(aTier, aSlot); + for (int i = 0; i < aSlot; i++) { + final int index = i; + fluidTanks[i] = new FluidStackTank( + () -> mStoredFluid[index], + fluid -> mStoredFluid[index] = fluid, + mCapacityPer); + } + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchMultiInput(mName, getMaxType(), mTier, mDescriptionArray, mTextures); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + if (mStoredFluid != null) { + for (int i = 0; i < mStoredFluid.length; i++) { + if (mStoredFluid[i] != null) + aNBT.setTag("mFluid" + i, mStoredFluid[i].writeToNBT(new NBTTagCompound())); + } + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (mStoredFluid != null) { + for (int i = 0; i < mStoredFluid.length; i++) { + if (aNBT.hasKey("mFluid" + i)) { + mStoredFluid[i] = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid" + i)); + } + } + } + } + + @Override + public boolean displaysStackSize() { + return true; + } + + public FluidStack[] getStoredFluid() { + return mStoredFluid; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_INPUT_HATCH_2x2) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_INPUT_HATCH_2x2) }; + } + + public int getMaxType() { + return mStoredFluid.length; + } + + @Override + public FluidStack getFluid() { + for (FluidStack tFluid : mStoredFluid) { + if (tFluid != null && tFluid.amount > 0) return tFluid; + } + return null; + } + + public FluidStack getFluid(int aSlot) { + if (mStoredFluid == null || aSlot < 0 || aSlot >= getMaxType()) return null; + return mStoredFluid[aSlot]; + } + + @Override + public int getFluidAmount() { + if (getFluid() != null) { + return getFluid().amount; + } + return 0; + } + + @Override + public int getCapacity() { + return mCapacityPer; + } + + public int getFirstEmptySlot() { + for (int i = 0; i < mStoredFluid.length; i++) { + if (mStoredFluid[i] == null) return i; + } + return -1; + } + + public boolean hasFluid(FluidStack aFluid) { + if (aFluid == null) return false; + for (FluidStack tFluid : mStoredFluid) { + if (aFluid.isFluidEqual(tFluid)) return true; + } + return false; + } + + public int getFluidSlot(FluidStack tFluid) { + if (tFluid == null) return -1; + for (int i = 0; i < mStoredFluid.length; i++) { + if (tFluid.equals(mStoredFluid[i])) return i; + } + return -1; + } + + public int getFluidAmount(FluidStack tFluid) { + int tSlot = getFluidSlot(tFluid); + if (tSlot != -1) { + return mStoredFluid[tSlot].amount; + } + return 0; + } + + public void setFluid(FluidStack aFluid, int aSlot) { + if (aSlot < 0 || aSlot >= getMaxType()) return; + mStoredFluid[aSlot] = aFluid; + } + + public void addFluid(FluidStack aFluid, int aSlot) { + if (aSlot < 0 || aSlot >= getMaxType()) return; + if (aFluid.equals(mStoredFluid[aSlot])) mStoredFluid[aSlot].amount += aFluid.amount; + if (mStoredFluid[aSlot] == null) mStoredFluid[aSlot] = aFluid.copy(); + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + mFluid = getFluid(); + } + super.onPreTick(aBaseMetaTileEntity, aTick); + } + + @Override + public int fill(FluidStack aFluid, boolean doFill) { + if (aFluid == null || aFluid.getFluid() + .getID() <= 0 || aFluid.amount <= 0 || !canTankBeFilled() || !isFluidInputAllowed(aFluid)) return 0; + if (!hasFluid(aFluid) && getFirstEmptySlot() != -1) { + int tFilled = Math.min(aFluid.amount, mCapacityPer); + if (doFill) { + FluidStack tFluid = aFluid.copy(); + tFluid.amount = tFilled; + addFluid(tFluid, getFirstEmptySlot()); + getBaseMetaTileEntity().markDirty(); + } + return tFilled; + } + if (hasFluid(aFluid)) { + int tLeft = mCapacityPer - getFluidAmount(aFluid); + int tFilled = Math.min(tLeft, aFluid.amount); + if (doFill) { + FluidStack tFluid = aFluid.copy(); + tFluid.amount = tFilled; + addFluid(tFluid, getFluidSlot(tFluid)); + getBaseMetaTileEntity().markDirty(); + } + return tFilled; + } + return 0; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (getFluid() == null || !canTankBeEmptied()) return null; + if (getFluid().amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(getFluid())); + getBaseMetaTileEntity().markDirty(); + return null; + } + FluidStack tRemove = getFluid().copy(); + tRemove.amount = Math.min(maxDrain, tRemove.amount); + if (doDrain) { + getFluid().amount -= tRemove.amount; + getBaseMetaTileEntity().markDirty(); + } + if (getFluid() == null || getFluid().amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(getFluid())); + getBaseMetaTileEntity().markDirty(); + } + return tRemove; + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return fill(resource, doFill); + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack aFluid, boolean doDrain) { + if (aFluid == null || !hasFluid(aFluid)) return null; + FluidStack tStored = mStoredFluid[getFluidSlot(aFluid)]; + if (tStored.amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(tStored)); + getBaseMetaTileEntity().markDirty(); + return null; + } + FluidStack tRemove = tStored.copy(); + tRemove.amount = Math.min(aFluid.amount, tRemove.amount); + if (doDrain) { + tStored.amount -= tRemove.amount; + getBaseMetaTileEntity().markDirty(); + } + if (tStored.amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(tStored)); + getBaseMetaTileEntity().markDirty(); + } + return tRemove; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + FluidTankInfo[] FTI = new FluidTankInfo[getMaxType()]; + for (int i = 0; i < getMaxType(); i++) { + FTI[i] = new FluidTankInfo(mStoredFluid[i], mCapacityPer); + } + return FTI; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide() && mStoredFluid != null) { + for (int i = 0; i < getMaxType(); i++) { + if (mStoredFluid[i] != null && mStoredFluid[i].amount <= 0) { + mStoredFluid[i] = null; + } + } + } + super.onPostTick(aBaseMetaTileEntity, aTick); + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex >= 4; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + final int SLOT_NUMBER = 4; + final Pos2d[] positions = new Pos2d[] { new Pos2d(70, 25), new Pos2d(88, 25), new Pos2d(70, 43), + new Pos2d(88, 43), }; + + for (int i = 0; i < SLOT_NUMBER; i++) { + builder.widget( + new FluidSlotWidget(fluidTanks[i]).setBackground(ModularUITextures.FLUID_SLOT) + .setPos(positions[i])); + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutput.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutput.java new file mode 100644 index 0000000000..3a9dd0dc96 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutput.java @@ -0,0 +1,493 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.FLUID_OUT_SIGN; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; + +import java.lang.ref.WeakReference; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; +import net.minecraftforge.fluids.IFluidHandler; + +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import gregtech.GTMod; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.fluid.IFluidStore; +import gregtech.api.interfaces.metatileentity.IFluidLockable; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtility; +import gregtech.common.gui.modularui.widget.FluidLockWidget; + +public class MTEHatchOutput extends MTEHatch implements IFluidStore, IFluidLockable, IAddUIWidgets { + + private String lockedFluidName = null; + private WeakReference playerThatLockedfluid = null; + public byte mMode = 0; + + public MTEHatchOutput(int aID, String aName, String aNameRegional, int aTier) { + super( + aID, + aName, + aNameRegional, + aTier, + 4, + new String[] { "Fluid Output for Multiblocks", + "Capacity: " + GTUtility.formatNumbers(8000L * (1L << aTier)) + "L", + "Right click with screwdriver to restrict output", + "Can be restricted to put out Items and/or Steam/No Steam/1 specific Fluid", + "Restricted Output Hatches are given priority for Multiblock Fluid output" }); + } + + public MTEHatchOutput(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 4, aDescription, aTextures); + } + + public MTEHatchOutput(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 4, aDescription, aTextures); + } + + public MTEHatchOutput(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, + int inventorySize) { + super(aID, aName, aNameRegional, aTier, inventorySize, aDescription); + } + + public MTEHatchOutput(String name, int tier, int slots, String[] description, ITexture[][][] textures) { + super(name, tier, slots, description, textures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(FLUID_OUT_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(FLUID_OUT_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isLiquidInput(ForgeDirection side) { + return false; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchOutput(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isAllowedToWork() && mFluid != null) { + IFluidHandler tTileEntity = aBaseMetaTileEntity + .getITankContainerAtSide(aBaseMetaTileEntity.getFrontFacing()); + if (tTileEntity != null) { + GTUtility.moveFluid( + aBaseMetaTileEntity, + tTileEntity, + aBaseMetaTileEntity.getFrontFacing(), + Math.max(1, mFluid.amount), + null); + } + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setByte("mMode", mMode); + if (isFluidLocked() && lockedFluidName != null && lockedFluidName.length() != 0) + aNBT.setString("lockedFluidName", lockedFluidName); + else aNBT.removeTag("lockedFluidName"); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + mMode = aNBT.getByte("mMode"); + if (isFluidLocked()) { + lockedFluidName = aNBT.getString("lockedFluidName"); + } + lockedFluidName = GTUtility.isStringInvalid(lockedFluidName) ? null : lockedFluidName; + } + + @Override + public boolean doesFillContainers() { + return true; + } + + @Override + public boolean doesEmptyContainers() { + return false; + } + + @Override + public boolean canTankBeFilled() { + return true; + } + + @Override + public boolean canTankBeEmptied() { + return true; + } + + @Override + public boolean displaysItemStack() { + return true; + } + + @Override + public boolean displaysStackSize() { + return false; + } + + public int getLockedDisplaySlot() { + return 3; + } + + @Override + public boolean isValidSlot(int aIndex) { + // Because getStackDisplaySlot() only allow return one int, this place I only can manually set. + return aIndex != getStackDisplaySlot() && aIndex != getLockedDisplaySlot(); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 1; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == aBaseMetaTileEntity.getFrontFacing() && aIndex == 0; + } + + @Override + public int getCapacity() { + return 8000 * (1 << mTier); + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) + .isGUIClickable()) return; + if (aPlayer.isSneaking()) { + mMode = (byte) ((mMode + 9) % 10); + } else { + mMode = (byte) ((mMode + 1) % 10); + } + final String inBrackets; + switch (mMode) { + case 0 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("108", "Outputs misc. Fluids, Steam and Items")); + this.setLockedFluidName(null); + } + case 1 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("109", "Outputs Steam and Items")); + this.setLockedFluidName(null); + } + case 2 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("110", "Outputs Steam and misc. Fluids")); + this.setLockedFluidName(null); + } + case 3 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("111", "Outputs Steam")); + this.setLockedFluidName(null); + } + case 4 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("112", "Outputs misc. Fluids and Items")); + this.setLockedFluidName(null); + } + case 5 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("113", "Outputs only Items")); + this.setLockedFluidName(null); + } + case 6 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("114", "Outputs only misc. Fluids")); + this.setLockedFluidName(null); + } + case 7 -> { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("115", "Outputs nothing")); + this.setLockedFluidName(null); + } + case 8 -> { + playerThatLockedfluid = new WeakReference<>(aPlayer); + if (mFluid == null) { + this.setLockedFluidName(null); + inBrackets = GTUtility.trans( + "115.3", + "currently none, will be locked to the next that is put in (or use fluid cell to lock)"); + } else { + this.setLockedFluidName( + this.getDrainableStack() + .getFluid() + .getName()); + inBrackets = this.getDrainableStack() + .getLocalizedName(); + } + GTUtility.sendChatToPlayer( + aPlayer, + String + .format("%s (%s)", GTUtility.trans("151.1", "Outputs items and 1 specific Fluid"), inBrackets)); + } + case 9 -> { + playerThatLockedfluid = new WeakReference<>(aPlayer); + if (mFluid == null) { + this.setLockedFluidName(null); + inBrackets = GTUtility.trans( + "115.3", + "currently none, will be locked to the next that is put in (or use fluid cell to lock)"); + } else { + this.setLockedFluidName( + this.getDrainableStack() + .getFluid() + .getName()); + inBrackets = this.getDrainableStack() + .getLocalizedName(); + } + GTUtility.sendChatToPlayer( + aPlayer, + String.format("%s (%s)", GTUtility.trans("151.2", "Outputs 1 specific Fluid"), inBrackets)); + } + } + } + + private boolean tryToLockHatch(EntityPlayer aPlayer, ForgeDirection side) { + if (!getBaseMetaTileEntity().getCoverInfoAtSide(side) + .isGUIClickable()) return false; + if (!isFluidLocked()) return false; + final ItemStack tCurrentItem = aPlayer.inventory.getCurrentItem(); + if (tCurrentItem == null) return false; + FluidStack tFluid = FluidContainerRegistry.getFluidForFilledItem(tCurrentItem); + if (tFluid == null && tCurrentItem.getItem() instanceof IFluidContainerItem) + tFluid = ((IFluidContainerItem) tCurrentItem.getItem()).getFluid(tCurrentItem); + if (tFluid != null) { + if (getLockedFluidName() != null && !getLockedFluidName().equals( + tFluid.getFluid() + .getName())) { + GTUtility.sendChatToPlayer( + aPlayer, + String.format( + "%s %s", + GTUtility.trans( + "151.3", + "Hatch is locked to a different fluid. To change the locking, empty it and made it locked to the next fluid with a screwdriver. Currently locked to"), + StatCollector.translateToLocal(getLockedFluidName()))); + } else { + setLockedFluidName( + tFluid.getFluid() + .getName()); + if (mMode == 8) GTUtility.sendChatToPlayer( + aPlayer, + String.format( + "%s (%s)", + GTUtility.trans("151.1", "Outputs items and 1 specific Fluid"), + tFluid.getLocalizedName())); + else GTUtility.sendChatToPlayer( + aPlayer, + String.format( + "%s (%s)", + GTUtility.trans("151.2", "Outputs 1 specific Fluid"), + tFluid.getLocalizedName())); + } + return true; + } + return false; + } + + public byte getMode() { + return mMode; + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side, + float aX, float aY, float aZ) { + if (tryToLockHatch(aPlayer, side)) return true; + return super.onRightclick(aBaseMetaTileEntity, aPlayer, side, aX, aY, aZ); + } + + public boolean outputsSteam() { + return mMode < 4; + } + + public boolean outputsLiquids() { + return mMode % 2 == 0 || mMode == 9; + } + + public boolean outputsItems() { + return mMode % 4 < 2 && mMode != 9; + } + + @Override + public String getLockedFluidName() { + return lockedFluidName; + } + + @Override + public void setLockedFluidName(String lockedFluidName) { + this.lockedFluidName = lockedFluidName; + markDirty(); + } + + @Override + public void lockFluid(boolean lock) { + if (lock) { + if (!isFluidLocked()) { + this.mMode = 9; + markDirty(); + } + } else { + this.mMode = 0; + setLockedFluidName(null); + markDirty(); + } + } + + @Override + public boolean isFluidLocked() { + return mMode == 8 || mMode == 9; + } + + @Override + public boolean acceptsFluidLock(String name) { + return true; + } + + @Override + public boolean isEmptyAndAcceptsAnyFluid() { + return mMode == 0 && getFluidAmount() == 0; + } + + @Override + public boolean canStoreFluid(@Nonnull FluidStack fluidStack) { + if (mFluid != null && !GTUtility.areFluidsEqual(mFluid, fluidStack)) { + return false; + } + if (isFluidLocked()) { + if (lockedFluidName == null) { + return true; + } + return lockedFluidName.equals( + fluidStack.getFluid() + .getName()); + } + if (GTModHandler.isSteam(fluidStack)) { + return outputsSteam(); + } + return outputsLiquids(); + } + + @Override + public int getTankPressure() { + return +100; + } + + @Override + protected void onEmptyingContainerWhenEmpty() { + if (this.lockedFluidName == null && this.mFluid != null && isFluidLocked()) { + this.setLockedFluidName( + this.mFluid.getFluid() + .getName()); + final EntityPlayer player; + if (playerThatLockedfluid == null || (player = playerThatLockedfluid.get()) == null) return; + GTUtility.sendChatToPlayer( + player, + String.format(GTUtility.trans("151.4", "Successfully locked Fluid to %s"), mFluid.getLocalizedName())); + playerThatLockedfluid = null; + } + } + + @Override + public boolean isGivingInformation() { + return true; + } + + @Override + public String[] getInfoData() { + return new String[] { EnumChatFormatting.BLUE + "Output Hatch" + EnumChatFormatting.RESET, "Stored Fluid:", + EnumChatFormatting.GOLD + (mFluid == null ? "No Fluid" : mFluid.getLocalizedName()) + + EnumChatFormatting.RESET, + EnumChatFormatting.GREEN + GTUtility.formatNumbers(mFluid == null ? 0 : mFluid.amount) + + " L" + + EnumChatFormatting.RESET + + " " + + EnumChatFormatting.YELLOW + + GTUtility.formatNumbers(getCapacity()) + + " L" + + EnumChatFormatting.RESET, + (!isFluidLocked() || lockedFluidName == null) ? "Not Locked" + : ("Locked to " + StatCollector.translateToLocal( + FluidRegistry.getFluidStack(lockedFluidName, 1) + .getUnlocalizedName())) }; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + super.addUIWidgets(builder, buildContext); + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_SCREEN_BLACK) + .setPos(98, 16) + .setSize(71, 45)) + .widget(new FluidLockWidget(this).setPos(149, 41)) + .widget( + new TextWidget("Locked Fluid").setDefaultColor(COLOR_TEXT_WHITE.get()) + .setPos(101, 20)) + .widget(TextWidget.dynamicString(() -> { + FluidStack fluidStack = FluidRegistry.getFluidStack(lockedFluidName, 1); + return fluidStack != null ? fluidStack.getLocalizedName() : "None"; + }) + .setDefaultColor(COLOR_TEXT_WHITE.get()) + .setTextAlignment(Alignment.CenterLeft) + .setMaxWidth(65) + .setPos(101, 30)) + .widget(new FakeSyncWidget.ByteSyncer(() -> mMode, val -> mMode = val)); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutputBus.java new file mode 100644 index 0000000000..31973f935b --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchOutputBus.java @@ -0,0 +1,320 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.Textures.BlockIcons.ITEM_OUT_SIGN; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT; +import static gregtech.api.util.GTUtility.moveMultipleItemStacks; + +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.util.ChatComponentTranslation; +import net.minecraftforge.common.util.ForgeDirection; + +import org.jetbrains.annotations.Nullable; + +import com.gtnewhorizons.modularui.api.forge.ItemHandlerHelper; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; + +import gregtech.GTMod; +import gregtech.api.enums.ItemList; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.widgets.PhantomItemButton; +import gregtech.api.interfaces.IDataCopyable; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IItemLockable; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTUtility; +import gregtech.api.util.extensions.ArrayExt; + +public class MTEHatchOutputBus extends MTEHatch implements IAddUIWidgets, IItemLockable, IDataCopyable { + + private static final String DATA_STICK_DATA_TYPE = "outputBusFilter"; + private static final String LOCKED_ITEM_NBT_KEY = "lockedItem"; + + protected ItemStack lockedItem = null; + + public MTEHatchOutputBus(int aID, String aName, String aNameRegional, int aTier) { + this(aID, aName, aNameRegional, aTier, getSlots(aTier)); + } + + public MTEHatchOutputBus(int id, String name, String nameRegional, int tier, int slots) { + super( + id, + name, + nameRegional, + tier, + slots, + ArrayExt.of( + "Item Output for Multiblocks", + "Capacity: " + getSlots(tier) + " stack" + (getSlots(tier) >= 2 ? "s" : ""), + "Left click with data stick to save filter config", + "Right click with data stick to load filter config")); + } + + public MTEHatchOutputBus(int aID, String aName, String aNameRegional, int aTier, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, getSlots(aTier), aDescription); + } + + public MTEHatchOutputBus(int aID, String aName, String aNameRegional, int aTier, String[] aDescription, + int inventorySize) { + super(aID, aName, aNameRegional, aTier, inventorySize, aDescription); + } + + public MTEHatchOutputBus(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, getSlots(aTier), aDescription, aTextures); + } + + public MTEHatchOutputBus(String name, int tier, int slots, String[] description, ITexture[][][] textures) { + super(name, tier, slots, description, textures); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(ITEM_OUT_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return GTMod.gregtechproxy.mRenderIndicatorsOnHatch + ? new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(ITEM_OUT_SIGN) } + : new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_PIPE_OUT) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return true; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchOutputBus(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + if (!acceptsItemLock() || !(aPlayer instanceof EntityPlayerMP)) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return super.onRightclick(aBaseMetaTileEntity, aPlayer); + } + + final ItemStack dataStick = aPlayer.inventory.getCurrentItem(); + if (!ItemList.Tool_DataStick.isStackEqual(dataStick, false, true)) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return super.onRightclick(aBaseMetaTileEntity, aPlayer); + } + + if (!pasteCopiedData(aPlayer, dataStick.stackTagCompound)) { + aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.output_bus.invalid")); + return false; + } + + aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.output_bus.loaded")); + return true; + + } + + @Override + public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + if (!acceptsItemLock() || !(aPlayer instanceof EntityPlayerMP)) { + return; + } + final ItemStack dataStick = aPlayer.inventory.getCurrentItem(); + if (!ItemList.Tool_DataStick.isStackEqual(dataStick, false, true)) { + return; + } + + dataStick.stackTagCompound = getCopiedData(aPlayer); + dataStick.setStackDisplayName("Output Bus Configuration"); + aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.output_bus.saved")); + } + + @Override + public NBTTagCompound getCopiedData(EntityPlayer player) { + final NBTTagCompound nbt = new NBTTagCompound(); + nbt.setString("type", DATA_STICK_DATA_TYPE); + if (lockedItem != null) { + nbt.setTag(LOCKED_ITEM_NBT_KEY, lockedItem.writeToNBT(new NBTTagCompound())); + } + return nbt; + } + + @Override + public boolean pasteCopiedData(EntityPlayer player, NBTTagCompound nbt) { + if (nbt == null || !DATA_STICK_DATA_TYPE.equals(nbt.getString("type"))) return false; + if (nbt.hasKey(LOCKED_ITEM_NBT_KEY)) { + lockedItem = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(LOCKED_ITEM_NBT_KEY)); + } else { + lockedItem = null; + } + return true; + } + + @Override + public String getCopiedDataIdentifier(EntityPlayer player) { + return DATA_STICK_DATA_TYPE; + } + + /** + * Attempt to store as many items as possible into the internal inventory of this output bus. If you need atomicity + * you should use {@link gregtech.api.interfaces.tileentity.IHasInventory#addStackToSlot(int, ItemStack)} + * + * @param aStack Assume valid. Will be mutated. Take over the ownership. Caller should not retain a reference to + * this stack if the call returns true. + * @return true if stack is fully accepted. false is stack is partially accepted or nothing is accepted + */ + public boolean storeAll(ItemStack aStack) { + markDirty(); + + if (lockedItem != null && !lockedItem.isItemEqual(aStack)) { + return false; + } + + for (int i = 0, mInventoryLength = mInventory.length; i < mInventoryLength && aStack.stackSize > 0; i++) { + ItemStack tSlot = mInventory[i]; + if (GTUtility.isStackInvalid(tSlot)) { + int tRealStackLimit = Math.min(getInventoryStackLimit(), aStack.getMaxStackSize()); + if (aStack.stackSize <= tRealStackLimit) { + mInventory[i] = aStack; + return true; + } + mInventory[i] = aStack.splitStack(tRealStackLimit); + } else { + int tRealStackLimit = Math.min(getInventoryStackLimit(), tSlot.getMaxStackSize()); + if (tSlot.stackSize < tRealStackLimit && tSlot.isItemEqual(aStack) + && ItemStack.areItemStackTagsEqual(tSlot, aStack)) { + if (aStack.stackSize + tSlot.stackSize <= tRealStackLimit) { + mInventory[i].stackSize += aStack.stackSize; + return true; + } else { + // more to serve + aStack.stackSize -= tRealStackLimit - tSlot.stackSize; + mInventory[i].stackSize = tRealStackLimit; + } + } + } + } + return false; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return side == aBaseMetaTileEntity.getFrontFacing(); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && aBaseMetaTileEntity.isAllowedToWork() && (aTick & 0x7) == 0) { + final IInventory tTileEntity = aBaseMetaTileEntity + .getIInventoryAtSide(aBaseMetaTileEntity.getFrontFacing()); + if (tTileEntity != null) { + moveMultipleItemStacks( + aBaseMetaTileEntity, + tTileEntity, + aBaseMetaTileEntity.getFrontFacing(), + aBaseMetaTileEntity.getBackFacing(), + null, + false, + (byte) 64, + (byte) 1, + (byte) 64, + (byte) 1, + mInventory.length); + for (int i = 0; i < mInventory.length; i++) + if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null; + } + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + if (lockedItem != null) { + aNBT.setTag(LOCKED_ITEM_NBT_KEY, lockedItem.writeToNBT(new NBTTagCompound())); + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (aNBT.hasKey(LOCKED_ITEM_NBT_KEY)) { + lockedItem = ItemStack.loadItemStackFromNBT(aNBT.getCompoundTag(LOCKED_ITEM_NBT_KEY)); + } + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + switch (mTier) { + case 0 -> getBaseMetaTileEntity().add1by1Slot(builder); + case 1 -> getBaseMetaTileEntity().add2by2Slots(builder); + case 2 -> getBaseMetaTileEntity().add3by3Slots(builder); + default -> getBaseMetaTileEntity().add4by4Slots(builder); + } + + if (acceptsItemLock()) { + builder.widget( + new PhantomItemButton(this).setPos(getGUIWidth() - 25, 40) + .setBackground(PhantomItemButton.FILTER_BACKGROUND)); + } + } + + @Override + public void setLockedItem(@Nullable ItemStack itemStack) { + if (itemStack == null) { + clearLock(); + } else { + lockedItem = ItemHandlerHelper.copyStackWithSize(itemStack, 1); + } + } + + @Nullable + @Override + public ItemStack getLockedItem() { + return lockedItem; + } + + @Override + public void clearLock() { + lockedItem = null; + } + + @Override + public boolean isLocked() { + return lockedItem != null; + } + + @Override + public boolean acceptsItemLock() { + return true; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchQuadrupleHumongous.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchQuadrupleHumongous.java new file mode 100644 index 0000000000..b0040d0c6a --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchQuadrupleHumongous.java @@ -0,0 +1,27 @@ +package gregtech.api.metatileentity.implementations; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; + +public class MTEHatchQuadrupleHumongous extends MTEHatchMultiInput { + + public MTEHatchQuadrupleHumongous(int aID, int aSlot, String aName, String aNameRegional) { + super(aID, aSlot, aName, aNameRegional, 13); + } + + public MTEHatchQuadrupleHumongous(String aName, int aSlot, int aTier, String[] aDescription, + ITexture[][][] aTextures) { + super(aName, aSlot, aTier, aDescription, aTextures); + } + + @Override + public int getCapacityPerTank(int aTier, int aSlot) { + return 500_000_000; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchQuadrupleHumongous(mName, getMaxType(), mTier, mDescriptionArray, mTextures); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEItem.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEItem.java new file mode 100644 index 0000000000..ba804e834e --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEItem.java @@ -0,0 +1,523 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.ALL_VALID_SIDES; +import static gregtech.api.enums.Textures.BlockIcons.PIPE_RESTRICTOR; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.tileentity.TileEntityHopper; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.GTMod; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.metatileentity.IMetaTileEntityItemPipe; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gregtech.api.metatileentity.MetaPipeEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.CoverBehaviorBase; +import gregtech.api.util.GTUtility; +import gregtech.api.util.ISerializableObject; +import gregtech.common.GTClient; +import gregtech.common.covers.CoverInfo; + +public class MTEItem extends MetaPipeEntity implements IMetaTileEntityItemPipe { + + public final float mThickNess; + public final Materials mMaterial; + public final int mStepSize; + public final int mTickTime; + public int mTransferredItems = 0; + public long mCurrentTransferStartTick = 0; + public ForgeDirection mLastReceivedFrom = ForgeDirection.UNKNOWN, oLastReceivedFrom = ForgeDirection.UNKNOWN; + public boolean mIsRestrictive = false; + private int[] cacheSides; + + public MTEItem(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, + int aInvSlotCount, int aStepSize, boolean aIsRestrictive, int aTickTime) { + super(aID, aName, aNameRegional, aInvSlotCount, false); + mIsRestrictive = aIsRestrictive; + mThickNess = aThickNess; + mMaterial = aMaterial; + mStepSize = aStepSize; + mTickTime = aTickTime; + addInfo(aID); + } + + public MTEItem(int aID, String aName, String aNameRegional, float aThickNess, Materials aMaterial, + int aInvSlotCount, int aStepSize, boolean aIsRestrictive) { + this(aID, aName, aNameRegional, aThickNess, aMaterial, aInvSlotCount, aStepSize, aIsRestrictive, 20); + } + + public MTEItem(String aName, float aThickNess, Materials aMaterial, int aInvSlotCount, int aStepSize, + boolean aIsRestrictive, int aTickTime) { + super(aName, aInvSlotCount); + mIsRestrictive = aIsRestrictive; + mThickNess = aThickNess; + mMaterial = aMaterial; + mStepSize = aStepSize; + mTickTime = aTickTime; + } + + @Override + public byte getTileEntityBaseType() { + return (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEItem(mName, mThickNess, mMaterial, mInventory.length, mStepSize, mIsRestrictive, mTickTime); + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, int aConnections, + int aColorIndex, boolean aConnected, boolean redstoneLevel) { + if (mIsRestrictive) { + if (aConnected) { + float tThickNess = getThickNess(); + if (tThickNess < 0.124F) return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + if (tThickNess < 0.374F) // 0.375 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeTiny.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + if (tThickNess < 0.499F) // 0.500 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeSmall.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + if (tThickNess < 0.749F) // 0.750 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeMedium.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + if (tThickNess < 0.874F) // 0.825 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeLarge.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeHuge.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + } + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)), TextureFactory.of(PIPE_RESTRICTOR) }; + } + if (aConnected) { + float tThickNess = getThickNess(); + if (tThickNess < 0.124F) return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + if (tThickNess < 0.374F) // 0.375 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeTiny.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + if (tThickNess < 0.499F) // 0.500 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeSmall.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + if (tThickNess < 0.749F) // 0.750 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeMedium.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + if (tThickNess < 0.874F) // 0.825 + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeLarge.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipeHuge.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + } + return new ITexture[] { TextureFactory.of( + mMaterial.mIconSet.mTextures[OrePrefixes.pipe.mTextureIndex], + Dyes.getModulation(aColorIndex, mMaterial.mRGBa)) }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return false; + } + + @Override + public boolean isValidSlot(int ignoredSlotIndex) { + return true; + } + + @Override + public final boolean renderInside(ForgeDirection side) { + return false; + } + + @Override + public int getProgresstime() { + return getPipeContent() * 64; + } + + @Override + public int maxProgresstime() { + return getMaxPipeCapacity() * 64; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setByte("mLastReceivedFrom", (byte) mLastReceivedFrom.ordinal()); + if (GTMod.gregtechproxy.gt6Pipe) aNBT.setByte("mConnections", mConnections); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + mLastReceivedFrom = ForgeDirection.getOrientation(aNBT.getByte("mLastReceivedFrom")); + if (GTMod.gregtechproxy.gt6Pipe) { + mConnections = aNBT.getByte("mConnections"); + } + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide() && (aTick - mCurrentTransferStartTick) % 10 == 0) { + if ((aTick - mCurrentTransferStartTick) % mTickTime == 0) { + mTransferredItems = 0; + mCurrentTransferStartTick = 0; + } + + if (!GTMod.gregtechproxy.gt6Pipe || mCheckConnections) checkConnections(); + + if (oLastReceivedFrom == mLastReceivedFrom) { + doTickProfilingInThisTick = false; + + final ArrayList tPipeList = new ArrayList<>(); + + for (boolean temp = true; temp && !isInventoryEmpty() && pipeCapacityCheck();) { + temp = false; + tPipeList.clear(); + for (IMetaTileEntityItemPipe tTileEntity : GTUtility + .sortMapByValuesAcending( + IMetaTileEntityItemPipe.Util.scanPipes(this, new HashMap<>(), 0, false, false)) + .keySet()) { + if (temp) break; + tPipeList.add(tTileEntity); + while (!temp && !isInventoryEmpty() && tTileEntity.sendItemStack(aBaseMetaTileEntity)) + for (IMetaTileEntityItemPipe tPipe : tPipeList) + if (!tPipe.incrementTransferCounter(1)) temp = true; + } + } + } + + if (isInventoryEmpty()) mLastReceivedFrom = ForgeDirection.UNKNOWN; + oLastReceivedFrom = mLastReceivedFrom; + } + } + + @Override + public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer, + float aX, float aY, float aZ) { + if (GTMod.gregtechproxy.gt6Pipe) { + final ForgeDirection tSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); + if (isConnectedAtSide(tSide)) { + disconnect(tSide); + GTUtility.sendChatToPlayer(entityPlayer, GTUtility.trans("215", "Disconnected")); + } else { + if (connect(tSide) > 0) GTUtility.sendChatToPlayer(entityPlayer, GTUtility.trans("214", "Connected")); + } + return true; + } + return false; + } + + @Override + public boolean letsIn(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return coverBehavior.letsItemsIn(side, aCoverID, aCoverVariable, -1, aTileEntity); + } + + @Override + public boolean letsOut(CoverBehavior coverBehavior, ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return coverBehavior.letsItemsOut(side, aCoverID, aCoverVariable, -1, aTileEntity); + } + + @Override + public boolean letsIn(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return coverBehavior.letsItemsIn(side, aCoverID, aCoverVariable, -1, aTileEntity); + } + + @Override + public boolean letsOut(CoverBehaviorBase coverBehavior, ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return coverBehavior.letsItemsOut(side, aCoverID, aCoverVariable, -1, aTileEntity); + } + + @Override + public boolean letsIn(CoverInfo coverInfo) { + return coverInfo.letsItemsOut(-1); + } + + @Override + public boolean letsOut(CoverInfo coverInfo) { + return coverInfo.letsItemsOut(-1); + } + + @Override + public boolean canConnect(ForgeDirection side, TileEntity tileEntity) { + if (tileEntity == null) return false; + + final ForgeDirection oppositeSide = side.getOpposite(); + boolean connectable = GTUtility.isConnectableNonInventoryPipe(tileEntity, oppositeSide); + + final IGregTechTileEntity gTileEntity = (tileEntity instanceof IGregTechTileEntity) + ? (IGregTechTileEntity) tileEntity + : null; + if (gTileEntity != null) { + if (gTileEntity.getMetaTileEntity() == null) return false; + if (gTileEntity.getMetaTileEntity() + .connectsToItemPipe(oppositeSide)) return true; + connectable = true; + } + + if (tileEntity instanceof IInventory) { + if (((IInventory) tileEntity).getSizeInventory() <= 0) return false; + connectable = true; + } + if (tileEntity instanceof ISidedInventory) { + final int[] tSlots = ((ISidedInventory) tileEntity).getAccessibleSlotsFromSide(oppositeSide.ordinal()); + if (tSlots == null || tSlots.length == 0) return false; + connectable = true; + } + + return connectable; + } + + @Override + public boolean getGT6StyleConnection() { + // Yes if GT6 pipes are enabled + return GTMod.gregtechproxy.gt6Pipe; + } + + @Override + public boolean incrementTransferCounter(int aIncrement) { + if (mTransferredItems == 0) mCurrentTransferStartTick = getBaseMetaTileEntity().getTimer(); + mTransferredItems += aIncrement; + return pipeCapacityCheck(); + } + + @Override + public boolean sendItemStack(Object aSender) { + if (pipeCapacityCheck()) { + final byte tOffset = (byte) getBaseMetaTileEntity().getRandomNumber(6); + for (final byte i : ALL_VALID_SIDES) { + final ForgeDirection tSide = ForgeDirection.getOrientation((i + tOffset) % 6); + if (isConnectedAtSide(tSide) + && (isInventoryEmpty() || (tSide != mLastReceivedFrom || aSender != getBaseMetaTileEntity()))) { + if (insertItemStackIntoTileEntity(aSender, tSide)) return true; + } + } + } + return false; + } + + @Override + public boolean insertItemStackIntoTileEntity(Object aSender, ForgeDirection side) { + if (getBaseMetaTileEntity().getCoverInfoAtSide(side) + .letsItemsOut(-1)) { + final TileEntity tInventory = getBaseMetaTileEntity().getTileEntityAtSide(side); + if (tInventory != null && !(tInventory instanceof BaseMetaPipeEntity)) { + if ((!(tInventory instanceof TileEntityHopper) && !(tInventory instanceof TileEntityDispenser)) + || getBaseMetaTileEntity().getMetaIDAtSide(side) != side.getOpposite() + .ordinal()) { + return GTUtility.moveMultipleItemStacks( + aSender, + tInventory, + ForgeDirection.UNKNOWN, + side.getOpposite(), + null, + false, + (byte) 64, + (byte) 1, + (byte) 64, + (byte) 1, + 1) > 0; + } + } + } + return false; + } + + @Override + public boolean pipeCapacityCheck() { + return mTransferredItems <= 0 || getPipeContent() < getMaxPipeCapacity(); + } + + private int getPipeContent() { + return mTransferredItems; + } + + private int getMaxPipeCapacity() { + return Math.max(1, getPipeCapacity()); + } + + /** + * Amount of ItemStacks this Pipe can conduct per Second. + */ + public int getPipeCapacity() { + return mInventory.length; + } + + @Override + public int getStepSize() { + return mStepSize; + } + + @Override + public boolean canInsertItem(int aIndex, ItemStack aStack, int ordinalSide) { + return isConnectedAtSide(ForgeDirection.getOrientation(ordinalSide)) + && super.canInsertItem(aIndex, aStack, ordinalSide); + } + + @Override + public boolean canExtractItem(int aIndex, ItemStack aStack, int ordinalSide) { + return isConnectedAtSide(ForgeDirection.getOrientation(ordinalSide)); + } + + @Override + public int[] getAccessibleSlotsFromSide(int ordinalSide) { + final IGregTechTileEntity tTileEntity = getBaseMetaTileEntity(); + final CoverInfo coverInfo = tTileEntity.getCoverInfoAtSide(ForgeDirection.getOrientation(ordinalSide)); + final boolean tAllow = coverInfo.letsItemsIn(-2) || coverInfo.letsItemsOut(-2); + if (tAllow) { + if (cacheSides == null) cacheSides = super.getAccessibleSlotsFromSide(ordinalSide); + return cacheSides; + } else { + return GTValues.emptyIntArray; + } + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return isConnectedAtSide(side); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (!isConnectedAtSide(side)) return false; + if (isInventoryEmpty()) mLastReceivedFrom = side; + return mLastReceivedFrom == side && mInventory[aIndex] == null; + } + + @Override + public String[] getDescription() { + if (mTickTime == 20) return new String[] { "Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/sec", + "Routing Value: %%%" + GTUtility.formatNumbers(mStepSize) }; + else if (mTickTime % 20 == 0) return new String[] { + "Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + (mTickTime / 20) + "%%% sec", + "Routing Value: %%%" + GTUtility.formatNumbers(mStepSize) }; + else return new String[] { + "Item Capacity: %%%" + getMaxPipeCapacity() + "%%% Stacks/%%%" + mTickTime + "%%% ticks", + "Routing Value: %%%" + GTUtility.formatNumbers(mStepSize) }; + } + + private boolean isInventoryEmpty() { + for (ItemStack tStack : mInventory) if (tStack != null) return false; + return true; + } + + @Override + public float getThickNess() { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x1) != 0) return 0.0625F; + return mThickNess; + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ) { + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x2) != 0) + return AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1, aY + 1, aZ + 1); + else return getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); + } + + private AxisAlignedBB getActualCollisionBoundingBoxFromPool(World ignoredAWorld, int aX, int aY, int aZ) { + final float tSpace = (1f - mThickNess) / 2; + float spaceDown = tSpace; + float spaceUp = 1f - tSpace; + float spaceNorth = tSpace; + float spaceSouth = 1f - tSpace; + float spaceWest = tSpace; + float spaceEast = 1f - tSpace; + + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.DOWN) != 0) { + spaceDown = spaceNorth = spaceWest = 0; + spaceSouth = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.UP) != 0) { + spaceNorth = spaceWest = 0; + spaceUp = spaceSouth = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.NORTH) != 0) { + spaceDown = spaceNorth = spaceWest = 0; + spaceUp = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.SOUTH) != 0) { + spaceDown = spaceWest = 0; + spaceUp = spaceSouth = spaceEast = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.WEST) != 0) { + spaceDown = spaceNorth = spaceWest = 0; + spaceUp = spaceSouth = 1; + } + if (getBaseMetaTileEntity().getCoverIDAtSide(ForgeDirection.EAST) != 0) { + spaceDown = spaceNorth = 0; + spaceUp = spaceSouth = spaceEast = 1; + } + + final byte tConn = ((BaseMetaPipeEntity) getBaseMetaTileEntity()).mConnections; + if ((tConn & ForgeDirection.DOWN.flag) != 0) spaceDown = 0f; + if ((tConn & ForgeDirection.UP.flag) != 0) spaceUp = 1f; + if ((tConn & ForgeDirection.NORTH.flag) != 0) spaceNorth = 0f; + if ((tConn & ForgeDirection.SOUTH.flag) != 0) spaceSouth = 1f; + if ((tConn & ForgeDirection.WEST.flag) != 0) spaceWest = 0f; + if ((tConn & ForgeDirection.EAST.flag) != 0) spaceEast = 1f; + + return AxisAlignedBB.getBoundingBox( + aX + spaceWest, + aY + spaceDown, + aZ + spaceNorth, + aX + spaceEast, + aY + spaceUp, + aZ + spaceSouth); + } + + @Override + public void addCollisionBoxesToList(World aWorld, int aX, int aY, int aZ, AxisAlignedBB inputAABB, + List outputAABB, Entity collider) { + super.addCollisionBoxesToList(aWorld, aX, aY, aZ, inputAABB, outputAABB, collider); + if (GTMod.instance.isClientSide() && (GTClient.hideValue & 0x2) != 0) { + final AxisAlignedBB aabb = getActualCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ); + if (inputAABB.intersectsWith(aabb)) outputAABB.add(aabb); + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java new file mode 100644 index 0000000000..ab70cf25ae --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEMultiBlockBase.java @@ -0,0 +1,2742 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.GTValues.VN; +import static gregtech.api.util.GTUtility.filterValidMTEs; +import static gregtech.api.util.GTUtility.formatNumbers; +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 java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.IntConsumer; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.client.Minecraft; +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.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +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 org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.TestOnly; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.gtnewhorizons.modularui.api.NumberFormatMUI; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.math.Alignment; +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.common.internal.network.NetworkUtils; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.GTMod; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.VoidingMode; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.fluid.IFluidStore; +import gregtech.api.interfaces.metatileentity.IItemLockable; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.modularui.IAddGregtechLogo; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.modularui.IBindPlayerInventoryUI; +import gregtech.api.interfaces.modularui.IControllerWithOptionalFeatures; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.MetaGeneratedTool; +import gregtech.api.logic.ProcessingLogic; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.objects.GTItemStack; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SingleRecipeCheck; +import gregtech.api.util.ExoticEnergyInputHelper; +import gregtech.api.util.GTClientPreference; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtil; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GTWaila; +import gregtech.api.util.OutputHatchWrapper; +import gregtech.api.util.OverclockCalculator; +import gregtech.api.util.ParallelHelper; +import gregtech.api.util.VoidProtectionHelper; +import gregtech.api.util.shutdown.ShutDownReason; +import gregtech.api.util.shutdown.ShutDownReasonRegistry; +import gregtech.client.GTSoundLoop; +import gregtech.common.Pollution; +import gregtech.common.config.machinestats.ConfigMachines; +import gregtech.common.gui.modularui.widget.CheckRecipeResultSyncer; +import gregtech.common.gui.modularui.widget.ShutDownReasonSyncer; +import gregtech.common.items.MetaGeneratedTool01; +import gregtech.common.tileentities.machines.IDualInputHatch; +import gregtech.common.tileentities.machines.IDualInputInventory; +import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch; +import gregtech.common.tileentities.machines.ISmartInputHatch; +import gregtech.common.tileentities.machines.MTEHatchCraftingInputME; +import gregtech.common.tileentities.machines.MTEHatchInputBusME; +import gregtech.common.tileentities.machines.MTEHatchInputME; +import gregtech.common.tileentities.machines.MTEHatchOutputBusME; +import gregtech.common.tileentities.machines.MTEHatchOutputME; +import gregtech.common.tileentities.machines.multi.MTELargeTurbine; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +public abstract class MTEMultiBlockBase extends MetaTileEntity + implements IControllerWithOptionalFeatures, IAddGregtechLogo, IAddUIWidgets, IBindPlayerInventoryUI { + + public static boolean disableMaintenance; + public boolean hasMaintenanceChecks = getDefaultHasMaintenanceChecks(); + public boolean mMachine = false, mWrench = false, mScrewdriver = false, mSoftHammer = false, mHardHammer = false, + mSolderingTool = false, mCrowbar = false, mRunningOnLoad = false; + public boolean mStructureChanged = false; + public int mPollution = 0, mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mEfficiencyIncrease = 0, + mStartUpCheck = 100, mRuntime = 0, mEfficiency = 0; + public volatile boolean mUpdated = false; + public int mUpdate = 0; + public ItemStack[] mOutputItems = null; + public FluidStack[] mOutputFluids = null; + public String mNEI; + public int damageFactorLow = 5; + public float damageFactorHigh = 0.6f; + public int machineMode = 0; + public List machineModeIcons = new ArrayList(); + + public boolean mLockedToSingleRecipe = getDefaultRecipeLockingMode(); + protected boolean inputSeparation = getDefaultInputSeparationMode(); + protected VoidingMode voidingMode = getDefaultVoidingMode(); + protected boolean batchMode = getDefaultBatchMode(); + protected @Nonnull CheckRecipeResult checkRecipeResult = CheckRecipeResultRegistry.NONE; + + protected static final String INPUT_SEPARATION_NBT_KEY = "inputSeparation"; + protected static final String VOID_EXCESS_NBT_KEY = "voidExcess"; + protected static final String VOIDING_MODE_NBT_KEY = "voidingMode"; + protected static final String BATCH_MODE_NBT_KEY = "batchMode"; + protected SingleRecipeCheck mSingleRecipeCheck = null; + + public ArrayList mInputHatches = new ArrayList<>(); + public ArrayList mOutputHatches = new ArrayList<>(); + public ArrayList mInputBusses = new ArrayList<>(); + public ArrayList mOutputBusses = new ArrayList<>(); + public ArrayList mDualInputHatches = new ArrayList<>(); + public ArrayList mSmartInputHatches = new ArrayList<>(); + public ArrayList mDynamoHatches = new ArrayList<>(); + public ArrayList mMufflerHatches = new ArrayList<>(); + public ArrayList mEnergyHatches = new ArrayList<>(); + public ArrayList mMaintenanceHatches = new ArrayList<>(); + protected List mExoticEnergyHatches = new ArrayList<>(); + protected final ProcessingLogic processingLogic; + @SideOnly(Side.CLIENT) + protected GTSoundLoop activitySoundLoop; + + protected long mLastWorkingTick = 0, mTotalRunTime = 0; + private static final int CHECK_INTERVAL = 100; // How often should we check for a new recipe on an idle machine? + private final int randomTickOffset = (int) (Math.random() * CHECK_INTERVAL + 1); + + protected static final byte INTERRUPT_SOUND_INDEX = 8; + protected static final byte PROCESS_START_SOUND_INDEX = 1; + + public MTEMultiBlockBase(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional, 2); + this.processingLogic = null; + MTEMultiBlockBase.disableMaintenance = ConfigMachines.disableMaintenanceChecks; + this.damageFactorLow = ConfigMachines.damageFactorLow; + this.damageFactorHigh = ConfigMachines.damageFactorHigh; + this.mNEI = ""; + if (!shouldCheckMaintenance()) fixAllIssues(); + } + + public MTEMultiBlockBase(String aName) { + super(aName, 2); + this.processingLogic = createProcessingLogic(); + MTEMultiBlockBase.disableMaintenance = ConfigMachines.disableMaintenanceChecks; + this.damageFactorLow = ConfigMachines.damageFactorLow; + this.damageFactorHigh = ConfigMachines.damageFactorHigh; + if (!shouldCheckMaintenance()) fixAllIssues(); + } + + @Override + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { + return side != getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) { + if (supportsSingleRecipeLocking()) { + mLockedToSingleRecipe = !mLockedToSingleRecipe; + if (mLockedToSingleRecipe) { + GTUtility.sendChatToPlayer( + aPlayer, + GTUtility.trans("223", "Single recipe locking enabled. Will lock to next recipe.")); + } else { + GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("220", "Single recipe locking disabled.")); + mSingleRecipeCheck = null; + } + } + } + + @Override + public boolean isSimpleMachine() { + return false; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex > 0; + } + + @Override + public int getProgresstime() { + return mProgresstime; + } + + @Override + public int maxProgresstime() { + return mMaxProgresstime; + } + + public long getTotalRuntimeInTicks() { + return mTotalRunTime; + } + + @Override + public int increaseProgress(int aProgress) { + return aProgress; + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setInteger("mEUt", mEUt); + aNBT.setInteger("mProgresstime", mProgresstime); + aNBT.setInteger("mMaxProgresstime", mMaxProgresstime); + aNBT.setInteger("mEfficiencyIncrease", mEfficiencyIncrease); + aNBT.setInteger("mEfficiency", mEfficiency); + aNBT.setInteger("mPollution", mPollution); + aNBT.setInteger("mRuntime", mRuntime); + aNBT.setLong("mTotalRunTime", mTotalRunTime); + aNBT.setLong("mLastWorkingTick", mLastWorkingTick); + aNBT.setString("checkRecipeResultID", checkRecipeResult.getID()); + aNBT.setTag("checkRecipeResult", checkRecipeResult.writeToNBT(new NBTTagCompound())); + + if (supportsMachineModeSwitch()) { + aNBT.setInteger("machineMode", machineMode); + } + + if (supportsSingleRecipeLocking()) { + aNBT.setBoolean("mLockedToSingleRecipe", mLockedToSingleRecipe); + if (mLockedToSingleRecipe && mSingleRecipeCheck != null) + aNBT.setTag("mSingleRecipeCheck", mSingleRecipeCheck.writeToNBT()); + } + + if (mOutputItems != null) { + aNBT.setInteger("mOutputItemsLength", mOutputItems.length); + for (int i = 0; i < mOutputItems.length; i++) if (mOutputItems[i] != null) { + GTUtility.saveItem(aNBT, "mOutputItem" + i, mOutputItems[i]); + } + } + if (mOutputFluids != null) { + aNBT.setInteger("mOutputFluidsLength", mOutputFluids.length); + for (int i = 0; i < mOutputFluids.length; i++) if (mOutputFluids[i] != null) { + NBTTagCompound tNBT = new NBTTagCompound(); + mOutputFluids[i].writeToNBT(tNBT); + aNBT.setTag("mOutputFluids" + i, tNBT); + } + } + aNBT.setBoolean("mWrench", mWrench); + aNBT.setBoolean("mScrewdriver", mScrewdriver); + aNBT.setBoolean("mSoftHammer", mSoftHammer); + aNBT.setBoolean("mHardHammer", mHardHammer); + aNBT.setBoolean("mSolderingTool", mSolderingTool); + aNBT.setBoolean("mCrowbar", mCrowbar); + aNBT.setBoolean(BATCH_MODE_NBT_KEY, batchMode); + aNBT.setBoolean(INPUT_SEPARATION_NBT_KEY, inputSeparation); + aNBT.setString(VOIDING_MODE_NBT_KEY, voidingMode.name); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + mEUt = aNBT.getInteger("mEUt"); + mProgresstime = aNBT.getInteger("mProgresstime"); + mMaxProgresstime = aNBT.getInteger("mMaxProgresstime"); + if (mMaxProgresstime > 0) mRunningOnLoad = true; + mEfficiencyIncrease = aNBT.getInteger("mEfficiencyIncrease"); + mEfficiency = aNBT.getInteger("mEfficiency"); + mPollution = aNBT.getInteger("mPollution"); + mRuntime = aNBT.getInteger("mRuntime"); + mTotalRunTime = aNBT.getLong("mTotalRunTime"); + mLastWorkingTick = aNBT.getLong("mLastWorkingTick"); + + String checkRecipeResultID = aNBT.getString("checkRecipeResultID"); + if (CheckRecipeResultRegistry.isRegistered(checkRecipeResultID)) { + CheckRecipeResult result = CheckRecipeResultRegistry.getSampleFromRegistry(checkRecipeResultID) + .newInstance(); + result.readFromNBT(aNBT.getCompoundTag("checkRecipeResult")); + checkRecipeResult = result; + } + + if (aNBT.hasKey("machineMode")) { + machineMode = aNBT.getInteger("machineMode"); + } + if (supportsSingleRecipeLocking()) { + mLockedToSingleRecipe = aNBT.getBoolean("mLockedToSingleRecipe"); + if (mLockedToSingleRecipe && aNBT.hasKey("mSingleRecipeCheck", Constants.NBT.TAG_COMPOUND)) { + SingleRecipeCheck c = loadSingleRecipeChecker(aNBT.getCompoundTag("mSingleRecipeCheck")); + if (c != null) mSingleRecipeCheck = c; + // the old recipe is gone. we disable the machine to prevent making garbage in case of shared inputs + // maybe use a better way to inform player in the future. + else getBaseMetaTileEntity().disableWorking(); + } + } + batchMode = aNBT.getBoolean(BATCH_MODE_NBT_KEY); + inputSeparation = aNBT.getBoolean(INPUT_SEPARATION_NBT_KEY); + if (aNBT.hasKey(VOIDING_MODE_NBT_KEY, Constants.NBT.TAG_STRING)) { + voidingMode = VoidingMode.fromName(aNBT.getString(VOIDING_MODE_NBT_KEY)); + } else if (aNBT.hasKey(VOID_EXCESS_NBT_KEY)) { + // backward compatibility + voidingMode = aNBT.getBoolean(VOID_EXCESS_NBT_KEY) ? VoidingMode.VOID_ALL : VoidingMode.VOID_NONE; + } + if (!getAllowedVoidingModes().contains(voidingMode)) voidingMode = getDefaultVoidingMode(); + + int aOutputItemsLength = aNBT.getInteger("mOutputItemsLength"); + if (aOutputItemsLength > 0) { + mOutputItems = new ItemStack[aOutputItemsLength]; + for (int i = 0; i < mOutputItems.length; i++) mOutputItems[i] = GTUtility.loadItem(aNBT, "mOutputItem" + i); + } + + int aOutputFluidsLength = aNBT.getInteger("mOutputFluidsLength"); + if (aOutputFluidsLength > 0) { + mOutputFluids = new FluidStack[aOutputFluidsLength]; + for (int i = 0; i < mOutputFluids.length; i++) + mOutputFluids[i] = GTUtility.loadFluid(aNBT, "mOutputFluids" + i); + } + if (shouldCheckMaintenance()) { + mWrench = aNBT.getBoolean("mWrench"); + mScrewdriver = aNBT.getBoolean("mScrewdriver"); + mSoftHammer = aNBT.getBoolean("mSoftHammer"); + mHardHammer = aNBT.getBoolean("mHardHammer"); + mSolderingTool = aNBT.getBoolean("mSolderingTool"); + mCrowbar = aNBT.getBoolean("mCrowbar"); + } else fixAllIssues(); + } + + protected SingleRecipeCheck loadSingleRecipeChecker(NBTTagCompound aNBT) { + return SingleRecipeCheck.tryLoad(getRecipeMap(), aNBT); + } + + public boolean saveOtherHatchConfiguration(EntityPlayer player) { + return true; + } + + public boolean loadOtherHatchConfiguration(EntityPlayer player) { + return true; + } + + @Override + public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + if (aBaseMetaTileEntity.isServerSide() && GTUtil.saveMultiblockInputConfiguration(this, aPlayer)) { + aPlayer.addChatComponentMessage(new ChatComponentTranslation("GT5U.MULTI_MACHINE_CONFIG.SAVE")); + return; + } + super.onLeftclick(aBaseMetaTileEntity, aPlayer); + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + if (GTUtil.hasMultiblockInputConfiguration(aPlayer.getHeldItem())) { + if (aBaseMetaTileEntity.isServerSide()) { + if (GTUtil.loadMultiblockInputConfiguration(this, aPlayer)) { + aPlayer.addChatComponentMessage(new ChatComponentTranslation("GT5U.MULTI_MACHINE_CONFIG.LOAD")); + } else { + aPlayer + .addChatComponentMessage(new ChatComponentTranslation("GT5U.MULTI_MACHINE_CONFIG.LOAD.FAIL")); + } + } + return true; + } + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public byte getTileEntityBaseType() { + return 2; + } + + /** + * Set the structure as having changed, and trigger an update. + */ + public void onStructureChange() { + mStructureChanged = true; + } + + @Override + public void onMachineBlockUpdate() { + mUpdated = true; + } + + /** + * ClearHatches as a part of structure check. If your multiblock has any hatches that need clearing override this + * method, call super, and clear your own hatches + */ + public void clearHatches() { + mInputHatches.clear(); + mInputBusses.clear(); + mOutputHatches.clear(); + mOutputBusses.clear(); + mDynamoHatches.clear(); + mEnergyHatches.clear(); + setMufflers(false); + mMufflerHatches.clear(); + mMaintenanceHatches.clear(); + mDualInputHatches.clear(); + mSmartInputHatches.clear(); + } + + public boolean checkStructure(boolean aForceReset) { + return checkStructure(aForceReset, getBaseMetaTileEntity()); + } + + public boolean checkStructure(boolean aForceReset, IGregTechTileEntity aBaseMetaTileEntity) { + if (!aBaseMetaTileEntity.isServerSide()) return mMachine; + // Only trigger an update if forced (from onPostTick, generally), or if the structure has changed + if ((mStructureChanged || aForceReset)) { + clearHatches(); + mMachine = checkMachine(aBaseMetaTileEntity, mInventory[1]); + } + mStructureChanged = false; + return mMachine; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + // Time Counter + mTotalRunTime++; + if (mEfficiency < 0) mEfficiency = 0; + if (mUpdated) { + // duct tape fix for too many updates on an overloaded server, causing the structure check to not run + if (mUpdate <= 0) mUpdate = 50; + mUpdated = false; + } + if (--mUpdate == 0 || --mStartUpCheck == 0) { + checkStructure(true, aBaseMetaTileEntity); + } + + if (mStartUpCheck < 0) { + if (mMachine) { + checkMaintenance(); + if (getRepairStatus() > 0) { + runMachine(aBaseMetaTileEntity, aTick); + } else if (aBaseMetaTileEntity.isAllowedToWork()) { + stopMachine(ShutDownReasonRegistry.NO_REPAIR); + } + } else if (aBaseMetaTileEntity.isAllowedToWork()) { + stopMachine(ShutDownReasonRegistry.STRUCTURE_INCOMPLETE); + } + } + aBaseMetaTileEntity.setErrorDisplayID( + (aBaseMetaTileEntity.getErrorDisplayID() & ~127) | (mWrench ? 0 : 1) + | (mScrewdriver ? 0 : 2) + | (mSoftHammer ? 0 : 4) + | (mHardHammer ? 0 : 8) + | (mSolderingTool ? 0 : 16) + | (mCrowbar ? 0 : 32) + | (mMachine ? 0 : 64)); + aBaseMetaTileEntity.setActive(mMaxProgresstime > 0); + boolean active = aBaseMetaTileEntity.isActive() && mPollution > 0; + setMufflers(active); + } else { + if (!aBaseMetaTileEntity.hasMufflerUpgrade()) { + doActivitySound(getActivitySoundLoop()); + } + } + } + + @Override + public void onTickFail(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onTickFail(aBaseMetaTileEntity, aTick); + if (aBaseMetaTileEntity.isServerSide()) { + aBaseMetaTileEntity.disableWorking(); + checkRecipeResult = CheckRecipeResultRegistry.CRASH; + } + } + + public void checkMaintenance() { + if (!shouldCheckMaintenance()) return; + + if (getRepairStatus() != getIdealStatus()) { + for (MTEHatchMaintenance tHatch : filterValidMTEs(mMaintenanceHatches)) { + if (tHatch.mAuto) tHatch.autoMaintainance(); + if (tHatch.mWrench) mWrench = true; + if (tHatch.mScrewdriver) mScrewdriver = true; + if (tHatch.mSoftHammer) mSoftHammer = true; + if (tHatch.mHardHammer) mHardHammer = true; + if (tHatch.mSolderingTool) mSolderingTool = true; + if (tHatch.mCrowbar) mCrowbar = true; + + tHatch.mWrench = false; + tHatch.mScrewdriver = false; + tHatch.mSoftHammer = false; + tHatch.mHardHammer = false; + tHatch.mSolderingTool = false; + tHatch.mCrowbar = false; + } + } + } + + /** + * Starts checking recipe with some operations needed to actually run the check. Overriding this without due care + * may result in dupe of items, hence it's marked as final. + *

+ * See {@link #createProcessingLogic()} or {@link #checkProcessing()} for what you want to override. + * + * @return If successfully found recipe and/or started processing + */ + protected final boolean checkRecipe() { + startRecipeProcessing(); + CheckRecipeResult result = checkProcessing(); + if (!CheckRecipeResultRegistry.isRegistered(result.getID())) { + throw new RuntimeException(String.format("Result %s is not registered for registry", result.getID())); + } + if (result.wasSuccessful()) { + sendStartMultiBlockSoundLoop(); + } + this.checkRecipeResult = result; + endRecipeProcessing(); + // Don't use `result` here because `endRecipeProcessing()` might mutate `this.checkRecipeResult` + return this.checkRecipeResult.wasSuccessful(); + } + + private boolean shouldCheckRecipeThisTick(long aTick) { + // do a recipe check if any crafting input hatch just got pushed in items + boolean shouldCheck = false; + // check all of them (i.e. do not return early) to reset the state of all of them. + for (IDualInputHatch craftingInputMe : mDualInputHatches) { + shouldCheck |= craftingInputMe.justUpdated(); + } + if (shouldCheck) return true; + // Do the same for Smart Input Hatches + for (ISmartInputHatch smartInputHatch : mSmartInputHatches) { + shouldCheck |= smartInputHatch.justUpdated(); + } + if (shouldCheck) return true; + + // Perform more frequent recipe change after the machine just shuts down. + long timeElapsed = mTotalRunTime - mLastWorkingTick; + + if (timeElapsed >= CHECK_INTERVAL) return (mTotalRunTime + randomTickOffset) % CHECK_INTERVAL == 0; + // Batch mode should be a lot less aggressive at recipe checking + if (!isBatchModeEnabled()) { + return timeElapsed == 5 || timeElapsed == 12 + || timeElapsed == 20 + || timeElapsed == 30 + || timeElapsed == 40 + || timeElapsed == 55 + || timeElapsed == 70 + || timeElapsed == 85; + } + return false; + } + + protected void runMachine(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (mMaxProgresstime > 0 && doRandomMaintenanceDamage()) { + if (onRunningTick(mInventory[1])) { + markDirty(); + if (!polluteEnvironment(getPollutionPerTick(mInventory[1]))) { + stopMachine(ShutDownReasonRegistry.POLLUTION_FAIL); + } + if (mMaxProgresstime > 0 && ++mProgresstime >= mMaxProgresstime) { + if (mOutputItems != null) { + for (ItemStack tStack : mOutputItems) { + if (tStack != null) { + try { + GTMod.achievements.issueAchivementHatch( + aBaseMetaTileEntity.getWorld() + .getPlayerEntityByName(aBaseMetaTileEntity.getOwnerName()), + tStack); + } catch (Exception ignored) {} + addOutput(tStack); + } + } + mOutputItems = null; + } + if (mOutputFluids != null) { + addFluidOutputs(mOutputFluids); + if (mOutputFluids.length > 1) { + try { + GTMod.achievements.issueAchievement( + aBaseMetaTileEntity.getWorld() + .getPlayerEntityByName(aBaseMetaTileEntity.getOwnerName()), + "oilplant"); + } catch (Exception ignored) {} + } + mOutputFluids = null; + } + mEfficiency = Math.max( + 0, + Math.min( + mEfficiency + mEfficiencyIncrease, + getMaxEfficiency(mInventory[1]) - ((getIdealStatus() - getRepairStatus()) * 1000))); + mOutputItems = null; + mProgresstime = 0; + mMaxProgresstime = 0; + mEfficiencyIncrease = 0; + mLastWorkingTick = mTotalRunTime; + if (aBaseMetaTileEntity.isAllowedToWork()) { + checkRecipe(); + } + } + } + } else { + // Check if the machine is enabled in the first place! + if (aBaseMetaTileEntity.isAllowedToWork()) { + + if (shouldCheckRecipeThisTick(aTick) || aBaseMetaTileEntity.hasWorkJustBeenEnabled() + || aBaseMetaTileEntity.hasInventoryBeenModified()) { + if (checkRecipe()) { + markDirty(); + } + } + if (mMaxProgresstime <= 0) mEfficiency = Math.max(0, mEfficiency - 1000); + } + } + } + + public boolean polluteEnvironment(int aPollutionLevel) { + mPollution += aPollutionLevel; + for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) { + if (mPollution >= 10000) { + if (tHatch.polluteEnvironment(this)) { + mPollution -= 10000; + } + } else { + break; + } + } + return mPollution < 10000; + } + + protected void sendStartMultiBlockSoundLoop() { + if (getProcessStartSound() != null) { + sendLoopStart(PROCESS_START_SOUND_INDEX); + } + } + + @Override + public void doSound(byte aIndex, double aX, double aY, double aZ) { + super.doSound(aIndex, aX, aY, aZ); + switch (aIndex) { + case PROCESS_START_SOUND_INDEX -> { + if (getProcessStartSound() != null) + GTUtility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); + } + case INTERRUPT_SOUND_INDEX -> GTUtility + .doSoundAtClient(SoundResource.IC2_MACHINES_INTERRUPT_ONE, 100, 1.0F, aX, aY, aZ); + } + } + + @Override + public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { + super.startSoundLoop(aIndex, aX, aY, aZ); + if (aIndex == PROCESS_START_SOUND_INDEX) { + if (getProcessStartSound() != null) + GTUtility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); + } + } + + @SideOnly(Side.CLIENT) + protected void doActivitySound(ResourceLocation activitySound) { + if (getBaseMetaTileEntity().isActive() && activitySound != null) { + if (activitySoundLoop == null) { + activitySoundLoop = new GTSoundLoop(activitySound, getBaseMetaTileEntity(), false, true); + Minecraft.getMinecraft() + .getSoundHandler() + .playSound(activitySoundLoop); + } + } else { + if (activitySoundLoop != null) { + activitySoundLoop = null; + } + } + } + + /** + * @return Time before the start process sound is played again + */ + protected int getTimeBetweenProcessSounds() { + return 100; + } + + /** + * @return Sound that will be played once, when the recipe check was valid + */ + protected SoundResource getProcessStartSound() { + return null; + } + + /** + * @return Sound that will be looped for as long as the machine is doing a recipe + */ + @SideOnly(Side.CLIENT) + protected ResourceLocation getActivitySoundLoop() { + return null; + } + + /** + * Called every tick the Machine runs + */ + public boolean onRunningTick(ItemStack aStack) { + if (mEUt > 0) { + addEnergyOutput(((long) mEUt * mEfficiency) / 10000); + return true; + } + if (mEUt < 0) { + if (!drainEnergyInput(getActualEnergyUsage())) { + stopMachine(ShutDownReasonRegistry.POWER_LOSS); + return false; + } + } + return true; + } + + protected long getActualEnergyUsage() { + return ((long) -mEUt * 10_000) / Math.max(1000, mEfficiency); + } + + /** + * Checks if this is a Correct Machine Part for this kind of Machine (Turbine Rotor for example) + */ + public abstract boolean isCorrectMachinePart(ItemStack aStack); + + /** + * @deprecated Use {@link #createProcessingLogic()} or {@link #checkProcessing()} + */ + @Deprecated + public boolean checkRecipe(ItemStack aStack) { + return false; + } + + /** + * Checks recipe and setup machine if it's successful. + *

+ * For generic machine working with recipemap, use {@link #createProcessingLogic()} to make use of shared codebase. + */ + @Nonnull + public CheckRecipeResult checkProcessing() { + // If no logic is found, try legacy checkRecipe + if (processingLogic == null) { + return checkRecipe(mInventory[1]) ? CheckRecipeResultRegistry.SUCCESSFUL + : CheckRecipeResultRegistry.NO_RECIPE; + } + + setupProcessingLogic(processingLogic); + + CheckRecipeResult result = doCheckRecipe(); + result = postCheckRecipe(result, processingLogic); + // inputs are consumed at this point + updateSlots(); + if (!result.wasSuccessful()) return result; + + mEfficiency = (10000 - (getIdealStatus() - getRepairStatus()) * 1000); + mEfficiencyIncrease = 10000; + mMaxProgresstime = processingLogic.getDuration(); + setEnergyUsage(processingLogic); + + mOutputItems = processingLogic.getOutputItems(); + mOutputFluids = processingLogic.getOutputFluids(); + + return result; + } + + /** + * @return If controller slot should be considered as inputs for {@link #doCheckRecipe} + */ + protected boolean canUseControllerSlotForRecipe() { + return true; + } + + /** + * Initializes processing logic for use. Unlike {@link #createProcessingLogic}, this method is called + * every time checking for recipes. + */ + protected void setupProcessingLogic(ProcessingLogic logic) { + logic.clear(); + logic.setMachine(this); + logic.setRecipeMapSupplier(this::getRecipeMap); + logic.setVoidProtection(protectsExcessItem(), protectsExcessFluid()); + logic.setBatchSize(isBatchModeEnabled() ? getMaxBatchSize() : 1); + logic.setRecipeLocking(this, isRecipeLockingEnabled()); + setProcessingLogicPower(logic); + } + + /** + * Initializes processing logic for use, specifically for power-related parameters. + * Unlike {@link #createProcessingLogic}, this method is called every time checking for recipes. + */ + protected void setProcessingLogicPower(ProcessingLogic logic) { + logic.setAvailableVoltage(getAverageInputVoltage()); + logic.setAvailableAmperage(getMaxInputAmps()); + logic.setAmperageOC(mEnergyHatches.size() != 1); + } + + protected boolean supportsCraftingMEBuffer() { + return true; + } + + /** + * Iterates over hatches and tries to find recipe. Assume {@link #processingLogic} is already set up for use. + * If return value is successful, inputs are consumed. + */ + @Nonnull + protected CheckRecipeResult doCheckRecipe() { + CheckRecipeResult result = CheckRecipeResultRegistry.NO_RECIPE; + // check crafting input hatches first + if (supportsCraftingMEBuffer()) { + for (IDualInputHatch dualInputHatch : mDualInputHatches) { + for (var it = dualInputHatch.inventories(); it.hasNext();) { + IDualInputInventory slot = it.next(); + processingLogic.setInputItems(slot.getItemInputs()); + processingLogic.setInputFluids(slot.getFluidInputs()); + CheckRecipeResult foundResult = processingLogic.process(); + if (foundResult.wasSuccessful()) { + return foundResult; + } + if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { + // Recipe failed in interesting way, so remember that and continue searching + result = foundResult; + } + } + } + } + + processingLogic.setInputFluids(getStoredFluids()); + + if (isInputSeparationEnabled()) { + if (mInputBusses.isEmpty()) { + CheckRecipeResult foundResult = processingLogic.process(); + if (foundResult.wasSuccessful()) { + return foundResult; + } + if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { + // Recipe failed in interesting way, so remember that and continue searching + result = foundResult; + } + } else { + for (MTEHatchInputBus bus : mInputBusses) { + if (bus instanceof MTEHatchCraftingInputME) { + continue; + } + List inputItems = new ArrayList<>(); + for (int i = bus.getSizeInventory() - 1; i >= 0; i--) { + ItemStack stored = bus.getStackInSlot(i); + if (stored != null) { + inputItems.add(stored); + } + } + if (canUseControllerSlotForRecipe() && getControllerSlot() != null) { + inputItems.add(getControllerSlot()); + } + processingLogic.setInputItems(inputItems.toArray(new ItemStack[0])); + CheckRecipeResult foundResult = processingLogic.process(); + if (foundResult.wasSuccessful()) { + return foundResult; + } + if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { + // Recipe failed in interesting way, so remember that and continue searching + result = foundResult; + } + } + } + } else { + List inputItems = getStoredInputs(); + if (canUseControllerSlotForRecipe() && getControllerSlot() != null) { + inputItems.add(getControllerSlot()); + } + processingLogic.setInputItems(inputItems); + CheckRecipeResult foundResult = processingLogic.process(); + if (foundResult.wasSuccessful()) { + return foundResult; + } + if (foundResult != CheckRecipeResultRegistry.NO_RECIPE) { + // Recipe failed in interesting way, so remember that + result = foundResult; + } + } + return result; + } + + /** + * Performs additional check for {@link #processingLogic} after all the calculations are done. + * As many as checks should be done inside of custom {@link ProcessingLogic}, which you can specify with + * {@link #createProcessingLogic()}, because when this method is called, inputs might have been already consumed. + * However, certain checks cannot be done like that; Checking energy overflow should be suppressed for + * long-power machines for example. + * + * @return Modified (or not modified) result + */ + @Nonnull + protected CheckRecipeResult postCheckRecipe(@Nonnull CheckRecipeResult result, + @Nonnull ProcessingLogic processingLogic) { + if (result.wasSuccessful() && processingLogic.getCalculatedEut() > Integer.MAX_VALUE) { + return CheckRecipeResultRegistry.POWER_OVERFLOW; + } + return result; + } + + /** + * Called after {@link #doCheckRecipe} and {@link #postCheckRecipe} being successful. + * Override to set energy usage for this machine. + */ + protected void setEnergyUsage(ProcessingLogic processingLogic) { + // getCalculatedEut() is guaranteed to not exceed int by postCheckRecipe() + mEUt = (int) processingLogic.getCalculatedEut(); + if (mEUt > 0) { + mEUt = (-mEUt); + } + } + + protected int getMaxBatchSize() { + return 128; + } + + /** + * Checks the Machine. You have to assign the MetaTileEntities for the Hatches here. + */ + public abstract boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack); + + /** + * Gets the maximum Efficiency that spare Part can get (0 - 10000) + */ + public abstract int getMaxEfficiency(ItemStack aStack); + + /** + * Gets the pollution this Device outputs to a Muffler per tick (10000 = one Pullution Block) + */ + public int getPollutionPerTick(ItemStack aStack) { + return getPollutionPerSecond(aStack) / 20; + } + + /** + * Gets the pollution produced per second by this multiblock, default to 0. Override this with its actual value in + * the code of the multiblock. + */ + public int getPollutionPerSecond(ItemStack aStack) { + return 0; + } + + /** + * Gets the damage to the ItemStack, usually 0 or 1. + */ + public abstract int getDamageToComponent(ItemStack aStack); + + /** + * If it explodes when the Component has to be replaced. + */ + public abstract boolean explodesOnComponentBreak(ItemStack aStack); + + /** + * @deprecated Use {@link #stopMachine(ShutDownReason)} + */ + @Deprecated + public void stopMachine() { + stopMachine(ShutDownReasonRegistry.NONE); + } + + /** + * @deprecated Use {@link #stopMachine(ShutDownReason)} + */ + @Deprecated + public void criticalStopMachine() { + stopMachine(ShutDownReasonRegistry.CRITICAL_NONE); + } + + public void stopMachine(@Nonnull ShutDownReason reason) { + if (!ShutDownReasonRegistry.isRegistered(reason.getID())) { + throw new RuntimeException(String.format("Reason %s is not registered for registry", reason.getID())); + } + mLastWorkingTick = mTotalRunTime; + mOutputItems = null; + mOutputFluids = null; + mEUt = 0; + mEfficiency = 0; + mProgresstime = 0; + mMaxProgresstime = 0; + mEfficiencyIncrease = 0; + getBaseMetaTileEntity().disableWorking(); + getBaseMetaTileEntity().setShutDownReason(reason); + getBaseMetaTileEntity().setShutdownStatus(true); + if (reason.wasCritical()) { + sendSound(INTERRUPT_SOUND_INDEX); + } + } + + public int getRepairStatus() { + return (mWrench ? 1 : 0) + (mScrewdriver ? 1 : 0) + + (mSoftHammer ? 1 : 0) + + (mHardHammer ? 1 : 0) + + (mSolderingTool ? 1 : 0) + + (mCrowbar ? 1 : 0); + } + + public int getIdealStatus() { + return 6; + } + + public int getCurrentEfficiency(ItemStack itemStack) { + int maxEff = getMaxEfficiency(itemStack); + return maxEff - (getIdealStatus() - getRepairStatus()) * maxEff / 10; + } + + public boolean doRandomMaintenanceDamage() { + if (!isCorrectMachinePart(mInventory[1])) { + stopMachine(ShutDownReasonRegistry.NO_MACHINE_PART); + return false; + } + if (shouldCheckMaintenance() && getRepairStatus() == 0) { + stopMachine(ShutDownReasonRegistry.NO_REPAIR); + return false; + } + if (mRuntime++ > 1000) { + mRuntime = 0; + if (shouldCheckMaintenance() && getBaseMetaTileEntity().getRandomNumber(6000) == 0) { + causeMaintenanceIssue(); + } + if (mInventory[1] != null && getBaseMetaTileEntity().getRandomNumber(2) == 0 + && !mInventory[1].getUnlocalizedName() + .startsWith("gt.blockmachines.basicmachine.")) { + if (mInventory[1].getItem() instanceof MetaGeneratedTool01) { + NBTTagCompound tNBT = mInventory[1].getTagCompound(); + ((MetaGeneratedTool) mInventory[1].getItem()).doDamage( + mInventory[1], + (long) getDamageToComponent(mInventory[1]) + * (long) Math.min(mEUt / this.damageFactorLow, Math.pow(mEUt, this.damageFactorHigh))); + if (mInventory[1].stackSize == 0) mInventory[1] = null; + } + } + } + return true; + } + + public void causeMaintenanceIssue() { + switch (getBaseMetaTileEntity().getRandomNumber(6)) { + case 0 -> mWrench = false; + case 1 -> mScrewdriver = false; + case 2 -> mSoftHammer = false; + case 3 -> mHardHammer = false; + case 4 -> mSolderingTool = false; + case 5 -> mCrowbar = false; + } + } + + public void explodeMultiblock() { + + GTLog.exp.println( + "MultiBlockExplosion at: " + this.getBaseMetaTileEntity() + .getXCoord() + + " | " + + this.getBaseMetaTileEntity() + .getYCoord() + + " | " + + this.getBaseMetaTileEntity() + .getZCoord() + + " DIMID: " + + this.getBaseMetaTileEntity() + .getWorld().provider.dimensionId + + "."); + + Pollution.addPollution(getBaseMetaTileEntity(), GTMod.gregtechproxy.mPollutionOnExplosion); + mInventory[1] = null; + // noinspection unchecked // In this case, the inspection only indicates that the array can be abused in runtime + Iterable allHatches = Iterables.concat( + mInputBusses, + mOutputBusses, + mInputHatches, + mOutputHatches, + mDynamoHatches, + mMufflerHatches, + mEnergyHatches, + mMaintenanceHatches); + for (MetaTileEntity tTileEntity : allHatches) { + if (tTileEntity != null && tTileEntity.getBaseMetaTileEntity() != null) { + tTileEntity.getBaseMetaTileEntity() + .doExplosion(V[8]); + } + } + getBaseMetaTileEntity().doExplosion(V[8]); + } + + public boolean addEnergyOutput(long aEU) { + if (aEU <= 0) { + return true; + } + if (mDynamoHatches.size() > 0) { + return addEnergyOutputMultipleDynamos(aEU, true); + } + return false; + } + + public boolean addEnergyOutputMultipleDynamos(long aEU, boolean aAllowMixedVoltageDynamos) { + int injected = 0; + long totalOutput = 0; + long aFirstVoltageFound = -1; + boolean aFoundMixedDynamos = false; + for (MTEHatchDynamo aDynamo : filterValidMTEs(mDynamoHatches)) { + long aVoltage = aDynamo.maxEUOutput(); + long aTotal = aDynamo.maxAmperesOut() * aVoltage; + // Check against voltage to check when hatch mixing + if (aFirstVoltageFound == -1) { + aFirstVoltageFound = aVoltage; + } else { + if (aFirstVoltageFound != aVoltage) { + aFoundMixedDynamos = true; + } + } + totalOutput += aTotal; + } + + if (totalOutput < aEU || (aFoundMixedDynamos && !aAllowMixedVoltageDynamos)) { + explodeMultiblock(); + return false; + } + + long leftToInject; + long aVoltage; + int aAmpsToInject; + int aRemainder; + int ampsOnCurrentHatch; + for (MTEHatchDynamo aDynamo : filterValidMTEs(mDynamoHatches)) { + leftToInject = aEU - injected; + aVoltage = aDynamo.maxEUOutput(); + aAmpsToInject = (int) (leftToInject / aVoltage); + aRemainder = (int) (leftToInject - (aAmpsToInject * aVoltage)); + ampsOnCurrentHatch = (int) Math.min(aDynamo.maxAmperesOut(), aAmpsToInject); + for (int i = 0; i < ampsOnCurrentHatch; i++) { + aDynamo.getBaseMetaTileEntity() + .increaseStoredEnergyUnits(aVoltage, false); + } + injected += aVoltage * ampsOnCurrentHatch; + if (aRemainder > 0 && ampsOnCurrentHatch < aDynamo.maxAmperesOut()) { + aDynamo.getBaseMetaTileEntity() + .increaseStoredEnergyUnits(aRemainder, false); + injected += aRemainder; + } + } + return injected > 0; + } + + /** + * Sums up voltage of energy hatches. Amperage does not matter. + */ + public long getMaxInputVoltage() { + long rVoltage = 0; + for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) rVoltage += tHatch.getBaseMetaTileEntity() + .getInputVoltage(); + return rVoltage; + } + + public long getAverageInputVoltage() { + return ExoticEnergyInputHelper.getAverageInputVoltageMulti(mEnergyHatches); + } + + public long getMaxInputAmps() { + return ExoticEnergyInputHelper.getMaxWorkingInputAmpsMulti(mEnergyHatches); + } + + public long getMaxInputEu() { + return ExoticEnergyInputHelper.getTotalEuMulti(mEnergyHatches); + } + + /** + * Sums up max input EU/t of energy hatches, amperage included. + */ + public long getMaxInputPower() { + long eut = 0; + for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) { + IGregTechTileEntity baseTile = tHatch.getBaseMetaTileEntity(); + eut += baseTile.getInputVoltage() * baseTile.getInputAmperage(); + } + return eut; + } + + /** + * Returns voltage tier of energy hatches. If multiple tiers are found, returns 0. + */ + public long getInputVoltageTier() { + long rTier = 0; + if (mEnergyHatches.size() > 0) { + rTier = mEnergyHatches.get(0) + .getInputTier(); + for (int i = 1; i < mEnergyHatches.size(); i++) { + if (mEnergyHatches.get(i) + .getInputTier() != rTier) return 0; + } + } + + return rTier; + } + + /** + * Calcualtes the overclockedness using long integers + * + * @param aEUt - recipe EUt + * @param aDuration - recipe Duration + * @param mAmperage - should be 1 ? + * @param maxInputVoltage - Multiblock Max input voltage. Voltage is rounded up to higher tier voltage. + * @param perfectOC - If the Multiblock OCs perfectly, i.e. the large Chemical Reactor + */ + protected void calculateOverclockedNessMultiInternal(long aEUt, int aDuration, int mAmperage, long maxInputVoltage, + boolean perfectOC) { + byte tier = (byte) Math.max(0, GTUtility.getTier(maxInputVoltage)); + OverclockCalculator calculator = new OverclockCalculator().setRecipeEUt(aEUt) + .setEUt(V[tier] * mAmperage) + .setDuration(aDuration) + .setDurationDecreasePerOC(perfectOC ? 4.0 : 2.0) + .calculate(); + mEUt = (int) calculator.getConsumption(); + mMaxProgresstime = calculator.getDuration(); + } + + @Deprecated + protected void calculateOverclockedNessMulti(int aEUt, int aDuration, int mAmperage, long maxInputVoltage) { + calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, false); + } + + protected void calculateOverclockedNessMulti(long aEUt, int aDuration, int mAmperage, long maxInputVoltage) { + calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, false); + } + + @Deprecated + protected void calculatePerfectOverclockedNessMulti(int aEUt, int aDuration, int mAmperage, long maxInputVoltage) { + calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, true); + } + + protected void calculatePerfectOverclockedNessMulti(long aEUt, int aDuration, int mAmperage, long maxInputVoltage) { + calculateOverclockedNessMultiInternal(aEUt, aDuration, mAmperage, maxInputVoltage, true); + } + + public boolean drainEnergyInput(long aEU) { + if (aEU <= 0) return true; + for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) { + if (tHatch.getBaseMetaTileEntity() + .decreaseStoredEnergyUnits(aEU, false)) return true; + } + return false; + } + + protected static boolean dumpFluid(List aOutputHatches, FluidStack copiedFluidStack, + boolean restrictiveHatchesOnly) { + for (MTEHatchOutput tHatch : filterValidMTEs(aOutputHatches)) { + if (restrictiveHatchesOnly && tHatch.mMode == 0) { + continue; + } + if (!tHatch.canStoreFluid(copiedFluidStack)) continue; + int tAmount = tHatch.fill(copiedFluidStack, false); + if (tAmount >= copiedFluidStack.amount) { + boolean filled = tHatch.fill(copiedFluidStack, true) >= copiedFluidStack.amount; + tHatch.onEmptyingContainerWhenEmpty(); + return filled; + } else if (tAmount > 0) { + copiedFluidStack.amount = copiedFluidStack.amount - tHatch.fill(copiedFluidStack, true); + tHatch.onEmptyingContainerWhenEmpty(); + } + } + return false; + } + + public boolean addOutput(FluidStack aLiquid) { + if (aLiquid == null) return false; + FluidStack copiedFluidStack = aLiquid.copy(); + if (!dumpFluid(mOutputHatches, copiedFluidStack, true)) { + dumpFluid(mOutputHatches, copiedFluidStack, false); + } + return false; + } + + protected void addFluidOutputs(FluidStack[] mOutputFluids2) { + for (FluidStack outputFluidStack : mOutputFluids2) { + addOutput(outputFluidStack); + } + } + + public boolean depleteInput(FluidStack aLiquid) { + return depleteInput(aLiquid, false); + } + + public boolean depleteInput(FluidStack aLiquid, boolean simulate) { + if (aLiquid == null) return false; + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + setHatchRecipeMap(tHatch); + FluidStack tLiquid = tHatch.drain(ForgeDirection.UNKNOWN, aLiquid, false); + if (tLiquid != null && tLiquid.amount >= aLiquid.amount) { + if (simulate) { + return true; + } + tLiquid = tHatch.drain(ForgeDirection.UNKNOWN, aLiquid, true); + return tLiquid != null && tLiquid.amount >= aLiquid.amount; + } + } + return false; + } + + public boolean addOutput(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return false; + aStack = GTUtility.copyOrNull(aStack); + + final List filteredBuses = filterValidMTEs(mOutputBusses); + if (dumpItem(filteredBuses, aStack, true) || dumpItem(filteredBuses, aStack, false)) { + return true; + } + + boolean outputSuccess = true; + // noinspection DataFlowIssue + while (outputSuccess && aStack.stackSize > 0) { + outputSuccess = false; + ItemStack single = aStack.splitStack(1); + for (MTEHatchOutput tHatch : filterValidMTEs(mOutputHatches)) { + if (!outputSuccess && tHatch.outputsItems()) { + if (tHatch.getBaseMetaTileEntity() + .addStackToSlot(1, single)) outputSuccess = true; + } + } + } + return outputSuccess; + } + + private boolean dumpItem(List outputBuses, ItemStack itemStack, boolean restrictiveBusesOnly) { + for (MTEHatchOutputBus outputBus : outputBuses) { + if (restrictiveBusesOnly && !outputBus.isLocked()) { + continue; + } + + if (outputBus.storeAll(itemStack)) { + return true; + } + } + + return false; + } + + public boolean depleteInput(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return false; + FluidStack aLiquid = GTUtility.getFluidForFilledItem(aStack, true); + if (aLiquid != null) return depleteInput(aLiquid); + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + setHatchRecipeMap(tHatch); + if (GTUtility.areStacksEqual( + aStack, + tHatch.getBaseMetaTileEntity() + .getStackInSlot(0))) { + if (tHatch.getBaseMetaTileEntity() + .getStackInSlot(0).stackSize >= aStack.stackSize) { + tHatch.getBaseMetaTileEntity() + .decrStackSize(0, aStack.stackSize); + return true; + } + } + } + for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) { + tHatch.mRecipeMap = getRecipeMap(); + for (int i = tHatch.getBaseMetaTileEntity() + .getSizeInventory() - 1; i >= 0; i--) { + if (GTUtility.areStacksEqual( + aStack, + tHatch.getBaseMetaTileEntity() + .getStackInSlot(i))) { + if (tHatch.getBaseMetaTileEntity() + .getStackInSlot(i).stackSize >= aStack.stackSize) { + tHatch.getBaseMetaTileEntity() + .decrStackSize(i, aStack.stackSize); + return true; + } + } + } + } + return false; + } + + public ArrayList getStoredOutputs() { + ArrayList rList = new ArrayList<>(); + for (MTEHatchOutputBus tHatch : filterValidMTEs(mOutputBusses)) { + for (int i = tHatch.getBaseMetaTileEntity() + .getSizeInventory() - 1; i >= 0; i--) { + rList.add( + tHatch.getBaseMetaTileEntity() + .getStackInSlot(i)); + } + } + return rList; + } + + public ArrayList getStoredFluids() { + ArrayList rList = new ArrayList<>(); + Map inputsFromME = new HashMap<>(); + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + setHatchRecipeMap(tHatch); + if (tHatch instanceof MTEHatchMultiInput multiInputHatch) { + for (FluidStack tFluid : multiInputHatch.getStoredFluid()) { + if (tFluid != null) { + rList.add(tFluid); + } + } + } else if (tHatch instanceof MTEHatchInputME meHatch) { + for (FluidStack fluidStack : meHatch.getStoredFluids()) { + if (fluidStack != null) { + // Prevent the same fluid from different ME hatches from being recognized + inputsFromME.put(fluidStack.getFluid(), fluidStack); + } + } + } else { + if (tHatch.getFillableStack() != null) { + rList.add(tHatch.getFillableStack()); + } + } + } + + if (!inputsFromME.isEmpty()) { + rList.addAll(inputsFromME.values()); + } + return rList; + } + + /** + * Drains fluid from the given hatch, including {@link IDualInputHatch}. Should never be used during recipe check! + * + * @param doDrain If false, fluid will not actually be consumed + * @return Whether the hatch contains enough fluid to drain + */ + public boolean drain(MTEHatch hatch, FluidStack fluid, boolean doDrain) { + if (fluid == null || hatch == null) return false; + if (supportsCraftingMEBuffer() && hatch instanceof IDualInputHatch tHatch && tHatch.supportsFluids()) { + Optional inventory = tHatch.getFirstNonEmptyInventory(); + if (inventory.isPresent()) { + for (FluidStack storedFluid : Lists.newArrayList( + inventory.get() + .getFluidInputs())) { + if (fluid.isFluidEqual(storedFluid)) { + if (doDrain) storedFluid.amount = Math.max(storedFluid.amount - fluid.amount, 0); + return storedFluid.amount >= fluid.amount; + } + } + } + } + + if (hatch instanceof MTEHatchInput tHatch && tHatch.isValid()) { + if (tHatch instanceof MTEHatchInputME meHatch) { + meHatch.startRecipeProcessing(); + FluidStack tFluid = meHatch.drain(ForgeDirection.UNKNOWN, fluid, doDrain); + meHatch.endRecipeProcessing(this); + return tFluid != null && tFluid.amount >= fluid.amount; + } else { + FluidStack tFluid = tHatch.drain(ForgeDirection.UNKNOWN, fluid, doDrain); + return tFluid != null && tFluid.amount >= fluid.amount; + } + } + + return false; + } + + public ArrayList getStoredInputs() { + ArrayList rList = new ArrayList<>(); + Map inputsFromME = new HashMap<>(); + for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) { + if (tHatch instanceof MTEHatchCraftingInputME) { + continue; + } + tHatch.mRecipeMap = getRecipeMap(); + IGregTechTileEntity tileEntity = tHatch.getBaseMetaTileEntity(); + boolean isMEBus = tHatch instanceof MTEHatchInputBusME; + for (int i = tileEntity.getSizeInventory() - 1; i >= 0; i--) { + ItemStack itemStack = tileEntity.getStackInSlot(i); + if (itemStack != null) { + if (isMEBus) { + // Prevent the same item from different ME buses from being recognized + inputsFromME.put(GTUtility.ItemId.createNoCopy(itemStack), itemStack); + } else { + rList.add(itemStack); + } + } + } + } + + if (getStackInSlot(1) != null && getStackInSlot(1).getUnlocalizedName() + .startsWith("gt.integrated_circuit")) rList.add(getStackInSlot(1)); + if (!inputsFromME.isEmpty()) { + rList.addAll(inputsFromME.values()); + } + return rList; + } + + /** + * Anything that is usually separated off in {@link #getStoredInputs()} (like crafting input bus/buffer) is also + * included here. + */ + public ArrayList getAllStoredInputs() { + ArrayList rList = new ArrayList<>(); + + if (supportsCraftingMEBuffer()) { + for (IDualInputHatch dualInputHatch : mDualInputHatches) { + Iterator inventoryIterator = dualInputHatch.inventories(); + while (inventoryIterator.hasNext()) { + ItemStack[] items = inventoryIterator.next() + .getItemInputs(); + if (items == null) { + continue; + } + for (int i = 0; i < items.length; i++) { + ItemStack item = items[i]; + if (item != null) { + rList.add(item); + } + } + } + } + } + + Map inputsFromME = new HashMap<>(); + for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) { + if (tHatch instanceof MTEHatchCraftingInputME) { + continue; + } + tHatch.mRecipeMap = getRecipeMap(); + IGregTechTileEntity tileEntity = tHatch.getBaseMetaTileEntity(); + boolean isMEBus = tHatch instanceof MTEHatchInputBusME; + for (int i = tileEntity.getSizeInventory() - 1; i >= 0; i--) { + ItemStack itemStack = tileEntity.getStackInSlot(i); + if (itemStack != null) { + if (isMEBus) { + // Prevent the same item from different ME buses from being recognized + inputsFromME.put(GTUtility.ItemId.createNoCopy(itemStack), itemStack); + } else { + rList.add(itemStack); + } + } + } + } + + if (getStackInSlot(1) != null && getStackInSlot(1).getUnlocalizedName() + .startsWith("gt.integrated_circuit")) rList.add(getStackInSlot(1)); + if (!inputsFromME.isEmpty()) { + rList.addAll(inputsFromME.values()); + } + return rList; + } + + public Map getStoredInputsFromME() { + Map inputsFromME = new Object2ReferenceOpenHashMap<>(); + for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) { + if (tHatch instanceof MTEHatchInputBusME meBus) { + for (int i = meBus.getSizeInventory() - 1; i >= 0; i--) { + ItemStack itemStack = meBus.getStackInSlot(i); + if (itemStack != null) { + // Prevent the same item from different ME buses from being recognized + inputsFromME.put(GTUtility.ItemId.createNoCopy(itemStack), itemStack); + } + } + } + } + return inputsFromME; + } + + public Map getStoredFluidsFromME() { + Map fluidsFromME = new Reference2ReferenceOpenHashMap<>(); + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) { + if (tHatch instanceof MTEHatchInputME meHatch) { + for (FluidStack fluid : meHatch.getStoredFluids()) { + if (fluid != null) { + // Prevent the same fluid from different ME hatches from being recognized + fluidsFromME.put(fluid.getFluid(), fluid); + } + } + } + } + return fluidsFromME; + } + + @Override + public RecipeMap getRecipeMap() { + return null; + } + + /** + * Creates logic to run recipe check based on recipemap. This runs only once, on class instantiation. + *

+ * If this machine doesn't use recipemap or does some complex things, override {@link #checkProcessing()}. + */ + @ApiStatus.OverrideOnly + protected ProcessingLogic createProcessingLogic() { + return null; + } + + public void updateSlots() { + for (MTEHatchInput tHatch : filterValidMTEs(mInputHatches)) tHatch.updateSlots(); + for (MTEHatchInputBus tHatch : filterValidMTEs(mInputBusses)) tHatch.updateSlots(); + } + + protected void startRecipeProcessing() { + for (MTEHatchInputBus hatch : filterValidMTEs(mInputBusses)) { + if (hatch instanceof IRecipeProcessingAwareHatch aware) { + aware.startRecipeProcessing(); + } + } + for (MTEHatchInput hatch : filterValidMTEs(mInputHatches)) { + if (hatch instanceof IRecipeProcessingAwareHatch aware) { + aware.startRecipeProcessing(); + } + } + } + + public void setResultIfFailure(CheckRecipeResult result) { + if (!result.wasSuccessful()) { + this.checkRecipeResult = result; + } + } + + protected void endRecipeProcessing() { + for (MTEHatchInputBus hatch : filterValidMTEs(mInputBusses)) { + if (hatch instanceof IRecipeProcessingAwareHatch aware) { + setResultIfFailure(aware.endRecipeProcessing(this)); + } + } + for (MTEHatchInput hatch : filterValidMTEs(mInputHatches)) { + if (hatch instanceof IRecipeProcessingAwareHatch aware) { + setResultIfFailure(aware.endRecipeProcessing(this)); + } + } + } + + public boolean addToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatch hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + } + if (aMetaTileEntity instanceof IDualInputHatch hatch) { + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mDualInputHatches.add(hatch); + } + if (aMetaTileEntity instanceof ISmartInputHatch hatch) { + // Only add them to be iterated if enabled for performance reasons + if (hatch.doFastRecipeCheck()) { + mSmartInputHatches.add(hatch); + } + } + if (aMetaTileEntity instanceof MTEHatchInput) { + setHatchRecipeMap((MTEHatchInput) aMetaTileEntity); + return mInputHatches.add((MTEHatchInput) aMetaTileEntity); + } + if (aMetaTileEntity instanceof MTEHatchInputBus) { + ((MTEHatchInputBus) aMetaTileEntity).mRecipeMap = getRecipeMap(); + return mInputBusses.add((MTEHatchInputBus) aMetaTileEntity); + } + if (aMetaTileEntity instanceof MTEHatchOutput) return mOutputHatches.add((MTEHatchOutput) aMetaTileEntity); + if (aMetaTileEntity instanceof MTEHatchOutputBus) return mOutputBusses.add((MTEHatchOutputBus) aMetaTileEntity); + if (aMetaTileEntity instanceof MTEHatchEnergy) return mEnergyHatches.add((MTEHatchEnergy) aMetaTileEntity); + if (aMetaTileEntity instanceof MTEHatchDynamo) return mDynamoHatches.add((MTEHatchDynamo) aMetaTileEntity); + if (aMetaTileEntity instanceof MTEHatchMaintenance) + return mMaintenanceHatches.add((MTEHatchMaintenance) aMetaTileEntity); + if (aMetaTileEntity instanceof MTEHatchMuffler) return mMufflerHatches.add((MTEHatchMuffler) aMetaTileEntity); + return false; + } + + public boolean addMaintenanceToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchMaintenance hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mMaintenanceHatches.add(hatch); + } + return false; + } + + public boolean addEnergyInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) { + return false; + } + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchEnergy hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mEnergyHatches.add(hatch); + } + return false; + } + + public boolean addExoticEnergyInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatch hatch && ExoticEnergyInputHelper.isExoticEnergyInput(aMetaTileEntity)) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mExoticEnergyHatches.add(hatch); + } + return false; + } + + public boolean addDynamoToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchDynamo hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mDynamoHatches.add(hatch); + } + return false; + } + + public boolean addMufflerToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchMuffler hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mMufflerHatches.add(hatch); + } + return false; + } + + public boolean addInputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + return addInputBusToMachineList(aTileEntity, aBaseCasingIndex) + || addInputHatchToMachineList(aTileEntity, aBaseCasingIndex); + } + + public boolean addOutputToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + return addOutputBusToMachineList(aTileEntity, aBaseCasingIndex) + || addOutputHatchToMachineList(aTileEntity, aBaseCasingIndex); + } + + public boolean addInputBusToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof IDualInputHatch hatch) { + if (!supportsCraftingMEBuffer()) return false; + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mDualInputHatches.add(hatch); + } + if (aMetaTileEntity instanceof ISmartInputHatch hatch) { + mSmartInputHatches.add(hatch); + } + if (aMetaTileEntity instanceof MTEHatchInputBus hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + hatch.mRecipeMap = getRecipeMap(); + return mInputBusses.add(hatch); + } + return false; + } + + public boolean addOutputBusToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchOutputBus hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mOutputBusses.add(hatch); + } + return false; + } + + public boolean addInputHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof ISmartInputHatch hatch) { + mSmartInputHatches.add(hatch); + } + if (aMetaTileEntity instanceof MTEHatchInput hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + setHatchRecipeMap(hatch); + return mInputHatches.add(hatch); + } + return false; + } + + public boolean addOutputHatchToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasingIndex) { + if (aTileEntity == null) return false; + IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) return false; + if (aMetaTileEntity instanceof MTEHatchOutput hatch) { + hatch.updateTexture(aBaseCasingIndex); + hatch.updateCraftingIcon(this.getMachineCraftingIcon()); + return mOutputHatches.add(hatch); + } + return false; + } + + protected void setHatchRecipeMap(MTEHatchInput hatch) { + if (filtersFluid()) { + hatch.mRecipeMap = getRecipeMap(); + } + } + + /** + * @return If this multi filters fluid input for hatches based on recipemap. + */ + protected boolean filtersFluid() { + return true; + } + + @Override + public String[] getInfoData() { + int mPollutionReduction = 0; + for (MTEHatchMuffler tHatch : filterValidMTEs(mMufflerHatches)) { + mPollutionReduction = Math.max(tHatch.calculatePollutionReduction(100), mPollutionReduction); + } + + long storedEnergy = 0; + long maxEnergy = 0; + for (MTEHatchEnergy tHatch : filterValidMTEs(mEnergyHatches)) { + storedEnergy += tHatch.getBaseMetaTileEntity() + .getStoredEU(); + maxEnergy += tHatch.getBaseMetaTileEntity() + .getEUCapacity(); + } + + return new String[] { + /* 1 */ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " + + EnumChatFormatting.GREEN + + formatNumbers(mProgresstime / 20) + + EnumChatFormatting.RESET + + " s / " + + EnumChatFormatting.YELLOW + + formatNumbers(mMaxProgresstime / 20) + + EnumChatFormatting.RESET + + " s", + /* 2 */ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + + EnumChatFormatting.GREEN + + formatNumbers(storedEnergy) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + formatNumbers(maxEnergy) + + EnumChatFormatting.RESET + + " EU", + /* 3 */ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " + + EnumChatFormatting.RED + + formatNumbers(getActualEnergyUsage()) + + EnumChatFormatting.RESET + + " EU/t", + /* 4 */ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " + + EnumChatFormatting.YELLOW + + formatNumbers(getMaxInputVoltage()) + + EnumChatFormatting.RESET + + " EU/t(*2A) " + + StatCollector.translateToLocal("GT5U.machines.tier") + + ": " + + EnumChatFormatting.YELLOW + + VN[GTUtility.getTier(getMaxInputVoltage())] + + EnumChatFormatting.RESET, + /* 5 */ StatCollector.translateToLocal("GT5U.multiblock.problems") + ": " + + EnumChatFormatting.RED + + (getIdealStatus() - getRepairStatus()) + + EnumChatFormatting.RESET + + " " + + StatCollector.translateToLocal("GT5U.multiblock.efficiency") + + ": " + + EnumChatFormatting.YELLOW + + mEfficiency / 100.0F + + EnumChatFormatting.RESET + + " %", + /* 6 */ StatCollector.translateToLocal("GT5U.multiblock.pollution") + ": " + + EnumChatFormatting.GREEN + + mPollutionReduction + + EnumChatFormatting.RESET + + " %" }; + } + + @Override + public boolean isGivingInformation() { + return true; + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return supportsSlotAutomation(aIndex); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return supportsSlotAutomation(aIndex); + } + + protected ItemStack[] getCompactedInputs() { + // TODO: repalce method with a cleaner one + ArrayList tInputList = getStoredInputs(); + int tInputList_sS = tInputList.size(); + for (int i = 0; i < tInputList_sS - 1; i++) { + for (int j = i + 1; j < tInputList_sS; j++) { + if (!GTUtility.areStacksEqual(tInputList.get(i), tInputList.get(j))) continue; + if (tInputList.get(i).stackSize >= tInputList.get(j).stackSize) { + tInputList.remove(j--); + tInputList_sS = tInputList.size(); + } else { + tInputList.remove(i--); + tInputList_sS = tInputList.size(); + break; + } + } + } + return tInputList.toArray(new ItemStack[0]); + } + + protected FluidStack[] getCompactedFluids() { + // TODO: repalce method with a cleaner one + ArrayList tFluidList = getStoredFluids(); + int tFluidList_sS = tFluidList.size(); + for (int i = 0; i < tFluidList_sS - 1; i++) { + for (int j = i + 1; j < tFluidList_sS; j++) { + if (!GTUtility.areFluidsEqual(tFluidList.get(i), tFluidList.get(j))) continue; + + if (tFluidList.get(i).amount >= tFluidList.get(j).amount) { + tFluidList.remove(j--); + tFluidList_sS = tFluidList.size(); + } else { + tFluidList.remove(i--); + tFluidList_sS = tFluidList.size(); + break; + } + } + } + return tFluidList.toArray(new FluidStack[0]); + } + + @Override + public void getWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + final NBTTagCompound tag = accessor.getNBTData(); + + if (tag.getBoolean("incompleteStructure")) { + currentTip.add(RED + "** INCOMPLETE STRUCTURE **" + RESET); + } + String efficiency = RESET + " Efficiency: " + tag.getFloat("efficiency") + "%"; + if (tag.getBoolean("hasProblems")) { + currentTip.add(RED + "** HAS PROBLEMS **" + efficiency); + } else if (!tag.getBoolean("incompleteStructure")) { + currentTip.add(GREEN + "Running Fine" + efficiency); + } + + boolean isActive = tag.getBoolean("isActive"); + if (isActive) { + long energyTier = tag.getLong("energyTier"); + long actualEnergyUsage = tag.getLong("energyUsage"); + if (energyTier > 0) { + if (actualEnergyUsage > 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.use_with_amperage", + formatNumbers(actualEnergyUsage), + GTUtility.getAmperageForTier(actualEnergyUsage, (byte) energyTier), + GTUtility.getColoredTierNameFromTier((byte) energyTier))); + } else if (actualEnergyUsage < 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.produce_with_amperage", + formatNumbers(-actualEnergyUsage), + GTUtility.getAmperageForTier(-actualEnergyUsage, (byte) energyTier), + GTUtility.getColoredTierNameFromTier((byte) energyTier))); + } + } else { + if (actualEnergyUsage > 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.use", + formatNumbers(actualEnergyUsage), + GTUtility.getColoredTierNameFromVoltage(actualEnergyUsage))); + } else if (actualEnergyUsage < 0) { + currentTip.add( + StatCollector.translateToLocalFormatted( + "GT5U.waila.energy.produce", + formatNumbers(-actualEnergyUsage), + GTUtility.getColoredTierNameFromVoltage(-actualEnergyUsage))); + } + } + } + currentTip + .add(GTWaila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); + // Show ns on the tooltip + if (GTMod.gregtechproxy.wailaAverageNS && tag.hasKey("averageNS")) { + int tAverageTime = tag.getInteger("averageNS"); + currentTip.add("Average CPU load of ~" + formatNumbers(tAverageTime) + " ns"); + } + super.getWailaBody(itemStack, currentTip, accessor, config); + } + + public final void getMTEWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + super.getWailaBody(itemStack, currentTip, accessor, config); + } + + @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.setBoolean("hasProblems", (getIdealStatus() - getRepairStatus()) > 0); + tag.setFloat("efficiency", mEfficiency / 100.0F); + tag.setInteger("progress", mProgresstime); + tag.setInteger("maxProgress", mMaxProgresstime); + tag.setBoolean("incompleteStructure", (getBaseMetaTileEntity().getErrorDisplayID() & 64) != 0); + + final IGregTechTileEntity tileEntity = getBaseMetaTileEntity(); + if (tileEntity != null) { + tag.setBoolean("isActive", tileEntity.isActive()); + if (tileEntity.isActive()) { + if (mEUt < 0) tag.setLong("energyUsage", getActualEnergyUsage()); + else tag.setLong("energyUsage", (long) -mEUt * mEfficiency / 10000); + tag.setLong("energyTier", getInputVoltageTier()); + } + } + + final GTClientPreference preference = GTMod.gregtechproxy.getClientPreference(player.getUniqueID()); + if (preference != null && preference.isWailaAverageNSEnabled()) { + getBaseMetaTileEntity().startTimeStatistics(); + int tAverageTime = 0; + int amountOfZero = 0; + for (int tTime : this.getBaseMetaTileEntity() + .getTimeStatistics()) { + tAverageTime += tTime; + if (tTime == 0) { + amountOfZero += 1; + } + } + + // tick time zero means it has not been updated yet + int samples = getBaseMetaTileEntity().getTimeStatistics().length - amountOfZero; + if (samples > 0) { + tag.setInteger("averageNS", tAverageTime / samples); + } + } + } + + protected void setMufflers(boolean state) { + for (MTEHatchMuffler aMuffler : mMufflerHatches) { + final IGregTechTileEntity iGTTileEntity = aMuffler.getBaseMetaTileEntity(); + if (iGTTileEntity != null && !iGTTileEntity.isDead()) { + iGTTileEntity.setActive(state); + } + } + } + + @Override + public void onRemoval() { + super.onRemoval(); + // Deactivate mufflers + setMufflers(false); + } + + public List getExoticEnergyHatches() { + return mExoticEnergyHatches; + } + + /** + * @return Returns true if there is 1 TT Energy Hatch OR up to 2 Energy Hatches + */ + 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; + } + + /** + * Checks if all the item / fluid outputs of the recipe can be outputted to the buses / hatches. + * If void protection is enabled, it also checks for {@link #protectsExcessItem()} and + * {@link #protectsExcessFluid()}, so you don't need to call them along with this method. + *

+ * If you're using {@link ParallelHelper}, it will handle void protection and return 0 parallel + * if all the output cannot be dumped into buses / hatches. In that case you won't use this method. + */ + protected boolean canOutputAll(@Nonnull GTRecipe recipe) { + return canOutputAll(recipe.mOutputs, recipe.mFluidOutputs); + } + + /** + * Checks if all the items can be outputted to the output buses. + * If void protection is enabled, it also checks for {@link #protectsExcessItem()}, + * so you don't need to call it along with this method. + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + protected boolean canOutputAll(ItemStack[] items) { + return canOutputAll(items, null); + } + + /** + * Checks if all the fluids can be outputted to the output hatches. + * If void protection is enabled, it also checks for {@link #protectsExcessFluid()}, + * so you don't need to call it along with this method. + */ + protected boolean canOutputAll(FluidStack[] fluids) { + return canOutputAll(null, fluids); + } + + /** + * Checks if all the items / fluids can be outputted to output buses / hatches. + * If void protection is enabled, it also checks for {@link #protectsExcessItem()} and + * {@link #protectsExcessFluid()}, so you don't need to call them along with this method. + */ + protected boolean canOutputAll(@Nullable ItemStack[] items, @Nullable FluidStack[] fluids) { + if (!protectsExcessItem() && !protectsExcessFluid()) { + return true; + } + + VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper().setMachine(this) + .setItemOutputs(items) + .setFluidOutputs(fluids) + .build(); + return voidProtectionHelper.getMaxParallel() > 0; + } + + @Override + public boolean isAllowedToWork() { + return getBaseMetaTileEntity() != null && getBaseMetaTileEntity().isAllowedToWork(); + } + + @Override + public void disableWorking() { + if (getBaseMetaTileEntity() != null) { + getBaseMetaTileEntity().disableWorking(); + } + } + + @Override + public void enableWorking() { + if (getBaseMetaTileEntity() != null) { + getBaseMetaTileEntity().enableWorking(); + } + } + + public ItemStack getControllerSlot() { + return mInventory[getControllerSlotIndex()]; + } + + public final int getControllerSlotIndex() { + return 1; + } + + // True if the slot with index aSlot may be interacted with through automation + protected boolean supportsSlotAutomation(int aSlot) { + return false; + } + + @Override + public Pos2d getPowerSwitchButtonPos() { + return new Pos2d(174, 148); + } + + @Override + public Pos2d getStructureUpdateButtonPos() { + return new Pos2d(174, 130); + } + + @Override + public int getStructureUpdateTime() { + return mUpdate; + } + + @Override + public void setStructureUpdateTime(int time) { + mUpdate = time; + } + + @Override + public boolean supportsVoidProtection() { + return false; + } + + @Override + public VoidingMode getVoidingMode() { + return voidingMode; + } + + @Override + public void setVoidingMode(VoidingMode mode) { + this.voidingMode = mode; + } + + @Override + public List getItemOutputSlots(ItemStack[] toOutput) { + List ret = new ArrayList<>(); + for (final MTEHatch tBus : filterValidMTEs(mOutputBusses)) { + if (!(tBus instanceof MTEHatchOutputBusME)) { + final IInventory tBusInv = tBus.getBaseMetaTileEntity(); + for (int i = 0; i < tBusInv.getSizeInventory(); i++) { + final ItemStack stackInSlot = tBus.getStackInSlot(i); + + if (stackInSlot == null && tBus instanceof IItemLockable lockable && lockable.isLocked()) { + // getItemOutputSlots is only used to calculate free room for the purposes of parallels and + // void protection. We can use a fake item stack here without creating weirdness in the output + // bus' actual inventory. + assert lockable.getLockedItem() != null; + ItemStack fakeItemStack = lockable.getLockedItem() + .copy(); + fakeItemStack.stackSize = 0; + ret.add(fakeItemStack); + } else { + ret.add(stackInSlot); + } + } + } + } + return ret; + } + + @Override + public List getFluidOutputSlots(FluidStack[] toOutput) { + return filterValidMTEs(mOutputHatches); + } + + /** + * Util method for DT-like structure to collect list of output hatches. + */ + protected List getFluidOutputSlotsByLayer(FluidStack[] toOutput, + List> hatchesByLayer) { + List ret = new ArrayList<>(); + for (int i = 0; i < toOutput.length; i++) { + if (i >= hatchesByLayer.size()) { + break; + } + FluidStack fluidOutputForLayer = toOutput[i]; + for (MTEHatchOutput hatch : hatchesByLayer.get(i)) { + if (!hatch.isValid()) continue; + if (fluidOutputForLayer != null) { + ret.add(new OutputHatchWrapper(hatch, f -> GTUtility.areFluidsEqual(f, fluidOutputForLayer))); + } else { + ret.add(hatch); + } + } + } + return ret; + } + + @Override + public boolean canDumpItemToME() { + for (MTEHatch tHatch : filterValidMTEs(mOutputBusses)) { + if (tHatch instanceof MTEHatchOutputBusME) { + if ((((MTEHatchOutputBusME) tHatch).canAcceptItem())) { + return true; + } + } + } + return false; + } + + @Override + public boolean canDumpFluidToME() { + for (IFluidStore tHatch : getFluidOutputSlots(new FluidStack[0])) { + if (tHatch instanceof MTEHatchOutputME) { + if ((((MTEHatchOutputME) tHatch).canAcceptFluid())) { + return true; + } + } + } + return false; + } + + @Override + public Pos2d getVoidingModeButtonPos() { + return new Pos2d(8, 91); + } + + @Override + public boolean supportsInputSeparation() { + return false; + } + + @Override + public boolean isInputSeparationEnabled() { + return inputSeparation; + } + + @Override + public void setInputSeparation(boolean enabled) { + this.inputSeparation = enabled; + } + + @Override + public Pos2d getInputSeparationButtonPos() { + return new Pos2d(26, 91); + } + + /** + * Creates the icon list for this machine. Override this and add the overlays to machineModeIcons in order. + */ + public void setMachineModeIcons() { + machineModeIcons.add(GTUITextures.OVERLAY_BUTTON_MACHINEMODE_DEFAULT); + machineModeIcons.add(GTUITextures.OVERLAY_BUTTON_MACHINEMODE_DEFAULT); + } + + /** + * Override this if you are a multi-machine and want a GUI button. You will also want to override + * setMachineModeIcons(). + * Override nextMachineMode() if you have more than 2 modes. + */ + @Override + public boolean supportsMachineModeSwitch() { + return false; + } + + @Override + public int getMachineMode() { + return machineMode; + } + + @Override + public UITexture getMachineModeIcon(int index) { + return machineModeIcons.get(index); + } + + @Override + public void setMachineMode(int index) { + machineMode = index; + } + + @Override + public int nextMachineMode() { + if (machineMode == 0) return 1; + else return 0; + } + + @Override + public Pos2d getMachineModeSwitchButtonPos() { + return new Pos2d(80, 91); + } + + @Override + public boolean supportsBatchMode() { + return false; + } + + @Override + public boolean isBatchModeEnabled() { + return batchMode; + } + + @Override + public void setBatchMode(boolean enabled) { + this.batchMode = enabled; + } + + @Override + public Pos2d getBatchModeButtonPos() { + return new Pos2d(44, 91); + } + + @Override + public boolean supportsSingleRecipeLocking() { + return false; + } + + @Override + public boolean isRecipeLockingEnabled() { + return mLockedToSingleRecipe; + } + + @Override + public void setRecipeLocking(boolean enabled) { + mLockedToSingleRecipe = enabled; + if (!enabled) { + setSingleRecipeCheck(null); + } + } + + @Override + public void setSingleRecipeCheck(SingleRecipeCheck recipeCheck) { + mSingleRecipeCheck = recipeCheck; + } + + @Override + public SingleRecipeCheck getSingleRecipeCheck() { + return mSingleRecipeCheck; + } + + @Override + public Pos2d getRecipeLockingButtonPos() { + return new Pos2d(62, 91); + } + + @Override + public int getGUIWidth() { + return 198; + } + + @Override + public int getGUIHeight() { + return 192; + } + + @Override + public void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.bindPlayerInventory(buildContext.getPlayer(), new Pos2d(7, 109), getGUITextureSet().getItemSlot()); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_SCREEN_BLACK) + .setPos(4, 4) + .setSize(190, 85)); + final SlotWidget inventorySlot = new SlotWidget(inventoryHandler, 1); + builder.widget( + inventorySlot.setPos(173, 167) + .setBackground(GTUITextures.SLOT_DARK_GRAY)); + + final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); + drawTexts(screenElements, inventorySlot); + builder.widget(screenElements); + + setMachineModeIcons(); + builder.widget(createPowerSwitchButton(builder)) + .widget(createVoidExcessButton(builder)) + .widget(createInputSeparationButton(builder)) + .widget(createModeSwitchButton(builder)) + .widget(createBatchModeButton(builder)) + .widget(createLockToSingleRecipeButton(builder)) + .widget(createStructureUpdateButton(builder)); + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) {} + + protected boolean shouldDisplayCheckRecipeResult() { + return true; + } + + public boolean shouldDisplayShutDownReason() { + return true; + } + + protected final NumberFormatMUI numberFormat = new NumberFormatMUI(); + + protected String generateCurrentRecipeInfoString() { + StringBuffer ret = new StringBuffer(EnumChatFormatting.WHITE + "Progress: "); + + numberFormat.setMinimumFractionDigits(2); + numberFormat.setMaximumFractionDigits(2); + numberFormat.format((double) mProgresstime / 20, ret); + ret.append("s / "); + numberFormat.format((double) mMaxProgresstime / 20, ret); + ret.append("s ("); + numberFormat.setMinimumFractionDigits(1); + numberFormat.setMaximumFractionDigits(1); + numberFormat.format((double) mProgresstime / mMaxProgresstime * 100, ret); + ret.append("%)\n"); + numberFormat.setMinimumFractionDigits(0); + numberFormat.setMaximumFractionDigits(2); + + IntConsumer appendRate = (amount) -> { + double processPerTick = (double) amount / mMaxProgresstime * 20; + if (processPerTick > 1) { + ret.append(" ("); + numberFormat.format(Math.round(processPerTick * 10) / 10.0, ret); + ret.append("/s)"); + } else { + ret.append(" ("); + numberFormat.format(Math.round(1 / processPerTick * 10) / 10.0, ret); + ret.append("s/ea)"); + } + }; + + int lines = 0; + int MAX_LINES = 5; + + if (mOutputItems != null) { + for (var item : mOutputItems) { + if (item == null) continue; + if (lines >= MAX_LINES) { + ret.append("..."); + return ret.toString(); + } + lines++; + ret.append(EnumChatFormatting.AQUA) + .append(item.getDisplayName()) + .append(EnumChatFormatting.WHITE) + .append(" x ") + .append(EnumChatFormatting.GOLD); + numberFormat.format(item.stackSize, ret); + ret.append(EnumChatFormatting.WHITE); + appendRate.accept(item.stackSize); + ret.append('\n'); + } + } + if (mOutputFluids != null) { + for (var fluid : mOutputFluids) { + if (fluid == null) continue; + if (lines >= MAX_LINES) { + ret.append("..."); + return ret.toString(); + } + lines++; + ret.append(EnumChatFormatting.AQUA) + .append(fluid.getLocalizedName()) + .append(EnumChatFormatting.WHITE) + .append(" x ") + .append(EnumChatFormatting.GOLD); + numberFormat.format(fluid.amount, ret); + ret.append("L") + .append(EnumChatFormatting.WHITE); + appendRate.accept(fluid.amount); + ret.append('\n'); + } + } + return ret.toString(); + } + + protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { + screenElements.setSynced(false) + .setSpace(0) + .setPos(10, 7); + if (supportsMachineModeSwitch()) { + screenElements.widget( + TextWidget.dynamicString( + () -> EnumChatFormatting.WHITE + GTUtility.trans("400", "Running mode: ") + + EnumChatFormatting.GOLD + + getMachineModeName())); + } + screenElements + .widget( + new TextWidget(GTUtility.trans("132", "Pipe is loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mWrench)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mWrench, val -> mWrench = val)); + screenElements + .widget( + new TextWidget(GTUtility.trans("133", "Screws are loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mScrewdriver)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mScrewdriver, val -> mScrewdriver = val)); + screenElements + .widget( + new TextWidget(GTUtility.trans("134", "Something is stuck.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mSoftHammer)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mSoftHammer, val -> mSoftHammer = val)); + screenElements + .widget( + new TextWidget(GTUtility.trans("135", "Platings are dented.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mHardHammer)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mHardHammer, val -> mHardHammer = val)); + screenElements + .widget( + new TextWidget(GTUtility.trans("136", "Circuitry burned out.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mSolderingTool)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mSolderingTool, val -> mSolderingTool = val)); + screenElements.widget( + new TextWidget(GTUtility.trans("137", "That doesn't belong there.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mCrowbar)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mCrowbar, val -> mCrowbar = val)); + screenElements + .widget( + new TextWidget(GTUtility.trans("138", "Incomplete Structure.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> !mMachine)) + .widget(new FakeSyncWidget.BooleanSyncer(() -> mMachine, val -> mMachine = val)); + screenElements.widget( + new TextWidget("Too Uncertain.").setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> (getBaseMetaTileEntity().getErrorDisplayID() & 128) != 0)); + screenElements.widget( + new TextWidget("Invalid Parameters.").setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> (getBaseMetaTileEntity().getErrorDisplayID() & 256) != 0)); + + screenElements.widget( + new TextWidget(GTUtility.trans("139", "Hit with Soft Mallet")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled( + widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && !getBaseMetaTileEntity().isActive())) + .widget( + new FakeSyncWidget.IntegerSyncer( + () -> getBaseMetaTileEntity().getErrorDisplayID(), + val -> getBaseMetaTileEntity().setErrorDisplayID(val))) + .widget( + new FakeSyncWidget.BooleanSyncer( + () -> getBaseMetaTileEntity().isActive(), + val -> getBaseMetaTileEntity().setActive(val))); + screenElements.widget( + new TextWidget(GTUtility.trans("140", "to (re-)start the Machine")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled( + widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && !getBaseMetaTileEntity().isActive())); + screenElements.widget( + new TextWidget(GTUtility.trans("141", "if it doesn't start.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled( + widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && !getBaseMetaTileEntity().isActive())); + screenElements.widget( + new TextWidget(GTUtility.trans("142", "Running perfectly.")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled( + widget -> getBaseMetaTileEntity().getErrorDisplayID() == 0 && getBaseMetaTileEntity().isActive())); + + screenElements.widget(TextWidget.dynamicString(() -> { + Duration time = Duration.ofSeconds((mTotalRunTime - mLastWorkingTick) / 20); + return StatCollector.translateToLocalFormatted( + "GT5U.gui.text.shutdown_duration", + time.toHours(), + time.toMinutes() % 60, + time.getSeconds() % 60); + }) + .setEnabled( + widget -> shouldDisplayShutDownReason() && !getBaseMetaTileEntity().isActive() + && getBaseMetaTileEntity().wasShutdown())) + .widget(new FakeSyncWidget.LongSyncer(() -> mTotalRunTime, time -> mTotalRunTime = time)) + .widget(new FakeSyncWidget.LongSyncer(() -> mLastWorkingTick, time -> mLastWorkingTick = time)); + screenElements.widget( + TextWidget.dynamicString( + () -> getBaseMetaTileEntity().getLastShutDownReason() + .getDisplayString()) + .setSynced(false) + .setTextAlignment(Alignment.CenterLeft) + .setEnabled( + widget -> shouldDisplayShutDownReason() && !getBaseMetaTileEntity().isActive() + && GTUtility.isStringValid( + getBaseMetaTileEntity().getLastShutDownReason() + .getDisplayString()) + && getBaseMetaTileEntity().wasShutdown())) + .widget( + new ShutDownReasonSyncer( + () -> getBaseMetaTileEntity().getLastShutDownReason(), + reason -> getBaseMetaTileEntity().setShutDownReason(reason))) + .widget( + new FakeSyncWidget.BooleanSyncer( + () -> getBaseMetaTileEntity().wasShutdown(), + wasShutDown -> getBaseMetaTileEntity().setShutdownStatus(wasShutDown))); + + screenElements.widget( + TextWidget.dynamicString(() -> checkRecipeResult.getDisplayString()) + .setSynced(false) + .setTextAlignment(Alignment.CenterLeft) + .setEnabled( + widget -> shouldDisplayCheckRecipeResult() + && GTUtility.isStringValid(checkRecipeResult.getDisplayString()) + && (isAllowedToWork() || getBaseMetaTileEntity().isActive() + || checkRecipeResult.persistsOnShutdown()))) + .widget(new CheckRecipeResultSyncer(() -> checkRecipeResult, (result) -> checkRecipeResult = result)); + + if (showRecipeTextInGUI()) { + // Display current recipe + screenElements.widget( + TextWidget.dynamicString(this::generateCurrentRecipeInfoString) + .setSynced(false) + .setTextAlignment(Alignment.CenterLeft) + .setEnabled( + widget -> (mOutputFluids != null && mOutputFluids.length > 0) + || (mOutputItems != null && mOutputItems.length > 0))) + .widget( + new FakeSyncWidget.ListSyncer<>( + () -> mOutputFluids != null ? Arrays.asList(mOutputFluids) : Collections.emptyList(), + val -> mOutputFluids = val.toArray(new FluidStack[0]), + NetworkUtils::writeFluidStack, + NetworkUtils::readFluidStack)) + .widget( + new FakeSyncWidget.ListSyncer<>( + () -> mOutputItems != null ? Arrays.asList(mOutputItems) : Collections.emptyList(), + val -> mOutputItems = val.toArray(new ItemStack[0]), + NetworkUtils::writeItemStack, + NetworkUtils::readItemStack)) + .widget(new FakeSyncWidget.IntegerSyncer(() -> mProgresstime, val -> mProgresstime = val)) + .widget(new FakeSyncWidget.IntegerSyncer(() -> mMaxProgresstime, val -> mMaxProgresstime = val)); + } + + screenElements.widget( + new TextWidget(GTUtility.trans("144", "Missing Turbine Rotor")).setDefaultColor(COLOR_TEXT_WHITE.get()) + .setEnabled(widget -> { + if (getBaseMetaTileEntity().isAllowedToWork()) return false; + if (getBaseMetaTileEntity().getErrorDisplayID() == 0 && this instanceof MTELargeTurbine) { + final ItemStack tItem = inventorySlot.getMcSlot() + .getStack(); + return tItem == null + || !(tItem.getItem() == MetaGeneratedTool01.INSTANCE && tItem.getItemDamage() >= 170 + && tItem.getItemDamage() <= 177); + } + return false; + })); + } + + protected boolean showRecipeTextInGUI() { + return true; + } + + @TestOnly + protected void setEnergyHatches(ArrayList EnergyHatches) { + this.mEnergyHatches = EnergyHatches; + } + + @TestOnly + protected void setExoticEnergyHatches(List ExoticEnergyHatches) { + this.mExoticEnergyHatches = ExoticEnergyHatches; + } + + public void fixAllIssues() { + mWrench = true; + mScrewdriver = true; + mSoftHammer = true; + mHardHammer = true; + mSolderingTool = true; + mCrowbar = true; + } + + public boolean getDefaultHasMaintenanceChecks() { + return true; + } + + public boolean shouldCheckMaintenance() { + return !disableMaintenance && hasMaintenanceChecks; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTESpecialFilter.java b/src/main/java/gregtech/api/metatileentity/implementations/MTESpecialFilter.java new file mode 100644 index 0000000000..c93b542805 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTESpecialFilter.java @@ -0,0 +1,132 @@ +package gregtech.api.metatileentity.implementations; + +import java.util.List; +import java.util.function.Function; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.drawable.Text; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.SlotGroup; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; + +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public abstract class MTESpecialFilter extends MTEFilterBase { + + private static final String ALLOW_NBT_TOOLTIP = "GT5U.machines.allow_nbt.tooltip"; + private boolean allowNbt = false; + + public MTESpecialFilter(int aID, String aName, String aNameRegional, int aTier, String[] aDescription) { + // 9 buffer slot, 1 representation slot, 1 holo slot. last seems not needed... + super(aID, aName, aNameRegional, aTier, 11, aDescription); + } + + public MTESpecialFilter(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public MTESpecialFilter(String aName, int aTier, int aInvSlotCount, String[] aDescription, + ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + aNBT.setBoolean("bNBTAllowed", this.allowNbt); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + this.allowNbt = aNBT.getBoolean("bNBTAllowed"); + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return (super.allowPutStack(aBaseMetaTileEntity, aIndex, side, aStack)) + && ((this.allowNbt) || (!aStack.hasTagCompound())) + && (this.isStackAllowed(aStack) != this.invertFilter); + } + + protected abstract boolean isStackAllowed(ItemStack aStack); + + protected List getEmptySlotTooltip() { + return null; + } + + protected Function, List> getItemStackReplacementTooltip() { + return list -> list; + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + super.addUIWidgets(builder, buildContext); + addAllowNbtButton(builder); + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_ARROW_24_WHITE.apply(27, false)) + .setPos(6, 19) + .setSize(27, 24)) + .widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_ARROW_24_BLUE.apply(42, true)) + .setPos(53, 19) + .setSize(42, 24)) + .widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_ARROW_24_RED.apply(19, true)) + .setPos(152, 19) + .setSize(19, 24)) + .widget( + createFilterIconSlot(BaseSlot.phantom(inventoryHandler, 9)).disableShiftInsert() + .setPos(34, 22) + .setBackground(GTUITextures.BUTTON_STANDARD)) + .widget( + SlotGroup.ofItemHandler(inventoryHandler, 3) + .endAtSlot(8) + .build() + .setPos(97, 4)); + } + + private void addAllowNbtButton(ModularWindow.Builder builder) { + builder.widget( + createToggleButton( + () -> allowNbt, + val -> allowNbt = val, + GTUITextures.OVERLAY_BUTTON_NBT, + () -> mTooltipCache.getData(ALLOW_NBT_TOOLTIP))); + } + + protected abstract SlotWidget createFilterIconSlot(BaseSlot slot); + + protected abstract class FilterIconSlotWidget extends SlotWidget { + + public FilterIconSlotWidget(BaseSlot slot) { + super(slot); + } + + @Override + protected abstract void phantomClick(ClickData clickData, ItemStack cursorStack); + + @Override + public void buildTooltip(List tooltip) { + super.buildTooltip(tooltip); + List emptySlotTooltip = getEmptySlotTooltip(); + if (emptySlotTooltip != null) { + tooltip.addAll(emptySlotTooltip); + } + } + + @Override + public Function, List> getOverwriteItemStackTooltip() { + return getItemStackReplacementTooltip(); + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTETieredMachineBlock.java b/src/main/java/gregtech/api/metatileentity/implementations/MTETieredMachineBlock.java new file mode 100644 index 0000000000..8bffeaf17e --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTETieredMachineBlock.java @@ -0,0 +1,119 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.GT; +import static gregtech.api.metatileentity.BaseTileEntity.BATTERY_SLOT_TOOLTIP; +import static gregtech.api.metatileentity.BaseTileEntity.BATTERY_SLOT_TOOLTIP_ALT; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; + +import com.gtnewhorizons.modularui.common.widget.SlotWidget; + +import gregtech.api.enums.GTValues; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.GTUtility; + +public abstract class MTETieredMachineBlock extends MetaTileEntity { + + /** + * Value between [0 - 9] to describe the Tier of this Machine. PLZ [0-15] works - READ! GT_Values class. + */ + public final byte mTier; + + /** + * A simple Description. + */ + public final String[] mDescriptionArray; + + /** + * Contains all Textures used by this Block. + */ + public final ITexture[][][] mTextures; + + public MTETieredMachineBlock(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String aDescription, ITexture... aTextures) { + super(aID, aName, aNameRegional, aInvSlotCount); + mTier = (byte) Math.max(0, Math.min(aTier, 14)); + mDescriptionArray = aDescription == null ? new String[0] : new String[] { aDescription }; + // must always be the last call! + if (GT.isClientSide()) mTextures = getTextureSet(aTextures); + else mTextures = null; + } + + public MTETieredMachineBlock(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, + String[] aDescription, ITexture... aTextures) { + super(aID, aName, aNameRegional, aInvSlotCount); + mTier = (byte) Math.max(0, Math.min(aTier, 15)); + mDescriptionArray = aDescription == null ? new String[0] : aDescription; + + // must always be the last call! + if (GT.isClientSide()) mTextures = getTextureSet(aTextures); + else mTextures = null; + } + + public MTETieredMachineBlock(String aName, int aTier, int aInvSlotCount, String aDescription, + ITexture[][][] aTextures) { + super(aName, aInvSlotCount); + mTier = (byte) aTier; + mDescriptionArray = aDescription == null ? new String[0] : new String[] { aDescription }; + mTextures = aTextures; + } + + public MTETieredMachineBlock(String aName, int aTier, int aInvSlotCount, String[] aDescription, + ITexture[][][] aTextures) { + super(aName, aInvSlotCount); + mTier = (byte) aTier; + mDescriptionArray = aDescription == null ? new String[0] : aDescription; + mTextures = aTextures; + } + + @Override + public byte getTileEntityBaseType() { + return (byte) (Math.min(3, mTier <= 0 ? 0 : 1 + ((mTier - 1) / 4))); + } + + @Override + public long getInputTier() { + return mTier; + } + + @Override + public long getOutputTier() { + return mTier; + } + + @Override + public String[] getDescription() { + return mDescriptionArray; + } + + /** + * Used Client Side to get a Texture Set for this Block. Called after setting the Tier and the Description so that + * those two are accessible. + * + * @param aTextures is the optional Array you can give to the Constructor. + */ + public abstract ITexture[][][] getTextureSet(ITexture[] aTextures); + + protected SlotWidget createChargerSlot(int x, int y) { + final String batterySlotTooltipKey; + final Object[] batterySlotTooltipArgs; + final String pTier1 = GTUtility.getColoredTierNameFromTier(mTier); + if (mTier == GTValues.VN.length - 1) { + batterySlotTooltipKey = BATTERY_SLOT_TOOLTIP_ALT; + batterySlotTooltipArgs = new String[] { pTier1 }; + } else { + batterySlotTooltipKey = BATTERY_SLOT_TOOLTIP; + batterySlotTooltipArgs = new String[] { pTier1, GTUtility.getColoredTierNameFromTier((byte) (mTier + 1)) }; + } + return createChargerSlot(x, y, batterySlotTooltipKey, batterySlotTooltipArgs); + } + + protected SlotWidget createChargerSlot(int x, int y, String tooltipKey, Object[] tooltipArgs) { + return (SlotWidget) new SlotWidget(inventoryHandler, rechargerSlotStartIndex()).disableShiftInsert() + .setGTTooltip(() -> mTooltipCache.getData(tooltipKey, tooltipArgs)) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setBackground(getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_CHARGER) + .setPos(x, y); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTETooltipMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTETooltipMultiBlockBase.java new file mode 100644 index 0000000000..71fce08c7e --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTETooltipMultiBlockBase.java @@ -0,0 +1,56 @@ +package gregtech.api.metatileentity.implementations; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +import org.lwjgl.input.Keyboard; + +import gregtech.api.GregTechAPI; +import gregtech.api.interfaces.ISecondaryDescribable; +import gregtech.api.util.MultiblockTooltipBuilder; + +/** + * A multiblock with tooltip {@link MultiblockTooltipBuilder} + */ +public abstract class MTETooltipMultiBlockBase extends MTEMultiBlockBase implements ISecondaryDescribable { + + private static final AtomicReferenceArray tooltips = new AtomicReferenceArray<>( + GregTechAPI.METATILEENTITIES.length); + + public MTETooltipMultiBlockBase(int aID, String aName, String aNameRegional) { + super(aID, aName, aNameRegional); + } + + public MTETooltipMultiBlockBase(String aName) { + super(aName); + } + + protected MultiblockTooltipBuilder getTooltip() { + int tId = getBaseMetaTileEntity().getMetaTileID(); + MultiblockTooltipBuilder tooltip = tooltips.get(tId); + if (tooltip == null) { + tooltip = createTooltip(); + tooltips.set(tId, tooltip); + } + return tooltip; + } + + protected abstract MultiblockTooltipBuilder createTooltip(); + + @Override + public String[] getDescription() { + return getCurrentDescription(); + } + + @Override + public boolean isDisplaySecondaryDescription() { + return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT); + } + + public String[] getPrimaryDescription() { + return getTooltip().getInformation(); + } + + public String[] getSecondaryDescription() { + return getTooltip().getStructureInformation(); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTETransformer.java b/src/main/java/gregtech/api/metatileentity/implementations/MTETransformer.java new file mode 100644 index 0000000000..d2b88d26bc --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTETransformer.java @@ -0,0 +1,325 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.Mods.EnderIO; +import static mcp.mobius.waila.api.SpecialChars.BLUE; +import static mcp.mobius.waila.api.SpecialChars.GOLD; +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 java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import cofh.api.energy.IEnergyProvider; +import cofh.api.energy.IEnergyStorage; +import crazypants.enderio.machine.capbank.TileCapBank; +import crazypants.enderio.machine.capbank.network.ICapBankNetwork; +import crazypants.enderio.power.IPowerContainer; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.GTUtility; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the main construct for my Basic Machines such as the Automatic Extractor Extend this class to make a simple + * Machine + */ +public class MTETransformer extends MTETieredMachineBlock { + + public MTETransformer(int aID, String aName, String aNameRegional, int aTier, String aDescription) { + super(aID, aName, aNameRegional, aTier, 0, aDescription); + } + + public MTETransformer(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + public MTETransformer(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[12][17][]; + for (byte i = -1; i < 16; i++) { + rTextures[0][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + rTextures[1][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + rTextures[2][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT[mTier] }; + rTextures[3][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + rTextures[4][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + rTextures[5][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + rTextures[6][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN[mTier] }; + rTextures[7][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN[mTier] }; + rTextures[8][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN[mTier] }; + rTextures[9][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + rTextures[10][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + rTextures[11][i + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][i + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + } + return rTextures; + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, + ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) { + return mTextures[Math.min(2, side.ordinal()) + (side == facingDirection ? 3 : 0) + + (baseMetaTileEntity.isAllowedToWork() ? 0 : 6)][colorIndex + 1]; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTETransformer(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isEnetInput() { + return true; + } + + @Override + public boolean isEnetOutput() { + return true; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + ForgeDirection blockFrontFacing = getBaseMetaTileEntity().getFrontFacing(); + + if (getBaseMetaTileEntity().isAllowedToWork()) { + return side == blockFrontFacing; + } else { + return side != blockFrontFacing; + } + } + + @Override + public boolean isOutputFacing(ForgeDirection side) { + return !isInputFacing(side); + } + + @Override + public boolean isTeleporterCompatible() { + return false; + } + + @Override + public long getMinimumStoredEU() { + return V[mTier + 1]; + } + + @Override + public long maxEUStore() { + return Math.max(512L, 1L << (mTier + 2)) + V[mTier + 1] * 4L; + } + + @Override + public long maxEUInput() { + return V[getBaseMetaTileEntity().isAllowedToWork() ? mTier + 1 : mTier]; + } + + @Override + public long maxEUOutput() { + return V[getBaseMetaTileEntity().isAllowedToWork() ? mTier : mTier + 1]; + } + + @Override + public long maxAmperesOut() { + return getBaseMetaTileEntity().isAllowedToWork() ? 4 : 1; + } + + @Override + public long maxAmperesIn() { + return getBaseMetaTileEntity().isAllowedToWork() ? 1 : 4; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide() && GregTechAPI.mInputRF) { + aBaseMetaTileEntity.setActive(aBaseMetaTileEntity.isAllowedToWork()); + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (aBaseMetaTileEntity.getStoredEU() >= aBaseMetaTileEntity.getEUCapacity()) break; + if (!aBaseMetaTileEntity.inputEnergyFrom(side)) continue; + final TileEntity tTileEntity = aBaseMetaTileEntity.getTileEntityAtSide(side); + if (tTileEntity instanceof IEnergyProvider energyProvider + && energyProvider.extractEnergy(side.getOpposite(), 1, true) == 1) { + long tEU = ((IEnergyProvider) tTileEntity).extractEnergy( + side.getOpposite(), + GTUtility.safeInt(maxEUInput() * 100L / GregTechAPI.mRFtoEU), + false); + tEU = tEU * GregTechAPI.mRFtoEU / 100; + aBaseMetaTileEntity.injectEnergyUnits(ForgeDirection.UNKNOWN, Math.min(tEU, maxEUInput()), 1); + } else if (tTileEntity instanceof IEnergyStorage energyStorage + && energyStorage.extractEnergy(1, true) == 1) { + long tEU = ((IEnergyStorage) tTileEntity) + .extractEnergy(GTUtility.safeInt(maxEUInput() * 100L / GregTechAPI.mRFtoEU), false); + tEU = tEU * GregTechAPI.mRFtoEU / 100; + aBaseMetaTileEntity.injectEnergyUnits(ForgeDirection.UNKNOWN, Math.min(tEU, maxEUInput()), 1); + } else if (EnderIO.isModLoaded() && tTileEntity instanceof IPowerContainer powerContainer + && powerContainer.getEnergyStored() > 0) { + final int storedRF = powerContainer.getEnergyStored(); + final int extractRF = GTUtility.safeInt(maxEUInput() * 100L / GregTechAPI.mRFtoEU); + long tEU = 0; + if (tTileEntity instanceof TileCapBank capBank) { + ICapBankNetwork network = capBank.getNetwork(); + if (network != null && network.getEnergyStoredL() > 0) { + tEU = Math.min( + (Math.min( + Math.min(network.getEnergyStoredL(), storedRF - extractRF), + network.getMaxOutput())) * (long) GregTechAPI.mRFtoEU / 100L, + maxEUInput()); + network.addEnergy(GTUtility.safeInt(-(tEU * 100 / GregTechAPI.mRFtoEU))); + } + } else { + if (storedRF > extractRF) { + powerContainer.setEnergyStored(storedRF - extractRF); + tEU = maxEUInput(); + } else { + powerContainer.setEnergyStored(0); + tEU = storedRF * (long) GregTechAPI.mRFtoEU / 100L; + } + } + aBaseMetaTileEntity + .injectEnergyUnits(ForgeDirection.UNKNOWN, Math.min(tEU, maxEUInput()), 1); + } + } + } + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + // + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + // + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean hasAlternativeModeText() { + return true; + } + + @Override + public String getAlternativeModeText() { + return (getBaseMetaTileEntity().isAllowedToWork() ? GTUtility.trans("145", "Step Down, In: ") + : GTUtility.trans("146", "Step Up, In: ")) + maxEUInput() + + GTUtility.trans("148", "V ") + + maxAmperesIn() + + GTUtility.trans("147", "A, Out: ") + + maxEUOutput() + + GTUtility.trans("148", "V ") + + maxAmperesOut() + + GTUtility.trans("149", "A"); + } + + @Override + public boolean shouldJoinIc2Enet() { + return true; + } + + @Override + public void getWailaBody(ItemStack itemStack, List currenttip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + final ForgeDirection facing = getBaseMetaTileEntity().getFrontFacing(); + final NBTTagCompound tag = accessor.getNBTData(); + final ForgeDirection side = accessor.getSide(); + final boolean allowedToWork = tag.getBoolean("isAllowedToWork"); + + final byte inputTier = GTUtility.getTier(tag.getLong("maxEUInput")); + final byte outputTier = GTUtility.getTier(tag.getLong("maxEUOutput")); + + currenttip.add( + String.format( + "%s %s(%dA) -> %s(%dA)", + (allowedToWork ? (GREEN + "Step Down") : (RED + "Step Up")) + RESET, + GTMod.gregtechproxy.mWailaTransformerVoltageTier ? GTUtility.getColoredTierNameFromTier(inputTier) + : tag.getLong("maxEUInput"), + tag.getLong("maxAmperesIn"), + GTMod.gregtechproxy.mWailaTransformerVoltageTier ? GTUtility.getColoredTierNameFromTier(outputTier) + : tag.getLong("maxEUOutput"), + tag.getLong("maxAmperesOut"))); + + if ((side == facing && allowedToWork) || (side != facing && !allowedToWork)) { + currenttip.add( + String.format( + GOLD + "Input:" + RESET + " %s(%dA)", + GTMod.gregtechproxy.mWailaTransformerVoltageTier ? GTUtility.getColoredTierNameFromTier(inputTier) + : tag.getLong("maxEUInput"), + tag.getLong("maxAmperesIn"))); + } else { + currenttip.add( + String.format( + BLUE + "Output:" + RESET + " %s(%dA)", + GTMod.gregtechproxy.mWailaTransformerVoltageTier ? GTUtility.getColoredTierNameFromTier(outputTier) + : tag.getLong("maxEUOutput"), + tag.getLong("maxAmperesOut"))); + } + + super.getWailaBody(itemStack, currenttip, accessor, config); + } + + @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.setBoolean("isAllowedToWork", getBaseMetaTileEntity().isAllowedToWork()); + tag.setLong("maxEUInput", maxEUInput()); + tag.setLong("maxAmperesIn", maxAmperesIn()); + tag.setLong("maxEUOutput", maxEUOutput()); + tag.setLong("maxAmperesOut", maxAmperesOut()); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEWetTransformer.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEWetTransformer.java new file mode 100644 index 0000000000..e2c2437311 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEWetTransformer.java @@ -0,0 +1,92 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.V; + +import net.minecraft.util.EnumChatFormatting; + +import org.apache.commons.lang3.ArrayUtils; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public class MTEWetTransformer extends MTETransformer { + + public MTEWetTransformer(int aID, String aName, String aNameRegional, int aTier, String aDescription) { + super(aID, aName, aNameRegional, aTier, aDescription); + } + + public MTEWetTransformer(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEWetTransformer(mName, mTier, mDescriptionArray, mTextures); + } + + @Override + public ITexture[][][] getTextureSet(ITexture[] aTextures) { + ITexture[][][] rTextures = new ITexture[12][17][]; + for (byte b = -1; b < 16; b++) { + rTextures[0][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + rTextures[1][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + rTextures[2][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_MULTI[mTier] }; + rTextures[3][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_POWER[mTier + 1] }; + rTextures[4][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_POWER[mTier + 1] }; + rTextures[5][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_POWER[mTier + 1] }; + rTextures[6][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + rTextures[7][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + rTextures[8][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI[mTier] }; + rTextures[9][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier + 1] }; + rTextures[10][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier + 1] }; + rTextures[11][b + 1] = new ITexture[] { Textures.BlockIcons.MACHINE_CASINGS[mTier][b + 1], + Textures.BlockIcons.OVERLAYS_ENERGY_OUT_POWER[mTier + 1] }; + } + return rTextures; + } + + @Override + public String[] getDescription() { + return ArrayUtils.addAll( + mDescriptionArray, + "Accepts 16A and outputs 64A", + EnumChatFormatting.BLUE + "Tec" + + EnumChatFormatting.DARK_BLUE + + "Tech" + + EnumChatFormatting.BLUE + + ": Interdimensional"); + } + + @Override + public long getMinimumStoredEU() { + return V[mTier + 1]; + } + + @Override + public long maxEUStore() { + return 512L + V[mTier + 1] * 128L; + } + + @Override + public long maxAmperesOut() { + return getBaseMetaTileEntity().isAllowedToWork() ? 64 : 16; + } + + @Override + public long maxAmperesIn() { + return getBaseMetaTileEntity().isAllowedToWork() ? 16 : 64; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessDynamo.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessDynamo.java new file mode 100644 index 0000000000..fc7bc3fae2 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessDynamo.java @@ -0,0 +1,144 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.AuthorColen; +import static gregtech.api.enums.GTValues.V; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; + +import java.util.UUID; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.IWirelessEnergyHatchInformation; +import gregtech.api.metatileentity.MetaTileEntity; + +public class MTEWirelessDynamo extends MTEHatchDynamo implements IWirelessEnergyHatchInformation { + + private UUID owner_uuid; + + public MTEWirelessDynamo(String aName, byte aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aDescription, aTextures); + } + + public MTEWirelessDynamo(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, new String[] { "" }); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isEnetOutput() { + return false; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public long getMinimumStoredEU() { + return 2 * V[mTier]; + } + + @Override + public long maxEUOutput() { + return V[mTier]; + } + + @Override + public long maxEUStore() { + return totalStorage(V[mTier]); + } + + @Override + public String[] getDescription() { + return new String[] { EnumChatFormatting.GRAY + "Stores energy globally in a network, up to 2^(2^31) EU.", + EnumChatFormatting.GRAY + "Does not connect to wires. This block accepts EU into the network.", + AuthorColen }; + } + + @Override + public long maxAmperesOut() { + return 2; + } + + @Override + public ConnectionType getConnectionType() { + return ConnectionType.WIRELESS; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEWirelessDynamo(mName, mTier, new String[] { "" }, mTextures); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPreTick(aBaseMetaTileEntity, aTick); + + if (aBaseMetaTileEntity.isServerSide()) { + + // On first tick find the player name and attempt to add them to the map. + if (aTick == 1) { + + // UUID and username of the owner. + owner_uuid = aBaseMetaTileEntity.getOwnerUuid(); + + strongCheckOrAddUser(owner_uuid); + } + + // Every ticks_between_energy_addition ticks change the energy content of the machine. + if (aTick % ticks_between_energy_addition == 0L) { + addEUToGlobalEnergyMap(owner_uuid, getEUVar()); + setEUVar(0L); + } + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessEnergy.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessEnergy.java new file mode 100644 index 0000000000..e195b4ab08 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEWirelessEnergy.java @@ -0,0 +1,167 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.enums.GTValues.AuthorColen; +import static gregtech.api.enums.GTValues.V; +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static java.lang.Long.min; + +import java.math.BigInteger; +import java.util.UUID; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.IWirelessEnergyHatchInformation; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.common.misc.spaceprojects.SpaceProjectManager; + +public class MTEWirelessEnergy extends MTEHatchEnergy implements IWirelessEnergyHatchInformation { + + private final BigInteger eu_transferred_per_operation = BigInteger + .valueOf(2 * V[mTier] * ticks_between_energy_addition); + private final long eu_transferred_per_operation_long = eu_transferred_per_operation.longValue(); + + private UUID owner_uuid; + + public MTEWirelessEnergy(String aName, byte aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, 0, aDescription, aTextures); + } + + public MTEWirelessEnergy(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, new String[] { "" }); + } + + @Override + public String[] getDescription() { + return new String[] { EnumChatFormatting.GRAY + "Stores energy globally in a network, up to 2^(2^31) EU.", + EnumChatFormatting.GRAY + "Does not connect to wires. This block withdraws EU from the network.", + AuthorColen }; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, Textures.BlockIcons.OVERLAYS_ENERGY_IN_MULTI_WIRELESS_ON[mTier] }; + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean isEnetInput() { + return false; + } + + @Override + public boolean isInputFacing(ForgeDirection side) { + return side == getBaseMetaTileEntity().getFrontFacing(); + } + + @Override + public boolean isValidSlot(int aIndex) { + return false; + } + + @Override + public long getMinimumStoredEU() { + return 2 * V[mTier]; + } + + @Override + public long maxEUInput() { + return V[mTier]; + } + + @Override + public long maxEUStore() { + return totalStorage(V[mTier]); + } + + @Override + public long maxAmperesIn() { + return 2; + } + + @Override + public ConnectionType getConnectionType() { + return ConnectionType.WIRELESS; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEWirelessEnergy(mName, mTier, new String[] { "" }, mTextures); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + return false; + } + + @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + super.onFirstTick(aBaseMetaTileEntity); + + if (!aBaseMetaTileEntity.isServerSide()) return; + + // UUID of the owner. + owner_uuid = aBaseMetaTileEntity.getOwnerUuid(); + + SpaceProjectManager.checkOrCreateTeam(owner_uuid);; + + tryFetchingEnergy(); + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + + super.onPreTick(aBaseMetaTileEntity, aTick); + + if (aBaseMetaTileEntity.isServerSide()) { + // This is set up in a way to be as optimised as possible. If a user has a relatively plentiful energy + // network + // it should make no difference to them. Minimising the number of operations on BigInteger is essential. + + // Every ticks_between_energy_addition add eu_transferred_per_operation to internal EU storage from network. + if (aTick % ticks_between_energy_addition == 0L) { + tryFetchingEnergy(); + } + } + } + + private void tryFetchingEnergy() { + long currentEU = getBaseMetaTileEntity().getStoredEU(); + long maxEU = maxEUStore(); + long euToTransfer = min(maxEU - currentEU, eu_transferred_per_operation_long); + if (euToTransfer <= 0) return; // nothing to transfer + if (!addEUToGlobalEnergyMap(owner_uuid, -euToTransfer)) return; + setEUVar(currentEU + euToTransfer); + } +} diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java index f5cf261be1..f1f4b8591a 100644 --- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java +++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java @@ -1,11 +1,11 @@ package gregtech.api.multitileentity; -import static gregtech.api.enums.GT_Values.OFFX; -import static gregtech.api.enums.GT_Values.OFFY; -import static gregtech.api.enums.GT_Values.OFFZ; -import static gregtech.api.util.GT_Util.LAST_BROKEN_TILEENTITY; -import static gregtech.api.util.GT_Util.getTileEntity; -import static gregtech.api.util.GT_Util.setTileEntity; +import static gregtech.api.enums.GTValues.OFFX; +import static gregtech.api.enums.GTValues.OFFY; +import static gregtech.api.enums.GTValues.OFFZ; +import static gregtech.api.util.GTUtil.LAST_BROKEN_TILEENTITY; +import static gregtech.api.util.GTUtil.getTileEntity; +import static gregtech.api.util.GTUtil.setTileEntity; import java.util.ArrayList; import java.util.List; @@ -44,7 +44,7 @@ import cpw.mods.fml.common.Optional; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; +import gregtech.api.GregTechAPI; import gregtech.api.enums.ItemList; import gregtech.api.enums.Textures; import gregtech.api.interfaces.IDebugableBlock; @@ -53,10 +53,10 @@ import gregtech.api.metatileentity.BaseTileEntity; import gregtech.api.metatileentity.CoverableTileEntity; import gregtech.api.multitileentity.interfaces.IMultiTileEntity; import gregtech.api.objects.XSTR; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Util; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtil; import gregtech.common.covers.CoverInfo; -import gregtech.common.render.GT_MultiTile_Renderer; +import gregtech.common.render.MultiTileRenderer; /* * MultiTileEntityBlock ported from GT6 @@ -85,7 +85,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl public MultiTileEntityBlock(Material material) { super(material); - if (GregTech_API.sPreloadFinished) + if (GregTechAPI.sPreloadFinished) throw new IllegalStateException("Blocks can only be initialized within preInit!"); } @@ -121,7 +121,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl public MultiTileEntityBlock register() { if (registered) throw new IllegalStateException("Block already registered " + internalName); - if (GregTech_API.sPreloadFinished) + if (GregTechAPI.sPreloadFinished) throw new IllegalStateException("Blocks can only be initialized within preInit!"); registered = true; @@ -141,7 +141,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl // spotless:off // if (aTileEntity instanceof IMTE_HasMultiBlockMachineRelevantData // && ((IMTE_HasMultiBlockMachineRelevantData) aTileEntity).hasMultiBlockMachineRelevantData()) - // GregTech_API.causeMachineUpdate(world, x, y, z); + // GregTechAPI.causeMachineUpdate(world, x, y, z); // spotless:on world.removeTileEntity(x, y, z); @@ -160,8 +160,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl @Override public int getRenderType() { - return GT_MultiTile_Renderer.INSTANCE == null ? super.getRenderType() - : GT_MultiTile_Renderer.INSTANCE.getRenderId(); + return MultiTileRenderer.INSTANCE == null ? super.getRenderType() : MultiTileRenderer.INSTANCE.getRenderId(); } @Override @@ -455,7 +454,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl @Override public boolean removedByPlayer(World world, EntityPlayer aPlayer, int x, int y, int z, boolean aWillHarvest) { - final TileEntity tileEntity = GT_Util.getTileEntity(world, x, y, z, true); + final TileEntity tileEntity = GTUtil.getTileEntity(world, x, y, z, true); if (tileEntity != null) LAST_BROKEN_TILEENTITY.set(tileEntity); return super.removedByPlayer(world, aPlayer, x, y, z, aWillHarvest); } @@ -467,7 +466,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl @Override public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { - return GregTech_API.sMachineFlammable && (world.getBlockMetadata(x, y, z) == 0) ? 100 : 0; + return GregTechAPI.sMachineFlammable && (world.getBlockMetadata(x, y, z) == 0) ? 100 : 0; } @Override @@ -502,7 +501,7 @@ public class MultiTileEntityBlock extends BlockContainer implements IDebugableBl final TileEntity tileEntity = getTileEntity(world, x, y, z, true); if (tileEntity != null) LAST_BROKEN_TILEENTITY.set(tileEntity); if (tileEntity instanceof IMultiTileEntity mute) { - GT_Log.exp.printf( + GTLog.exp.printf( "Explosion at : %d | %d | %d DIMID: %s due to near explosion!%n", x, y, diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java index 325f583149..ca265e529e 100644 --- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java +++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity; -import static gregtech.api.enums.GT_Values.NBT; +import static gregtech.api.enums.GTValues.NBT; import java.lang.ref.WeakReference; @@ -11,7 +11,7 @@ import gregtech.api.enums.Materials; import gregtech.api.multitileentity.base.MultiTileEntity; import gregtech.api.multitileentity.multiblock.casing.FunctionalCasing; import gregtech.api.multitileentity.multiblock.casing.UpgradeCasing; -import gregtech.api.util.GT_Util; +import gregtech.api.util.GTUtil; import gregtech.common.tileentities.casings.upgrade.Inventory; import gregtech.common.tileentities.casings.upgrade.Tank; @@ -43,7 +43,7 @@ public class MultiTileEntityClassContainer { if (parameters.hasKey(NBT.MATERIAL) && !parameters.hasKey(NBT.COLOR)) parameters.setInteger( NBT.COLOR, - GT_Util.getRGBInt( + GTUtil.getRGBInt( Materials.get(parameters.getString(NBT.MATERIAL)) .getRGBA())); @@ -80,7 +80,7 @@ public class MultiTileEntityClassContainer { public MultiTileEntityClassContainer material(Materials material) { // Sets the material, and the color from the material, if not already set parameters.setString(NBT.MATERIAL, material.toString()); - if (!parameters.hasKey(NBT.COLOR)) parameters.setInteger(NBT.COLOR, GT_Util.getRGBInt(material.getRGBA())); + if (!parameters.hasKey(NBT.COLOR)) parameters.setInteger(NBT.COLOR, GTUtil.getRGBInt(material.getRGBA())); return this; } @@ -90,7 +90,7 @@ public class MultiTileEntityClassContainer { } public MultiTileEntityClassContainer color(short[] rgba) { - parameters.setInteger(NBT.COLOR, GT_Util.getRGBInt(rgba)); + parameters.setInteger(NBT.COLOR, GTUtil.getRGBInt(rgba)); return this; } @@ -154,7 +154,7 @@ public class MultiTileEntityClassContainer { * Merge in arbitrary NBT tuples of (key, value). Useful for anything for which a custom method has not yet been * exposed */ - parameters = GT_Util.fuseNBT(parameters, GT_Util.makeNBT(aTags)); + parameters = GTUtil.fuseNBT(parameters, GTUtil.makeNBT(aTags)); return this; } diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityItem.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityItem.java index e67ab61e96..bf7259626f 100644 --- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityItem.java +++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityItem.java @@ -1,7 +1,7 @@ package gregtech.api.multitileentity; -import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.SIDE_TOP; +import static gregtech.GTMod.GT_FML_LOGGER; +import static gregtech.api.enums.GTValues.SIDE_TOP; import java.util.List; @@ -132,7 +132,7 @@ public class MultiTileEntityItem extends ItemBlock { * Add back if needed */ // try { - // GregTech_API.causeMachineUpdate(world, x, y, z); + // GregTechAPI.causeMachineUpdate(world, x, y, z); // } catch (Throwable e) { // GT_FML_LOGGER.error("causeMachineUpdate", e); // } diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityRegistry.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityRegistry.java index 0b5afbb043..186110abb7 100644 --- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityRegistry.java +++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityRegistry.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity; -import static gregtech.GT_Mod.GT_FML_LOGGER; +import static gregtech.GTMod.GT_FML_LOGGER; import java.util.ArrayList; import java.util.HashMap; @@ -21,12 +21,12 @@ import com.gtnewhorizon.gtnhlib.util.map.ItemStackMap; import appeng.core.CreativeTab; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.LoaderState; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.multitileentity.base.MultiTileEntity; import gregtech.api.multitileentity.interfaces.IMultiTileEntity; -import gregtech.api.util.GT_LanguageManager; -import gregtech.api.util.GT_Util; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTUtil; +import gregtech.api.util.GTUtility; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; @@ -61,7 +61,7 @@ public class MultiTileEntityRegistry { this.block = block; GT_FML_LOGGER.info(internalName + " " + Block.getIdFromBlock(block) + " This is the answer"); this.block.setRegistry(this); - REGISTRIES.put(new ItemStack(Item.getItemById(Block.getIdFromBlock(block)), 1, GT_Values.W), this); + REGISTRIES.put(new ItemStack(Item.getItemById(Block.getIdFromBlock(block)), 1, GTValues.W), this); NAMED_REGISTRIES.put(internalName, this); } @@ -84,7 +84,7 @@ public class MultiTileEntityRegistry { } public static MultiTileEntityRegistry getRegistry(int aRegistryID) { - return REGISTRIES.get(new ItemStack(Item.getItemById(aRegistryID), 1, GT_Values.W)); + return REGISTRIES.get(new ItemStack(Item.getItemById(aRegistryID), 1, GTValues.W)); } public static MultiTileEntityRegistry getRegistry(String aRegistryName) { @@ -101,7 +101,7 @@ public class MultiTileEntityRegistry { */ public ItemStack add(String aLocalised, MultiTileEntityClassContainer aClassContainer) { boolean tFailed = false; - if (GT_Utility.isStringInvalid(aLocalised)) { + if (GTUtility.isStringInvalid(aLocalised)) { GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Localisation Missing!"); tFailed = true; } @@ -113,7 +113,7 @@ public class MultiTileEntityRegistry { GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Class inside Class Container is null!"); tFailed = true; } - if (aClassContainer.getMuteID() == GT_Values.W) { + if (aClassContainer.getMuteID() == GTValues.W) { GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Class Container uses Wildcard MetaData!"); tFailed = true; } @@ -138,8 +138,7 @@ public class MultiTileEntityRegistry { return null; } - GT_LanguageManager - .addStringLocalization(internalName + "." + aClassContainer.getMuteID() + ".name", aLocalised); + GTLanguageManager.addStringLocalization(internalName + "." + aClassContainer.getMuteID() + ".name", aLocalised); registry.put(aClassContainer.getMuteID(), aClassContainer); mLastRegisteredID = aClassContainer.getMuteID(); registrations.add(aClassContainer); @@ -154,7 +153,7 @@ public class MultiTileEntityRegistry { return getItem(aClassContainer.getMuteID()); } - public short mLastRegisteredID = GT_Values.W; + public short mLastRegisteredID = GTValues.W; public ItemStack getItem() { return getItem(mLastRegisteredID, 1, null); @@ -206,14 +205,14 @@ public class MultiTileEntityRegistry { public TileEntity getNewTileEntity(World aWorld, int x, int y, int z, int metaID, NBTTagCompound nbt) { final MultiTileEntityClassContainer container = registry.get((short) metaID); if (container == null) return null; - final MultiTileEntity te = (MultiTileEntity) GT_Utility + final MultiTileEntity te = (MultiTileEntity) GTUtility .callConstructor(container.getMuteClass(), -1, null, true); te.setWorldObj(aWorld); te.xCoord = x; te.yCoord = y; te.zCoord = z; nbt = (nbt == null || nbt.hasNoTags()) ? container.getParameters() - : GT_Util.fuseNBT(nbt, container.getParameters()); + : GTUtil.fuseNBT(nbt, container.getParameters()); te.initFromNBT(nbt, (short) metaID, (short) Block.getIdFromBlock(block)); return te; } diff --git a/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java index eeadfe7602..24163f9c20 100644 --- a/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java +++ b/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java @@ -1,7 +1,7 @@ package gregtech.api.multitileentity.base; -import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.VALID_SIDES; +import static gregtech.GTMod.GT_FML_LOGGER; +import static gregtech.api.enums.GTValues.VALID_SIDES; import java.io.IOException; import java.util.ArrayList; @@ -35,15 +35,15 @@ import net.minecraftforge.fluids.Fluid; import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils; import cpw.mods.fml.common.registry.GameRegistry; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.GT_Values.NBT; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.GTValues.NBT; import gregtech.api.enums.Materials; 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.gui.modularui.GT_UIInfos; +import gregtech.api.gui.modularui.GTUIInfos; import gregtech.api.interfaces.ITexture; import gregtech.api.metatileentity.CoverableTileEntity; import gregtech.api.metatileentity.GregTechTileClientEvents; @@ -52,18 +52,18 @@ import gregtech.api.multitileentity.MultiTileEntityClassContainer; import gregtech.api.multitileentity.MultiTileEntityRegistry; import gregtech.api.multitileentity.interfaces.IMultiTileEntity; import gregtech.api.multitileentity.interfaces.SyncedMultiTileEntity; -import gregtech.api.net.GT_Packet_MultiTileEntity; -import gregtech.api.net.GT_Packet_New; +import gregtech.api.net.GTPacketMultiTileEntity; +import gregtech.api.net.GTPacketNew; import gregtech.api.net.data.CommonData; import gregtech.api.net.data.CoordinateData; import gregtech.api.net.data.MultiTileEntityData; -import gregtech.api.objects.GT_ItemStack; +import gregtech.api.objects.GTItemStack; import gregtech.api.objects.XSTR; import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Util; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTUtil; +import gregtech.api.util.GTUtility; import gregtech.common.render.MultiTileBasicRender; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; @@ -98,16 +98,16 @@ public abstract class MultiTileEntity extends CoverableTileEntity protected ForgeDirection facing = ForgeDirection.WEST; // Default to WEST, so it renders facing Left in the // inventory protected byte color; - protected int rgba = GT_Values.UNCOLORED; - private short mteID = GT_Values.W, mteRegistry = GT_Values.W; + protected int rgba = GTValues.UNCOLORED; + private short mteID = GTValues.W, mteRegistry = GTValues.W; private String customName = null; private String ownerName = ""; - private UUID ownerUUID = GT_Utility.defaultUuid; + private UUID ownerUUID = GTUtility.defaultUuid; private boolean lockUpgrade = false; - private final GT_Packet_MultiTileEntity fullPacket = new GT_Packet_MultiTileEntity(false); - private final GT_Packet_MultiTileEntity timedPacket = new GT_Packet_MultiTileEntity(false); - private final GT_Packet_MultiTileEntity graphicPacket = new GT_Packet_MultiTileEntity(false); + private final GTPacketMultiTileEntity fullPacket = new GTPacketMultiTileEntity(false); + private final GTPacketMultiTileEntity timedPacket = new GTPacketMultiTileEntity(false); + private final GTPacketMultiTileEntity graphicPacket = new GTPacketMultiTileEntity(false); public MultiTileEntity(boolean isTicking) { this.isTicking = isTicking; @@ -213,7 +213,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity @Override public void readFromNBT(NBTTagCompound nbt) { // Check if it is a World/Chunk-Loading Process calling readFromNBT - if (mteID == GT_Values.W || mteRegistry == GT_Values.W) { + if (mteID == GTValues.W || mteRegistry == GTValues.W) { // Read the ID Tags first mteID = nbt.getShort(NBT.MTE_ID); mteRegistry = nbt.getShort(NBT.MTE_REG); @@ -224,7 +224,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity if (tClass != null) { // Add the Default Parameters. Useful for things that differ between different tiers/types of the // same machine - nbt = GT_Util.fuseNBT(nbt, tClass.getParameters()); + nbt = GTUtil.fuseNBT(nbt, tClass.getParameters()); } } } @@ -255,7 +255,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity readMultiTileNBT(nbt); if (NetworkUtils.isDedicatedClient()) { - if (GregTech_API.sBlockIcons == null && nbt.hasKey(NBT.TEXTURE_FOLDER)) { + if (GregTechAPI.sBlockIcons == null && nbt.hasKey(NBT.TEXTURE_FOLDER)) { loadTextures(nbt.getString(NBT.TEXTURE_FOLDER)); } else { copyTextures(); @@ -284,7 +284,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity nbt.setShort(NBT.MTE_ID, mteID); nbt.setShort(NBT.MTE_REG, mteRegistry); // write the Custom Name - if (GT_Utility.isStringValid(customName)) { + if (GTUtility.isStringValid(customName)) { final NBTTagCompound displayNBT; if (nbt.hasKey(NBT.DISPLAY)) { displayNBT = nbt.getCompoundTag(NBT.DISPLAY); @@ -349,7 +349,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity public TileEntity getTileEntity(int aX, int aY, int aZ) { if (worldObj == null || (ignoreUnloadedChunks && crossedChunkBorder(aX, aZ) && !worldObj.blockExists(aX, aY, aZ))) return null; - return GT_Util.getTileEntity(worldObj, aX, aY, aZ, true); + return GTUtil.getTileEntity(worldObj, aX, aY, aZ, true); } @Override @@ -410,7 +410,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity @Override public String getCustomName() { - return GT_Utility.isStringValid(customName) ? customName : null; + return GTUtility.isStringValid(customName) ? customName : null; } @Override @@ -468,7 +468,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity if (shouldTriggerBlockUpdate()) { // If we're triggering a block update this will call onMachineBlockUpdate() - GregTech_API.causeMachineUpdate(worldObj, xCoord, yCoord, zCoord); + GregTechAPI.causeMachineUpdate(worldObj, xCoord, yCoord, zCoord); } else { // If we're not trigger a cascading one, call the update here. onMachineBlockUpdate(); @@ -653,7 +653,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity } @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { return true; } @@ -696,13 +696,13 @@ public abstract class MultiTileEntity extends CoverableTileEntity @Override public String getOwnerName() { - if (GT_Utility.isStringInvalid(ownerName)) return "Player"; + if (GTUtility.isStringInvalid(ownerName)) return "Player"; return ownerName; } @Override public String setOwnerName(String aName) { - if (GT_Utility.isStringInvalid(aName)) return ownerName = "Player"; + if (GTUtility.isStringInvalid(aName)) return ownerName = "Player"; return ownerName = aName; } @@ -741,7 +741,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity return allowRightclick(aPlayer) && onRightClick(aPlayer, side, aX, aY, aZ); } catch (Throwable e) { GT_FML_LOGGER.error("onBlockActivated Failed", e); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); return true; } } @@ -752,7 +752,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity // Configure Cover, sneak can also be: screwdriver, wrench, side cutter, soldering iron if (aPlayer.isSneaking()) { final ForgeDirection tSide = (getCoverIDAtSide(side) == 0) - ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) + ? GTUtility.determineWrenchingSide(side, aX, aY, aZ) : side; return (getCoverBehaviorAtSideNew(tSide).hasCoverGUI()); } else if (getCoverBehaviorAtSideNew(side).onCoverRightclickClient(side, this, aPlayer, aX, aY, aZ)) { @@ -764,37 +764,37 @@ public abstract class MultiTileEntity extends CoverableTileEntity if (!privateAccess() || aPlayer.getDisplayName() .equalsIgnoreCase(getOwnerName())) { final ItemStack tCurrentItem = aPlayer.inventory.getCurrentItem(); - final ForgeDirection wrenchSide = GT_Utility.determineWrenchingSide(side, aX, aY, aZ); + final ForgeDirection wrenchSide = GTUtility.determineWrenchingSide(side, aX, aY, aZ); if (tCurrentItem != null) { if (getColorization() >= 0 - && GT_Utility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) { + && GTUtility.areStacksEqual(new ItemStack(Items.water_bucket, 1), tCurrentItem)) { // TODO (Colorization) } - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWrenchList)) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sWrenchList)) return onWrenchRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ, tCurrentItem); - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sScrewdriverList)) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sScrewdriverList)) return onScrewdriverRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ, tCurrentItem); - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sHardHammerList)) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sHardHammerList)) return onHammerRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ, tCurrentItem); - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSoftHammerList)) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sSoftHammerList)) return onMalletRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ, tCurrentItem); - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sSolderingToolList)) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sSolderingToolList)) return onSolderingRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ, tCurrentItem); - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sWireCutterList)) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sWireCutterList)) return onWireCutterRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ, tCurrentItem); final ForgeDirection coverSide = getCoverIDAtSide(side) == 0 ? wrenchSide : side; if (getCoverIDAtSide(coverSide) == 0) { - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCovers.keySet())) { - if (GregTech_API.getCoverBehaviorNew(tCurrentItem) + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sCovers.keySet())) { + if (GregTechAPI.getCoverBehaviorNew(tCurrentItem) .isCoverPlaceable(coverSide, tCurrentItem, this) - && allowCoverOnSide(coverSide, new GT_ItemStack(tCurrentItem))) { + && allowCoverOnSide(coverSide, new GTItemStack(tCurrentItem))) { setCoverItemAtSide(coverSide, tCurrentItem); if (!aPlayer.capabilities.isCreativeMode) tCurrentItem.stackSize--; - GT_Utility.sendSoundToPlayers( + GTUtility.sendSoundToPlayers( worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, @@ -808,9 +808,9 @@ public abstract class MultiTileEntity extends CoverableTileEntity return true; } } else { - if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCrowbarList)) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { - GT_Utility.sendSoundToPlayers( + if (GTUtility.isStackInList(tCurrentItem, GregTechAPI.sCrowbarList)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer)) { + GTUtility.sendSoundToPlayers( worldObj, SoundResource.RANDOM_BREAK, 1.0F, @@ -825,7 +825,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity } } } else if (aPlayer.isSneaking()) { // Sneak click, no tool -> open cover config if possible. - side = (getCoverIDAtSide(side) == 0) ? GT_Utility.determineWrenchingSide(side, aX, aY, aZ) : side; + side = (getCoverIDAtSide(side) == 0) ? GTUtility.determineWrenchingSide(side, aX, aY, aZ) : side; return getCoverIDAtSide(side) > 0 && getCoverBehaviorAtSideNew(side).onCoverShiftRightClick( side, getCoverIDAtSide(side), @@ -867,7 +867,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity return false; } - GT_UIInfos.openGTTileEntityUI(this, aPlayer); + GTUIInfos.openGTTileEntityUI(this, aPlayer); System.out.println("Trying to open a UI"); return true; } @@ -875,15 +875,15 @@ public abstract class MultiTileEntity extends CoverableTileEntity public boolean onWrenchRightClick(EntityPlayer aPlayer, ItemStack tCurrentItem, ForgeDirection wrenchSide, float aX, float aY, float aZ, ItemStack aTool) { if (setMainFacing(wrenchSide)) { - GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); - GT_Utility.sendSoundToPlayers(worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1, xCoord, yCoord, zCoord); + GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer); + GTUtility.sendSoundToPlayers(worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1, xCoord, yCoord, zCoord); } return onWrenchRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ); } public boolean onScrewdriverRightClick(EntityPlayer aPlayer, ItemStack tCurrentItem, ForgeDirection wrenchSide, float aX, float aY, float aZ, ItemStack aTool) { - if (GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) { + if (GTModHandler.damageOrDechargeItem(tCurrentItem, 1, 200, aPlayer)) { setCoverDataAtSide( wrenchSide, getCoverBehaviorAtSideNew(wrenchSide).onCoverScrewdriverClick( @@ -896,7 +896,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity aY, aZ)); // TODO: Update connections! - GT_Utility.sendSoundToPlayers(worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1, xCoord, yCoord, zCoord); + GTUtility.sendSoundToPlayers(worldObj, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1, xCoord, yCoord, zCoord); } return onScrewdriverRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ); } @@ -1033,20 +1033,20 @@ public abstract class MultiTileEntity extends CoverableTileEntity /** * @return a Packet containing all Data which has to be synchronised to the Client - Override as needed */ - public GT_Packet_MultiTileEntity getClientDataPacket() { + public GTPacketMultiTileEntity getClientDataPacket() { - final GT_Packet_MultiTileEntity packet = new GT_Packet_MultiTileEntity(false); + final GTPacketMultiTileEntity packet = new GTPacketMultiTileEntity(false); return packet; } @Override public void sendClientData(EntityPlayerMP aPlayer) { if (worldObj == null || worldObj.isRemote) return; - final GT_Packet_New tPacket = getClientDataPacket(); + final GTPacketNew tPacket = getClientDataPacket(); if (aPlayer == null) { - GT_Values.NW.sendPacketToAllPlayersInRange(worldObj, tPacket, getXCoord(), getZCoord()); + GTValues.NW.sendPacketToAllPlayersInRange(worldObj, tPacket, getXCoord(), getZCoord()); } else { - GT_Values.NW.sendToPlayer(tPacket, aPlayer); + GTValues.NW.sendToPlayer(tPacket, aPlayer); } sendCoverDataIfNeeded(); } @@ -1339,20 +1339,20 @@ public abstract class MultiTileEntity extends CoverableTileEntity } @Override - public void getFullPacketData(GT_Packet_MultiTileEntity packet) { + public void getFullPacketData(GTPacketMultiTileEntity packet) { packet.addData(new CoordinateData(getCoords())); packet.addData(new CommonData(mStrongRedstone, color, (byte) 0)); packet.addData(new MultiTileEntityData(mteRegistry, mteID)); } @Override - public void getGraphicPacketData(GT_Packet_MultiTileEntity packet) { + public void getGraphicPacketData(GTPacketMultiTileEntity packet) { packet.addData(new CoordinateData(getCoords())); packet.addData(new MultiTileEntityData(mteRegistry, mteID)); } @Override - public void getTimedPacketData(GT_Packet_MultiTileEntity packet) { + public void getTimedPacketData(GTPacketMultiTileEntity packet) { packet.addData(new CoordinateData(getCoords())); packet.addData(new MultiTileEntityData(mteRegistry, mteID)); } @@ -1361,21 +1361,21 @@ public abstract class MultiTileEntity extends CoverableTileEntity public void sendFullPacket(@Nonnull EntityPlayerMP player) { fullPacket.clearData(); getFullPacketData(fullPacket); - GT_Values.NW.sendToPlayer(fullPacket, player); + GTValues.NW.sendToPlayer(fullPacket, player); } @Override public void sendGraphicPacket() { graphicPacket.clearData(); getGraphicPacketData(graphicPacket); - GT_Values.NW.sendPacketToAllPlayersInRange(worldObj, graphicPacket, getXCoord(), getZCoord()); + GTValues.NW.sendPacketToAllPlayersInRange(worldObj, graphicPacket, getXCoord(), getZCoord()); } @Override public void sendTimedPacket() { timedPacket.clearData(); getTimedPacketData(timedPacket); - GT_Values.NW.sendPacketToAllPlayersInRange(worldObj, timedPacket, getXCoord(), getZCoord()); + GTValues.NW.sendPacketToAllPlayersInRange(worldObj, timedPacket, getXCoord(), getZCoord()); } @Override diff --git a/src/main/java/gregtech/api/multitileentity/base/NonTickableMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/NonTickableMultiTileEntity.java index 2837a88180..7866ad69dc 100644 --- a/src/main/java/gregtech/api/multitileentity/base/NonTickableMultiTileEntity.java +++ b/src/main/java/gregtech/api/multitileentity/base/NonTickableMultiTileEntity.java @@ -1,12 +1,12 @@ package gregtech.api.multitileentity.base; -import static gregtech.api.enums.GT_Values.NW; +import static gregtech.api.enums.GTValues.NW; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.Packet; import net.minecraftforge.common.util.ForgeDirection; -import gregtech.api.net.GT_Packet_SendCoverData; +import gregtech.api.net.GTPacketSendCoverData; import gregtech.api.util.ISerializableObject; import gregtech.common.covers.CoverInfo; @@ -45,7 +45,7 @@ public abstract class NonTickableMultiTileEntity extends MultiTileEntity { } else { // Otherwise, send the data right away final CoverInfo coverInfo = getCoverInfoAtSide(side); - NW.sendPacketToAllPlayersInRange(worldObj, new GT_Packet_SendCoverData(coverInfo, this), xCoord, zCoord); + NW.sendPacketToAllPlayersInRange(worldObj, new GTPacketSendCoverData(coverInfo, this), xCoord, zCoord); // Just in case coverInfo.setNeedsUpdate(false); diff --git a/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java index 987a4c18b3..dfc600483b 100644 --- a/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java +++ b/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity.base; -import static gregtech.GT_Mod.GT_FML_LOGGER; +import static gregtech.GTMod.GT_FML_LOGGER; import java.util.HashMap; import java.util.Map; @@ -14,11 +14,11 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.task.TaskHost; import gregtech.api.task.TickableTask; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Util; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtil; public abstract class TickableMultiTileEntity extends MultiTileEntity implements TaskHost { @@ -57,7 +57,7 @@ public abstract class TickableMultiTileEntity extends MultiTileEntity implements try { if (timer++ == 0) { markDirty(); - GT_Util.markChunkDirty(this); + GTUtil.markChunkDirty(this); onFirstTick(isServerSide); } if (isDead()) { @@ -80,7 +80,7 @@ public abstract class TickableMultiTileEntity extends MultiTileEntity implements } catch (Throwable e) { GT_FML_LOGGER.error("UpdateEntity Failed", e); - e.printStackTrace(GT_Log.err); + e.printStackTrace(GTLog.err); try { onTickFailed(timer, isServerSide); } catch (Throwable e2) { @@ -133,8 +133,8 @@ public abstract class TickableMultiTileEntity extends MultiTileEntity implements @Override protected final void readTasksNBT(NBTTagCompound nbt) { - if (nbt.hasKey(GT_Values.NBT.TASKS)) { - NBTTagCompound tasksTag = nbt.getCompoundTag(GT_Values.NBT.TASKS); + if (nbt.hasKey(GTValues.NBT.TASKS)) { + NBTTagCompound tasksTag = nbt.getCompoundTag(GTValues.NBT.TASKS); for (TickableTask task : tasks.values()) { if (tasksTag.hasKey(task.getName())) { task.readFromNBT(tasksTag.getCompoundTag(task.getName())); @@ -151,7 +151,7 @@ public abstract class TickableMultiTileEntity extends MultiTileEntity implements task.writeToNBT(tag); tasksTag.setTag(task.getName(), tag); } - aNBT.setTag(GT_Values.NBT.TASKS, tasksTag); + aNBT.setTag(GTValues.NBT.TASKS, tasksTag); } @Override diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java index 73bd55738a..4efaff34d7 100644 --- a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java +++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java @@ -3,7 +3,7 @@ package gregtech.api.multitileentity.enums; import static gregtech.api.util.GT_StructureUtilityMuTE.createMuTEStructureCasing; import static gregtech.loaders.preload.GT_Loader_MultiTileEntities.CASING_REGISTRY_NAME; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.util.GT_StructureUtilityMuTE; public enum GT_MultiTileCasing { @@ -19,7 +19,7 @@ public enum GT_MultiTileCasing { LaserEngraverUpgrade2(8), LaserEngraverUpgrade3(9), LaserEngraverUpgrade4(10), - NONE(GT_Values.W); + NONE(GTValues.W); private final int meta; private final GT_StructureUtilityMuTE.MuTEStructureCasing casing; diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java index e062ecc705..431da32353 100644 --- a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java +++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity.enums; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; public enum GT_MultiTileComponentCasing { @@ -116,7 +116,7 @@ public enum GT_MultiTileComponentCasing { UMV_FieldGenerator(109), UXV_FieldGenerator(110), MAX_FieldGenerator(111), - NONE(GT_Values.W); + NONE(GTValues.W); private final int meta; diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java index 7cdde78986..6787ab00d7 100644 --- a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java +++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java @@ -1,11 +1,11 @@ package gregtech.api.multitileentity.enums; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; public enum GT_MultiTileMachine { CokeOven(0), - NONE(GT_Values.W); + NONE(GTValues.W); private final int meta; diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileUpgradeCasing.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileUpgradeCasing.java index 296bae546d..5acdd5aeef 100644 --- a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileUpgradeCasing.java +++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileUpgradeCasing.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity.enums; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; public enum GT_MultiTileUpgradeCasing { @@ -57,7 +57,7 @@ public enum GT_MultiTileUpgradeCasing { Insulator_NextGen(107), Insulator_Omnipotent(108), Insulator_OmegaType(109), - NONE(GT_Values.W); + NONE(GTValues.W); private final int meta; diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/SyncedMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/interfaces/SyncedMultiTileEntity.java index 2045f28d67..0f959c6bce 100644 --- a/src/main/java/gregtech/api/multitileentity/interfaces/SyncedMultiTileEntity.java +++ b/src/main/java/gregtech/api/multitileentity/interfaces/SyncedMultiTileEntity.java @@ -4,7 +4,7 @@ import javax.annotation.Nonnull; import net.minecraft.entity.player.EntityPlayerMP; -import gregtech.api.net.GT_Packet_MultiTileEntity; +import gregtech.api.net.GTPacketMultiTileEntity; public interface SyncedMultiTileEntity { @@ -19,10 +19,10 @@ public interface SyncedMultiTileEntity { /** * Should always collect all the data that the controller or casing has and should send * Called by {@link #sendFullPacket()} - * + * * @param packet The packet which will be sent */ - void getFullPacketData(GT_Packet_MultiTileEntity packet); + void getFullPacketData(GTPacketMultiTileEntity packet); /** * Will send a packet at a certain period of time, defined by {@link #getTimedPacketPeriod()}, to all players around @@ -35,10 +35,10 @@ public interface SyncedMultiTileEntity { * Collects all the data that should be sent out at a certain period of time defined by * {@link #getTimedPacketPeriod()} * Called by {@link #sendTimedPacket()} - * + * * @param packet The packet which will be sent */ - void getTimedPacketData(GT_Packet_MultiTileEntity packet); + void getTimedPacketData(GTPacketMultiTileEntity packet); /** * Defines the period of time at which a timed packet should be sent out. Default 20 ticks @@ -56,8 +56,8 @@ public interface SyncedMultiTileEntity { /** * Collects all the data that is needed to be send every single tick * Called by {@link #sendGraphicPacket()} - * + * * @param packet The packet which will be sent */ - void getGraphicPacketData(GT_Packet_MultiTileEntity packet); + void getGraphicPacketData(GTPacketMultiTileEntity packet); } diff --git a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java index 0953b4905c..32b87126ca 100644 --- a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java +++ b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity.machine; -import static gregtech.api.enums.GT_Values.*; +import static gregtech.api.enums.GTValues.*; import static gregtech.api.enums.TickTime.MINUTE; import java.io.IOException; @@ -30,8 +30,8 @@ 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.GTValues; +import gregtech.api.enums.GTValues.NBT; import gregtech.api.enums.InventoryType; import gregtech.api.enums.Mods; import gregtech.api.enums.SoundResource; @@ -55,8 +55,8 @@ import gregtech.api.multitileentity.base.TickableMultiTileEntity; import gregtech.api.multitileentity.interfaces.IMultiTileMachine; import gregtech.api.render.TextureFactory; import gregtech.api.task.tasks.ProcessingTask; -import gregtech.api.util.GT_Utility; -import gregtech.client.GT_SoundLoop; +import gregtech.api.util.GTUtility; +import gregtech.client.GTSoundLoop; import gregtech.common.gui.MachineGUIProvider; public abstract class MultiTileBasicMachine

> extends TickableMultiTileEntity @@ -106,7 +106,7 @@ public abstract class MultiTileBasicMachine

> ex protected GUIProvider guiProvider = createGUIProvider(); @SideOnly(Side.CLIENT) - protected GT_SoundLoop activitySoundLoop; + protected GTSoundLoop activitySoundLoop; public MultiTileBasicMachine() { new ProcessingTask<>(this); @@ -388,16 +388,16 @@ public abstract class MultiTileBasicMachine

> ex switch (aIndex) { case PROCESS_START_SOUND_INDEX -> { if (getProcessStartSound() != null) - GT_Utility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); + GTUtility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); } - case INTERRUPT_SOUND_INDEX -> GT_Utility + case INTERRUPT_SOUND_INDEX -> GTUtility .doSoundAtClient(SoundResource.IC2_MACHINES_INTERRUPT_ONE, 100, 1.0F, aX, aY, aZ); } } public void startSoundLoop(byte aIndex, double aX, double aY, double aZ) { if (aIndex == PROCESS_START_SOUND_INDEX && getProcessStartSound() != null) { - GT_Utility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); + GTUtility.doSoundAtClient(getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, aX, aY, aZ); } } @@ -412,7 +412,7 @@ public abstract class MultiTileBasicMachine

> ex @SideOnly(Side.CLIENT) protected void doActivitySound(ResourceLocation activitySound) { if (isActive() && activitySound != null && activitySoundLoop == null) { - activitySoundLoop = new GT_SoundLoop(activitySound, this, false, true); + activitySoundLoop = new GTSoundLoop(activitySound, this, false, true); Minecraft.getMinecraft() .getSoundHandler() .playSound(activitySoundLoop); @@ -549,7 +549,7 @@ public abstract class MultiTileBasicMachine

> ex @Override protected void addDebugInfo(EntityPlayer player, int logLevel, ArrayList list) { list.add( - GT_Utility.trans("186", "Owned by: ") + EnumChatFormatting.BLUE + GTUtility.trans("186", "Owned by: ") + EnumChatFormatting.BLUE + getOwnerName() + EnumChatFormatting.RESET + " (" @@ -567,30 +567,30 @@ public abstract class MultiTileBasicMachine

> ex list.add( StatCollector.translateToLocal("GT5U.multiblock.energy") + ": " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(logic.getStoredEnergy()) + + GTUtility.formatNumbers(logic.getStoredEnergy()) + EnumChatFormatting.RESET + " EU / " + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(logic.getCapacity()) + + GTUtility.formatNumbers(logic.getCapacity()) + EnumChatFormatting.RESET + " EU"); list.add( StatCollector.translateToLocal("GT5U.multiblock.usage") + ": " + EnumChatFormatting.RED - + GT_Utility.formatNumbers(getProcessingLogic().getCalculatedEut()) + + GTUtility.formatNumbers(getProcessingLogic().getCalculatedEut()) + EnumChatFormatting.RESET + " EU/t"); list.add( StatCollector.translateToLocal("GT5U.multiblock.mei") + ": " + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(logic.getVoltage()) + + GTUtility.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())] + + VN[GTUtility.getTier(logic.getVoltage())] + EnumChatFormatting.RESET); } @@ -598,11 +598,11 @@ public abstract class MultiTileBasicMachine

> ex // TODO: Add CPU load calculator list.add( - "Average CPU load of ~" + GT_Utility.formatNumbers(0) + "Average CPU load of ~" + GTUtility.formatNumbers(0) + "ns over " - + GT_Utility.formatNumbers(0) + + GTUtility.formatNumbers(0) + " ticks with worst time of " - + GT_Utility.formatNumbers(0) + + GTUtility.formatNumbers(0) + "ns."); } @@ -613,11 +613,11 @@ public abstract class MultiTileBasicMachine

> ex list.add( StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(progressTime > 20 ? progressTime / 20 : progressTime) + + GTUtility.formatNumbers(progressTime > 20 ? progressTime / 20 : progressTime) + EnumChatFormatting.RESET + (progressTime > 20 ? " s / " : " ticks / ") + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(maxProgressTime > 20 ? maxProgressTime / 20 : maxProgressTime) + + GTUtility.formatNumbers(maxProgressTime > 20 ? maxProgressTime / 20 : maxProgressTime) + EnumChatFormatting.RESET + (maxProgressTime > 20 ? " s" : " ticks")); } @@ -678,7 +678,7 @@ public abstract class MultiTileBasicMachine

> ex switch (soundEventValue) { case PROCESS_START_SOUND_INDEX -> { - if (getProcessStartSound() != null) GT_Utility.doSoundAtClient( + if (getProcessStartSound() != null) GTUtility.doSoundAtClient( getProcessStartSound(), getTimeBetweenProcessSounds(), 1.0F, @@ -686,7 +686,7 @@ public abstract class MultiTileBasicMachine

> ex getYCoord(), getZCoord()); } - case INTERRUPT_SOUND_INDEX -> GT_Utility.doSoundAtClient( + case INTERRUPT_SOUND_INDEX -> GTUtility.doSoundAtClient( SoundResource.IC2_MACHINES_INTERRUPT_ONE, 100, 1.0F, @@ -765,8 +765,8 @@ public abstract class MultiTileBasicMachine

> ex } protected void updatePowerLogic() { - power.setEnergyCapacity(GT_Values.V[tier] * power.getMaxAmperage() * 2 * MINUTE); - power.setMaxVoltage(GT_Values.V[tier]); + power.setEnergyCapacity(GTValues.V[tier] * power.getMaxAmperage() * 2 * MINUTE); + power.setMaxVoltage(GTValues.V[tier]); power.setMaxAmperage(1); } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java index cdcb77d6e5..3abb69dd51 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java @@ -15,8 +15,8 @@ import net.minecraft.util.StatCollector; import net.minecraft.world.World; import gregtech.api.logic.ComplexParallelProcessingLogic; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.GT_Waila; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GTWaila; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; @@ -56,12 +56,12 @@ public abstract class ComplexParallelController 20 ? processing.getProgress(i) / 20 : processing.getProgress(i)) + EnumChatFormatting.RESET + (processing.getProgress(i) > 20 ? " s / " : " ticks / ") + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers( + + GTUtility.formatNumbers( processing.getDuration(i) > 20 ? processing.getDuration(i) / 20 : processing.getDuration(i)) + EnumChatFormatting.RESET + (processing.getDuration(i) > 20 ? " s" : " ticks")); @@ -92,7 +92,7 @@ public abstract class ComplexParallelController 0 && maxProgress >= progress, maxProgress, progress)); } } 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 552cf6d94e..1eaae5997d 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java @@ -1,6 +1,6 @@ package gregtech.api.multitileentity.multiblock.base; -import static gregtech.api.util.GT_Utility.moveMultipleItemStacks; +import static gregtech.api.util.GTUtility.moveMultipleItemStacks; import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; import static mcp.mobius.waila.api.SpecialChars.*; @@ -46,7 +46,7 @@ import com.gtnewhorizon.structurelib.util.Vec3Impl; import com.gtnewhorizons.modularui.api.screen.ModularWindow; import cpw.mods.fml.common.network.NetworkRegistry; -import gregtech.api.enums.GT_Values.NBT; +import gregtech.api.enums.GTValues.NBT; import gregtech.api.enums.InventoryType; import gregtech.api.enums.VoidingMode; import gregtech.api.interfaces.IDescribable; @@ -64,11 +64,11 @@ import gregtech.api.multitileentity.interfaces.IMultiBlockPart; 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.util.GT_Multiblock_Tooltip_Builder; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.GT_Waila; +import gregtech.api.net.GTPacketMultiTileEntity; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GTWaila; +import gregtech.api.util.MultiblockTooltipBuilder; import mcp.mobius.waila.api.IWailaConfigHandler; import mcp.mobius.waila.api.IWailaDataAccessor; @@ -81,7 +81,7 @@ public abstract class Controller, P extends MuTEProce public static final String ALL_INVENTORIES_NAME = "all"; protected static final int AUTO_OUTPUT_FREQUENCY_TICK = 20; - private static final Map tooltip = new ConcurrentHashMap<>(); + private static final Map tooltip = new ConcurrentHashMap<>(); private final List> upgradeCasings = new ArrayList<>(); private final List> functionalCasings = new ArrayList<>(); protected BuildState buildState = new BuildState(); @@ -131,7 +131,7 @@ public abstract class Controller, P extends MuTEProce /** * Create the tooltip for this multi block controller. */ - protected abstract GT_Multiblock_Tooltip_Builder createTooltip(); + protected abstract MultiblockTooltipBuilder createTooltip(); /** * @return The starting offset for the structure builder @@ -269,8 +269,8 @@ public abstract class Controller, P extends MuTEProce return getMultiTileEntityRegistryID() << 16 + getMultiTileEntityID(); } - protected GT_Multiblock_Tooltip_Builder getTooltip() { - GT_Multiblock_Tooltip_Builder builder = tooltip.get(getToolTipID()); + protected MultiblockTooltipBuilder getTooltip() { + MultiblockTooltipBuilder builder = tooltip.get(getToolTipID()); if (builder == null) { builder = createTooltip(); tooltip.put(getToolTipID(), builder); @@ -423,7 +423,7 @@ public abstract class Controller, P extends MuTEProce if (aPlayer.isSneaking()) { // we won't be allowing horizontal flips, as it can be perfectly emulated by rotating twice and flipping // horizontally allowing an extra round of flip make it hard to draw meaningful flip markers in - // GT_Proxy#drawGrid + // GTProxy#drawGrid toolSetFlip(getFlip().isHorizontallyFlipped() ? Flip.NONE : Flip.HORIZONTAL); } else { toolSetRotation(null); @@ -615,7 +615,7 @@ public abstract class Controller, P extends MuTEProce } @Override - public boolean allowCoverOnSide(ForgeDirection side, GT_ItemStack aCoverID) { + public boolean allowCoverOnSide(ForgeDirection side, GTItemStack aCoverID) { return side != facing; } @@ -992,7 +992,7 @@ public abstract class Controller, P extends MuTEProce if (isSimpleMachine) { boolean isActive = tag.getBoolean("isActive"); currentTip.add( - GT_Waila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); + GTWaila.getMachineProgressString(isActive, tag.getInteger("maxProgress"), tag.getInteger("progress"))); } boolean isActive = tag.getBoolean("isActive"); if (isActive) { @@ -1002,23 +1002,23 @@ public abstract class Controller, P extends MuTEProce 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))); + GTUtility.formatNumbers(actualEnergyUsage), + GTUtility.getAmperageForTier(actualEnergyUsage, (byte) energyTier), + GTUtility.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))); + GTUtility.formatNumbers(-actualEnergyUsage), + GTUtility.getAmperageForTier(-actualEnergyUsage, (byte) energyTier), + GTUtility.getColoredTierNameFromTier((byte) energyTier))); } } } @Override - public GT_Packet_MultiTileEntity getClientDataPacket() { - final GT_Packet_MultiTileEntity packet = super.getClientDataPacket(); + public GTPacketMultiTileEntity getClientDataPacket() { + final GTPacketMultiTileEntity packet = super.getClientDataPacket(); return packet; diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java index 5a16ed4b38..2c3cafc67d 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java @@ -1,7 +1,7 @@ package gregtech.api.multitileentity.multiblock.base; import static com.google.common.math.LongMath.log2; -import static gregtech.api.enums.GT_Values.B; +import static gregtech.api.enums.GTValues.B; import static gregtech.api.enums.Textures.BlockIcons.FLUID_IN_SIGN; import static gregtech.api.enums.Textures.BlockIcons.FLUID_OUT_SIGN; import static gregtech.api.enums.Textures.BlockIcons.ITEM_IN_SIGN; @@ -36,9 +36,9 @@ import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder; import com.gtnewhorizons.modularui.api.screen.UIBuildContext; import com.gtnewhorizons.modularui.common.widget.DrawableWidget; -import gregtech.api.enums.GT_Values.NBT; +import gregtech.api.enums.GTValues.NBT; import gregtech.api.enums.InventoryType; -import gregtech.api.fluid.FluidTankGT; +import gregtech.api.fluid.GTFluidTank; import gregtech.api.gui.GUIHost; import gregtech.api.gui.GUIProvider; import gregtech.api.interfaces.ITexture; @@ -54,7 +54,7 @@ import gregtech.api.multitileentity.enums.MultiTileCasingPurpose; import gregtech.api.multitileentity.interfaces.IMultiBlockController; import gregtech.api.multitileentity.interfaces.IMultiBlockPart; import gregtech.api.render.TextureFactory; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import gregtech.common.covers.CoverInfo; import gregtech.common.gui.PartGUIProvider; import mcp.mobius.waila.api.IWailaConfigHandler; @@ -80,7 +80,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity protected UUID lockedInventory; protected int mLockedInventoryIndex = 0; - protected FluidTankGT configurationTank = new FluidTankGT(); + protected GTFluidTank configurationTank = new GTFluidTank(); @Nonnull protected final GUIProvider guiProvider = createGUIProvider(); @@ -436,7 +436,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity if (aPlayer.isSneaking()) { facing = wrenchSide; } - GT_Utility.sendChatToPlayer(aPlayer, "Mode set to `" + getModeName(mode) + "' (" + mode + ")"); + GTUtility.sendChatToPlayer(aPlayer, "Mode set to `" + getModeName(mode) + "' (" + mode + ")"); sendClientData((EntityPlayerMP) aPlayer); return true; } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java b/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java index bc3c857fd6..d48bbd03fd 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java @@ -2,7 +2,7 @@ package gregtech.api.multitileentity.multiblock.casing; import net.minecraft.nbt.NBTTagCompound; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.multitileentity.multiblock.base.MultiBlockPart; public abstract class FunctionalCasing extends MultiBlockPart { @@ -19,7 +19,7 @@ public abstract class FunctionalCasing extends MultiBlockPart { @Override public void readMultiTileNBT(NBTTagCompound nbt) { super.readMultiTileNBT(nbt); - tier = nbt.getInteger(GT_Values.NBT.TIER); + tier = nbt.getInteger(GTValues.NBT.TIER); } @Override diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/casing/UpgradeCasing.java b/src/main/java/gregtech/api/multitileentity/multiblock/casing/UpgradeCasing.java index 566afcd770..ae5b36c1e0 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/casing/UpgradeCasing.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/casing/UpgradeCasing.java @@ -2,7 +2,7 @@ package gregtech.api.multitileentity.multiblock.casing; import net.minecraft.nbt.NBTTagCompound; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.multitileentity.interfaces.IMultiBlockController; import gregtech.api.multitileentity.multiblock.base.MultiBlockPart; @@ -27,7 +27,7 @@ public abstract class UpgradeCasing extends MultiBlockPart { @Override public void readMultiTileNBT(NBTTagCompound aNBT) { super.readMultiTileNBT(aNBT); - tier = aNBT.getInteger(GT_Values.NBT.TIER); + tier = aNBT.getInteger(GTValues.NBT.TIER); } protected abstract void customWork(IMultiBlockController aTarget); diff --git a/src/main/java/gregtech/api/net/GTPacket.java b/src/main/java/gregtech/api/net/GTPacket.java new file mode 100644 index 0000000000..1d2de3303b --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacket.java @@ -0,0 +1,59 @@ +package gregtech.api.net; + +import net.minecraft.network.INetHandler; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import io.netty.buffer.ByteBuf; + +/** + * @deprecated Use {@link GTPacketNew} instead + */ +@Deprecated +public abstract class GTPacket { + + public GTPacket(boolean aIsReference) { + // + } + + /** + * I use constant IDs instead of Dynamic ones, since that is much more fail safe + * + * @return a Packet ID for this Class + */ + public abstract byte getPacketID(); + + /** + * @return encoded byte Stream + * @deprecated Use {@link #encode(ByteBuf)} instead + */ + @Deprecated + public abstract byte[] encode(); + + /** + * Encode the data into given byte buffer without creating an intermediate byte array. Default implementation just + * throw {@link UnsupportedOperationException}. + */ + public void encode(ByteBuf aOut) { + throw new UnsupportedOperationException(); + } + + /** + * @return encoded byte Stream + */ + public abstract GTPacket decode(ByteArrayDataInput aData); + + /** + * Process the packet + * + * @param aWorld null if message is received on server side, the client world if message is received on client side + */ + public abstract void process(IBlockAccess aWorld); + + /** + * This will be called just before {@link #process(IBlockAccess)} to inform the handler about the source and type of + * connection + */ + public void setINetHandler(INetHandler aHandler) {} +} diff --git a/src/main/java/gregtech/api/net/GTPacketBlockEvent.java b/src/main/java/gregtech/api/net/GTPacketBlockEvent.java new file mode 100644 index 0000000000..a2164f4f07 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketBlockEvent.java @@ -0,0 +1,63 @@ +package gregtech.api.net; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import io.netty.buffer.ByteBuf; + +/** + * Used to transfer Block Events in a much better fashion + */ +public class GTPacketBlockEvent extends GTPacketNew { + + private int mX, mZ; + private short mY; + private byte mID, mValue; + + public GTPacketBlockEvent() { + super(true); + } + + public GTPacketBlockEvent(int aX, short aY, int aZ, byte aID, byte aValue) { + super(false); + mX = aX; + mY = aY; + mZ = aZ; + mID = aID; + mValue = aValue; + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(mX); + aOut.writeShort(mY); + aOut.writeInt(mZ); + aOut.writeByte(mID); + aOut.writeByte(mValue); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketBlockEvent( + aData.readInt(), + aData.readShort(), + aData.readInt(), + aData.readByte(), + aData.readByte()); + } + + @Override + public void process(IBlockAccess aWorld) { + if (aWorld != null) { + final TileEntity tTileEntity = aWorld.getTileEntity(mX, mY, mZ); + if (tTileEntity != null) tTileEntity.receiveClientEvent(mID, mValue); + } + } + + @Override + public byte getPacketID() { + return GTPacketTypes.BLOCK_EVENT.id; + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketClientPreference.java b/src/main/java/gregtech/api/net/GTPacketClientPreference.java new file mode 100644 index 0000000000..ea5d9ec476 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketClientPreference.java @@ -0,0 +1,58 @@ +package gregtech.api.net; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.GTMod; +import gregtech.api.util.GTClientPreference; +import io.netty.buffer.ByteBuf; + +public class GTPacketClientPreference extends GTPacketNew { + + private GTClientPreference mPreference; + private EntityPlayerMP mPlayer; + + public GTPacketClientPreference() { + super(true); + } + + public GTPacketClientPreference(GTClientPreference mPreference) { + super(false); + this.mPreference = mPreference; + } + + @Override + public byte getPacketID() { + return GTPacketTypes.CLIENT_PREFERENCE.id; + } + + @Override + public void setINetHandler(INetHandler aHandler) { + if (aHandler instanceof NetHandlerPlayServer) { + mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity; + } + } + + @Override + public void process(IBlockAccess aWorld) { + if (mPlayer != null) GTMod.gregtechproxy.setClientPreference(mPlayer.getUniqueID(), mPreference); + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeBoolean(mPreference.isSingleBlockInitialFilterEnabled()); + aOut.writeBoolean(mPreference.isSingleBlockInitialMultiStackEnabled()); + aOut.writeBoolean(mPreference.isInputBusInitialFilterEnabled()); + aOut.writeBoolean(mPreference.isWailaAverageNSEnabled()); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketClientPreference( + new GTClientPreference(aData.readBoolean(), aData.readBoolean(), aData.readBoolean(), aData.readBoolean())); + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketMultiTileEntity.java b/src/main/java/gregtech/api/net/GTPacketMultiTileEntity.java new file mode 100644 index 0000000000..b151f8eb5f --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketMultiTileEntity.java @@ -0,0 +1,254 @@ +package gregtech.api.net; + +import static gregtech.api.enums.GTValues.B; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.net.data.CasingData; +import gregtech.api.net.data.CommonData; +import gregtech.api.net.data.CoordinateData; +import gregtech.api.net.data.MultiTileEntityData; +import gregtech.api.net.data.MultiTileEntityProcess; +import gregtech.api.net.data.PacketData; +import io.netty.buffer.ByteBuf; + +public class GTPacketMultiTileEntity extends GTPacketNew { + + private final Set> data = new HashSet<>(); + public static final int COVERS = B[0], REDSTONE = B[1], MODES = B[2], CONTROLLER = B[3], INVENTORY_INDEX = B[4], + INVENTORY_NAME_ID = B[5], BOOLEANS = B[6], SOUND = B[7]; + + public GTPacketMultiTileEntity(boolean reference) { + super(reference); + } + + @Override + public void encode(ByteBuf aOut) { + Set> set = data.stream() + .sorted() + .collect( + HashSet>::new, + HashSet>::add, + HashSet>::addAll); + clearData(); + data.addAll(set); + int features = 0; + for (PacketData data : data) { + features |= 1 << data.getId(); + } + + aOut.writeInt(features); + + for (PacketData data : data) { + data.encode(aOut); + } + /* + * TODO Move to new system + * if ((features & COVERS) == COVERS) { + * aOut.writeInt(mC0); + * aOut.writeInt(mC1); + * aOut.writeInt(mC2); + * aOut.writeInt(mC3); + * aOut.writeInt(mC4); + * aOut.writeInt(mC5); + * } + * if ((features & MODES) == MODES) { + * aOut.writeInt(mode); + * aOut.writeInt(allowedModes); + * } + * if ((features & CONTROLLER) == CONTROLLER) { + * aOut.writeInt(mTargetPos.posX); + * aOut.writeShort(mTargetPos.posY); + * aOut.writeInt(mTargetPos.posZ); + * } + * if ((features & INVENTORY_INDEX) == INVENTORY_INDEX) { + * aOut.writeInt(mLockedInventoryIndex); + * } + * if ((features & INVENTORY_NAME_ID) == INVENTORY_NAME_ID) { + * if (mInventoryName != null && mInventoryName.length() > 0) { + * byte[] bytes = mInventoryName.getBytes(); + * aOut.writeInt(bytes.length); + * aOut.writeBytes(bytes); + * } else { + * aOut.writeInt(0); + * } + * if (inventoryID != null && inventoryID.length() > 0) { + * byte[] bytes = inventoryID.getBytes(); + * aOut.writeInt(bytes.length); + * aOut.writeBytes(bytes); + * } else { + * aOut.writeInt(0); + * } + * } + * if ((features & BOOLEANS) == BOOLEANS) { + * aOut.writeInt(booleans); + * } + * if ((features & SOUND) == SOUND) { + * aOut.writeByte(soundEvent); + * aOut.writeInt(soundEventValue); + * } + */ + } + + @Override + public GTPacketNew decode(ByteArrayDataInput in) { + Objects.requireNonNull(in); + final int packetFeatures = in.readInt(); + + final GTPacketMultiTileEntity packet = new GTPacketMultiTileEntity(false); + + if (containsBit(packetFeatures, CoordinateData.COORDINATE_DATA_ID)) { + packet.addData(new CoordinateData()); + } + if (containsBit(packetFeatures, MultiTileEntityData.MULTI_TILE_ENTITY_DATA_ID)) { + packet.addData(new MultiTileEntityData()); + } + if (containsBit(packetFeatures, CommonData.COMMON_DATA_ID)) { + packet.addData(new CommonData()); + } + if (containsBit(packetFeatures, CasingData.CASING_DATA_ID)) { + packet.addData(new CasingData()); + } + + Set> set = packet.data.stream() + .sorted() + .collect( + HashSet>::new, + HashSet>::add, + HashSet>::addAll); + packet.clearData(); + packet.data.addAll(set); + for (PacketData data : packet.data) { + data.decode(in); + } + /* + * if ((packetFeatures & COVERS) == COVERS) { + * packet.setCoverData( + * in.readInt(), + * in.readInt(), + * in.readInt(), + * in.readInt(), + * in.readInt(), + * in.readInt()); + * } + * if ((packetFeatures & INVENTORY_INDEX) == INVENTORY_INDEX) { + * packet.setInventoryIndex(aData.readInt()); + * } + * if ((packetFeatures & INVENTORY_NAME_ID) == INVENTORY_NAME_ID) { + * int nameLength = aData.readInt(); + * String inventoryName; + * if (nameLength > 0) { + * byte[] bytes = new byte[nameLength]; + * for (int i = 0; i < nameLength; i++) { + * bytes[i] = aData.readByte(); + * } + * inventoryName = new String(bytes); + * } else { + * inventoryName = null; + * } + * int idLength = aData.readInt(); + * String inventoryID; + * if (idLength > 0) { + * byte[] bytes = new byte[idLength]; + * for (int i = 0; i < idLength; i++) { + * bytes[i] = aData.readByte(); + * } + * inventoryID = new String(bytes); + * } else { + * inventoryID = null; + * } + * packet.setInventoryName(inventoryName, inventoryID); + * } + * if ((packetFeatures & BOOLEANS) == BOOLEANS) { + * packet.setBooleans(aData.readInt()); + * } + * if ((packetFeatures & SOUND) == SOUND) { + * packet.setSoundEvent(aData.readByte(), aData.readInt()); + * } + */ + return packet; + } + + @Override + public void process(IBlockAccess aWorld) { + if (aWorld == null) return; + MultiTileEntityProcess process = new MultiTileEntityProcess(aWorld); + for (PacketData data : data) { + data.process(process); + } + process.process(); + /* + * final TileEntity tTileEntity = aWorld.getTileEntity(mX, mY, mZ); + * try { + * final Block tBlock = aWorld.getBlock(mX, mY, mZ); + * if (tBlock instanceof MultiTileEntityBlock mteBlock) { + * final IMultiTileEntity mte = mteBlock.receiveMultiTileEntityData(aWorld, mX, mY, mZ, mRID, mID); + * if (mte == null) return; + * mte.receiveClientData(GregTechTileClientEvents.CHANGE_COMMON_DATA, mCommonData); + * mte.receiveClientData(GregTechTileClientEvents.CHANGE_COLOR, mColor); + * if ((features & COVERS) == COVERS) { + * mteBlock.receiveCoverData(mte, mC0, mC1, mC2, mC3, mC4, mC5); + * } + * if ((features & REDSTONE) == REDSTONE) { + * mte.receiveClientData(GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT, mRedstone); + * } + * if ((features & MODES) == MODES && mte instanceof IMultiTileEntity.IMTE_HasModes mteModes) { + * mteModes.setMode(mode); + * mteModes.setAllowedModes(allowedModes); + * } + * if ((features & INVENTORY_NAME_ID) == INVENTORY_NAME_ID && mte instanceof Inventory invUpg) { + * invUpg.setInventoryName(mInventoryName); + * invUpg.setInventoryId(inventoryID); + * } + * if ((features & CONTROLLER) == CONTROLLER && mte instanceof IMultiBlockPart) { + * final IMultiBlockPart mtePart = (IMultiBlockPart) mte; + * mtePart.setTargetPos(mTargetPos); + * } + * if ((features & INVENTORY_INDEX) == INVENTORY_INDEX && mte instanceof IMultiBlockPart) { + * final IMultiBlockPart mtePart = (IMultiBlockPart) mte; + * mtePart.setLockedInventoryIndex(mLockedInventoryIndex); + * } + * if ((features & BOOLEANS) == BOOLEANS && mte instanceof IMultiTileMachine) { + * final IMultiTileMachine machine = (IMultiTileMachine) mte; + * machine.setBooleans(booleans); + * } + * if ((features & SOUND) == SOUND && mte instanceof IMultiTileMachine) { + * final IMultiTileMachine machine = (IMultiTileMachine) mte; + * machine.setSound(soundEvent, soundEventValue); + * } + * } + * } catch (Exception e) { + * e.printStackTrace(); + * GTMod.GT_FML_LOGGER.error( + * "Exception setting tile entity data for tile entity {} at ({}, {}, {})", + * tTileEntity, + * mX, + * mY, + * mZ); + * } + */ + } + + @Override + public byte getPacketID() { + return GTPacketTypes.MULTI_TILE_ENTITY.id; + } + + public void clearData() { + data.clear(); + } + + public void addData(PacketData data) { + this.data.add(data); + } + + private static boolean containsBit(int toCheck, int bit) { + return (toCheck & (1 << bit)) > 0; + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketMusicSystemData.java b/src/main/java/gregtech/api/net/GTPacketMusicSystemData.java new file mode 100644 index 0000000000..c650188594 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketMusicSystemData.java @@ -0,0 +1,58 @@ +package gregtech.api.net; + +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.util.GTMusicSystem; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public class GTPacketMusicSystemData extends GTPacketNew { + + ByteBuf storedData; + + public GTPacketMusicSystemData() { + super(true); + } + + public GTPacketMusicSystemData(ByteBuf data) { + super(false); + this.storedData = data; + } + + @Override + public byte getPacketID() { + return GTPacketTypes.MUSIC_SYSTEM_DATA.id; + } + + @Override + public void encode(ByteBuf aOut) { + if (storedData == null) { + return; + } + storedData.markReaderIndex(); + final int len = storedData.readableBytes(); + aOut.writeInt(len); + aOut.writeBytes(storedData); + storedData.resetReaderIndex(); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + final int len = aData.readInt(); + final byte[] fullData = new byte[len]; + aData.readFully(fullData); + return new GTPacketMusicSystemData(Unpooled.wrappedBuffer(fullData)); + } + + @Override + public void process(IBlockAccess aWorld) { + if (aWorld == null || storedData == null) { + return; + } + storedData.markReaderIndex(); + GTMusicSystem.ClientSystem.loadUpdatedSources(storedData); + storedData.resetReaderIndex(); + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketNew.java b/src/main/java/gregtech/api/net/GTPacketNew.java new file mode 100644 index 0000000000..d3fee800c6 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketNew.java @@ -0,0 +1,30 @@ +package gregtech.api.net; + +import com.google.common.io.ByteArrayDataInput; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +@SuppressWarnings("deprecation") +public abstract class GTPacketNew extends GTPacket { + + public GTPacketNew(boolean aIsReference) { + super(aIsReference); + } + + @Override + @Deprecated + public final byte[] encode() { + final ByteBuf tOut = Unpooled.buffer(); + encode(tOut); + final byte[] bytes = new byte[tOut.readableBytes()]; + tOut.readBytes(bytes); + return bytes; + } + + @Override + public abstract void encode(ByteBuf aOut); + + @Override + public abstract GTPacketNew decode(ByteArrayDataInput aData); +} diff --git a/src/main/java/gregtech/api/net/GTPacketPollution.java b/src/main/java/gregtech/api/net/GTPacketPollution.java new file mode 100644 index 0000000000..2f4805aad8 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketPollution.java @@ -0,0 +1,47 @@ +package gregtech.api.net; + +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.common.GTClient; +import io.netty.buffer.ByteBuf; + +public class GTPacketPollution extends GTPacketNew { + + private ChunkCoordIntPair chunk; + private int pollution; + + public GTPacketPollution() { + super(true); + } + + public GTPacketPollution(ChunkCoordIntPair chunk, int pollution) { + super(false); + this.chunk = chunk; + this.pollution = pollution; + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(chunk.chunkXPos) + .writeInt(chunk.chunkZPos) + .writeInt(pollution); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketPollution(new ChunkCoordIntPair(aData.readInt(), aData.readInt()), aData.readInt()); + } + + @Override + public void process(IBlockAccess aWorld) { + GTClient.recieveChunkPollutionPacket(chunk, pollution); + } + + @Override + public byte getPacketID() { + return GTPacketTypes.POLLUTION.id; + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketRequestCoverData.java b/src/main/java/gregtech/api/net/GTPacketRequestCoverData.java new file mode 100644 index 0000000000..4679643624 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketRequestCoverData.java @@ -0,0 +1,113 @@ +package gregtech.api.net; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.util.ForgeDirection; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.metatileentity.CoverableTileEntity; +import gregtech.common.covers.CoverInfo; +import io.netty.buffer.ByteBuf; + +/** + * Client -> Server : ask for cover data + */ +public class GTPacketRequestCoverData extends GTPacketNew { + + protected int mX; + protected short mY; + protected int mZ; + + protected ForgeDirection side; + protected int coverID; + + protected EntityPlayerMP mPlayer; + + public GTPacketRequestCoverData() { + super(true); + } + + public GTPacketRequestCoverData(CoverInfo info, ICoverable tile) { + super(false); + this.mX = tile.getXCoord(); + this.mY = tile.getYCoord(); + this.mZ = tile.getZCoord(); + + this.side = info.getSide(); + this.coverID = info.getCoverID(); + } + + public GTPacketRequestCoverData(int mX, short mY, int mZ, ForgeDirection coverSide, int coverID) { + super(false); + this.mX = mX; + this.mY = mY; + this.mZ = mZ; + + this.side = coverSide; + this.coverID = coverID; + } + + public GTPacketRequestCoverData(ForgeDirection coverSide, int coverID, ICoverable tile) { + super(false); + this.mX = tile.getXCoord(); + this.mY = tile.getYCoord(); + this.mZ = tile.getZCoord(); + + this.side = coverSide; + this.coverID = coverID; + } + + @Override + public byte getPacketID() { + return GTPacketTypes.REQUEST_COVER_DATA.id; + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(mX); + aOut.writeShort(mY); + aOut.writeInt(mZ); + + aOut.writeByte(side.ordinal()); + aOut.writeInt(coverID); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketRequestCoverData( + aData.readInt(), + aData.readShort(), + aData.readInt(), + ForgeDirection.getOrientation(aData.readByte()), + aData.readInt()); + } + + @Override + public void setINetHandler(INetHandler aHandler) { + if (aHandler instanceof NetHandlerPlayServer) { + mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity; + } + } + + @Override + public void process(IBlockAccess aWorld) { + // impossible, but who knows + if (mPlayer == null) return; + final World world = DimensionManager.getWorld(mPlayer.dimension); + if (world != null) { + final TileEntity tile = world.getTileEntity(mX, mY, mZ); + if (tile instanceof CoverableTileEntity te) { + if (!te.isDead() && te.getCoverIDAtSide(side) == coverID) { + te.issueCoverUpdate(side); + } + } + } + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketSendCoverData.java b/src/main/java/gregtech/api/net/GTPacketSendCoverData.java new file mode 100644 index 0000000000..76adb75d31 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketSendCoverData.java @@ -0,0 +1,107 @@ +package gregtech.api.net; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.GregTechAPI; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.metatileentity.CoverableTileEntity; +import gregtech.api.util.ISerializableObject; +import gregtech.common.covers.CoverInfo; +import io.netty.buffer.ByteBuf; + +/** + * Server -> Client : Update cover data + */ +public class GTPacketSendCoverData extends GTPacketNew { + + protected int mX; + protected short mY; + protected int mZ; + + protected ForgeDirection side; + protected int coverID; + protected ISerializableObject coverData; + + public GTPacketSendCoverData() { + super(true); + } + + public GTPacketSendCoverData(int mX, short mY, int mZ, ForgeDirection coverSide, int coverID, + ISerializableObject coverData) { + super(false); + this.mX = mX; + this.mY = mY; + this.mZ = mZ; + + this.side = coverSide; + this.coverID = coverID; + this.coverData = coverData; + } + + public GTPacketSendCoverData(CoverInfo info, ICoverable tile) { + super(false); + this.mX = tile.getXCoord(); + this.mY = tile.getYCoord(); + this.mZ = tile.getZCoord(); + + this.side = info.getSide(); + this.coverID = info.getCoverID(); + this.coverData = info.getCoverData(); + } + + public GTPacketSendCoverData(ForgeDirection coverSide, int coverID, ISerializableObject coverData, + ICoverable tile) { + super(false); + this.mX = tile.getXCoord(); + this.mY = tile.getYCoord(); + this.mZ = tile.getZCoord(); + + this.side = coverSide; + this.coverID = coverID; + this.coverData = coverData; + } + + @Override + public byte getPacketID() { + return GTPacketTypes.SEND_COVER_DATA.id; + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(mX); + aOut.writeShort(mY); + aOut.writeInt(mZ); + + aOut.writeByte(side.ordinal()); + aOut.writeInt(coverID); + coverData.writeToByteBuf(aOut); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + final int coverId; + return new GTPacketSendCoverData( + aData.readInt(), + aData.readShort(), + aData.readInt(), + ForgeDirection.getOrientation(aData.readByte()), + coverId = aData.readInt(), + GregTechAPI.getCoverBehaviorNew(coverId) + .createDataObject() + .readFromPacket(aData, null)); + } + + @Override + public void process(IBlockAccess aWorld) { + if (aWorld != null) { + final TileEntity tile = aWorld.getTileEntity(mX, mY, mZ); + if (tile instanceof CoverableTileEntity coverable && !coverable.isDead()) { + coverable.receiveCoverData(side, coverID, coverData, null); + } + } + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketSendOregenPattern.java b/src/main/java/gregtech/api/net/GTPacketSendOregenPattern.java new file mode 100644 index 0000000000..9db0e9a471 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketSendOregenPattern.java @@ -0,0 +1,56 @@ +package gregtech.api.net; + +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.util.GTLog; +import gregtech.common.GTWorldgenerator; +import gregtech.common.GTWorldgenerator.OregenPattern; +import io.netty.buffer.ByteBuf; + +public class GTPacketSendOregenPattern extends GTPacketNew { + + protected OregenPattern pattern = OregenPattern.AXISSYMMETRICAL; + + public GTPacketSendOregenPattern() { + super(true); + } + + public GTPacketSendOregenPattern(OregenPattern pattern) { + super(false); + this.pattern = pattern; + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(this.pattern.ordinal()); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + int ordinal = aData.readInt(); + // make sure we get valid data: + if (ordinal >= 0 && ordinal < OregenPattern.values().length) { + return new GTPacketSendOregenPattern(OregenPattern.values()[ordinal]); + } + // invalid data, default to AXISSYMMETRICAL: + GTLog.err.println( + String.format( + "Received invalid data! Received %d but value must be between 0 and %d! Default (0) will be used.", + ordinal, + OregenPattern.values().length - 1)); + return new GTPacketSendOregenPattern(); + } + + @Override + public byte getPacketID() { + return GTPacketTypes.SEND_OREGEN_PATTERN.id; + } + + @Override + public void process(IBlockAccess aWorld) { + GTWorldgenerator.oregenPattern = this.pattern; + } + +} diff --git a/src/main/java/gregtech/api/net/GTPacketSetConfigurationCircuit.java b/src/main/java/gregtech/api/net/GTPacketSetConfigurationCircuit.java new file mode 100644 index 0000000000..8984cea509 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketSetConfigurationCircuit.java @@ -0,0 +1,110 @@ +package gregtech.api.net; + +import net.minecraft.item.ItemStack; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.DimensionManager; + +import com.google.common.io.ByteArrayDataInput; + +import cpw.mods.fml.common.network.ByteBufUtils; +import gregtech.api.interfaces.IConfigurationCircuitSupport; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.IHasInventory; +import gregtech.api.metatileentity.BaseTileEntity; +import gregtech.api.util.GTUtility; +import gregtech.api.util.ISerializableObject; +import io.netty.buffer.ByteBuf; + +/** + * Client -> Server: Update machine configuration data + */ +public class GTPacketSetConfigurationCircuit extends GTPacketNew { + + protected int mX; + protected short mY; + protected int mZ; + protected int dimId; + + protected ItemStack circuit; + + public GTPacketSetConfigurationCircuit() { + super(true); + } + + public GTPacketSetConfigurationCircuit(IGregTechTileEntity tile, ItemStack circuit) { + this(tile.getXCoord(), tile.getYCoord(), tile.getZCoord(), circuit); + } + + public GTPacketSetConfigurationCircuit(BaseTileEntity tile, ItemStack circuit) { + this(tile.getXCoord(), tile.getYCoord(), tile.getZCoord(), circuit); + } + + public GTPacketSetConfigurationCircuit(int x, short y, int z, ItemStack circuit) { + super(false); + + this.mX = x; + this.mY = y; + this.mZ = z; + + this.circuit = circuit; + } + + @Override + public byte getPacketID() { + return GTPacketTypes.SET_CONFIGURATION_CIRCUIT.id; + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(mX); + aOut.writeShort(mY); + aOut.writeInt(mZ); + + // no null check needed. ByteBufUtils will handle it + ByteBufUtils.writeItemStack(aOut, this.circuit); + } + + @Override + public void setINetHandler(INetHandler aHandler) { + if (aHandler instanceof NetHandlerPlayServer) { + dimId = ((NetHandlerPlayServer) aHandler).playerEntity.dimension; + } else { + // packet sent to wrong side, so we need to ignore this one + // but there is no way to disrupt packet pipeline + // so we will instead go find world -2, which (hopefully) doesn't exist + // then we will fail silently in process() + dimId = -2; + } + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketSetConfigurationCircuit( + aData.readInt(), + aData.readShort(), + aData.readInt(), + ISerializableObject.readItemStackFromGreggyByteBuf(aData)); + } + + @Override + public void process(IBlockAccess aWorld) { + final World world = DimensionManager.getWorld(dimId); + if (world == null) return; + + final TileEntity tile = world.getTileEntity(mX, mY, mZ); + if (!(tile instanceof BaseTileEntity) || ((BaseTileEntity) tile).isDead()) return; + + final IConfigurationCircuitSupport machine = ((BaseTileEntity) tile).getConfigurationCircuitSupport(); + if (machine == null) return; + if (!machine.allowSelectCircuit()) return; + machine.getConfigurationCircuits() + .stream() + .filter(stack -> GTUtility.areStacksEqual(stack, circuit)) + .findFirst() + .ifPresent(stack -> ((IHasInventory) tile).setInventorySlotContents(machine.getCircuitSlot(), stack)); + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketSound.java b/src/main/java/gregtech/api/net/GTPacketSound.java new file mode 100644 index 0000000000..95f95e641d --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketSound.java @@ -0,0 +1,73 @@ +package gregtech.api.net; + +import java.io.IOException; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtility; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; + +public class GTPacketSound extends GTPacketNew { + + private int mX, mZ; + private short mY; + private String mSoundName; + private float mSoundStrength, mSoundPitch; + + public GTPacketSound() { + super(true); + } + + public GTPacketSound(String aSoundName, float aSoundStrength, float aSoundPitch, int aX, short aY, int aZ) { + super(false); + mX = aX; + mY = aY; + mZ = aZ; + mSoundName = aSoundName; + mSoundStrength = aSoundStrength; + mSoundPitch = aSoundPitch; + } + + @Override + public void encode(ByteBuf aOut) { + try (ByteBufOutputStream byteOutputStream = new ByteBufOutputStream(aOut)) { + byteOutputStream.writeUTF(mSoundName); + byteOutputStream.writeFloat(mSoundStrength); + byteOutputStream.writeFloat(mSoundPitch); + byteOutputStream.writeInt(mX); + byteOutputStream.writeShort(mY); + byteOutputStream.writeInt(mZ); + } catch (IOException e) { + // this really shouldn't happen, but whatever + e.printStackTrace(GTLog.err); + } + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketSound( + aData.readUTF(), + aData.readFloat(), + aData.readFloat(), + aData.readInt(), + aData.readShort(), + aData.readInt()); + } + + @Override + public void process(IBlockAccess aWorld) { + if (mSoundName != null) { + GTUtility.doSoundAtClient(new ResourceLocation(mSoundName), 1, mSoundStrength, mSoundPitch, mX, mY, mZ); + } + } + + @Override + public byte getPacketID() { + return GTPacketTypes.SOUND.id; + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketTileEntity.java b/src/main/java/gregtech/api/net/GTPacketTileEntity.java new file mode 100644 index 0000000000..eecb16d6da --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketTileEntity.java @@ -0,0 +1,157 @@ +package gregtech.api.net; + +import net.minecraft.block.Block; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.GTMod; +import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import io.netty.buffer.ByteBuf; + +public class GTPacketTileEntity extends GTPacketNew { + + private int mX, mZ, mC0, mC1, mC2, mC3, mC4, mC5; + private short mY, mID, mRID; + private byte mTexture, mTexturePage, mUpdate, mRedstone, mColor; + + public GTPacketTileEntity() { + super(true); + } + + // For multi tiles + public GTPacketTileEntity(int aX, short aY, int aZ, short aRID, short aID, int aC0, int aC1, int aC2, int aC3, + int aC4, int aC5, byte aTexture, byte aTexturePage, byte aUpdate, byte aRedstone, byte aColor) { + super(false); + mX = aX; + mY = aY; + mZ = aZ; + mC0 = aC0; + mC1 = aC1; + mC2 = aC2; + mC3 = aC3; + mC4 = aC4; + mC5 = aC5; + mRID = aRID; + mID = aID; + mTexture = aTexture; + mTexturePage = aTexturePage; + mUpdate = aUpdate; + mRedstone = aRedstone; + mColor = aColor; + } + + // For meta tiles + public GTPacketTileEntity(int aX, short aY, int aZ, short aID, int aC0, int aC1, int aC2, int aC3, int aC4, int aC5, + byte aTexture, byte aTexturePage, byte aUpdate, byte aRedstone, byte aColor) { + this( + aX, + aY, + aZ, + (short) 0, + aID, + aC0, + aC1, + aC2, + aC3, + aC4, + aC5, + aTexture, + aTexturePage, + aUpdate, + aRedstone, + aColor); + } + + // For pipes + public GTPacketTileEntity(int aX, short aY, int aZ, short aID, int aC0, int aC1, int aC2, int aC3, int aC4, int aC5, + byte aTexture, byte aUpdate, byte aRedstone, byte aColor) { + this(aX, aY, aZ, (short) 0, aID, aC0, aC1, aC2, aC3, aC4, aC5, aTexture, (byte) 0, aUpdate, aRedstone, aColor); + } + + @Override + public void encode(ByteBuf aOut) { + aOut.writeInt(mX); + aOut.writeShort(mY); + aOut.writeInt(mZ); + + aOut.writeShort(mRID); + aOut.writeShort(mID); + + aOut.writeInt(mC0); + aOut.writeInt(mC1); + aOut.writeInt(mC2); + aOut.writeInt(mC3); + aOut.writeInt(mC4); + aOut.writeInt(mC5); + + aOut.writeByte(mTexture); + aOut.writeByte(mTexturePage); + aOut.writeByte(mUpdate); + aOut.writeByte(mRedstone); + aOut.writeByte(mColor); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketTileEntity( + // Coords + aData.readInt(), + aData.readShort(), + aData.readInt(), + // Registry & ID + aData.readShort(), + aData.readShort(), + // Covers + aData.readInt(), + aData.readInt(), + aData.readInt(), + aData.readInt(), + aData.readInt(), + aData.readInt(), + // Everything else + aData.readByte(), + aData.readByte(), + aData.readByte(), + aData.readByte(), + aData.readByte()); + } + + @Override + public void process(IBlockAccess aWorld) { + if (aWorld == null) return; + final TileEntity tTileEntity = aWorld.getTileEntity(mX, mY, mZ); + try { + final Block tBlock; + if (tTileEntity instanceof BaseMetaTileEntity) ((BaseMetaTileEntity) tTileEntity).receiveMetaTileEntityData( + mID, + mC0, + mC1, + mC2, + mC3, + mC4, + mC5, + mTexture, + mTexturePage, + mUpdate, + mRedstone, + mColor); + else if (tTileEntity instanceof BaseMetaPipeEntity) ((BaseMetaPipeEntity) tTileEntity) + .receiveMetaTileEntityData(mID, mC0, mC1, mC2, mC3, mC4, mC5, mTexture, mUpdate, mRedstone, mColor); + } catch (Exception e) { + GTMod.GT_FML_LOGGER.error( + "Exception setting tile entity data for tile entity {} at ({}, {}, {})", + tTileEntity, + mX, + mY, + mZ); + } + } + + @Override + public byte getPacketID() { + return GTPacketTypes.TILE_ENTITY.id; + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketToolSwitchMode.java b/src/main/java/gregtech/api/net/GTPacketToolSwitchMode.java new file mode 100644 index 0000000000..57cabcf2bf --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketToolSwitchMode.java @@ -0,0 +1,52 @@ +package gregtech.api.net; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import gregtech.api.items.MetaGeneratedTool; +import io.netty.buffer.ByteBuf; + +public class GTPacketToolSwitchMode extends GTPacketNew { + + private EntityPlayerMP player; + + public GTPacketToolSwitchMode() { + super(true); + } + + @Override + public byte getPacketID() { + return GTPacketTypes.TOOL_SWITCH_MODE.id; + } + + @Override + public void encode(ByteBuf aOut) { + + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketToolSwitchMode(); + } + + @Override + public void setINetHandler(INetHandler aHandler) { + player = ((NetHandlerPlayServer) aHandler).playerEntity; + } + + @Override + public void process(IBlockAccess aWorld) { + ItemStack currentItem = player.inventory.getCurrentItem(); + if (currentItem == null || (!(currentItem.getItem() instanceof MetaGeneratedTool item))) return; + byte maxMode = item.getToolMaxMode(currentItem); + if (maxMode <= 1) return; + byte newMode = (byte) ((MetaGeneratedTool.getToolMode(currentItem) + 1) % maxMode); + MetaGeneratedTool.setToolMode(currentItem, newMode); + player.sendSlotContents(player.inventoryContainer, player.inventory.currentItem, currentItem); + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketTypes.java b/src/main/java/gregtech/api/net/GTPacketTypes.java new file mode 100644 index 0000000000..d635706e68 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketTypes.java @@ -0,0 +1,64 @@ +package gregtech.api.net; + +import java.util.Arrays; + +import gregtech.common.blocks.PacketOres; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +/** + * Centralized place to keep all the GT packet ID constants + */ +public enum GTPacketTypes { + + TILE_ENTITY(0, new GTPacketTileEntity()), + SOUND(1, new GTPacketSound()), + BLOCK_EVENT(2, new GTPacketBlockEvent()), + ORES(3, new PacketOres()), + POLLUTION(4, new GTPacketPollution()), + CLIENT_PREFERENCE(9, new GTPacketClientPreference()), + SET_CONFIGURATION_CIRCUIT(12, new GTPacketSetConfigurationCircuit()), + UPDATE_ITEM(13, new GTPacketUpdateItem()), + SEND_COVER_DATA(16, new GTPacketSendCoverData()), + REQUEST_COVER_DATA(17, new GTPacketRequestCoverData()), + MULTI_TILE_ENTITY(18, new GTPacketMultiTileEntity(true)), + SEND_OREGEN_PATTERN(19, new GTPacketSendOregenPattern()), + TOOL_SWITCH_MODE(20, new GTPacketToolSwitchMode()), + MUSIC_SYSTEM_DATA(21, new GTPacketMusicSystemData()), + // merge conflict prevention comment, keep a trailing comma above + ; + + static { + // Validate no duplicate IDs + final GTPacketTypes[] types = values(); + final Int2ObjectOpenHashMap foundIds = new Int2ObjectOpenHashMap<>(types.length); + for (GTPacketTypes type : types) { + final GTPacketNew previous = foundIds.get(type.id); + if (previous != null) { + throw new IllegalStateException( + "Duplicate packet IDs defined: " + type.id + + " for " + + type.getClass() + + " and " + + previous.getClass()); + } + foundIds.put(type.id, type.referencePacket); + } + } + + public final byte id; + public final GTPacketNew referencePacket; + + GTPacketTypes(int id, GTPacketNew referencePacket) { + if (((int) (byte) id) != id) { + throw new IllegalArgumentException("Value outside of byte normal range: " + id); + } + this.id = (byte) id; + this.referencePacket = referencePacket; + } + + public static GTPacketNew[] referencePackets() { + return Arrays.stream(values()) + .map(p -> p.referencePacket) + .toArray(GTPacketNew[]::new); + } +} diff --git a/src/main/java/gregtech/api/net/GTPacketUpdateItem.java b/src/main/java/gregtech/api/net/GTPacketUpdateItem.java new file mode 100644 index 0000000000..54846cdcc9 --- /dev/null +++ b/src/main/java/gregtech/api/net/GTPacketUpdateItem.java @@ -0,0 +1,64 @@ +package gregtech.api.net; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.world.IBlockAccess; + +import com.google.common.io.ByteArrayDataInput; + +import cpw.mods.fml.common.network.ByteBufUtils; +import gregtech.api.interfaces.INetworkUpdatableItem; +import gregtech.api.util.ISerializableObject; +import io.netty.buffer.ByteBuf; + +/** + * Client -> Server: send arbitrary data to server and update the currently held item. + */ +public class GTPacketUpdateItem extends GTPacketNew { + + private NBTTagCompound tag; + private EntityPlayerMP mPlayer; + + public GTPacketUpdateItem() { + super(true); + } + + public GTPacketUpdateItem(NBTTagCompound tag) { + super(false); + this.tag = tag; + } + + @Override + public byte getPacketID() { + return GTPacketTypes.UPDATE_ITEM.id; + } + + @Override + public void setINetHandler(INetHandler aHandler) { + if (aHandler instanceof NetHandlerPlayServer) { + mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity; + } + } + + @Override + public void encode(ByteBuf aOut) { + ByteBufUtils.writeTag(aOut, tag); + } + + @Override + public GTPacketNew decode(ByteArrayDataInput aData) { + return new GTPacketUpdateItem(ISerializableObject.readCompoundTagFromGreggyByteBuf(aData)); + } + + @Override + public void process(IBlockAccess aWorld) { + if (mPlayer == null) return; + ItemStack stack = mPlayer.inventory.getCurrentItem(); + if (stack != null && stack.getItem() instanceof INetworkUpdatableItem) { + ((INetworkUpdatableItem) stack.getItem()).receive(stack, mPlayer, tag); + } + } +} diff --git a/src/main/java/gregtech/api/net/GT_Packet.java b/src/main/java/gregtech/api/net/GT_Packet.java deleted file mode 100644 index d06ea7d0d3..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet.java +++ /dev/null @@ -1,59 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.network.INetHandler; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import io.netty.buffer.ByteBuf; - -/** - * @deprecated Use {@link GT_Packet_New} instead - */ -@Deprecated -public abstract class GT_Packet { - - public GT_Packet(boolean aIsReference) { - // - } - - /** - * I use constant IDs instead of Dynamic ones, since that is much more fail safe - * - * @return a Packet ID for this Class - */ - public abstract byte getPacketID(); - - /** - * @return encoded byte Stream - * @deprecated Use {@link #encode(ByteBuf)} instead - */ - @Deprecated - public abstract byte[] encode(); - - /** - * Encode the data into given byte buffer without creating an intermediate byte array. Default implementation just - * throw {@link UnsupportedOperationException}. - */ - public void encode(ByteBuf aOut) { - throw new UnsupportedOperationException(); - } - - /** - * @return encoded byte Stream - */ - public abstract GT_Packet decode(ByteArrayDataInput aData); - - /** - * Process the packet - * - * @param aWorld null if message is received on server side, the client world if message is received on client side - */ - public abstract void process(IBlockAccess aWorld); - - /** - * This will be called just before {@link #process(IBlockAccess)} to inform the handler about the source and type of - * connection - */ - public void setINetHandler(INetHandler aHandler) {} -} diff --git a/src/main/java/gregtech/api/net/GT_PacketTypes.java b/src/main/java/gregtech/api/net/GT_PacketTypes.java deleted file mode 100644 index 5907b2176b..0000000000 --- a/src/main/java/gregtech/api/net/GT_PacketTypes.java +++ /dev/null @@ -1,64 +0,0 @@ -package gregtech.api.net; - -import java.util.Arrays; - -import gregtech.common.blocks.GT_Packet_Ores; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; - -/** - * Centralized place to keep all the GT packet ID constants - */ -public enum GT_PacketTypes { - - TILE_ENTITY(0, new GT_Packet_TileEntity()), - SOUND(1, new GT_Packet_Sound()), - BLOCK_EVENT(2, new GT_Packet_Block_Event()), - ORES(3, new GT_Packet_Ores()), - POLLUTION(4, new GT_Packet_Pollution()), - CLIENT_PREFERENCE(9, new GT_Packet_ClientPreference()), - SET_CONFIGURATION_CIRCUIT(12, new GT_Packet_SetConfigurationCircuit()), - UPDATE_ITEM(13, new GT_Packet_UpdateItem()), - SEND_COVER_DATA(16, new GT_Packet_SendCoverData()), - REQUEST_COVER_DATA(17, new GT_Packet_RequestCoverData()), - MULTI_TILE_ENTITY(18, new GT_Packet_MultiTileEntity(true)), - SEND_OREGEN_PATTERN(19, new GT_Packet_SendOregenPattern()), - TOOL_SWITCH_MODE(20, new GT_Packet_ToolSwitchMode()), - MUSIC_SYSTEM_DATA(21, new GT_Packet_MusicSystemData()), - // merge conflict prevention comment, keep a trailing comma above - ; - - static { - // Validate no duplicate IDs - final GT_PacketTypes[] types = values(); - final Int2ObjectOpenHashMap foundIds = new Int2ObjectOpenHashMap<>(types.length); - for (GT_PacketTypes type : types) { - final GT_Packet_New previous = foundIds.get(type.id); - if (previous != null) { - throw new IllegalStateException( - "Duplicate packet IDs defined: " + type.id - + " for " - + type.getClass() - + " and " - + previous.getClass()); - } - foundIds.put(type.id, type.referencePacket); - } - } - - public final byte id; - public final GT_Packet_New referencePacket; - - GT_PacketTypes(int id, GT_Packet_New referencePacket) { - if (((int) (byte) id) != id) { - throw new IllegalArgumentException("Value outside of byte normal range: " + id); - } - this.id = (byte) id; - this.referencePacket = referencePacket; - } - - public static GT_Packet_New[] referencePackets() { - return Arrays.stream(values()) - .map(p -> p.referencePacket) - .toArray(GT_Packet_New[]::new); - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_Block_Event.java b/src/main/java/gregtech/api/net/GT_Packet_Block_Event.java deleted file mode 100644 index 9adf583698..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_Block_Event.java +++ /dev/null @@ -1,63 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import io.netty.buffer.ByteBuf; - -/** - * Used to transfer Block Events in a much better fashion - */ -public class GT_Packet_Block_Event extends GT_Packet_New { - - private int mX, mZ; - private short mY; - private byte mID, mValue; - - public GT_Packet_Block_Event() { - super(true); - } - - public GT_Packet_Block_Event(int aX, short aY, int aZ, byte aID, byte aValue) { - super(false); - mX = aX; - mY = aY; - mZ = aZ; - mID = aID; - mValue = aValue; - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(mX); - aOut.writeShort(mY); - aOut.writeInt(mZ); - aOut.writeByte(mID); - aOut.writeByte(mValue); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_Block_Event( - aData.readInt(), - aData.readShort(), - aData.readInt(), - aData.readByte(), - aData.readByte()); - } - - @Override - public void process(IBlockAccess aWorld) { - if (aWorld != null) { - final TileEntity tTileEntity = aWorld.getTileEntity(mX, mY, mZ); - if (tTileEntity != null) tTileEntity.receiveClientEvent(mID, mValue); - } - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.BLOCK_EVENT.id; - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_ClientPreference.java b/src/main/java/gregtech/api/net/GT_Packet_ClientPreference.java deleted file mode 100644 index a5fd8a2e08..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_ClientPreference.java +++ /dev/null @@ -1,62 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.GT_Mod; -import gregtech.api.util.GT_ClientPreference; -import io.netty.buffer.ByteBuf; - -public class GT_Packet_ClientPreference extends GT_Packet_New { - - private GT_ClientPreference mPreference; - private EntityPlayerMP mPlayer; - - public GT_Packet_ClientPreference() { - super(true); - } - - public GT_Packet_ClientPreference(GT_ClientPreference mPreference) { - super(false); - this.mPreference = mPreference; - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.CLIENT_PREFERENCE.id; - } - - @Override - public void setINetHandler(INetHandler aHandler) { - if (aHandler instanceof NetHandlerPlayServer) { - mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity; - } - } - - @Override - public void process(IBlockAccess aWorld) { - if (mPlayer != null) GT_Mod.gregtechproxy.setClientPreference(mPlayer.getUniqueID(), mPreference); - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeBoolean(mPreference.isSingleBlockInitialFilterEnabled()); - aOut.writeBoolean(mPreference.isSingleBlockInitialMultiStackEnabled()); - aOut.writeBoolean(mPreference.isInputBusInitialFilterEnabled()); - aOut.writeBoolean(mPreference.isWailaAverageNSEnabled()); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_ClientPreference( - new GT_ClientPreference( - aData.readBoolean(), - aData.readBoolean(), - aData.readBoolean(), - aData.readBoolean())); - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java b/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java deleted file mode 100644 index 33cb4f2dcf..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java +++ /dev/null @@ -1,254 +0,0 @@ -package gregtech.api.net; - -import static gregtech.api.enums.GT_Values.B; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.net.data.CasingData; -import gregtech.api.net.data.CommonData; -import gregtech.api.net.data.CoordinateData; -import gregtech.api.net.data.MultiTileEntityData; -import gregtech.api.net.data.MultiTileEntityProcess; -import gregtech.api.net.data.PacketData; -import io.netty.buffer.ByteBuf; - -public class GT_Packet_MultiTileEntity extends GT_Packet_New { - - private final Set> data = new HashSet<>(); - public static final int COVERS = B[0], REDSTONE = B[1], MODES = B[2], CONTROLLER = B[3], INVENTORY_INDEX = B[4], - INVENTORY_NAME_ID = B[5], BOOLEANS = B[6], SOUND = B[7]; - - public GT_Packet_MultiTileEntity(boolean reference) { - super(reference); - } - - @Override - public void encode(ByteBuf aOut) { - Set> set = data.stream() - .sorted() - .collect( - HashSet>::new, - HashSet>::add, - HashSet>::addAll); - clearData(); - data.addAll(set); - int features = 0; - for (PacketData data : data) { - features |= 1 << data.getId(); - } - - aOut.writeInt(features); - - for (PacketData data : data) { - data.encode(aOut); - } - /* - * TODO Move to new system - * if ((features & COVERS) == COVERS) { - * aOut.writeInt(mC0); - * aOut.writeInt(mC1); - * aOut.writeInt(mC2); - * aOut.writeInt(mC3); - * aOut.writeInt(mC4); - * aOut.writeInt(mC5); - * } - * if ((features & MODES) == MODES) { - * aOut.writeInt(mode); - * aOut.writeInt(allowedModes); - * } - * if ((features & CONTROLLER) == CONTROLLER) { - * aOut.writeInt(mTargetPos.posX); - * aOut.writeShort(mTargetPos.posY); - * aOut.writeInt(mTargetPos.posZ); - * } - * if ((features & INVENTORY_INDEX) == INVENTORY_INDEX) { - * aOut.writeInt(mLockedInventoryIndex); - * } - * if ((features & INVENTORY_NAME_ID) == INVENTORY_NAME_ID) { - * if (mInventoryName != null && mInventoryName.length() > 0) { - * byte[] bytes = mInventoryName.getBytes(); - * aOut.writeInt(bytes.length); - * aOut.writeBytes(bytes); - * } else { - * aOut.writeInt(0); - * } - * if (inventoryID != null && inventoryID.length() > 0) { - * byte[] bytes = inventoryID.getBytes(); - * aOut.writeInt(bytes.length); - * aOut.writeBytes(bytes); - * } else { - * aOut.writeInt(0); - * } - * } - * if ((features & BOOLEANS) == BOOLEANS) { - * aOut.writeInt(booleans); - * } - * if ((features & SOUND) == SOUND) { - * aOut.writeByte(soundEvent); - * aOut.writeInt(soundEventValue); - * } - */ - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput in) { - Objects.requireNonNull(in); - final int packetFeatures = in.readInt(); - - final GT_Packet_MultiTileEntity packet = new GT_Packet_MultiTileEntity(false); - - if (containsBit(packetFeatures, CoordinateData.COORDINATE_DATA_ID)) { - packet.addData(new CoordinateData()); - } - if (containsBit(packetFeatures, MultiTileEntityData.MULTI_TILE_ENTITY_DATA_ID)) { - packet.addData(new MultiTileEntityData()); - } - if (containsBit(packetFeatures, CommonData.COMMON_DATA_ID)) { - packet.addData(new CommonData()); - } - if (containsBit(packetFeatures, CasingData.CASING_DATA_ID)) { - packet.addData(new CasingData()); - } - - Set> set = packet.data.stream() - .sorted() - .collect( - HashSet>::new, - HashSet>::add, - HashSet>::addAll); - packet.clearData(); - packet.data.addAll(set); - for (PacketData data : packet.data) { - data.decode(in); - } - /* - * if ((packetFeatures & COVERS) == COVERS) { - * packet.setCoverData( - * in.readInt(), - * in.readInt(), - * in.readInt(), - * in.readInt(), - * in.readInt(), - * in.readInt()); - * } - * if ((packetFeatures & INVENTORY_INDEX) == INVENTORY_INDEX) { - * packet.setInventoryIndex(aData.readInt()); - * } - * if ((packetFeatures & INVENTORY_NAME_ID) == INVENTORY_NAME_ID) { - * int nameLength = aData.readInt(); - * String inventoryName; - * if (nameLength > 0) { - * byte[] bytes = new byte[nameLength]; - * for (int i = 0; i < nameLength; i++) { - * bytes[i] = aData.readByte(); - * } - * inventoryName = new String(bytes); - * } else { - * inventoryName = null; - * } - * int idLength = aData.readInt(); - * String inventoryID; - * if (idLength > 0) { - * byte[] bytes = new byte[idLength]; - * for (int i = 0; i < idLength; i++) { - * bytes[i] = aData.readByte(); - * } - * inventoryID = new String(bytes); - * } else { - * inventoryID = null; - * } - * packet.setInventoryName(inventoryName, inventoryID); - * } - * if ((packetFeatures & BOOLEANS) == BOOLEANS) { - * packet.setBooleans(aData.readInt()); - * } - * if ((packetFeatures & SOUND) == SOUND) { - * packet.setSoundEvent(aData.readByte(), aData.readInt()); - * } - */ - return packet; - } - - @Override - public void process(IBlockAccess aWorld) { - if (aWorld == null) return; - MultiTileEntityProcess process = new MultiTileEntityProcess(aWorld); - for (PacketData data : data) { - data.process(process); - } - process.process(); - /* - * final TileEntity tTileEntity = aWorld.getTileEntity(mX, mY, mZ); - * try { - * final Block tBlock = aWorld.getBlock(mX, mY, mZ); - * if (tBlock instanceof MultiTileEntityBlock mteBlock) { - * final IMultiTileEntity mte = mteBlock.receiveMultiTileEntityData(aWorld, mX, mY, mZ, mRID, mID); - * if (mte == null) return; - * mte.receiveClientData(GregTechTileClientEvents.CHANGE_COMMON_DATA, mCommonData); - * mte.receiveClientData(GregTechTileClientEvents.CHANGE_COLOR, mColor); - * if ((features & COVERS) == COVERS) { - * mteBlock.receiveCoverData(mte, mC0, mC1, mC2, mC3, mC4, mC5); - * } - * if ((features & REDSTONE) == REDSTONE) { - * mte.receiveClientData(GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT, mRedstone); - * } - * if ((features & MODES) == MODES && mte instanceof IMultiTileEntity.IMTE_HasModes mteModes) { - * mteModes.setMode(mode); - * mteModes.setAllowedModes(allowedModes); - * } - * if ((features & INVENTORY_NAME_ID) == INVENTORY_NAME_ID && mte instanceof Inventory invUpg) { - * invUpg.setInventoryName(mInventoryName); - * invUpg.setInventoryId(inventoryID); - * } - * if ((features & CONTROLLER) == CONTROLLER && mte instanceof IMultiBlockPart) { - * final IMultiBlockPart mtePart = (IMultiBlockPart) mte; - * mtePart.setTargetPos(mTargetPos); - * } - * if ((features & INVENTORY_INDEX) == INVENTORY_INDEX && mte instanceof IMultiBlockPart) { - * final IMultiBlockPart mtePart = (IMultiBlockPart) mte; - * mtePart.setLockedInventoryIndex(mLockedInventoryIndex); - * } - * if ((features & BOOLEANS) == BOOLEANS && mte instanceof IMultiTileMachine) { - * final IMultiTileMachine machine = (IMultiTileMachine) mte; - * machine.setBooleans(booleans); - * } - * if ((features & SOUND) == SOUND && mte instanceof IMultiTileMachine) { - * final IMultiTileMachine machine = (IMultiTileMachine) mte; - * machine.setSound(soundEvent, soundEventValue); - * } - * } - * } catch (Exception e) { - * e.printStackTrace(); - * GT_Mod.GT_FML_LOGGER.error( - * "Exception setting tile entity data for tile entity {} at ({}, {}, {})", - * tTileEntity, - * mX, - * mY, - * mZ); - * } - */ - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.MULTI_TILE_ENTITY.id; - } - - public void clearData() { - data.clear(); - } - - public void addData(PacketData data) { - this.data.add(data); - } - - private static boolean containsBit(int toCheck, int bit) { - return (toCheck & (1 << bit)) > 0; - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_MusicSystemData.java b/src/main/java/gregtech/api/net/GT_Packet_MusicSystemData.java deleted file mode 100644 index 13ebf49205..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_MusicSystemData.java +++ /dev/null @@ -1,58 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.util.GT_MusicSystem; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -public class GT_Packet_MusicSystemData extends GT_Packet_New { - - ByteBuf storedData; - - public GT_Packet_MusicSystemData() { - super(true); - } - - public GT_Packet_MusicSystemData(ByteBuf data) { - super(false); - this.storedData = data; - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.MUSIC_SYSTEM_DATA.id; - } - - @Override - public void encode(ByteBuf aOut) { - if (storedData == null) { - return; - } - storedData.markReaderIndex(); - final int len = storedData.readableBytes(); - aOut.writeInt(len); - aOut.writeBytes(storedData); - storedData.resetReaderIndex(); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - final int len = aData.readInt(); - final byte[] fullData = new byte[len]; - aData.readFully(fullData); - return new GT_Packet_MusicSystemData(Unpooled.wrappedBuffer(fullData)); - } - - @Override - public void process(IBlockAccess aWorld) { - if (aWorld == null || storedData == null) { - return; - } - storedData.markReaderIndex(); - GT_MusicSystem.ClientSystem.loadUpdatedSources(storedData); - storedData.resetReaderIndex(); - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_New.java b/src/main/java/gregtech/api/net/GT_Packet_New.java deleted file mode 100644 index 41eb1740b3..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_New.java +++ /dev/null @@ -1,30 +0,0 @@ -package gregtech.api.net; - -import com.google.common.io.ByteArrayDataInput; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -@SuppressWarnings("deprecation") -public abstract class GT_Packet_New extends GT_Packet { - - public GT_Packet_New(boolean aIsReference) { - super(aIsReference); - } - - @Override - @Deprecated - public final byte[] encode() { - final ByteBuf tOut = Unpooled.buffer(); - encode(tOut); - final byte[] bytes = new byte[tOut.readableBytes()]; - tOut.readBytes(bytes); - return bytes; - } - - @Override - public abstract void encode(ByteBuf aOut); - - @Override - public abstract GT_Packet_New decode(ByteArrayDataInput aData); -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_Pollution.java b/src/main/java/gregtech/api/net/GT_Packet_Pollution.java deleted file mode 100644 index 9b4a367dc4..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_Pollution.java +++ /dev/null @@ -1,47 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.common.GT_Client; -import io.netty.buffer.ByteBuf; - -public class GT_Packet_Pollution extends GT_Packet_New { - - private ChunkCoordIntPair chunk; - private int pollution; - - public GT_Packet_Pollution() { - super(true); - } - - public GT_Packet_Pollution(ChunkCoordIntPair chunk, int pollution) { - super(false); - this.chunk = chunk; - this.pollution = pollution; - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(chunk.chunkXPos) - .writeInt(chunk.chunkZPos) - .writeInt(pollution); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_Pollution(new ChunkCoordIntPair(aData.readInt(), aData.readInt()), aData.readInt()); - } - - @Override - public void process(IBlockAccess aWorld) { - GT_Client.recieveChunkPollutionPacket(chunk, pollution); - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.POLLUTION.id; - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java b/src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java deleted file mode 100644 index bca97b69a5..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java +++ /dev/null @@ -1,113 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.util.ForgeDirection; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.metatileentity.CoverableTileEntity; -import gregtech.common.covers.CoverInfo; -import io.netty.buffer.ByteBuf; - -/** - * Client -> Server : ask for cover data - */ -public class GT_Packet_RequestCoverData extends GT_Packet_New { - - protected int mX; - protected short mY; - protected int mZ; - - protected ForgeDirection side; - protected int coverID; - - protected EntityPlayerMP mPlayer; - - public GT_Packet_RequestCoverData() { - super(true); - } - - public GT_Packet_RequestCoverData(CoverInfo info, ICoverable tile) { - super(false); - this.mX = tile.getXCoord(); - this.mY = tile.getYCoord(); - this.mZ = tile.getZCoord(); - - this.side = info.getSide(); - this.coverID = info.getCoverID(); - } - - public GT_Packet_RequestCoverData(int mX, short mY, int mZ, ForgeDirection coverSide, int coverID) { - super(false); - this.mX = mX; - this.mY = mY; - this.mZ = mZ; - - this.side = coverSide; - this.coverID = coverID; - } - - public GT_Packet_RequestCoverData(ForgeDirection coverSide, int coverID, ICoverable tile) { - super(false); - this.mX = tile.getXCoord(); - this.mY = tile.getYCoord(); - this.mZ = tile.getZCoord(); - - this.side = coverSide; - this.coverID = coverID; - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.REQUEST_COVER_DATA.id; - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(mX); - aOut.writeShort(mY); - aOut.writeInt(mZ); - - aOut.writeByte(side.ordinal()); - aOut.writeInt(coverID); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_RequestCoverData( - aData.readInt(), - aData.readShort(), - aData.readInt(), - ForgeDirection.getOrientation(aData.readByte()), - aData.readInt()); - } - - @Override - public void setINetHandler(INetHandler aHandler) { - if (aHandler instanceof NetHandlerPlayServer) { - mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity; - } - } - - @Override - public void process(IBlockAccess aWorld) { - // impossible, but who knows - if (mPlayer == null) return; - final World world = DimensionManager.getWorld(mPlayer.dimension); - if (world != null) { - final TileEntity tile = world.getTileEntity(mX, mY, mZ); - if (tile instanceof CoverableTileEntity te) { - if (!te.isDead() && te.getCoverIDAtSide(side) == coverID) { - te.issueCoverUpdate(side); - } - } - } - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java b/src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java deleted file mode 100644 index 268aaab803..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java +++ /dev/null @@ -1,107 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; -import net.minecraftforge.common.util.ForgeDirection; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.GregTech_API; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.metatileentity.CoverableTileEntity; -import gregtech.api.util.ISerializableObject; -import gregtech.common.covers.CoverInfo; -import io.netty.buffer.ByteBuf; - -/** - * Server -> Client : Update cover data - */ -public class GT_Packet_SendCoverData extends GT_Packet_New { - - protected int mX; - protected short mY; - protected int mZ; - - protected ForgeDirection side; - protected int coverID; - protected ISerializableObject coverData; - - public GT_Packet_SendCoverData() { - super(true); - } - - public GT_Packet_SendCoverData(int mX, short mY, int mZ, ForgeDirection coverSide, int coverID, - ISerializableObject coverData) { - super(false); - this.mX = mX; - this.mY = mY; - this.mZ = mZ; - - this.side = coverSide; - this.coverID = coverID; - this.coverData = coverData; - } - - public GT_Packet_SendCoverData(CoverInfo info, ICoverable tile) { - super(false); - this.mX = tile.getXCoord(); - this.mY = tile.getYCoord(); - this.mZ = tile.getZCoord(); - - this.side = info.getSide(); - this.coverID = info.getCoverID(); - this.coverData = info.getCoverData(); - } - - public GT_Packet_SendCoverData(ForgeDirection coverSide, int coverID, ISerializableObject coverData, - ICoverable tile) { - super(false); - this.mX = tile.getXCoord(); - this.mY = tile.getYCoord(); - this.mZ = tile.getZCoord(); - - this.side = coverSide; - this.coverID = coverID; - this.coverData = coverData; - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.SEND_COVER_DATA.id; - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(mX); - aOut.writeShort(mY); - aOut.writeInt(mZ); - - aOut.writeByte(side.ordinal()); - aOut.writeInt(coverID); - coverData.writeToByteBuf(aOut); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - final int coverId; - return new GT_Packet_SendCoverData( - aData.readInt(), - aData.readShort(), - aData.readInt(), - ForgeDirection.getOrientation(aData.readByte()), - coverId = aData.readInt(), - GregTech_API.getCoverBehaviorNew(coverId) - .createDataObject() - .readFromPacket(aData, null)); - } - - @Override - public void process(IBlockAccess aWorld) { - if (aWorld != null) { - final TileEntity tile = aWorld.getTileEntity(mX, mY, mZ); - if (tile instanceof CoverableTileEntity coverable && !coverable.isDead()) { - coverable.receiveCoverData(side, coverID, coverData, null); - } - } - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_SendOregenPattern.java b/src/main/java/gregtech/api/net/GT_Packet_SendOregenPattern.java deleted file mode 100644 index 8213ee9c71..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_SendOregenPattern.java +++ /dev/null @@ -1,56 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.util.GT_Log; -import gregtech.common.GT_Worldgenerator; -import gregtech.common.GT_Worldgenerator.OregenPattern; -import io.netty.buffer.ByteBuf; - -public class GT_Packet_SendOregenPattern extends GT_Packet_New { - - protected OregenPattern pattern = OregenPattern.AXISSYMMETRICAL; - - public GT_Packet_SendOregenPattern() { - super(true); - } - - public GT_Packet_SendOregenPattern(OregenPattern pattern) { - super(false); - this.pattern = pattern; - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(this.pattern.ordinal()); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - int ordinal = aData.readInt(); - // make sure we get valid data: - if (ordinal >= 0 && ordinal < OregenPattern.values().length) { - return new GT_Packet_SendOregenPattern(OregenPattern.values()[ordinal]); - } - // invalid data, default to AXISSYMMETRICAL: - GT_Log.err.println( - String.format( - "Received invalid data! Received %d but value must be between 0 and %d! Default (0) will be used.", - ordinal, - OregenPattern.values().length - 1)); - return new GT_Packet_SendOregenPattern(); - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.SEND_OREGEN_PATTERN.id; - } - - @Override - public void process(IBlockAccess aWorld) { - GT_Worldgenerator.oregenPattern = this.pattern; - } - -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_SetConfigurationCircuit.java b/src/main/java/gregtech/api/net/GT_Packet_SetConfigurationCircuit.java deleted file mode 100644 index 2bfdbca9d2..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_SetConfigurationCircuit.java +++ /dev/null @@ -1,110 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.item.ItemStack; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; - -import com.google.common.io.ByteArrayDataInput; - -import cpw.mods.fml.common.network.ByteBufUtils; -import gregtech.api.interfaces.IConfigurationCircuitSupport; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.interfaces.tileentity.IHasInventory; -import gregtech.api.metatileentity.BaseTileEntity; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.ISerializableObject; -import io.netty.buffer.ByteBuf; - -/** - * Client -> Server: Update machine configuration data - */ -public class GT_Packet_SetConfigurationCircuit extends GT_Packet_New { - - protected int mX; - protected short mY; - protected int mZ; - protected int dimId; - - protected ItemStack circuit; - - public GT_Packet_SetConfigurationCircuit() { - super(true); - } - - public GT_Packet_SetConfigurationCircuit(IGregTechTileEntity tile, ItemStack circuit) { - this(tile.getXCoord(), tile.getYCoord(), tile.getZCoord(), circuit); - } - - public GT_Packet_SetConfigurationCircuit(BaseTileEntity tile, ItemStack circuit) { - this(tile.getXCoord(), tile.getYCoord(), tile.getZCoord(), circuit); - } - - public GT_Packet_SetConfigurationCircuit(int x, short y, int z, ItemStack circuit) { - super(false); - - this.mX = x; - this.mY = y; - this.mZ = z; - - this.circuit = circuit; - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.SET_CONFIGURATION_CIRCUIT.id; - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(mX); - aOut.writeShort(mY); - aOut.writeInt(mZ); - - // no null check needed. ByteBufUtils will handle it - ByteBufUtils.writeItemStack(aOut, this.circuit); - } - - @Override - public void setINetHandler(INetHandler aHandler) { - if (aHandler instanceof NetHandlerPlayServer) { - dimId = ((NetHandlerPlayServer) aHandler).playerEntity.dimension; - } else { - // packet sent to wrong side, so we need to ignore this one - // but there is no way to disrupt packet pipeline - // so we will instead go find world -2, which (hopefully) doesn't exist - // then we will fail silently in process() - dimId = -2; - } - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_SetConfigurationCircuit( - aData.readInt(), - aData.readShort(), - aData.readInt(), - ISerializableObject.readItemStackFromGreggyByteBuf(aData)); - } - - @Override - public void process(IBlockAccess aWorld) { - final World world = DimensionManager.getWorld(dimId); - if (world == null) return; - - final TileEntity tile = world.getTileEntity(mX, mY, mZ); - if (!(tile instanceof BaseTileEntity) || ((BaseTileEntity) tile).isDead()) return; - - final IConfigurationCircuitSupport machine = ((BaseTileEntity) tile).getConfigurationCircuitSupport(); - if (machine == null) return; - if (!machine.allowSelectCircuit()) return; - machine.getConfigurationCircuits() - .stream() - .filter(stack -> GT_Utility.areStacksEqual(stack, circuit)) - .findFirst() - .ifPresent(stack -> ((IHasInventory) tile).setInventorySlotContents(machine.getCircuitSlot(), stack)); - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_Sound.java b/src/main/java/gregtech/api/net/GT_Packet_Sound.java deleted file mode 100644 index 93bfdfd3aa..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_Sound.java +++ /dev/null @@ -1,73 +0,0 @@ -package gregtech.api.net; - -import java.io.IOException; - -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_Utility; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufOutputStream; - -public class GT_Packet_Sound extends GT_Packet_New { - - private int mX, mZ; - private short mY; - private String mSoundName; - private float mSoundStrength, mSoundPitch; - - public GT_Packet_Sound() { - super(true); - } - - public GT_Packet_Sound(String aSoundName, float aSoundStrength, float aSoundPitch, int aX, short aY, int aZ) { - super(false); - mX = aX; - mY = aY; - mZ = aZ; - mSoundName = aSoundName; - mSoundStrength = aSoundStrength; - mSoundPitch = aSoundPitch; - } - - @Override - public void encode(ByteBuf aOut) { - try (ByteBufOutputStream byteOutputStream = new ByteBufOutputStream(aOut)) { - byteOutputStream.writeUTF(mSoundName); - byteOutputStream.writeFloat(mSoundStrength); - byteOutputStream.writeFloat(mSoundPitch); - byteOutputStream.writeInt(mX); - byteOutputStream.writeShort(mY); - byteOutputStream.writeInt(mZ); - } catch (IOException e) { - // this really shouldn't happen, but whatever - e.printStackTrace(GT_Log.err); - } - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_Sound( - aData.readUTF(), - aData.readFloat(), - aData.readFloat(), - aData.readInt(), - aData.readShort(), - aData.readInt()); - } - - @Override - public void process(IBlockAccess aWorld) { - if (mSoundName != null) { - GT_Utility.doSoundAtClient(new ResourceLocation(mSoundName), 1, mSoundStrength, mSoundPitch, mX, mY, mZ); - } - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.SOUND.id; - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_TileEntity.java b/src/main/java/gregtech/api/net/GT_Packet_TileEntity.java deleted file mode 100644 index b07277dc00..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_TileEntity.java +++ /dev/null @@ -1,157 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.block.Block; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.GT_Mod; -import gregtech.api.metatileentity.BaseMetaPipeEntity; -import gregtech.api.metatileentity.BaseMetaTileEntity; -import io.netty.buffer.ByteBuf; - -public class GT_Packet_TileEntity extends GT_Packet_New { - - private int mX, mZ, mC0, mC1, mC2, mC3, mC4, mC5; - private short mY, mID, mRID; - private byte mTexture, mTexturePage, mUpdate, mRedstone, mColor; - - public GT_Packet_TileEntity() { - super(true); - } - - // For multi tiles - public GT_Packet_TileEntity(int aX, short aY, int aZ, short aRID, short aID, int aC0, int aC1, int aC2, int aC3, - int aC4, int aC5, byte aTexture, byte aTexturePage, byte aUpdate, byte aRedstone, byte aColor) { - super(false); - mX = aX; - mY = aY; - mZ = aZ; - mC0 = aC0; - mC1 = aC1; - mC2 = aC2; - mC3 = aC3; - mC4 = aC4; - mC5 = aC5; - mRID = aRID; - mID = aID; - mTexture = aTexture; - mTexturePage = aTexturePage; - mUpdate = aUpdate; - mRedstone = aRedstone; - mColor = aColor; - } - - // For meta tiles - public GT_Packet_TileEntity(int aX, short aY, int aZ, short aID, int aC0, int aC1, int aC2, int aC3, int aC4, - int aC5, byte aTexture, byte aTexturePage, byte aUpdate, byte aRedstone, byte aColor) { - this( - aX, - aY, - aZ, - (short) 0, - aID, - aC0, - aC1, - aC2, - aC3, - aC4, - aC5, - aTexture, - aTexturePage, - aUpdate, - aRedstone, - aColor); - } - - // For pipes - public GT_Packet_TileEntity(int aX, short aY, int aZ, short aID, int aC0, int aC1, int aC2, int aC3, int aC4, - int aC5, byte aTexture, byte aUpdate, byte aRedstone, byte aColor) { - this(aX, aY, aZ, (short) 0, aID, aC0, aC1, aC2, aC3, aC4, aC5, aTexture, (byte) 0, aUpdate, aRedstone, aColor); - } - - @Override - public void encode(ByteBuf aOut) { - aOut.writeInt(mX); - aOut.writeShort(mY); - aOut.writeInt(mZ); - - aOut.writeShort(mRID); - aOut.writeShort(mID); - - aOut.writeInt(mC0); - aOut.writeInt(mC1); - aOut.writeInt(mC2); - aOut.writeInt(mC3); - aOut.writeInt(mC4); - aOut.writeInt(mC5); - - aOut.writeByte(mTexture); - aOut.writeByte(mTexturePage); - aOut.writeByte(mUpdate); - aOut.writeByte(mRedstone); - aOut.writeByte(mColor); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_TileEntity( - // Coords - aData.readInt(), - aData.readShort(), - aData.readInt(), - // Registry & ID - aData.readShort(), - aData.readShort(), - // Covers - aData.readInt(), - aData.readInt(), - aData.readInt(), - aData.readInt(), - aData.readInt(), - aData.readInt(), - // Everything else - aData.readByte(), - aData.readByte(), - aData.readByte(), - aData.readByte(), - aData.readByte()); - } - - @Override - public void process(IBlockAccess aWorld) { - if (aWorld == null) return; - final TileEntity tTileEntity = aWorld.getTileEntity(mX, mY, mZ); - try { - final Block tBlock; - if (tTileEntity instanceof BaseMetaTileEntity) ((BaseMetaTileEntity) tTileEntity).receiveMetaTileEntityData( - mID, - mC0, - mC1, - mC2, - mC3, - mC4, - mC5, - mTexture, - mTexturePage, - mUpdate, - mRedstone, - mColor); - else if (tTileEntity instanceof BaseMetaPipeEntity) ((BaseMetaPipeEntity) tTileEntity) - .receiveMetaTileEntityData(mID, mC0, mC1, mC2, mC3, mC4, mC5, mTexture, mUpdate, mRedstone, mColor); - } catch (Exception e) { - GT_Mod.GT_FML_LOGGER.error( - "Exception setting tile entity data for tile entity {} at ({}, {}, {})", - tTileEntity, - mX, - mY, - mZ); - } - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.TILE_ENTITY.id; - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_ToolSwitchMode.java b/src/main/java/gregtech/api/net/GT_Packet_ToolSwitchMode.java deleted file mode 100644 index c7984d7434..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_ToolSwitchMode.java +++ /dev/null @@ -1,52 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import gregtech.api.items.GT_MetaGenerated_Tool; -import io.netty.buffer.ByteBuf; - -public class GT_Packet_ToolSwitchMode extends GT_Packet_New { - - private EntityPlayerMP player; - - public GT_Packet_ToolSwitchMode() { - super(true); - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.TOOL_SWITCH_MODE.id; - } - - @Override - public void encode(ByteBuf aOut) { - - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_ToolSwitchMode(); - } - - @Override - public void setINetHandler(INetHandler aHandler) { - player = ((NetHandlerPlayServer) aHandler).playerEntity; - } - - @Override - public void process(IBlockAccess aWorld) { - ItemStack currentItem = player.inventory.getCurrentItem(); - if (currentItem == null || (!(currentItem.getItem() instanceof GT_MetaGenerated_Tool item))) return; - byte maxMode = item.getToolMaxMode(currentItem); - if (maxMode <= 1) return; - byte newMode = (byte) ((GT_MetaGenerated_Tool.getToolMode(currentItem) + 1) % maxMode); - GT_MetaGenerated_Tool.setToolMode(currentItem, newMode); - player.sendSlotContents(player.inventoryContainer, player.inventory.currentItem, currentItem); - } -} diff --git a/src/main/java/gregtech/api/net/GT_Packet_UpdateItem.java b/src/main/java/gregtech/api/net/GT_Packet_UpdateItem.java deleted file mode 100644 index 1b8a453234..0000000000 --- a/src/main/java/gregtech/api/net/GT_Packet_UpdateItem.java +++ /dev/null @@ -1,64 +0,0 @@ -package gregtech.api.net; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.world.IBlockAccess; - -import com.google.common.io.ByteArrayDataInput; - -import cpw.mods.fml.common.network.ByteBufUtils; -import gregtech.api.interfaces.INetworkUpdatableItem; -import gregtech.api.util.ISerializableObject; -import io.netty.buffer.ByteBuf; - -/** - * Client -> Server: send arbitrary data to server and update the currently held item. - */ -public class GT_Packet_UpdateItem extends GT_Packet_New { - - private NBTTagCompound tag; - private EntityPlayerMP mPlayer; - - public GT_Packet_UpdateItem() { - super(true); - } - - public GT_Packet_UpdateItem(NBTTagCompound tag) { - super(false); - this.tag = tag; - } - - @Override - public byte getPacketID() { - return GT_PacketTypes.UPDATE_ITEM.id; - } - - @Override - public void setINetHandler(INetHandler aHandler) { - if (aHandler instanceof NetHandlerPlayServer) { - mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity; - } - } - - @Override - public void encode(ByteBuf aOut) { - ByteBufUtils.writeTag(aOut, tag); - } - - @Override - public GT_Packet_New decode(ByteArrayDataInput aData) { - return new GT_Packet_UpdateItem(ISerializableObject.readCompoundTagFromGreggyByteBuf(aData)); - } - - @Override - public void process(IBlockAccess aWorld) { - if (mPlayer == null) return; - ItemStack stack = mPlayer.inventory.getCurrentItem(); - if (stack != null && stack.getItem() instanceof INetworkUpdatableItem) { - ((INetworkUpdatableItem) stack.getItem()).receive(stack, mPlayer, tag); - } - } -} diff --git a/src/main/java/gregtech/api/net/IGT_NetworkHandler.java b/src/main/java/gregtech/api/net/IGT_NetworkHandler.java index 8436a89e9b..3569317b01 100644 --- a/src/main/java/gregtech/api/net/IGT_NetworkHandler.java +++ b/src/main/java/gregtech/api/net/IGT_NetworkHandler.java @@ -8,15 +8,15 @@ import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @SuppressWarnings("deprecation") public interface IGT_NetworkHandler { - void sendToPlayer(GT_Packet aPacket, EntityPlayerMP aPlayer); + void sendToPlayer(GTPacket aPacket, EntityPlayerMP aPlayer); - void sendToAllAround(GT_Packet aPacket, TargetPoint aPosition); + void sendToAllAround(GTPacket aPacket, TargetPoint aPosition); - default void sendToAll(GT_Packet aPacket) { + default void sendToAll(GTPacket aPacket) { throw new UnsupportedOperationException("sendToAll not implemented"); } - void sendToServer(GT_Packet aPacket); + void sendToServer(GTPacket aPacket); - void sendPacketToAllPlayersInRange(World aWorld, GT_Packet aPacket, int aX, int aZ); + void sendPacketToAllPlayersInRange(World aWorld, GTPacket aPacket, int aX, int aZ); } diff --git a/src/main/java/gregtech/api/objects/AE2DigitalChestHandler.java b/src/main/java/gregtech/api/objects/AE2DigitalChestHandler.java index c2e0556de9..3ede25f5ea 100644 --- a/src/main/java/gregtech/api/objects/AE2DigitalChestHandler.java +++ b/src/main/java/gregtech/api/objects/AE2DigitalChestHandler.java @@ -4,7 +4,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import gregtech.api.metatileentity.BaseMetaTileEntity; -import gregtech.common.tileentities.storage.GT_MetaTileEntity_DigitalChestBase; +import gregtech.common.tileentities.storage.MTEDigitalChestBase; public class AE2DigitalChestHandler implements appeng.api.storage.IExternalStorageHandler { @@ -12,14 +12,14 @@ public class AE2DigitalChestHandler implements appeng.api.storage.IExternalStora public boolean canHandle(final TileEntity te, final ForgeDirection d, final appeng.api.storage.StorageChannel chan, final appeng.api.networking.security.BaseActionSource mySrc) { return chan == appeng.api.storage.StorageChannel.ITEMS && te instanceof BaseMetaTileEntity - && ((BaseMetaTileEntity) te).getMetaTileEntity() instanceof GT_MetaTileEntity_DigitalChestBase; + && ((BaseMetaTileEntity) te).getMetaTileEntity() instanceof MTEDigitalChestBase; } @Override public appeng.api.storage.IMEInventory getInventory(final TileEntity te, final ForgeDirection d, final appeng.api.storage.StorageChannel chan, final appeng.api.networking.security.BaseActionSource src) { if (chan == appeng.api.storage.StorageChannel.ITEMS) { - return ((GT_MetaTileEntity_DigitalChestBase) (((BaseMetaTileEntity) te).getMetaTileEntity())); + return ((MTEDigitalChestBase) (((BaseMetaTileEntity) te).getMetaTileEntity())); } return null; } diff --git a/src/main/java/gregtech/api/objects/GTArrayList.java b/src/main/java/gregtech/api/objects/GTArrayList.java new file mode 100644 index 0000000000..33fbb18571 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTArrayList.java @@ -0,0 +1,73 @@ +package gregtech.api.objects; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +import com.google.common.collect.Collections2; + +public class GTArrayList extends ArrayList { + + private static final long serialVersionUID = 1L; + private int size_sS; + + private final boolean mAllowNulls; + + public GTArrayList(boolean aAllowNulls, int aCapacity) { + super(aCapacity); + mAllowNulls = aAllowNulls; + } + + @SafeVarargs + public GTArrayList(boolean aAllowNulls, E... aArray) { + super(Arrays.asList(aArray)); + mAllowNulls = aAllowNulls; + if (!mAllowNulls) { + size_sS = size(); + for (int i = 0; i < size_sS; i++) if (get(i) == null) { + remove(i--); + size_sS = size(); + } + } + } + + public GTArrayList(boolean aAllowNulls, Collection aList) { + super(aList); + mAllowNulls = aAllowNulls; + if (!mAllowNulls) { + size_sS = size(); + for (int i = 0; i < size_sS; i++) if (get(i) == null) { + remove(i--); + size_sS = size(); + } + } + } + + @Override + public E set(int aIndex, E aElement) { + if (mAllowNulls || aElement != null) return super.set(aIndex, aElement); + return null; + } + + @Override + public boolean add(E aElement) { + if (mAllowNulls || aElement != null) return super.add(aElement); + return false; + } + + @Override + public void add(int aIndex, E aElement) { + if (mAllowNulls || aElement != null) super.add(aIndex, aElement); + } + + @Override + public boolean addAll(Collection aList) { + return super.addAll(Collections2.filter(aList, Objects::nonNull)); + } + + @Override + public boolean addAll(int aIndex, Collection aList) { + return super.addAll(aIndex, Collections2.filter(aList, Objects::nonNull)); + } +} diff --git a/src/main/java/gregtech/api/objects/GTChunkManager.java b/src/main/java/gregtech/api/objects/GTChunkManager.java new file mode 100644 index 0000000000..59bc90aa1c --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTChunkManager.java @@ -0,0 +1,204 @@ +package gregtech.api.objects; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeChunkManager; +import net.minecraftforge.common.ForgeChunkManager.Ticket; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; + +import gregtech.GTMod; +import gregtech.api.enums.GTValues; +import gregtech.api.interfaces.IChunkLoader; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.GTLog; + +/** + * Handles re-initialization of chunks after a server restart. + */ +public class GTChunkManager + implements ForgeChunkManager.OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { + + private final Map registeredTickets = new HashMap<>(); + public static GTChunkManager instance = new GTChunkManager(); + + public static void init() { + ForgeChunkManager.setForcedChunkLoadingCallback(GTMod.instance, instance); + } + + @Override + public void ticketsLoaded(List tickets, World world) {} + + /** + * Determines if tickets should be kept. Based on if the ticket is a machine or a working-chunk ticket. + * Working-chunk tickets are tossed and recreated when the machine reactivates. + * Machine tickets are kept only if the config {@code alwaysReloadChunkloaders} is true. + * Otherwise, machine chunks are tossed and recreated only when the machine reactivates, + * similarly to a Passive Anchor. + * + * @param tickets The tickets that you will want to select from. + * The list is immutable and cannot be manipulated directly. Copy it first. + * @param world The world + * @param maxTicketCount The maximum number of tickets that will be allowed. + * @return list of tickets + */ + + @Override + public List ticketsLoaded(List tickets, World world, int maxTicketCount) { + List validTickets = new ArrayList<>(); + if (GTValues.alwaysReloadChunkloaders) { + for (Ticket ticket : tickets) { + int x = ticket.getModData() + .getInteger("OwnerX"); + int y = ticket.getModData() + .getInteger("OwnerY"); + int z = ticket.getModData() + .getInteger("OwnerZ"); + if (y > 0) { + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof IGregTechTileEntity && ((IGregTechTileEntity) tile).isAllowedToWork()) { + ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(x >> 4, z >> 4)); + if (!registeredTickets.containsKey(tile)) { + registeredTickets.put(tile, ticket); + if (((IGregTechTileEntity) tile).getMetaTileEntity() instanceof IChunkLoader) + ForgeChunkManager.forceChunk( + ticket, + ((IChunkLoader) ((IGregTechTileEntity) tile).getMetaTileEntity()).getActiveChunk()); + validTickets.add(ticket); + } + } + } + } + } + return validTickets; + } + + /** + * Determines if player tickets should be kept. This is where a ticket list per-player would be created and + * maintained. When a player joins, an event occurs, their name/UUID/etc is compared against tickets on this list + * and those tickets are reactivated. + * Since that info would be maintained/dealt with on a per-player startup, the list returned back to Forge is empty. + * + * @param tickets The tickets that you will want to select from. + * The list is immutable and cannot be manipulated directly. Copy it first. + * @param world The world + * @return the list of string-ticket paris + */ + @Override + public ListMultimap playerTicketsLoaded(ListMultimap tickets, World world) { + // Not currently used, so just return an empty list. + return ArrayListMultimap.create(); + } + + /** + * Requests a chunk to be loaded for this machine. May pass a {@code null} chunk to load just the machine itself if + * {@code alwaysReloadChunkloaders} is enabled in config. + * + * @param owner owner of the TileEntity + * @param chunkXZ chunk coordinates + * @param player player + * @return if the chunk was loaded successfully + */ + public static boolean requestPlayerChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ, String player) { + if (!GTValues.enableChunkloaders) return false; + if (!GTValues.alwaysReloadChunkloaders && chunkXZ == null) return false; + if (GTValues.debugChunkloaders && chunkXZ != null) + GTLog.out.println("GT_ChunkManager: Chunk request: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); + if (instance.registeredTickets.containsKey(owner)) { + ForgeChunkManager.forceChunk(instance.registeredTickets.get(owner), chunkXZ); + } else { + Ticket ticket; + if (player.equals("")) ticket = ForgeChunkManager + .requestTicket(GTMod.instance, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL); + else ticket = ForgeChunkManager + .requestPlayerTicket(GTMod.instance, player, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL); + if (ticket == null) { + if (GTValues.debugChunkloaders) + GTLog.out.println("GT_ChunkManager: ForgeChunkManager.requestTicket failed"); + return false; + } + if (GTValues.debugChunkloaders) GTLog.out.println( + "GT_ChunkManager: ticket issued for machine at: (" + owner.xCoord + + ", " + + owner.yCoord + + ", " + + owner.zCoord + + ")"); + NBTTagCompound tag = ticket.getModData(); + tag.setInteger("OwnerX", owner.xCoord); + tag.setInteger("OwnerY", owner.yCoord); + tag.setInteger("OwnerZ", owner.zCoord); + ForgeChunkManager.forceChunk(ticket, chunkXZ); + if (GTValues.alwaysReloadChunkloaders) + ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(owner.xCoord >> 4, owner.zCoord >> 4)); + instance.registeredTickets.put(owner, ticket); + } + return true; + } + + @SuppressWarnings("UnusedReturnValue") + public static boolean requestChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ) { + return requestPlayerChunkLoad(owner, chunkXZ, ""); + } + + public static void releaseChunk(TileEntity owner, ChunkCoordIntPair chunkXZ) { + if (!GTValues.enableChunkloaders) return; + Ticket ticket = instance.registeredTickets.get(owner); + if (ticket != null) { + if (GTValues.debugChunkloaders) GTLog.out + .println("GT_ChunkManager: Chunk release: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); + ForgeChunkManager.unforceChunk(ticket, chunkXZ); + } + } + + public static void releaseTicket(TileEntity owner) { + if (!GTValues.enableChunkloaders) return; + Ticket ticket = instance.registeredTickets.get(owner); + if (ticket != null) { + if (GTValues.debugChunkloaders) { + GTLog.out.println( + "GT_ChunkManager: ticket released by machine at: (" + owner.xCoord + + ", " + + owner.yCoord + + ", " + + owner.zCoord + + ")"); + for (ChunkCoordIntPair chunk : ticket.getChunkList()) GTLog.out + .println("GT_ChunkManager: Chunk release: (" + chunk.chunkXPos + ", " + chunk.chunkZPos + ")"); + } + ForgeChunkManager.releaseTicket(ticket); + instance.registeredTickets.remove(owner); + } + } + + public static void printTickets() { + GTLog.out.println("GT_ChunkManager: Start forced chunks dump:"); + instance.registeredTickets.forEach((machine, ticket) -> { + GTLog.out.print( + "GT_ChunkManager: Chunks forced by the machine at (" + machine.xCoord + + ", " + + machine.yCoord + + ", " + + machine.zCoord + + ")"); + if (ticket.isPlayerTicket()) GTLog.out.print(" Owner: " + ticket.getPlayerName()); + GTLog.out.print(" :"); + for (ChunkCoordIntPair c : ticket.getChunkList()) { + GTLog.out.print("("); + GTLog.out.print(c.chunkXPos); + GTLog.out.print(", "); + GTLog.out.print(c.chunkZPos); + GTLog.out.print("), "); + } + }); + GTLog.out.println("GT_ChunkManager: End forced chunks dump:"); + } +} diff --git a/src/main/java/gregtech/api/objects/GTCopiedBlockTexture.java b/src/main/java/gregtech/api/objects/GTCopiedBlockTexture.java new file mode 100644 index 0000000000..79be90c3b6 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTCopiedBlockTexture.java @@ -0,0 +1,36 @@ +package gregtech.api.objects; + +import net.minecraft.block.Block; + +import gregtech.api.enums.Dyes; +import gregtech.api.interfaces.ITexture; +import gregtech.common.render.GTCopiedBlockTextureRender; + +/** + * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. + */ +@Deprecated +public class GTCopiedBlockTexture extends GTCopiedBlockTextureRender implements ITexture { + + // Backwards Compat + @Deprecated + public short[] mRGBa; + + public GTCopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta, short[] aRGBa, boolean aAllowAlpha) { + super(aBlock, ordinalSide, aMeta, aRGBa, aAllowAlpha); + GTCopiedBlockTexture.this.mRGBa = aRGBa; + } + + public GTCopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta, short[] aRGBa) { + this(aBlock, ordinalSide, aMeta, aRGBa, true); + } + + public GTCopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta) { + this(aBlock, ordinalSide, aMeta, Dyes._NULL.mRGBa); + } + + @Override + public boolean isOldTexture() { + return true; + } +} diff --git a/src/main/java/gregtech/api/objects/GTCoverDefault.java b/src/main/java/gregtech/api/objects/GTCoverDefault.java new file mode 100644 index 0000000000..6e9664c355 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTCoverDefault.java @@ -0,0 +1,81 @@ +package gregtech.api.objects; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; + +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.GTUtility; + +public class GTCoverDefault extends CoverBehavior { + + /** + * This is the Dummy, if there is a generic Cover without behavior + */ + public GTCoverDefault() { + super(); + } + + @Override + public boolean isSimpleCover() { + return true; + } + + @Override + public int onCoverScrewdriverclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer, float aX, float aY, float aZ) { + aCoverVariable = ((aCoverVariable + 1) & 15); + GTUtility.sendChatToPlayer( + aPlayer, + ((aCoverVariable & 1) != 0 ? GTUtility.trans("128.1", "Redstone ") : "") + + ((aCoverVariable & 2) != 0 ? GTUtility.trans("129.1", "Energy ") : "") + + ((aCoverVariable & 4) != 0 ? GTUtility.trans("130.1", "Fluids ") : "") + + ((aCoverVariable & 8) != 0 ? GTUtility.trans("131.1", "Items ") : "")); + return aCoverVariable; + } + + @Override + public boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return (aCoverVariable & 1) != 0; + } + + @Override + public boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return (aCoverVariable & 1) != 0; + } + + @Override + public boolean letsEnergyIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return (aCoverVariable & 2) != 0; + } + + @Override + public boolean letsEnergyOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return (aCoverVariable & 2) != 0; + } + + @Override + public boolean letsFluidIn(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return (aCoverVariable & 4) != 0; + } + + @Override + public boolean letsFluidOut(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return (aCoverVariable & 4) != 0; + } + + @Override + public boolean letsItemsIn(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return (aCoverVariable & 8) != 0; + } + + @Override + public boolean letsItemsOut(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return (aCoverVariable & 8) != 0; + } +} diff --git a/src/main/java/gregtech/api/objects/GTCoverNone.java b/src/main/java/gregtech/api/objects/GTCoverNone.java new file mode 100644 index 0000000000..2c07538186 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTCoverNone.java @@ -0,0 +1,237 @@ +package gregtech.api.objects; + +import static gregtech.api.enums.GTValues.E; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; + +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.util.CoverBehavior; +import gregtech.api.util.ISerializableObject; + +public class GTCoverNone extends CoverBehavior { + + /** + * This is the Dummy, if there is no Cover + */ + public GTCoverNone() {} + + @Override + public float getBlastProofLevel(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return 10.0F; + } + + @Override + public boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsEnergyIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsEnergyOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsFluidIn(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsFluidOut(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsItemsIn(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return true; + } + + @Override + public boolean letsItemsOut(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return true; + } + + @Override + public boolean isGUIClickable(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + public boolean manipulatesSidedRedstoneOutput(ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + @Override + public boolean onCoverRightclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer, float aX, float aY, float aZ) { + return false; + } + + @Override + public boolean onCoverRemoval(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + boolean aForced) { + return true; + } + + @Override + public int doCoverThings(ForgeDirection side, byte aInputRedstone, int aCoverID, int aCoverVariable, + ICoverable aTileEntity, long aTimer) { + return 0; + } + + @Override + public boolean isSimpleCover() { + return true; + } + + @Override + protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { + return false; + } + + @Override + protected ISerializableObject.LegacyCoverData doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, + int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { + return aCoverVariable; + } + + @Override + protected boolean onCoverRightClickImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, + float aY, float aZ) { + return false; + } + + @Override + protected ISerializableObject.LegacyCoverData onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, + float aY, float aZ) { + return aCoverVariable; + } + + @Override + protected boolean onCoverShiftRightClickImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer) { + return false; + } + + @Override + protected boolean onCoverRemovalImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, boolean aForced) { + return true; + } + + @Override + protected String getDescriptionImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return E; + } + + @Override + protected float getBlastProofLevelImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return 10.0F; + } + + @Override + protected boolean letsRedstoneGoInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsRedstoneGoOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { + return true; + } + + @Override + protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return false; + } + + @Override + protected boolean alwaysLookConnectedImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return false; + } + + @Override + protected byte getRedstoneInputImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return aInputRedstone; + } + + @Override + protected int getTickRateImpl(ForgeDirection side, int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, + ICoverable aTileEntity) { + return 0; + } + + @Override + protected byte getLensColorImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return -1; + } + + @Override + protected ItemStack getDropImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return null; + } +} diff --git a/src/main/java/gregtech/api/objects/GTFluid.java b/src/main/java/gregtech/api/objects/GTFluid.java new file mode 100644 index 0000000000..9ffeac5b8f --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTFluid.java @@ -0,0 +1,36 @@ +package gregtech.api.objects; + +import static gregtech.api.enums.Mods.GregTech; + +import net.minecraftforge.fluids.Fluid; + +import gregtech.api.GregTechAPI; +import gregtech.api.fluid.GTFluidFactory; + +/** + * @deprecated use {@link GTFluidFactory#builder} + */ +@Deprecated +public class GTFluid extends Fluid implements Runnable { + + public final String mTextureName; + private final short[] mRGBa; + + public GTFluid(String aName, String aTextureName, short[] aRGBa) { + super(aName); + mRGBa = aRGBa; + mTextureName = aTextureName; + GregTechAPI.sGTBlockIconload.add(this); + } + + @Override + public int getColor() { + return (Math.max(0, Math.min(255, mRGBa[0])) << 16) | (Math.max(0, Math.min(255, mRGBa[1])) << 8) + | Math.max(0, Math.min(255, mRGBa[2])); + } + + @Override + public void run() { + setIcons(GregTechAPI.sBlockIcons.registerIcon(GregTech.getResourcePath("fluids", "fluid." + mTextureName))); + } +} diff --git a/src/main/java/gregtech/api/objects/GTHashSet.java b/src/main/java/gregtech/api/objects/GTHashSet.java new file mode 100644 index 0000000000..df012c05f7 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTHashSet.java @@ -0,0 +1,91 @@ +package gregtech.api.objects; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import net.minecraft.item.ItemStack; + +import gregtech.api.GregTechAPI; +import gregtech.api.util.GTUtility; + +public class GTHashSet extends AbstractSet { + + private static final Object OBJECT = new Object(); + private final transient HashMap map; + + public GTHashSet() { + map = new HashMap<>(); + GregTechAPI.sItemStackMappings.add(map); + } + + public GTHashSet(Collection c) { + map = new HashMap<>(Math.max((int) (c.size() / .75f) + 1, 16)); + addAll(c); + GregTechAPI.sItemStackMappings.add(map); + } + + public GTHashSet(int initialCapacity, float loadFactor) { + map = new HashMap<>(initialCapacity, loadFactor); + GregTechAPI.sItemStackMappings.add(map); + } + + public GTHashSet(int initialCapacity) { + map = new HashMap<>(initialCapacity); + GregTechAPI.sItemStackMappings.add(map); + } + + GTHashSet(int initialCapacity, float loadFactor, boolean dummy) { + map = new LinkedHashMap<>(initialCapacity, loadFactor); + GregTechAPI.sItemStackMappings.add(map); + } + + public Map getMap() { + return map; + } + + @SuppressWarnings("unchecked") // The downcasting below will throw ClassCastException unless E is GT_ItemStack. + @Override + public Iterator iterator() { + return (Iterator) map.keySet() + .iterator(); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return map.containsKey(o); + } + + public boolean add(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return false; + return map.put(new GTItemStack(aStack), OBJECT) == null; + } + + @Override + public boolean add(E e) { + return map.put(e, OBJECT) == null; + } + + @Override + public boolean remove(Object o) { + return map.remove(o) == OBJECT; + } + + @Override + public void clear() { + map.clear(); + } +} diff --git a/src/main/java/gregtech/api/objects/GTItemStack.java b/src/main/java/gregtech/api/objects/GTItemStack.java new file mode 100644 index 0000000000..3ddfcd706a --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTItemStack.java @@ -0,0 +1,107 @@ +package gregtech.api.objects; + +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.GTValues; +import gregtech.api.util.GTUtility; +import gregtech.api.util.item.ItemHolder; +import it.unimi.dsi.fastutil.Hash; + +/** + * An optimization of {@link ItemStack} to have a better {@code hashcode} and {@code equals} in order to improve + * {@code HashMap} and {@code Set} performance + */ +public class GTItemStack extends ItemHolder { + + /** + * A better {@link Hash.Strategy} for {@link ItemStack}. Implementation originally from {@code GT_ItemStack2}. + */ + public static final Hash.Strategy ITEMSTACK_HASH_STRATEGY2 = new Hash.Strategy<>() { + + @Override + public int hashCode(ItemStack o) { + return o.getItem() + .hashCode() * 38197 + Items.feather.getDamage(o); + } + + @Override + public boolean equals(ItemStack a, ItemStack b) { + if (a == b) return true; + if (a == null || b == null) return false; + return a.getItem() == b.getItem() && Items.feather.getDamage(a) == Items.feather.getDamage(b); + } + }; + + public final Item mItem; + public final byte mStackSize; + public final short mMetaData; + + public GTItemStack(Item aItem, long aStackSize, long aMetaData) { + super(new ItemStack(aItem, 1, (int) aMetaData)); + mItem = aItem; + mStackSize = (byte) aStackSize; + mMetaData = (short) aMetaData; + } + + public GTItemStack(ItemStack aStack) { + this(aStack, false); + } + + public GTItemStack(ItemStack aStack, boolean wildcard) { + this( + aStack == null ? null : aStack.getItem(), + aStack == null ? 0 : aStack.stackSize, + aStack == null ? 0 : wildcard ? GTValues.W : Items.feather.getDamage(aStack)); + } + + public GTItemStack(int aHashCode) { + this(GTUtility.intToStack(aHashCode)); + } + + public final ItemStack toStack() { + if (mItem == null) return null; + return new ItemStack(mItem, 1, mMetaData); + } + + public final boolean isStackEqual(ItemStack aStack) { + return GTUtility.areStacksEqual(toStack(), aStack); + } + + public final boolean isStackEqual(GTItemStack aStack) { + return GTUtility.areStacksEqual(toStack(), aStack.toStack()); + } + + @Override + public boolean equals(Object aStack) { + if (aStack == this) return true; + if (aStack instanceof GTItemStack) { + return ((GTItemStack) aStack).mItem == mItem && ((GTItemStack) aStack).mMetaData == mMetaData; + } + return false; + } + + @Override + public int hashCode() { + return GTUtility.stackToInt(toStack()); + } + + /** + * @see #internalCopyStack(ItemStack, boolean) + */ + public static ItemStack internalCopyStack(ItemStack aStack) { + return internalCopyStack(aStack, false); + } + + /** + * Replicates the copy behavior of {@link #toStack()} but for normal {@link ItemStack}s. + * + * @param aStack the stack to copy + * @param wildcard whether to use wildcard damage value + * @return a copy of the stack with stack size 1 and no NBT + */ + public static ItemStack internalCopyStack(ItemStack aStack, boolean wildcard) { + return new ItemStack(aStack.getItem(), 1, wildcard ? GTValues.W : Items.feather.getDamage(aStack)); + } +} diff --git a/src/main/java/gregtech/api/objects/GTItemStack2.java b/src/main/java/gregtech/api/objects/GTItemStack2.java new file mode 100644 index 0000000000..798915d848 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTItemStack2.java @@ -0,0 +1,41 @@ +package gregtech.api.objects; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +/** + * GT_ItemStack, but with a better hashCode(). Due to this change, it should not be placed in the same hash based data + * structure with GT_ItemStack. It also shouldn't be used to construct search query into a hash based data structure + * that contains GT_ItemStack. + * + * @deprecated See {@link GTItemStack#ITEMSTACK_HASH_STRATEGY2} + */ +@Deprecated +public class GTItemStack2 extends GTItemStack { + + public GTItemStack2(Item aItem, long aStackSize, long aMetaData) { + super(aItem, aStackSize, aMetaData); + } + + public GTItemStack2(ItemStack aStack) { + super(aStack); + } + + public GTItemStack2(ItemStack aStack, boolean wildcard) { + super(aStack, wildcard); + } + + @Override + public boolean equals(Object aStack) { + if (aStack == this) return true; + if (aStack instanceof GTItemStack) { + return ((GTItemStack) aStack).mItem == mItem && ((GTItemStack) aStack).mMetaData == mMetaData; + } + return false; + } + + @Override + public int hashCode() { + return mItem.hashCode() * 38197 + mMetaData; + } +} diff --git a/src/main/java/gregtech/api/objects/GTMultiTexture.java b/src/main/java/gregtech/api/objects/GTMultiTexture.java new file mode 100644 index 0000000000..ecd2f55661 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTMultiTexture.java @@ -0,0 +1,27 @@ +package gregtech.api.objects; + +import gregtech.api.interfaces.ITexture; +import gregtech.common.render.GTMultiTextureRender; + +/** + *

+ * Lets Multiple ITextures Render overlay over each other.< + *

+ *

+ * I should have done this much earlier... + *

+ * + * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. + */ +@Deprecated +public class GTMultiTexture extends GTMultiTextureRender implements ITexture { + + public GTMultiTexture(ITexture... aTextures) { + super(aTextures); + } + + @Override + public boolean isOldTexture() { + return true; + } +} diff --git a/src/main/java/gregtech/api/objects/GTRenderedTexture.java b/src/main/java/gregtech/api/objects/GTRenderedTexture.java new file mode 100644 index 0000000000..a4d0a064ff --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTRenderedTexture.java @@ -0,0 +1,33 @@ +package gregtech.api.objects; + +import gregtech.api.enums.Dyes; +import gregtech.api.interfaces.IColorModulationContainer; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.ITexture; + +@Deprecated +public class GTRenderedTexture extends gregtech.common.render.GTRenderedTexture + implements ITexture, IColorModulationContainer { + + @Deprecated + public short[] mRGBa; + + public GTRenderedTexture(IIconContainer aIcon, short[] aRGBa, boolean aAllowAlpha) { + super(aIcon, aRGBa, aAllowAlpha, false, true, false); + if (aRGBa.length != 4) throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_RenderedTexture"); + mRGBa = aRGBa; + } + + public GTRenderedTexture(IIconContainer aIcon, short[] aRGBa) { + this(aIcon, aRGBa, true); + } + + public GTRenderedTexture(IIconContainer aIcon) { + this(aIcon, Dyes._NULL.mRGBa); + } + + @Override + public boolean isOldTexture() { + return true; + } +} diff --git a/src/main/java/gregtech/api/objects/GTSidedTexture.java b/src/main/java/gregtech/api/objects/GTSidedTexture.java new file mode 100644 index 0000000000..d7b2291386 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTSidedTexture.java @@ -0,0 +1,48 @@ +package gregtech.api.objects; + +import gregtech.api.enums.Dyes; +import gregtech.api.interfaces.IColorModulationContainer; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.interfaces.ITexture; +import gregtech.common.render.GTSidedTextureRender; + +/** + * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. + */ +@Deprecated +public class GTSidedTexture extends GTSidedTextureRender implements ITexture, IColorModulationContainer { + + @Deprecated + public short[] mRGBa; + + public GTSidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2, IIconContainer aIcon3, + IIconContainer aIcon4, IIconContainer aIcon5, short[] aRGBa, boolean aAllowAlpha) { + super(aIcon0, aIcon1, aIcon2, aIcon3, aIcon4, aIcon5, aRGBa, aAllowAlpha); + + // Backwards Compat + GTSidedTexture.this.mRGBa = aRGBa; + } + + public GTSidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2, IIconContainer aIcon3, + IIconContainer aIcon4, IIconContainer aIcon5, short[] aRGBa) { + this(aIcon0, aIcon1, aIcon2, aIcon3, aIcon4, aIcon5, aRGBa, true); + } + + public GTSidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2, IIconContainer aIcon3, + IIconContainer aIcon4, IIconContainer aIcon5) { + this(aIcon0, aIcon1, aIcon2, aIcon3, aIcon4, aIcon5, Dyes._NULL.mRGBa); + } + + public GTSidedTexture(IIconContainer aBottom, IIconContainer aTop, IIconContainer aSides, short[] aRGBa) { + this(aBottom, aTop, aSides, aSides, aSides, aSides, aRGBa); + } + + public GTSidedTexture(IIconContainer aBottom, IIconContainer aTop, IIconContainer aSides) { + this(aBottom, aTop, aSides, Dyes._NULL.mRGBa); + } + + @Override + public boolean isOldTexture() { + return true; + } +} diff --git a/src/main/java/gregtech/api/objects/GTStdRenderedTexture.java b/src/main/java/gregtech/api/objects/GTStdRenderedTexture.java new file mode 100644 index 0000000000..11a3a4818f --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTStdRenderedTexture.java @@ -0,0 +1,46 @@ +package gregtech.api.objects; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.enums.Dyes; +import gregtech.api.interfaces.IIconContainer; +import gregtech.api.util.LightingHelper; + +/** + * This ITexture implementation extends the GT_RenderedTexture class to render with bottom side flipped as with dumb + * blocks rendering. It is used in Ore blocks rendering so they better blends with dumb block ores from vanilla or other + * mods, when seen from bottom. + * + * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. + */ +@Deprecated +public class GTStdRenderedTexture extends GTRenderedTexture { + + @SuppressWarnings("unused") + public GTStdRenderedTexture(IIconContainer aIcon, short[] aRGBa, boolean aAllowAlpha) { + super(aIcon, aRGBa, aAllowAlpha); + } + + public GTStdRenderedTexture(IIconContainer aIcon, short[] aRGBa) { + super(aIcon, aRGBa, true); + } + + @SuppressWarnings("unused") + public GTStdRenderedTexture(IIconContainer aIcon) { + super(aIcon, Dyes._NULL.mRGBa); + } + + @Override + public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) { + LightingHelper lighting = new LightingHelper(aRenderer); + lighting.setupLightingYNeg(aBlock, aX, aY, aZ) + .setupColor(ForgeDirection.DOWN, mRGBa); + aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, mIconContainer.getIcon()); + if (mIconContainer.getOverlayIcon() != null) { + lighting.setupColor(ForgeDirection.DOWN, 0xffffff); + aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, mIconContainer.getOverlayIcon()); + } + } +} diff --git a/src/main/java/gregtech/api/objects/GTUODimension.java b/src/main/java/gregtech/api/objects/GTUODimension.java new file mode 100644 index 0000000000..2fe10196bd --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTUODimension.java @@ -0,0 +1,54 @@ +package gregtech.api.objects; + +import java.util.Random; + +import net.minecraftforge.common.config.ConfigCategory; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +public class GTUODimension { + + private final BiMap fFluids; + private int maxChance; + public String Dimension = "null"; + + public GTUODimension(ConfigCategory aConfigCategory) { // TODO CONFIGURE + fFluids = HashBiMap.create(); + if (aConfigCategory.containsKey("Dimension")) { + aConfigCategory.get("Dimension").comment = "Dimension ID or Class Name"; + Dimension = aConfigCategory.get("Dimension") + .getString(); + } + maxChance = 0; + // GT_FML_LOGGER.info("GT UO "+aConfigCategory.getName()+" Dimension:"+Dimension); + for (int i = 0; i < aConfigCategory.getChildren() + .size(); i++) { + GTUOFluid fluid = new GTUOFluid( + (ConfigCategory) aConfigCategory.getChildren() + .toArray()[i]); + fFluids.put(fluid.Registry, fluid); + maxChance += fluid.Chance; + } + } + + public GTUOFluid getRandomFluid(Random aRandom) { + int random = aRandom.nextInt(1000); + for (BiMap.Entry fl : fFluids.entrySet()) { + int chance = fl.getValue().Chance * 1000 / maxChance; + if (random <= chance) return fl.getValue(); + // GT_FML_LOGGER.info("GT UO "+fl.getValue().Registry+" Chance:"+chance+" Random:"+random); + random -= chance; + } + return null; + } + + public String getUOFluidKey(GTUOFluid uoFluid) { + return fFluids.inverse() + .get(uoFluid); + } + + public GTUOFluid getUOFluid(String key) { + return fFluids.get(key); + } +} diff --git a/src/main/java/gregtech/api/objects/GTUODimensionList.java b/src/main/java/gregtech/api/objects/GTUODimensionList.java new file mode 100644 index 0000000000..60d11fdaa7 --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTUODimensionList.java @@ -0,0 +1,648 @@ +package gregtech.api.objects; + +import static gregtech.api.enums.Dimensions.AlphaCentauriBb; +import static gregtech.api.enums.Dimensions.BarnardaC; +import static gregtech.api.enums.Dimensions.BarnardaE; +import static gregtech.api.enums.Dimensions.BarnardaF; +import static gregtech.api.enums.Dimensions.Callisto; +import static gregtech.api.enums.Dimensions.Europa; +import static gregtech.api.enums.Dimensions.Io; +import static gregtech.api.enums.Dimensions.Makemake; +import static gregtech.api.enums.Dimensions.Mars; +import static gregtech.api.enums.Dimensions.Mercury; +import static gregtech.api.enums.Dimensions.Miranda; +import static gregtech.api.enums.Dimensions.Moon; +import static gregtech.api.enums.Dimensions.Oberon; +import static gregtech.api.enums.Dimensions.Overworld; +import static gregtech.api.enums.Dimensions.Pluto; +import static gregtech.api.enums.Dimensions.Proteus; +import static gregtech.api.enums.Dimensions.Ross128b; +import static gregtech.api.enums.Dimensions.Ross128ba; +import static gregtech.api.enums.Dimensions.TCetiE; +import static gregtech.api.enums.Dimensions.Titan; +import static gregtech.api.enums.Dimensions.Triton; +import static gregtech.api.enums.Dimensions.Venus; +import static gregtech.api.enums.UndergroundFluidNames.carbonDioxide; +import static gregtech.api.enums.UndergroundFluidNames.carbonMonoxide; +import static gregtech.api.enums.UndergroundFluidNames.chlorobenzene; +import static gregtech.api.enums.UndergroundFluidNames.deuterium; +import static gregtech.api.enums.UndergroundFluidNames.distilledWater; +import static gregtech.api.enums.UndergroundFluidNames.ethane; +import static gregtech.api.enums.UndergroundFluidNames.ethylene; +import static gregtech.api.enums.UndergroundFluidNames.fluorine; +import static gregtech.api.enums.UndergroundFluidNames.heavyOil; +import static gregtech.api.enums.UndergroundFluidNames.helium3; +import static gregtech.api.enums.UndergroundFluidNames.hydrofluoricAcid; +import static gregtech.api.enums.UndergroundFluidNames.hydrogen; +import static gregtech.api.enums.UndergroundFluidNames.hydrogenSulfide; +import static gregtech.api.enums.UndergroundFluidNames.lava; +import static gregtech.api.enums.UndergroundFluidNames.lightOil; +import static gregtech.api.enums.UndergroundFluidNames.liquidAir; +import static gregtech.api.enums.UndergroundFluidNames.mediumOil; +import static gregtech.api.enums.UndergroundFluidNames.methane; +import static gregtech.api.enums.UndergroundFluidNames.moltenCopper; +import static gregtech.api.enums.UndergroundFluidNames.moltenIron; +import static gregtech.api.enums.UndergroundFluidNames.moltenLead; +import static gregtech.api.enums.UndergroundFluidNames.moltenTin; +import static gregtech.api.enums.UndergroundFluidNames.naturalGas; +import static gregtech.api.enums.UndergroundFluidNames.nitrogen; +import static gregtech.api.enums.UndergroundFluidNames.oil; +import static gregtech.api.enums.UndergroundFluidNames.oxygen; +import static gregtech.api.enums.UndergroundFluidNames.saltWater; +import static gregtech.api.enums.UndergroundFluidNames.sulfuricAcid; +import static gregtech.api.enums.UndergroundFluidNames.unknownWater; +import static gregtech.api.enums.UndergroundFluidNames.veryHeavyOil; + +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.Configuration; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +import gregtech.api.enums.Dimensions; +import gregtech.api.enums.UndergroundFluidNames; + +public class GTUODimensionList { + + private Configuration fConfig; + private String fCategory; + private final BiMap fDimensionList; + + public int[] blackList = new int[0]; + + public GTUODimensionList() { + fDimensionList = HashBiMap.create(); + } + + public void save() { + fConfig.save(); + } + + public GTUODimension GetDimension(int aDimension) { + if (CheckBlackList(aDimension)) return null; + if (fDimensionList.containsKey(Integer.toString(aDimension))) + return fDimensionList.get(Integer.toString(aDimension)); + for (BiMap.Entry dl : fDimensionList.entrySet()) + if (DimensionManager.getProvider(aDimension) + .getClass() + .getName() + .contains(dl.getValue().Dimension)) return dl.getValue(); + return fDimensionList.get("Default"); + } + + private boolean CheckBlackList(int aDimensionId) { + try { + return java.util.Arrays.binarySearch(blackList, aDimensionId) >= 0; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public void SetConfigValues(String aDimensionName, String aDimension, String aName, String aRegistry, + int aMinAmount, int aMaxAmount, int aChance, int aDecreasePerOperationAmount) { + String Category = fCategory + "." + aDimensionName; + fConfig.get(Category, "Dimension", aDimension) + .getString(); + Category += "." + aName; + fConfig.get(Category, "Registry", aRegistry) + .getString(); + fConfig.get(Category, "MinAmount", aMinAmount) + .getInt(aMinAmount); + fConfig.get(Category, "MaxAmount", aMaxAmount) + .getInt(aMaxAmount); + fConfig.get(Category, "Chance", aChance) + .getInt(aChance); + fConfig.get(Category, "DecreasePerOperationAmount", aDecreasePerOperationAmount) + .getInt(aDecreasePerOperationAmount); + // IT IS IN BUCKETS!!! + } + + private void setOverworldValues() { + new ConfigSetter().dimension(Overworld) + .fluid(naturalGas) + .chance(20) + .decreaseAmount(5) + .maxAmount(350) + .minAmount(10) + .writeToConfig(); + + new ConfigSetter().dimension(Overworld) + .fluid(lightOil) + .chance(20) + .decreaseAmount(5) + .maxAmount(350) + .minAmount(10) + .writeToConfig(); + + new ConfigSetter().dimension(Overworld) + .fluid(mediumOil) + .chance(20) + .decreaseAmount(5) + .maxAmount(625) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Overworld) + .fluid(heavyOil) + .chance(20) + .decreaseAmount(5) + .maxAmount(625) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Overworld) + .fluid(oil) + .chance(20) + .decreaseAmount(5) + .maxAmount(625) + .minAmount(0) + .writeToConfig(); + } + + private void setMoonValues() { + new ConfigSetter().dimension(Moon) + .fluid(helium3) + .chance(100) + .decreaseAmount(5) + .maxAmount(425) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Moon) + .fluid(saltWater) + .chance(20) + .decreaseAmount(5) + .maxAmount(200) + .minAmount(0) + .writeToConfig(); + } + + private void setMercuryValues() { + new ConfigSetter().dimension(Mercury) + .fluid(helium3) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Mercury) + .fluid(moltenIron) + .chance(30) + .decreaseAmount(5) + .maxAmount(400) + .minAmount(0) + .writeToConfig(); + } + + private void setVenusValues() { + new ConfigSetter().dimension(Venus) + .fluid(moltenLead) + .chance(100) + .decreaseAmount(5) + .maxAmount(1600) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Venus) + .fluid(sulfuricAcid) + .chance(100) + .decreaseAmount(5) + .maxAmount(250) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Venus) + .fluid(carbonDioxide) + .chance(100) + .decreaseAmount(5) + .maxAmount(1500) + .minAmount(0) + .writeToConfig(); + } + + private void setMarsValues() { + new ConfigSetter().dimension(Mars) + .fluid(saltWater) + .chance(100) + .decreaseAmount(5) + .maxAmount(400) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Mars) + .fluid(chlorobenzene) + .chance(100) + .decreaseAmount(5) + .maxAmount(400) + .minAmount(0) + .writeToConfig(); + } + + private void setIoValues() { + new ConfigSetter().dimension(Io) + .fluid(moltenLead) + .chance(20) + .decreaseAmount(5) + .maxAmount(650) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Io) + .fluid(sulfuricAcid) + .chance(80) + .decreaseAmount(5) + .maxAmount(350) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Io) + .fluid(carbonDioxide) + .chance(80) + .decreaseAmount(5) + .maxAmount(750) + .minAmount(0) + .writeToConfig(); + } + + private void setEuropaValues() { + new ConfigSetter().dimension(Europa) + .fluid(saltWater) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Europa) + .fluid(veryHeavyOil) + .chance(20) + .decreaseAmount(5) + .maxAmount(200) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Europa) + .fluid(distilledWater) + .chance(80) + .decreaseAmount(5) + .maxAmount(3500) + .minAmount(0) + .writeToConfig(); + } + + private void setCallistoValues() { + new ConfigSetter().dimension(Callisto) + .fluid(oxygen) + .chance(100) + .decreaseAmount(5) + .maxAmount(200) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Callisto) + .fluid(liquidAir) + .chance(100) + .decreaseAmount(5) + .maxAmount(200) + .minAmount(0) + .writeToConfig(); + } + + private void setTitanValues() { + new ConfigSetter().dimension(Titan) + .fluid(methane) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Titan) + .fluid(ethane) + .chance(100) + .decreaseAmount(5) + .maxAmount(200) + .minAmount(0) + .writeToConfig(); + } + + private void setMirandaValues() { + new ConfigSetter().dimension(Miranda) + .fluid(hydrogenSulfide) + .chance(100) + .decreaseAmount(5) + .maxAmount(900) + .minAmount(0) + .writeToConfig(); + } + + private void setOberonValues() { + new ConfigSetter().dimension(Oberon) + .fluid(carbonMonoxide) + .chance(100) + .decreaseAmount(5) + .maxAmount(2000) + .minAmount(0) + .writeToConfig(); + } + + private void setTritonValues() { + new ConfigSetter().dimension(Triton) + .fluid(nitrogen) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Triton) + .fluid(ethylene) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + } + + private void setProteusValues() { + new ConfigSetter().dimension(Proteus) + .fluid(deuterium) + .chance(100) + .decreaseAmount(5) + .maxAmount(700) + .minAmount(0) + .writeToConfig(); + } + + private void setPlutoValues() { + new ConfigSetter().dimension(Pluto) + .fluid(nitrogen) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Pluto) + .fluid(oxygen) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Pluto) + .fluid(liquidAir) + .chance(40) + .decreaseAmount(5) + .maxAmount(300) + .minAmount(4) + .writeToConfig(); + + new ConfigSetter().dimension(Pluto) + .fluid(fluorine) + .chance(80) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(4) + .writeToConfig(); + } + + private void setMakeMakeValues() { + new ConfigSetter().dimension(Makemake) + .fluid(hydrofluoricAcid) + .chance(80) + .decreaseAmount(5) + .maxAmount(300) + .minAmount(0) + .writeToConfig(); + } + + private void setAlphaCentauriBBValues() { + new ConfigSetter().dimension(AlphaCentauriBb) + .fluid(moltenCopper) + .chance(10) + .decreaseAmount(5) + .maxAmount(300) + .minAmount(0) + .writeToConfig(); + } + + private void setBarnardaCValues() { + new ConfigSetter().dimension(BarnardaC) + .fluid(veryHeavyOil) + .chance(100) + .decreaseAmount(5) + .maxAmount(800) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(BarnardaC) + .fluid(unknownWater) + .chance(100) + .decreaseAmount(5) + .maxAmount(300) + .minAmount(0) + .writeToConfig(); + } + + private void setBarnardaEValues() { + new ConfigSetter().dimension(BarnardaE) + .fluid(liquidAir) + .chance(20) + .decreaseAmount(5) + .maxAmount(400) + .minAmount(0) + .writeToConfig(); + } + + private void setBarnardaFValues() { + new ConfigSetter().dimension(BarnardaF) + .fluid(moltenTin) + .chance(15) + .decreaseAmount(5) + .maxAmount(400) + .minAmount(0) + .writeToConfig(); + } + + private void setTcetiEValues() { + new ConfigSetter().dimension(TCetiE) + .fluid(veryHeavyOil) + .chance(100) + .decreaseAmount(5) + .maxAmount(200) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(TCetiE) + .fluid(hydrogen) + .chance(50) + .decreaseAmount(5) + .maxAmount(700) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(TCetiE) + .fluid(distilledWater) + .chance(100) + .decreaseAmount(5) + .maxAmount(10_000) + .minAmount(0) + .writeToConfig(); + } + + private void setRoss128bValues() { + new ConfigSetter().dimension(Ross128b) + .fluid(veryHeavyOil) + .chance(40) + .decreaseAmount(5) + .maxAmount(625) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Ross128b) + .fluid(lava) + .chance(5) + .decreaseAmount(5) + .maxAmount(820) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Ross128b) + .fluid(naturalGas) + .chance(65) + .decreaseAmount(5) + .maxAmount(625) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Ross128b) + .fluid(distilledWater) + .chance(100) + .decreaseAmount(5) + .maxAmount(5000) + .minAmount(0) + .writeToConfig(); + } + + private void setRoss128baValues() { + new ConfigSetter().dimension(Ross128ba) + .fluid(saltWater) + .chance(40) + .decreaseAmount(5) + .maxAmount(1250) + .minAmount(0) + .writeToConfig(); + + new ConfigSetter().dimension(Ross128ba) + .fluid(helium3) + .chance(60) + .decreaseAmount(5) + .maxAmount(1250) + .minAmount(0) + .writeToConfig(); + } + + public void setDefaultValues() { + setOverworldValues(); + setMoonValues(); + setMercuryValues(); + setVenusValues(); + setMarsValues(); + setIoValues(); + setEuropaValues(); + setCallistoValues(); + setTitanValues(); + setMirandaValues(); + setOberonValues(); + setTritonValues(); + setProteusValues(); + setPlutoValues(); + setMakeMakeValues(); + setAlphaCentauriBBValues(); + setBarnardaCValues(); + setBarnardaEValues(); + setBarnardaFValues(); + setTcetiEValues(); + setRoss128bValues(); + setRoss128baValues(); + } + + public void getConfig(Configuration aConfig, String aCategory) { + fCategory = aCategory; + fConfig = aConfig; + if (!fConfig.hasCategory(fCategory)) setDefaultValues(); + + blackList = new int[] { -1, 1 }; + blackList = aConfig.get(fCategory, "DimBlackList", blackList, "Dimension IDs Black List") + .getIntList(); + java.util.Arrays.sort(blackList); + + for (int i = 0; i < fConfig.getCategory(fCategory) + .getChildren() + .size(); i++) { + GTUODimension Dimension = new GTUODimension( + (ConfigCategory) fConfig.getCategory(fCategory) + .getChildren() + .toArray()[i]); + fDimensionList.put(Dimension.Dimension, Dimension); + } + save(); + } + + public class ConfigSetter { + + private int chance; + private int decreaseAmount; + private int maxAmount; + private int minAmount; + private UndergroundFluidNames fluid; + private Dimensions dim; + + public ConfigSetter chance(int chance) { + this.chance = chance; + return this; + } + + public ConfigSetter decreaseAmount(int decreaseAmount) { + this.decreaseAmount = decreaseAmount; + return this; + } + + public ConfigSetter maxAmount(int maxAmount) { + this.maxAmount = maxAmount; + return this; + } + + public ConfigSetter minAmount(int minAmount) { + this.minAmount = minAmount; + return this; + } + + public ConfigSetter fluid(UndergroundFluidNames fluid) { + this.fluid = fluid; + return this; + } + + public ConfigSetter dimension(Dimensions dim) { + this.dim = dim; + return this; + } + + public void writeToConfig() { + SetConfigValues( + dim.toString(), + dim.id, + fluid.toString(), + fluid.name, + minAmount, + maxAmount, + chance, + decreaseAmount); + } + } +} diff --git a/src/main/java/gregtech/api/objects/GTUOFluid.java b/src/main/java/gregtech/api/objects/GTUOFluid.java new file mode 100644 index 0000000000..cd019dbc8e --- /dev/null +++ b/src/main/java/gregtech/api/objects/GTUOFluid.java @@ -0,0 +1,69 @@ +package gregtech.api.objects; + +import static gregtech.common.UndergroundOil.DIVIDER; + +import java.util.Random; + +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +public class GTUOFluid { + + public String Registry = "null"; + public int MaxAmount = 0; + public int MinAmount = 0; + public int Chance = 0; + public int DecreasePerOperationAmount = 5; + + public GTUOFluid(ConfigCategory aConfigCategory) { // TODO CONFIGURE + if (aConfigCategory.containsKey("Registry")) { + aConfigCategory.get("Registry").comment = "Fluid registry name"; + Registry = aConfigCategory.get("Registry") + .getString(); + } + if (aConfigCategory.containsKey("MaxAmount")) { + aConfigCategory + .get("MaxAmount").comment = "Max amount generation (per operation, sets the VeinData) 80000 MAX"; + MaxAmount = aConfigCategory.get("MaxAmount") + .getInt(0); + } + if (aConfigCategory.containsKey("MinAmount")) { + aConfigCategory.get("MinAmount").comment = "Min amount generation (per operation, sets the VeinData) 0 MIN"; + MinAmount = aConfigCategory.get("MinAmount") + .getInt(0); + } + if (aConfigCategory.containsKey("Chance")) { + aConfigCategory + .get("Chance").comment = "Chance generating (weighted chance!, there will be a fluid in chunk always!)"; + Chance = aConfigCategory.get("Chance") + .getInt(0); + } + if (aConfigCategory.containsKey("DecreasePerOperationAmount")) { + aConfigCategory.get( + "DecreasePerOperationAmount").comment = "Decrease per operation (actual fluid gained works like (Litre)VeinData/5000)"; + DecreasePerOperationAmount = aConfigCategory.get("DecreasePerOperationAmount") + .getInt(5); + } + // GT_FML_LOGGER.info("GT UO "+aConfigCategory.getName()+" Fluid:"+Registry+" Max:"+MaxAmount+" + // Min:"+MinAmount+" Chance:"+Chance); + } + + public Fluid getFluid() { + try { + return FluidRegistry.getFluid(this.Registry); + } catch (Exception e) { + return null; + } + } + + public int getRandomAmount(Random aRandom) { // generates some random ass number that correlates to extraction + // speeds + int smax = (int) Math.floor(Math.pow(MaxAmount * 100.d * DIVIDER, 0.2d)); // use scaled max and min values for + // the randomness to make high values + // more rare. + double smin = Math.pow(MinAmount * 100.d * DIVIDER, 0.2d); + double samount = Math.max(smin, aRandom.nextInt(smax) + aRandom.nextDouble()); + return (int) (Math.pow(samount, 5) / 100); // reverses the computation above + } +} diff --git a/src/main/java/gregtech/api/objects/GT_ArrayList.java b/src/main/java/gregtech/api/objects/GT_ArrayList.java deleted file mode 100644 index 9124ef8616..0000000000 --- a/src/main/java/gregtech/api/objects/GT_ArrayList.java +++ /dev/null @@ -1,73 +0,0 @@ -package gregtech.api.objects; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Objects; - -import com.google.common.collect.Collections2; - -public class GT_ArrayList extends ArrayList { - - private static final long serialVersionUID = 1L; - private int size_sS; - - private final boolean mAllowNulls; - - public GT_ArrayList(boolean aAllowNulls, int aCapacity) { - super(aCapacity); - mAllowNulls = aAllowNulls; - } - - @SafeVarargs - public GT_ArrayList(boolean aAllowNulls, E... aArray) { - super(Arrays.asList(aArray)); - mAllowNulls = aAllowNulls; - if (!mAllowNulls) { - size_sS = size(); - for (int i = 0; i < size_sS; i++) if (get(i) == null) { - remove(i--); - size_sS = size(); - } - } - } - - public GT_ArrayList(boolean aAllowNulls, Collection aList) { - super(aList); - mAllowNulls = aAllowNulls; - if (!mAllowNulls) { - size_sS = size(); - for (int i = 0; i < size_sS; i++) if (get(i) == null) { - remove(i--); - size_sS = size(); - } - } - } - - @Override - public E set(int aIndex, E aElement) { - if (mAllowNulls || aElement != null) return super.set(aIndex, aElement); - return null; - } - - @Override - public boolean add(E aElement) { - if (mAllowNulls || aElement != null) return super.add(aElement); - return false; - } - - @Override - public void add(int aIndex, E aElement) { - if (mAllowNulls || aElement != null) super.add(aIndex, aElement); - } - - @Override - public boolean addAll(Collection aList) { - return super.addAll(Collections2.filter(aList, Objects::nonNull)); - } - - @Override - public boolean addAll(int aIndex, Collection aList) { - return super.addAll(aIndex, Collections2.filter(aList, Objects::nonNull)); - } -} diff --git a/src/main/java/gregtech/api/objects/GT_ChunkManager.java b/src/main/java/gregtech/api/objects/GT_ChunkManager.java deleted file mode 100644 index 14baaddd3d..0000000000 --- a/src/main/java/gregtech/api/objects/GT_ChunkManager.java +++ /dev/null @@ -1,204 +0,0 @@ -package gregtech.api.objects; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.World; -import net.minecraftforge.common.ForgeChunkManager; -import net.minecraftforge.common.ForgeChunkManager.Ticket; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; - -import gregtech.GT_Mod; -import gregtech.api.enums.GT_Values; -import gregtech.api.interfaces.IChunkLoader; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.util.GT_Log; - -/** - * Handles re-initialization of chunks after a server restart. - */ -public class GT_ChunkManager - implements ForgeChunkManager.OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback { - - private final Map registeredTickets = new HashMap<>(); - public static GT_ChunkManager instance = new GT_ChunkManager(); - - public static void init() { - ForgeChunkManager.setForcedChunkLoadingCallback(GT_Mod.instance, instance); - } - - @Override - public void ticketsLoaded(List tickets, World world) {} - - /** - * Determines if tickets should be kept. Based on if the ticket is a machine or a working-chunk ticket. - * Working-chunk tickets are tossed and recreated when the machine reactivates. - * Machine tickets are kept only if the config {@code alwaysReloadChunkloaders} is true. - * Otherwise, machine chunks are tossed and recreated only when the machine reactivates, - * similarly to a Passive Anchor. - * - * @param tickets The tickets that you will want to select from. - * The list is immutable and cannot be manipulated directly. Copy it first. - * @param world The world - * @param maxTicketCount The maximum number of tickets that will be allowed. - * @return list of tickets - */ - - @Override - public List ticketsLoaded(List tickets, World world, int maxTicketCount) { - List validTickets = new ArrayList<>(); - if (GT_Values.alwaysReloadChunkloaders) { - for (Ticket ticket : tickets) { - int x = ticket.getModData() - .getInteger("OwnerX"); - int y = ticket.getModData() - .getInteger("OwnerY"); - int z = ticket.getModData() - .getInteger("OwnerZ"); - if (y > 0) { - TileEntity tile = world.getTileEntity(x, y, z); - if (tile instanceof IGregTechTileEntity && ((IGregTechTileEntity) tile).isAllowedToWork()) { - ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(x >> 4, z >> 4)); - if (!registeredTickets.containsKey(tile)) { - registeredTickets.put(tile, ticket); - if (((IGregTechTileEntity) tile).getMetaTileEntity() instanceof IChunkLoader) - ForgeChunkManager.forceChunk( - ticket, - ((IChunkLoader) ((IGregTechTileEntity) tile).getMetaTileEntity()).getActiveChunk()); - validTickets.add(ticket); - } - } - } - } - } - return validTickets; - } - - /** - * Determines if player tickets should be kept. This is where a ticket list per-player would be created and - * maintained. When a player joins, an event occurs, their name/UUID/etc is compared against tickets on this list - * and those tickets are reactivated. - * Since that info would be maintained/dealt with on a per-player startup, the list returned back to Forge is empty. - * - * @param tickets The tickets that you will want to select from. - * The list is immutable and cannot be manipulated directly. Copy it first. - * @param world The world - * @return the list of string-ticket paris - */ - @Override - public ListMultimap playerTicketsLoaded(ListMultimap tickets, World world) { - // Not currently used, so just return an empty list. - return ArrayListMultimap.create(); - } - - /** - * Requests a chunk to be loaded for this machine. May pass a {@code null} chunk to load just the machine itself if - * {@code alwaysReloadChunkloaders} is enabled in config. - * - * @param owner owner of the TileEntity - * @param chunkXZ chunk coordinates - * @param player player - * @return if the chunk was loaded successfully - */ - public static boolean requestPlayerChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ, String player) { - if (!GT_Values.enableChunkloaders) return false; - if (!GT_Values.alwaysReloadChunkloaders && chunkXZ == null) return false; - if (GT_Values.debugChunkloaders && chunkXZ != null) GT_Log.out - .println("GT_ChunkManager: Chunk request: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); - if (instance.registeredTickets.containsKey(owner)) { - ForgeChunkManager.forceChunk(instance.registeredTickets.get(owner), chunkXZ); - } else { - Ticket ticket; - if (player.equals("")) ticket = ForgeChunkManager - .requestTicket(GT_Mod.instance, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL); - else ticket = ForgeChunkManager - .requestPlayerTicket(GT_Mod.instance, player, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL); - if (ticket == null) { - if (GT_Values.debugChunkloaders) - GT_Log.out.println("GT_ChunkManager: ForgeChunkManager.requestTicket failed"); - return false; - } - if (GT_Values.debugChunkloaders) GT_Log.out.println( - "GT_ChunkManager: ticket issued for machine at: (" + owner.xCoord - + ", " - + owner.yCoord - + ", " - + owner.zCoord - + ")"); - NBTTagCompound tag = ticket.getModData(); - tag.setInteger("OwnerX", owner.xCoord); - tag.setInteger("OwnerY", owner.yCoord); - tag.setInteger("OwnerZ", owner.zCoord); - ForgeChunkManager.forceChunk(ticket, chunkXZ); - if (GT_Values.alwaysReloadChunkloaders) - ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(owner.xCoord >> 4, owner.zCoord >> 4)); - instance.registeredTickets.put(owner, ticket); - } - return true; - } - - @SuppressWarnings("UnusedReturnValue") - public static boolean requestChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ) { - return requestPlayerChunkLoad(owner, chunkXZ, ""); - } - - public static void releaseChunk(TileEntity owner, ChunkCoordIntPair chunkXZ) { - if (!GT_Values.enableChunkloaders) return; - Ticket ticket = instance.registeredTickets.get(owner); - if (ticket != null) { - if (GT_Values.debugChunkloaders) GT_Log.out - .println("GT_ChunkManager: Chunk release: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")"); - ForgeChunkManager.unforceChunk(ticket, chunkXZ); - } - } - - public static void releaseTicket(TileEntity owner) { - if (!GT_Values.enableChunkloaders) return; - Ticket ticket = instance.registeredTickets.get(owner); - if (ticket != null) { - if (GT_Values.debugChunkloaders) { - GT_Log.out.println( - "GT_ChunkManager: ticket released by machine at: (" + owner.xCoord - + ", " - + owner.yCoord - + ", " - + owner.zCoord - + ")"); - for (ChunkCoordIntPair chunk : ticket.getChunkList()) GT_Log.out - .println("GT_ChunkManager: Chunk release: (" + chunk.chunkXPos + ", " + chunk.chunkZPos + ")"); - } - ForgeChunkManager.releaseTicket(ticket); - instance.registeredTickets.remove(owner); - } - } - - public static void printTickets() { - GT_Log.out.println("GT_ChunkManager: Start forced chunks dump:"); - instance.registeredTickets.forEach((machine, ticket) -> { - GT_Log.out.print( - "GT_ChunkManager: Chunks forced by the machine at (" + machine.xCoord - + ", " - + machine.yCoord - + ", " - + machine.zCoord - + ")"); - if (ticket.isPlayerTicket()) GT_Log.out.print(" Owner: " + ticket.getPlayerName()); - GT_Log.out.print(" :"); - for (ChunkCoordIntPair c : ticket.getChunkList()) { - GT_Log.out.print("("); - GT_Log.out.print(c.chunkXPos); - GT_Log.out.print(", "); - GT_Log.out.print(c.chunkZPos); - GT_Log.out.print("), "); - } - }); - GT_Log.out.println("GT_ChunkManager: End forced chunks dump:"); - } -} diff --git a/src/main/java/gregtech/api/objects/GT_CopiedBlockTexture.java b/src/main/java/gregtech/api/objects/GT_CopiedBlockTexture.java deleted file mode 100644 index c5307b4803..0000000000 --- a/src/main/java/gregtech/api/objects/GT_CopiedBlockTexture.java +++ /dev/null @@ -1,35 +0,0 @@ -package gregtech.api.objects; - -import net.minecraft.block.Block; - -import gregtech.api.enums.Dyes; -import gregtech.api.interfaces.ITexture; - -/** - * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. - */ -@Deprecated -public class GT_CopiedBlockTexture extends gregtech.common.render.GT_CopiedBlockTexture implements ITexture { - - // Backwards Compat - @Deprecated - public short[] mRGBa; - - public GT_CopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta, short[] aRGBa, boolean aAllowAlpha) { - super(aBlock, ordinalSide, aMeta, aRGBa, aAllowAlpha); - GT_CopiedBlockTexture.this.mRGBa = aRGBa; - } - - public GT_CopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta, short[] aRGBa) { - this(aBlock, ordinalSide, aMeta, aRGBa, true); - } - - public GT_CopiedBlockTexture(Block aBlock, int ordinalSide, int aMeta) { - this(aBlock, ordinalSide, aMeta, Dyes._NULL.mRGBa); - } - - @Override - public boolean isOldTexture() { - return true; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_Cover_Default.java b/src/main/java/gregtech/api/objects/GT_Cover_Default.java deleted file mode 100644 index cc5f96eef3..0000000000 --- a/src/main/java/gregtech/api/objects/GT_Cover_Default.java +++ /dev/null @@ -1,81 +0,0 @@ -package gregtech.api.objects; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.Fluid; - -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.GT_Utility; - -public class GT_Cover_Default extends GT_CoverBehavior { - - /** - * This is the Dummy, if there is a generic Cover without behavior - */ - public GT_Cover_Default() { - super(); - } - - @Override - public boolean isSimpleCover() { - return true; - } - - @Override - public int onCoverScrewdriverclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer, float aX, float aY, float aZ) { - aCoverVariable = ((aCoverVariable + 1) & 15); - GT_Utility.sendChatToPlayer( - aPlayer, - ((aCoverVariable & 1) != 0 ? GT_Utility.trans("128.1", "Redstone ") : "") - + ((aCoverVariable & 2) != 0 ? GT_Utility.trans("129.1", "Energy ") : "") - + ((aCoverVariable & 4) != 0 ? GT_Utility.trans("130.1", "Fluids ") : "") - + ((aCoverVariable & 8) != 0 ? GT_Utility.trans("131.1", "Items ") : "")); - return aCoverVariable; - } - - @Override - public boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return (aCoverVariable & 1) != 0; - } - - @Override - public boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return (aCoverVariable & 1) != 0; - } - - @Override - public boolean letsEnergyIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return (aCoverVariable & 2) != 0; - } - - @Override - public boolean letsEnergyOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return (aCoverVariable & 2) != 0; - } - - @Override - public boolean letsFluidIn(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return (aCoverVariable & 4) != 0; - } - - @Override - public boolean letsFluidOut(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return (aCoverVariable & 4) != 0; - } - - @Override - public boolean letsItemsIn(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return (aCoverVariable & 8) != 0; - } - - @Override - public boolean letsItemsOut(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return (aCoverVariable & 8) != 0; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_Cover_None.java b/src/main/java/gregtech/api/objects/GT_Cover_None.java deleted file mode 100644 index 279efe63d8..0000000000 --- a/src/main/java/gregtech/api/objects/GT_Cover_None.java +++ /dev/null @@ -1,237 +0,0 @@ -package gregtech.api.objects; - -import static gregtech.api.enums.GT_Values.E; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.Fluid; - -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.util.GT_CoverBehavior; -import gregtech.api.util.ISerializableObject; - -public class GT_Cover_None extends GT_CoverBehavior { - - /** - * This is the Dummy, if there is no Cover - */ - public GT_Cover_None() {} - - @Override - public float getBlastProofLevel(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return 10.0F; - } - - @Override - public boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsEnergyIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsEnergyOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsFluidIn(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsFluidOut(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsItemsIn(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return true; - } - - @Override - public boolean letsItemsOut(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return true; - } - - @Override - public boolean isGUIClickable(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - public boolean manipulatesSidedRedstoneOutput(ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - @Override - public boolean onCoverRightclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer, float aX, float aY, float aZ) { - return false; - } - - @Override - public boolean onCoverRemoval(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - boolean aForced) { - return true; - } - - @Override - public int doCoverThings(ForgeDirection side, byte aInputRedstone, int aCoverID, int aCoverVariable, - ICoverable aTileEntity, long aTimer) { - return 0; - } - - @Override - public boolean isSimpleCover() { - return true; - } - - @Override - protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { - return false; - } - - @Override - protected ISerializableObject.LegacyCoverData doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, - int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { - return aCoverVariable; - } - - @Override - protected boolean onCoverRightClickImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, - float aY, float aZ) { - return false; - } - - @Override - protected ISerializableObject.LegacyCoverData onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, - float aY, float aZ) { - return aCoverVariable; - } - - @Override - protected boolean onCoverShiftRightClickImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer) { - return false; - } - - @Override - protected boolean onCoverRemovalImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, boolean aForced) { - return true; - } - - @Override - protected String getDescriptionImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return E; - } - - @Override - protected float getBlastProofLevelImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return 10.0F; - } - - @Override - protected boolean letsRedstoneGoInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsRedstoneGoOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { - return true; - } - - @Override - protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return false; - } - - @Override - protected boolean alwaysLookConnectedImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return false; - } - - @Override - protected byte getRedstoneInputImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return aInputRedstone; - } - - @Override - protected int getTickRateImpl(ForgeDirection side, int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, - ICoverable aTileEntity) { - return 0; - } - - @Override - protected byte getLensColorImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return -1; - } - - @Override - protected ItemStack getDropImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return null; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_Fluid.java b/src/main/java/gregtech/api/objects/GT_Fluid.java deleted file mode 100644 index 10824d6327..0000000000 --- a/src/main/java/gregtech/api/objects/GT_Fluid.java +++ /dev/null @@ -1,36 +0,0 @@ -package gregtech.api.objects; - -import static gregtech.api.enums.Mods.GregTech; - -import net.minecraftforge.fluids.Fluid; - -import gregtech.api.GregTech_API; -import gregtech.api.fluid.GT_FluidFactory; - -/** - * @deprecated use {@link GT_FluidFactory#builder} - */ -@Deprecated -public class GT_Fluid extends Fluid implements Runnable { - - public final String mTextureName; - private final short[] mRGBa; - - public GT_Fluid(String aName, String aTextureName, short[] aRGBa) { - super(aName); - mRGBa = aRGBa; - mTextureName = aTextureName; - GregTech_API.sGTBlockIconload.add(this); - } - - @Override - public int getColor() { - return (Math.max(0, Math.min(255, mRGBa[0])) << 16) | (Math.max(0, Math.min(255, mRGBa[1])) << 8) - | Math.max(0, Math.min(255, mRGBa[2])); - } - - @Override - public void run() { - setIcons(GregTech_API.sBlockIcons.registerIcon(GregTech.getResourcePath("fluids", "fluid." + mTextureName))); - } -} diff --git a/src/main/java/gregtech/api/objects/GT_HashSet.java b/src/main/java/gregtech/api/objects/GT_HashSet.java deleted file mode 100644 index d42f194e5d..0000000000 --- a/src/main/java/gregtech/api/objects/GT_HashSet.java +++ /dev/null @@ -1,91 +0,0 @@ -package gregtech.api.objects; - -import java.util.AbstractSet; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import net.minecraft.item.ItemStack; - -import gregtech.api.GregTech_API; -import gregtech.api.util.GT_Utility; - -public class GT_HashSet extends AbstractSet { - - private static final Object OBJECT = new Object(); - private final transient HashMap map; - - public GT_HashSet() { - map = new HashMap<>(); - GregTech_API.sItemStackMappings.add(map); - } - - public GT_HashSet(Collection c) { - map = new HashMap<>(Math.max((int) (c.size() / .75f) + 1, 16)); - addAll(c); - GregTech_API.sItemStackMappings.add(map); - } - - public GT_HashSet(int initialCapacity, float loadFactor) { - map = new HashMap<>(initialCapacity, loadFactor); - GregTech_API.sItemStackMappings.add(map); - } - - public GT_HashSet(int initialCapacity) { - map = new HashMap<>(initialCapacity); - GregTech_API.sItemStackMappings.add(map); - } - - GT_HashSet(int initialCapacity, float loadFactor, boolean dummy) { - map = new LinkedHashMap<>(initialCapacity, loadFactor); - GregTech_API.sItemStackMappings.add(map); - } - - public Map getMap() { - return map; - } - - @SuppressWarnings("unchecked") // The downcasting below will throw ClassCastException unless E is GT_ItemStack. - @Override - public Iterator iterator() { - return (Iterator) map.keySet() - .iterator(); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return map.containsKey(o); - } - - public boolean add(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return false; - return map.put(new GT_ItemStack(aStack), OBJECT) == null; - } - - @Override - public boolean add(E e) { - return map.put(e, OBJECT) == null; - } - - @Override - public boolean remove(Object o) { - return map.remove(o) == OBJECT; - } - - @Override - public void clear() { - map.clear(); - } -} diff --git a/src/main/java/gregtech/api/objects/GT_ItemStack.java b/src/main/java/gregtech/api/objects/GT_ItemStack.java deleted file mode 100644 index 492655740d..0000000000 --- a/src/main/java/gregtech/api/objects/GT_ItemStack.java +++ /dev/null @@ -1,107 +0,0 @@ -package gregtech.api.objects; - -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -import gregtech.api.enums.GT_Values; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.item.ItemHolder; -import it.unimi.dsi.fastutil.Hash; - -/** - * An optimization of {@link ItemStack} to have a better {@code hashcode} and {@code equals} in order to improve - * {@code HashMap} and {@code Set} performance - */ -public class GT_ItemStack extends ItemHolder { - - /** - * A better {@link Hash.Strategy} for {@link ItemStack}. Implementation originally from {@code GT_ItemStack2}. - */ - public static final Hash.Strategy ITEMSTACK_HASH_STRATEGY2 = new Hash.Strategy<>() { - - @Override - public int hashCode(ItemStack o) { - return o.getItem() - .hashCode() * 38197 + Items.feather.getDamage(o); - } - - @Override - public boolean equals(ItemStack a, ItemStack b) { - if (a == b) return true; - if (a == null || b == null) return false; - return a.getItem() == b.getItem() && Items.feather.getDamage(a) == Items.feather.getDamage(b); - } - }; - - public final Item mItem; - public final byte mStackSize; - public final short mMetaData; - - public GT_ItemStack(Item aItem, long aStackSize, long aMetaData) { - super(new ItemStack(aItem, 1, (int) aMetaData)); - mItem = aItem; - mStackSize = (byte) aStackSize; - mMetaData = (short) aMetaData; - } - - public GT_ItemStack(ItemStack aStack) { - this(aStack, false); - } - - public GT_ItemStack(ItemStack aStack, boolean wildcard) { - this( - aStack == null ? null : aStack.getItem(), - aStack == null ? 0 : aStack.stackSize, - aStack == null ? 0 : wildcard ? GT_Values.W : Items.feather.getDamage(aStack)); - } - - public GT_ItemStack(int aHashCode) { - this(GT_Utility.intToStack(aHashCode)); - } - - public final ItemStack toStack() { - if (mItem == null) return null; - return new ItemStack(mItem, 1, mMetaData); - } - - public final boolean isStackEqual(ItemStack aStack) { - return GT_Utility.areStacksEqual(toStack(), aStack); - } - - public final boolean isStackEqual(GT_ItemStack aStack) { - return GT_Utility.areStacksEqual(toStack(), aStack.toStack()); - } - - @Override - public boolean equals(Object aStack) { - if (aStack == this) return true; - if (aStack instanceof GT_ItemStack) { - return ((GT_ItemStack) aStack).mItem == mItem && ((GT_ItemStack) aStack).mMetaData == mMetaData; - } - return false; - } - - @Override - public int hashCode() { - return GT_Utility.stackToInt(toStack()); - } - - /** - * @see #internalCopyStack(ItemStack, boolean) - */ - public static ItemStack internalCopyStack(ItemStack aStack) { - return internalCopyStack(aStack, false); - } - - /** - * Replicates the copy behavior of {@link #toStack()} but for normal {@link ItemStack}s. - * - * @param aStack the stack to copy - * @param wildcard whether to use wildcard damage value - * @return a copy of the stack with stack size 1 and no NBT - */ - public static ItemStack internalCopyStack(ItemStack aStack, boolean wildcard) { - return new ItemStack(aStack.getItem(), 1, wildcard ? GT_Values.W : Items.feather.getDamage(aStack)); - } -} diff --git a/src/main/java/gregtech/api/objects/GT_ItemStack2.java b/src/main/java/gregtech/api/objects/GT_ItemStack2.java deleted file mode 100644 index aa93876830..0000000000 --- a/src/main/java/gregtech/api/objects/GT_ItemStack2.java +++ /dev/null @@ -1,41 +0,0 @@ -package gregtech.api.objects; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -/** - * GT_ItemStack, but with a better hashCode(). Due to this change, it should not be placed in the same hash based data - * structure with GT_ItemStack. It also shouldn't be used to construct search query into a hash based data structure - * that contains GT_ItemStack. - * - * @deprecated See {@link GT_ItemStack#ITEMSTACK_HASH_STRATEGY2} - */ -@Deprecated -public class GT_ItemStack2 extends GT_ItemStack { - - public GT_ItemStack2(Item aItem, long aStackSize, long aMetaData) { - super(aItem, aStackSize, aMetaData); - } - - public GT_ItemStack2(ItemStack aStack) { - super(aStack); - } - - public GT_ItemStack2(ItemStack aStack, boolean wildcard) { - super(aStack, wildcard); - } - - @Override - public boolean equals(Object aStack) { - if (aStack == this) return true; - if (aStack instanceof GT_ItemStack) { - return ((GT_ItemStack) aStack).mItem == mItem && ((GT_ItemStack) aStack).mMetaData == mMetaData; - } - return false; - } - - @Override - public int hashCode() { - return mItem.hashCode() * 38197 + mMetaData; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_MultiTexture.java b/src/main/java/gregtech/api/objects/GT_MultiTexture.java deleted file mode 100644 index 9748ecb934..0000000000 --- a/src/main/java/gregtech/api/objects/GT_MultiTexture.java +++ /dev/null @@ -1,26 +0,0 @@ -package gregtech.api.objects; - -import gregtech.api.interfaces.ITexture; - -/** - *

- * Lets Multiple ITextures Render overlay over each other.< - *

- *

- * I should have done this much earlier... - *

- * - * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. - */ -@Deprecated -public class GT_MultiTexture extends gregtech.common.render.GT_MultiTexture implements ITexture { - - public GT_MultiTexture(ITexture... aTextures) { - super(aTextures); - } - - @Override - public boolean isOldTexture() { - return true; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_RenderedTexture.java b/src/main/java/gregtech/api/objects/GT_RenderedTexture.java deleted file mode 100644 index bbb22e7d36..0000000000 --- a/src/main/java/gregtech/api/objects/GT_RenderedTexture.java +++ /dev/null @@ -1,33 +0,0 @@ -package gregtech.api.objects; - -import gregtech.api.enums.Dyes; -import gregtech.api.interfaces.IColorModulationContainer; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.interfaces.ITexture; - -@Deprecated -public class GT_RenderedTexture extends gregtech.common.render.GT_RenderedTexture - implements ITexture, IColorModulationContainer { - - @Deprecated - public short[] mRGBa; - - public GT_RenderedTexture(IIconContainer aIcon, short[] aRGBa, boolean aAllowAlpha) { - super(aIcon, aRGBa, aAllowAlpha, false, true, false); - if (aRGBa.length != 4) throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_RenderedTexture"); - mRGBa = aRGBa; - } - - public GT_RenderedTexture(IIconContainer aIcon, short[] aRGBa) { - this(aIcon, aRGBa, true); - } - - public GT_RenderedTexture(IIconContainer aIcon) { - this(aIcon, Dyes._NULL.mRGBa); - } - - @Override - public boolean isOldTexture() { - return true; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_SidedTexture.java b/src/main/java/gregtech/api/objects/GT_SidedTexture.java deleted file mode 100644 index d042ebede9..0000000000 --- a/src/main/java/gregtech/api/objects/GT_SidedTexture.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.api.objects; - -import gregtech.api.enums.Dyes; -import gregtech.api.interfaces.IColorModulationContainer; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.interfaces.ITexture; - -/** - * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. - */ -@Deprecated -public class GT_SidedTexture extends gregtech.common.render.GT_SidedTexture - implements ITexture, IColorModulationContainer { - - @Deprecated - public short[] mRGBa; - - public GT_SidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2, IIconContainer aIcon3, - IIconContainer aIcon4, IIconContainer aIcon5, short[] aRGBa, boolean aAllowAlpha) { - super(aIcon0, aIcon1, aIcon2, aIcon3, aIcon4, aIcon5, aRGBa, aAllowAlpha); - - // Backwards Compat - GT_SidedTexture.this.mRGBa = aRGBa; - } - - public GT_SidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2, IIconContainer aIcon3, - IIconContainer aIcon4, IIconContainer aIcon5, short[] aRGBa) { - this(aIcon0, aIcon1, aIcon2, aIcon3, aIcon4, aIcon5, aRGBa, true); - } - - public GT_SidedTexture(IIconContainer aIcon0, IIconContainer aIcon1, IIconContainer aIcon2, IIconContainer aIcon3, - IIconContainer aIcon4, IIconContainer aIcon5) { - this(aIcon0, aIcon1, aIcon2, aIcon3, aIcon4, aIcon5, Dyes._NULL.mRGBa); - } - - public GT_SidedTexture(IIconContainer aBottom, IIconContainer aTop, IIconContainer aSides, short[] aRGBa) { - this(aBottom, aTop, aSides, aSides, aSides, aSides, aRGBa); - } - - public GT_SidedTexture(IIconContainer aBottom, IIconContainer aTop, IIconContainer aSides) { - this(aBottom, aTop, aSides, Dyes._NULL.mRGBa); - } - - @Override - public boolean isOldTexture() { - return true; - } -} diff --git a/src/main/java/gregtech/api/objects/GT_StdRenderedTexture.java b/src/main/java/gregtech/api/objects/GT_StdRenderedTexture.java deleted file mode 100644 index d4b8d16da6..0000000000 --- a/src/main/java/gregtech/api/objects/GT_StdRenderedTexture.java +++ /dev/null @@ -1,46 +0,0 @@ -package gregtech.api.objects; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraftforge.common.util.ForgeDirection; - -import gregtech.api.enums.Dyes; -import gregtech.api.interfaces.IIconContainer; -import gregtech.api.util.LightingHelper; - -/** - * This ITexture implementation extends the GT_RenderedTexture class to render with bottom side flipped as with dumb - * blocks rendering. It is used in Ore blocks rendering so they better blends with dumb block ores from vanilla or other - * mods, when seen from bottom. - * - * @deprecated Replaced by the {@link gregtech.api.render.TextureFactory} API. - */ -@Deprecated -public class GT_StdRenderedTexture extends GT_RenderedTexture { - - @SuppressWarnings("unused") - public GT_StdRenderedTexture(IIconContainer aIcon, short[] aRGBa, boolean aAllowAlpha) { - super(aIcon, aRGBa, aAllowAlpha); - } - - public GT_StdRenderedTexture(IIconContainer aIcon, short[] aRGBa) { - super(aIcon, aRGBa, true); - } - - @SuppressWarnings("unused") - public GT_StdRenderedTexture(IIconContainer aIcon) { - super(aIcon, Dyes._NULL.mRGBa); - } - - @Override - public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) { - LightingHelper lighting = new LightingHelper(aRenderer); - lighting.setupLightingYNeg(aBlock, aX, aY, aZ) - .setupColor(ForgeDirection.DOWN, mRGBa); - aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, mIconContainer.getIcon()); - if (mIconContainer.getOverlayIcon() != null) { - lighting.setupColor(ForgeDirection.DOWN, 0xffffff); - aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, mIconContainer.getOverlayIcon()); - } - } -} diff --git a/src/main/java/gregtech/api/objects/GT_UO_Dimension.java b/src/main/java/gregtech/api/objects/GT_UO_Dimension.java deleted file mode 100644 index af82c35dab..0000000000 --- a/src/main/java/gregtech/api/objects/GT_UO_Dimension.java +++ /dev/null @@ -1,54 +0,0 @@ -package gregtech.api.objects; - -import java.util.Random; - -import net.minecraftforge.common.config.ConfigCategory; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; - -public class GT_UO_Dimension { - - private final BiMap fFluids; - private int maxChance; - public String Dimension = "null"; - - public GT_UO_Dimension(ConfigCategory aConfigCategory) { // TODO CONFIGURE - fFluids = HashBiMap.create(); - if (aConfigCategory.containsKey("Dimension")) { - aConfigCategory.get("Dimension").comment = "Dimension ID or Class Name"; - Dimension = aConfigCategory.get("Dimension") - .getString(); - } - maxChance = 0; - // GT_FML_LOGGER.info("GT UO "+aConfigCategory.getName()+" Dimension:"+Dimension); - for (int i = 0; i < aConfigCategory.getChildren() - .size(); i++) { - GT_UO_Fluid fluid = new GT_UO_Fluid( - (ConfigCategory) aConfigCategory.getChildren() - .toArray()[i]); - fFluids.put(fluid.Registry, fluid); - maxChance += fluid.Chance; - } - } - - public GT_UO_Fluid getRandomFluid(Random aRandom) { - int random = aRandom.nextInt(1000); - for (BiMap.Entry fl : fFluids.entrySet()) { - int chance = fl.getValue().Chance * 1000 / maxChance; - if (random <= chance) return fl.getValue(); - // GT_FML_LOGGER.info("GT UO "+fl.getValue().Registry+" Chance:"+chance+" Random:"+random); - random -= chance; - } - return null; - } - - public String getUOFluidKey(GT_UO_Fluid uoFluid) { - return fFluids.inverse() - .get(uoFluid); - } - - public GT_UO_Fluid getUOFluid(String key) { - return fFluids.get(key); - } -} diff --git a/src/main/java/gregtech/api/objects/GT_UO_DimensionList.java b/src/main/java/gregtech/api/objects/GT_UO_DimensionList.java deleted file mode 100644 index f057614ccf..0000000000 --- a/src/main/java/gregtech/api/objects/GT_UO_DimensionList.java +++ /dev/null @@ -1,648 +0,0 @@ -package gregtech.api.objects; - -import static gregtech.api.enums.Dimensions.AlphaCentauriBb; -import static gregtech.api.enums.Dimensions.BarnardaC; -import static gregtech.api.enums.Dimensions.BarnardaE; -import static gregtech.api.enums.Dimensions.BarnardaF; -import static gregtech.api.enums.Dimensions.Callisto; -import static gregtech.api.enums.Dimensions.Europa; -import static gregtech.api.enums.Dimensions.Io; -import static gregtech.api.enums.Dimensions.Makemake; -import static gregtech.api.enums.Dimensions.Mars; -import static gregtech.api.enums.Dimensions.Mercury; -import static gregtech.api.enums.Dimensions.Miranda; -import static gregtech.api.enums.Dimensions.Moon; -import static gregtech.api.enums.Dimensions.Oberon; -import static gregtech.api.enums.Dimensions.Overworld; -import static gregtech.api.enums.Dimensions.Pluto; -import static gregtech.api.enums.Dimensions.Proteus; -import static gregtech.api.enums.Dimensions.Ross128b; -import static gregtech.api.enums.Dimensions.Ross128ba; -import static gregtech.api.enums.Dimensions.TCetiE; -import static gregtech.api.enums.Dimensions.Titan; -import static gregtech.api.enums.Dimensions.Triton; -import static gregtech.api.enums.Dimensions.Venus; -import static gregtech.api.enums.UndergroundFluidNames.carbonDioxide; -import static gregtech.api.enums.UndergroundFluidNames.carbonMonoxide; -import static gregtech.api.enums.UndergroundFluidNames.chlorobenzene; -import static gregtech.api.enums.UndergroundFluidNames.deuterium; -import static gregtech.api.enums.UndergroundFluidNames.distilledWater; -import static gregtech.api.enums.UndergroundFluidNames.ethane; -import static gregtech.api.enums.UndergroundFluidNames.ethylene; -import static gregtech.api.enums.UndergroundFluidNames.fluorine; -import static gregtech.api.enums.UndergroundFluidNames.heavyOil; -import static gregtech.api.enums.UndergroundFluidNames.helium3; -import static gregtech.api.enums.UndergroundFluidNames.hydrofluoricAcid; -import static gregtech.api.enums.UndergroundFluidNames.hydrogen; -import static gregtech.api.enums.UndergroundFluidNames.hydrogenSulfide; -import static gregtech.api.enums.UndergroundFluidNames.lava; -import static gregtech.api.enums.UndergroundFluidNames.lightOil; -import static gregtech.api.enums.UndergroundFluidNames.liquidAir; -import static gregtech.api.enums.UndergroundFluidNames.mediumOil; -import static gregtech.api.enums.UndergroundFluidNames.methane; -import static gregtech.api.enums.UndergroundFluidNames.moltenCopper; -import static gregtech.api.enums.UndergroundFluidNames.moltenIron; -import static gregtech.api.enums.UndergroundFluidNames.moltenLead; -import static gregtech.api.enums.UndergroundFluidNames.moltenTin; -import static gregtech.api.enums.UndergroundFluidNames.naturalGas; -import static gregtech.api.enums.UndergroundFluidNames.nitrogen; -import static gregtech.api.enums.UndergroundFluidNames.oil; -import static gregtech.api.enums.UndergroundFluidNames.oxygen; -import static gregtech.api.enums.UndergroundFluidNames.saltWater; -import static gregtech.api.enums.UndergroundFluidNames.sulfuricAcid; -import static gregtech.api.enums.UndergroundFluidNames.unknownWater; -import static gregtech.api.enums.UndergroundFluidNames.veryHeavyOil; - -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.config.ConfigCategory; -import net.minecraftforge.common.config.Configuration; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; - -import gregtech.api.enums.Dimensions; -import gregtech.api.enums.UndergroundFluidNames; - -public class GT_UO_DimensionList { - - private Configuration fConfig; - private String fCategory; - private final BiMap fDimensionList; - - public int[] blackList = new int[0]; - - public GT_UO_DimensionList() { - fDimensionList = HashBiMap.create(); - } - - public void save() { - fConfig.save(); - } - - public GT_UO_Dimension GetDimension(int aDimension) { - if (CheckBlackList(aDimension)) return null; - if (fDimensionList.containsKey(Integer.toString(aDimension))) - return fDimensionList.get(Integer.toString(aDimension)); - for (BiMap.Entry dl : fDimensionList.entrySet()) - if (DimensionManager.getProvider(aDimension) - .getClass() - .getName() - .contains(dl.getValue().Dimension)) return dl.getValue(); - return fDimensionList.get("Default"); - } - - private boolean CheckBlackList(int aDimensionId) { - try { - return java.util.Arrays.binarySearch(blackList, aDimensionId) >= 0; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - public void SetConfigValues(String aDimensionName, String aDimension, String aName, String aRegistry, - int aMinAmount, int aMaxAmount, int aChance, int aDecreasePerOperationAmount) { - String Category = fCategory + "." + aDimensionName; - fConfig.get(Category, "Dimension", aDimension) - .getString(); - Category += "." + aName; - fConfig.get(Category, "Registry", aRegistry) - .getString(); - fConfig.get(Category, "MinAmount", aMinAmount) - .getInt(aMinAmount); - fConfig.get(Category, "MaxAmount", aMaxAmount) - .getInt(aMaxAmount); - fConfig.get(Category, "Chance", aChance) - .getInt(aChance); - fConfig.get(Category, "DecreasePerOperationAmount", aDecreasePerOperationAmount) - .getInt(aDecreasePerOperationAmount); - // IT IS IN BUCKETS!!! - } - - private void setOverworldValues() { - new ConfigSetter().dimension(Overworld) - .fluid(naturalGas) - .chance(20) - .decreaseAmount(5) - .maxAmount(350) - .minAmount(10) - .writeToConfig(); - - new ConfigSetter().dimension(Overworld) - .fluid(lightOil) - .chance(20) - .decreaseAmount(5) - .maxAmount(350) - .minAmount(10) - .writeToConfig(); - - new ConfigSetter().dimension(Overworld) - .fluid(mediumOil) - .chance(20) - .decreaseAmount(5) - .maxAmount(625) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Overworld) - .fluid(heavyOil) - .chance(20) - .decreaseAmount(5) - .maxAmount(625) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Overworld) - .fluid(oil) - .chance(20) - .decreaseAmount(5) - .maxAmount(625) - .minAmount(0) - .writeToConfig(); - } - - private void setMoonValues() { - new ConfigSetter().dimension(Moon) - .fluid(helium3) - .chance(100) - .decreaseAmount(5) - .maxAmount(425) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Moon) - .fluid(saltWater) - .chance(20) - .decreaseAmount(5) - .maxAmount(200) - .minAmount(0) - .writeToConfig(); - } - - private void setMercuryValues() { - new ConfigSetter().dimension(Mercury) - .fluid(helium3) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Mercury) - .fluid(moltenIron) - .chance(30) - .decreaseAmount(5) - .maxAmount(400) - .minAmount(0) - .writeToConfig(); - } - - private void setVenusValues() { - new ConfigSetter().dimension(Venus) - .fluid(moltenLead) - .chance(100) - .decreaseAmount(5) - .maxAmount(1600) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Venus) - .fluid(sulfuricAcid) - .chance(100) - .decreaseAmount(5) - .maxAmount(250) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Venus) - .fluid(carbonDioxide) - .chance(100) - .decreaseAmount(5) - .maxAmount(1500) - .minAmount(0) - .writeToConfig(); - } - - private void setMarsValues() { - new ConfigSetter().dimension(Mars) - .fluid(saltWater) - .chance(100) - .decreaseAmount(5) - .maxAmount(400) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Mars) - .fluid(chlorobenzene) - .chance(100) - .decreaseAmount(5) - .maxAmount(400) - .minAmount(0) - .writeToConfig(); - } - - private void setIoValues() { - new ConfigSetter().dimension(Io) - .fluid(moltenLead) - .chance(20) - .decreaseAmount(5) - .maxAmount(650) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Io) - .fluid(sulfuricAcid) - .chance(80) - .decreaseAmount(5) - .maxAmount(350) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Io) - .fluid(carbonDioxide) - .chance(80) - .decreaseAmount(5) - .maxAmount(750) - .minAmount(0) - .writeToConfig(); - } - - private void setEuropaValues() { - new ConfigSetter().dimension(Europa) - .fluid(saltWater) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Europa) - .fluid(veryHeavyOil) - .chance(20) - .decreaseAmount(5) - .maxAmount(200) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Europa) - .fluid(distilledWater) - .chance(80) - .decreaseAmount(5) - .maxAmount(3500) - .minAmount(0) - .writeToConfig(); - } - - private void setCallistoValues() { - new ConfigSetter().dimension(Callisto) - .fluid(oxygen) - .chance(100) - .decreaseAmount(5) - .maxAmount(200) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Callisto) - .fluid(liquidAir) - .chance(100) - .decreaseAmount(5) - .maxAmount(200) - .minAmount(0) - .writeToConfig(); - } - - private void setTitanValues() { - new ConfigSetter().dimension(Titan) - .fluid(methane) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Titan) - .fluid(ethane) - .chance(100) - .decreaseAmount(5) - .maxAmount(200) - .minAmount(0) - .writeToConfig(); - } - - private void setMirandaValues() { - new ConfigSetter().dimension(Miranda) - .fluid(hydrogenSulfide) - .chance(100) - .decreaseAmount(5) - .maxAmount(900) - .minAmount(0) - .writeToConfig(); - } - - private void setOberonValues() { - new ConfigSetter().dimension(Oberon) - .fluid(carbonMonoxide) - .chance(100) - .decreaseAmount(5) - .maxAmount(2000) - .minAmount(0) - .writeToConfig(); - } - - private void setTritonValues() { - new ConfigSetter().dimension(Triton) - .fluid(nitrogen) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Triton) - .fluid(ethylene) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - } - - private void setProteusValues() { - new ConfigSetter().dimension(Proteus) - .fluid(deuterium) - .chance(100) - .decreaseAmount(5) - .maxAmount(700) - .minAmount(0) - .writeToConfig(); - } - - private void setPlutoValues() { - new ConfigSetter().dimension(Pluto) - .fluid(nitrogen) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Pluto) - .fluid(oxygen) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Pluto) - .fluid(liquidAir) - .chance(40) - .decreaseAmount(5) - .maxAmount(300) - .minAmount(4) - .writeToConfig(); - - new ConfigSetter().dimension(Pluto) - .fluid(fluorine) - .chance(80) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(4) - .writeToConfig(); - } - - private void setMakeMakeValues() { - new ConfigSetter().dimension(Makemake) - .fluid(hydrofluoricAcid) - .chance(80) - .decreaseAmount(5) - .maxAmount(300) - .minAmount(0) - .writeToConfig(); - } - - private void setAlphaCentauriBBValues() { - new ConfigSetter().dimension(AlphaCentauriBb) - .fluid(moltenCopper) - .chance(10) - .decreaseAmount(5) - .maxAmount(300) - .minAmount(0) - .writeToConfig(); - } - - private void setBarnardaCValues() { - new ConfigSetter().dimension(BarnardaC) - .fluid(veryHeavyOil) - .chance(100) - .decreaseAmount(5) - .maxAmount(800) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(BarnardaC) - .fluid(unknownWater) - .chance(100) - .decreaseAmount(5) - .maxAmount(300) - .minAmount(0) - .writeToConfig(); - } - - private void setBarnardaEValues() { - new ConfigSetter().dimension(BarnardaE) - .fluid(liquidAir) - .chance(20) - .decreaseAmount(5) - .maxAmount(400) - .minAmount(0) - .writeToConfig(); - } - - private void setBarnardaFValues() { - new ConfigSetter().dimension(BarnardaF) - .fluid(moltenTin) - .chance(15) - .decreaseAmount(5) - .maxAmount(400) - .minAmount(0) - .writeToConfig(); - } - - private void setTcetiEValues() { - new ConfigSetter().dimension(TCetiE) - .fluid(veryHeavyOil) - .chance(100) - .decreaseAmount(5) - .maxAmount(200) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(TCetiE) - .fluid(hydrogen) - .chance(50) - .decreaseAmount(5) - .maxAmount(700) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(TCetiE) - .fluid(distilledWater) - .chance(100) - .decreaseAmount(5) - .maxAmount(10_000) - .minAmount(0) - .writeToConfig(); - } - - private void setRoss128bValues() { - new ConfigSetter().dimension(Ross128b) - .fluid(veryHeavyOil) - .chance(40) - .decreaseAmount(5) - .maxAmount(625) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Ross128b) - .fluid(lava) - .chance(5) - .decreaseAmount(5) - .maxAmount(820) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Ross128b) - .fluid(naturalGas) - .chance(65) - .decreaseAmount(5) - .maxAmount(625) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Ross128b) - .fluid(distilledWater) - .chance(100) - .decreaseAmount(5) - .maxAmount(5000) - .minAmount(0) - .writeToConfig(); - } - - private void setRoss128baValues() { - new ConfigSetter().dimension(Ross128ba) - .fluid(saltWater) - .chance(40) - .decreaseAmount(5) - .maxAmount(1250) - .minAmount(0) - .writeToConfig(); - - new ConfigSetter().dimension(Ross128ba) - .fluid(helium3) - .chance(60) - .decreaseAmount(5) - .maxAmount(1250) - .minAmount(0) - .writeToConfig(); - } - - public void setDefaultValues() { - setOverworldValues(); - setMoonValues(); - setMercuryValues(); - setVenusValues(); - setMarsValues(); - setIoValues(); - setEuropaValues(); - setCallistoValues(); - setTitanValues(); - setMirandaValues(); - setOberonValues(); - setTritonValues(); - setProteusValues(); - setPlutoValues(); - setMakeMakeValues(); - setAlphaCentauriBBValues(); - setBarnardaCValues(); - setBarnardaEValues(); - setBarnardaFValues(); - setTcetiEValues(); - setRoss128bValues(); - setRoss128baValues(); - } - - public void getConfig(Configuration aConfig, String aCategory) { - fCategory = aCategory; - fConfig = aConfig; - if (!fConfig.hasCategory(fCategory)) setDefaultValues(); - - blackList = new int[] { -1, 1 }; - blackList = aConfig.get(fCategory, "DimBlackList", blackList, "Dimension IDs Black List") - .getIntList(); - java.util.Arrays.sort(blackList); - - for (int i = 0; i < fConfig.getCategory(fCategory) - .getChildren() - .size(); i++) { - GT_UO_Dimension Dimension = new GT_UO_Dimension( - (ConfigCategory) fConfig.getCategory(fCategory) - .getChildren() - .toArray()[i]); - fDimensionList.put(Dimension.Dimension, Dimension); - } - save(); - } - - public class ConfigSetter { - - private int chance; - private int decreaseAmount; - private int maxAmount; - private int minAmount; - private UndergroundFluidNames fluid; - private Dimensions dim; - - public ConfigSetter chance(int chance) { - this.chance = chance; - return this; - } - - public ConfigSetter decreaseAmount(int decreaseAmount) { - this.decreaseAmount = decreaseAmount; - return this; - } - - public ConfigSetter maxAmount(int maxAmount) { - this.maxAmount = maxAmount; - return this; - } - - public ConfigSetter minAmount(int minAmount) { - this.minAmount = minAmount; - return this; - } - - public ConfigSetter fluid(UndergroundFluidNames fluid) { - this.fluid = fluid; - return this; - } - - public ConfigSetter dimension(Dimensions dim) { - this.dim = dim; - return this; - } - - public void writeToConfig() { - SetConfigValues( - dim.toString(), - dim.id, - fluid.toString(), - fluid.name, - minAmount, - maxAmount, - chance, - decreaseAmount); - } - } -} diff --git a/src/main/java/gregtech/api/objects/GT_UO_Fluid.java b/src/main/java/gregtech/api/objects/GT_UO_Fluid.java deleted file mode 100644 index 7f9898e02e..0000000000 --- a/src/main/java/gregtech/api/objects/GT_UO_Fluid.java +++ /dev/null @@ -1,69 +0,0 @@ -package gregtech.api.objects; - -import static gregtech.common.GT_UndergroundOil.DIVIDER; - -import java.util.Random; - -import net.minecraftforge.common.config.ConfigCategory; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; - -public class GT_UO_Fluid { - - public String Registry = "null"; - public int MaxAmount = 0; - public int MinAmount = 0; - public int Chance = 0; - public int DecreasePerOperationAmount = 5; - - public GT_UO_Fluid(ConfigCategory aConfigCategory) { // TODO CONFIGURE - if (aConfigCategory.containsKey("Registry")) { - aConfigCategory.get("Registry").comment = "Fluid registry name"; - Registry = aConfigCategory.get("Registry") - .getString(); - } - if (aConfigCategory.containsKey("MaxAmount")) { - aConfigCategory - .get("MaxAmount").comment = "Max amount generation (per operation, sets the VeinData) 80000 MAX"; - MaxAmount = aConfigCategory.get("MaxAmount") - .getInt(0); - } - if (aConfigCategory.containsKey("MinAmount")) { - aConfigCategory.get("MinAmount").comment = "Min amount generation (per operation, sets the VeinData) 0 MIN"; - MinAmount = aConfigCategory.get("MinAmount") - .getInt(0); - } - if (aConfigCategory.containsKey("Chance")) { - aConfigCategory - .get("Chance").comment = "Chance generating (weighted chance!, there will be a fluid in chunk always!)"; - Chance = aConfigCategory.get("Chance") - .getInt(0); - } - if (aConfigCategory.containsKey("DecreasePerOperationAmount")) { - aConfigCategory.get( - "DecreasePerOperationAmount").comment = "Decrease per operation (actual fluid gained works like (Litre)VeinData/5000)"; - DecreasePerOperationAmount = aConfigCategory.get("DecreasePerOperationAmount") - .getInt(5); - } - // GT_FML_LOGGER.info("GT UO "+aConfigCategory.getName()+" Fluid:"+Registry+" Max:"+MaxAmount+" - // Min:"+MinAmount+" Chance:"+Chance); - } - - public Fluid getFluid() { - try { - return FluidRegistry.getFluid(this.Registry); - } catch (Exception e) { - return null; - } - } - - public int getRandomAmount(Random aRandom) { // generates some random ass number that correlates to extraction - // speeds - int smax = (int) Math.floor(Math.pow(MaxAmount * 100.d * DIVIDER, 0.2d)); // use scaled max and min values for - // the randomness to make high values - // more rare. - double smin = Math.pow(MinAmount * 100.d * DIVIDER, 0.2d); - double samount = Math.max(smin, aRandom.nextInt(smax) + aRandom.nextDouble()); - return (int) (Math.pow(samount, 5) / 100); // reverses the computation above - } -} diff --git a/src/main/java/gregtech/api/objects/ItemData.java b/src/main/java/gregtech/api/objects/ItemData.java index 779e45ac8b..071b09a55f 100644 --- a/src/main/java/gregtech/api/objects/ItemData.java +++ b/src/main/java/gregtech/api/objects/ItemData.java @@ -13,7 +13,7 @@ public class ItemData { private static final MaterialStack[] EMPTY_MATERIALSTACK_ARRAY = new MaterialStack[0]; - public final List mExtraData = new GT_ArrayList<>(false, 1); + public final List mExtraData = new GTArrayList<>(false, 1); public final OrePrefixes mPrefix; public final MaterialStack mMaterial; public final MaterialStack[] mByProducts; diff --git a/src/main/java/gregtech/api/objects/MaterialStack.java b/src/main/java/gregtech/api/objects/MaterialStack.java index 0a433e0d99..742c210901 100644 --- a/src/main/java/gregtech/api/objects/MaterialStack.java +++ b/src/main/java/gregtech/api/objects/MaterialStack.java @@ -1,7 +1,7 @@ package gregtech.api.objects; import gregtech.api.enums.Materials; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class MaterialStack implements Cloneable { @@ -44,7 +44,7 @@ public class MaterialStack implements Cloneable { public String toString(boolean single) { String temp1 = "", temp2 = mMaterial.getToolTip(true), temp3 = "", temp4 = ""; if (mAmount > 1) { - temp4 = GT_Utility.toSubscript(mAmount); + temp4 = GTUtility.toSubscript(mAmount); } if ((!single || mAmount > 1) && isMaterialListComplex(this)) { temp1 = "("; diff --git a/src/main/java/gregtech/api/objects/overclockdescriber/EUNoOverclockDescriber.java b/src/main/java/gregtech/api/objects/overclockdescriber/EUNoOverclockDescriber.java index 1e29e2d812..6f73b5467a 100644 --- a/src/main/java/gregtech/api/objects/overclockdescriber/EUNoOverclockDescriber.java +++ b/src/main/java/gregtech/api/objects/overclockdescriber/EUNoOverclockDescriber.java @@ -1,13 +1,13 @@ package gregtech.api.objects.overclockdescriber; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.ParametersAreNonnullByDefault; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.api.util.OverclockCalculator; import gregtech.nei.RecipeDisplayInfo; @ParametersAreNonnullByDefault @@ -28,13 +28,13 @@ public class EUNoOverclockDescriber extends OverclockDescriber { } @Override - public GT_OverclockCalculator createCalculator(GT_OverclockCalculator template, GT_Recipe recipe) { - return GT_OverclockCalculator.ofNoOverclock(recipe); + public OverclockCalculator createCalculator(OverclockCalculator template, GTRecipe recipe) { + return OverclockCalculator.ofNoOverclock(recipe); } @Override public String getTierString() { - return GT_Utility.getColoredTierNameFromTier(tier); + return GTUtility.getColoredTierNameFromTier(tier); } @Override @@ -60,48 +60,48 @@ public class EUNoOverclockDescriber extends OverclockDescriber { } } - protected String getTotalPowerString(GT_OverclockCalculator calculator) { - return GT_Utility.formatNumbers(calculator.getConsumption() * calculator.getDuration()) + " EU"; + protected String getTotalPowerString(OverclockCalculator calculator) { + return GTUtility.formatNumbers(calculator.getConsumption() * calculator.getDuration()) + " EU"; } /** * @return If amperage should be shown on NEI. */ - protected boolean shouldShowAmperage(GT_OverclockCalculator calculator) { + protected boolean shouldShowAmperage(OverclockCalculator calculator) { return amperage != 1; } /** * @return Whole EU/t usage, without tier display. */ - protected String getEUtWithoutTier(GT_OverclockCalculator calculator) { - return GT_Utility.formatNumbers(calculator.getConsumption()) + " EU/t"; + protected String getEUtWithoutTier(OverclockCalculator calculator) { + return GTUtility.formatNumbers(calculator.getConsumption()) + " EU/t"; } /** * @return Whole EU/t usage, with tier display. */ - protected String getEUtWithTier(GT_OverclockCalculator calculator) { - return getEUtWithoutTier(calculator) + GT_Utility.getTierNameWithParentheses(calculator.getConsumption()); + protected String getEUtWithTier(OverclockCalculator calculator) { + return getEUtWithoutTier(calculator) + GTUtility.getTierNameWithParentheses(calculator.getConsumption()); } /** * @return Whole EU/t usage. Also displays voltage tier if it should be shown. */ - protected String getEUtDisplay(GT_OverclockCalculator calculator) { + protected String getEUtDisplay(OverclockCalculator calculator) { return shouldShowAmperage(calculator) ? getEUtWithoutTier(calculator) : getEUtWithTier(calculator); } /** * @return EU/t usage, divided by amperage. With tier display. */ - protected String getVoltageString(GT_OverclockCalculator calculator) { + protected String getVoltageString(OverclockCalculator calculator) { long voltage = computeVoltageForEURate(calculator.getConsumption()); - return GT_Utility.formatNumbers(voltage) + " EU/t" + GT_Utility.getTierNameWithParentheses(voltage); + return GTUtility.formatNumbers(voltage) + " EU/t" + GTUtility.getTierNameWithParentheses(voltage); } - protected String getAmperageString(GT_OverclockCalculator calculator) { - return GT_Utility.formatNumbers(amperage); + protected String getAmperageString(OverclockCalculator calculator) { + return GTUtility.formatNumbers(amperage); } protected long computeVoltageForEURate(long euPerTick) { diff --git a/src/main/java/gregtech/api/objects/overclockdescriber/EUOverclockDescriber.java b/src/main/java/gregtech/api/objects/overclockdescriber/EUOverclockDescriber.java index 9d53711515..42b459e874 100644 --- a/src/main/java/gregtech/api/objects/overclockdescriber/EUOverclockDescriber.java +++ b/src/main/java/gregtech/api/objects/overclockdescriber/EUOverclockDescriber.java @@ -1,17 +1,17 @@ package gregtech.api.objects.overclockdescriber; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.ParametersAreNonnullByDefault; import com.google.common.primitives.Ints; -import gregtech.GT_Mod; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.GTMod; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.api.util.OverclockCalculator; import gregtech.nei.RecipeDisplayInfo; @ParametersAreNonnullByDefault @@ -23,7 +23,7 @@ public class EUOverclockDescriber extends EUNoOverclockDescriber { } @Override - public GT_OverclockCalculator createCalculator(GT_OverclockCalculator template, GT_Recipe recipe) { + public OverclockCalculator createCalculator(OverclockCalculator template, GTRecipe recipe) { return template.setEUt(Ints.saturatedCast(V[tier] * amperage)); } @@ -38,9 +38,9 @@ public class EUOverclockDescriber extends EUNoOverclockDescriber { if (shouldShowAmperage(recipeInfo.calculator)) { recipeInfo.drawText(trans("154", "Voltage: ") + getVoltageString(recipeInfo.calculator)); } - if (GT_Mod.gregtechproxy.mNEIOriginalVoltage) { + if (GTMod.gregtechproxy.mNEIOriginalVoltage) { EUNoOverclockDescriber originalPower = new EUNoOverclockDescriber(tier, amperage); - GT_OverclockCalculator originalPowerCalculator = GT_OverclockCalculator.ofNoOverclock(recipeInfo.recipe) + OverclockCalculator originalPowerCalculator = OverclockCalculator.ofNoOverclock(recipeInfo.recipe) .calculate(); recipeInfo .drawText(trans("275", "Original usage: ") + originalPower.getEUtDisplay(originalPowerCalculator)); @@ -51,30 +51,30 @@ public class EUOverclockDescriber extends EUNoOverclockDescriber { } @Override - protected String getEUtWithoutTier(GT_OverclockCalculator calculator) { + protected String getEUtWithoutTier(OverclockCalculator calculator) { return decorateWithOverclockLabel(super.getEUtWithoutTier(calculator), calculator); } @Override - protected String getEUtWithTier(GT_OverclockCalculator calculator) { - return this.getEUtWithoutTier(calculator) + GT_Utility.getTierNameWithParentheses(calculator.getConsumption()); + protected String getEUtWithTier(OverclockCalculator calculator) { + return this.getEUtWithoutTier(calculator) + GTUtility.getTierNameWithParentheses(calculator.getConsumption()); } @Override - protected String getVoltageString(GT_OverclockCalculator calculator) { + protected String getVoltageString(OverclockCalculator calculator) { long voltage = computeVoltageForEURate(calculator.getConsumption()); - return decorateWithOverclockLabel(GT_Utility.formatNumbers(voltage) + " EU/t", calculator) - + GT_Utility.getTierNameWithParentheses(voltage); + return decorateWithOverclockLabel(GTUtility.formatNumbers(voltage) + " EU/t", calculator) + + GTUtility.getTierNameWithParentheses(voltage); } - protected String decorateWithOverclockLabel(String s, GT_OverclockCalculator calculator) { + protected String decorateWithOverclockLabel(String s, OverclockCalculator calculator) { if (wasOverclocked(calculator)) { s += " (OC)"; } return s; } - protected boolean wasOverclocked(GT_OverclockCalculator calculator) { + protected boolean wasOverclocked(OverclockCalculator calculator) { return calculator.getPerformedOverclocks() > 0; } } diff --git a/src/main/java/gregtech/api/objects/overclockdescriber/FusionOverclockDescriber.java b/src/main/java/gregtech/api/objects/overclockdescriber/FusionOverclockDescriber.java index b570ebcab5..019af073f0 100644 --- a/src/main/java/gregtech/api/objects/overclockdescriber/FusionOverclockDescriber.java +++ b/src/main/java/gregtech/api/objects/overclockdescriber/FusionOverclockDescriber.java @@ -4,11 +4,11 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.util.EnumChatFormatting; -import gregtech.api.enums.GT_Values; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.enums.GTValues; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.api.util.OverclockCalculator; import gregtech.nei.formatter.FusionSpecialValueFormatter; @ParametersAreNonnullByDefault @@ -23,7 +23,7 @@ public class FusionOverclockDescriber extends EUOverclockDescriber { } @Override - public GT_OverclockCalculator createCalculator(GT_OverclockCalculator template, GT_Recipe recipe) { + public OverclockCalculator createCalculator(OverclockCalculator template, GTRecipe recipe) { return super.createCalculator(template, recipe) .limitOverclockCount(overclock(recipe.mSpecialValue, recipe.mEUt)) .setEUtIncreasePerOC(getEUtIncreasePerOC()) @@ -40,12 +40,12 @@ public class FusionOverclockDescriber extends EUOverclockDescriber { @Override public String getTierString() { - return GT_Values.TIER_COLORS[tier] + "MK " + getFusionTier() + EnumChatFormatting.RESET; + return GTValues.TIER_COLORS[tier] + "MK " + getFusionTier() + EnumChatFormatting.RESET; } @Override - public boolean canHandle(GT_Recipe recipe) { - byte tier = GT_Utility.getTier(recipe.mEUt); + public boolean canHandle(GTRecipe recipe) { + byte tier = GTUtility.getTier(recipe.mEUt); if (this.tier < tier) { return false; } diff --git a/src/main/java/gregtech/api/objects/overclockdescriber/OverclockDescriber.java b/src/main/java/gregtech/api/objects/overclockdescriber/OverclockDescriber.java index 0b253c95fa..9f995e4758 100644 --- a/src/main/java/gregtech/api/objects/overclockdescriber/OverclockDescriber.java +++ b/src/main/java/gregtech/api/objects/overclockdescriber/OverclockDescriber.java @@ -1,14 +1,14 @@ package gregtech.api.objects.overclockdescriber; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.ParametersAreNonnullByDefault; -import gregtech.GT_Mod; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.GTMod; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.api.util.OverclockCalculator; import gregtech.nei.RecipeDisplayInfo; /** @@ -45,12 +45,12 @@ public abstract class OverclockDescriber { /** * Creates overclock calculator from given template. This template should be used instead of building from the * ground to avoid issues coming from different caller using different templates, but it's not applicable when using - * {@link GT_OverclockCalculator#ofNoOverclock(GT_Recipe)}. + * {@link OverclockCalculator#ofNoOverclock(GTRecipe)}. * * @param template Calculator that can be used as template. Recipe EU/t and duration are already set. * @param recipe Recipe to calculate. */ - public abstract GT_OverclockCalculator createCalculator(GT_OverclockCalculator template, GT_Recipe recipe); + public abstract OverclockCalculator createCalculator(OverclockCalculator template, GTRecipe recipe); /** * Draws info about the energy this object can handle on NEI recipe GUI. @@ -61,7 +61,7 @@ public abstract class OverclockDescriber { if (getDurationTicks(recipeInfo.calculator) <= 0) return; String textToDraw = trans("158", "Time: "); - if (GT_Mod.gregtechproxy.mNEIRecipeSecondMode) { + if (GTMod.gregtechproxy.mNEIRecipeSecondMode) { textToDraw += getDurationStringSeconds(recipeInfo.calculator); if (getDurationSeconds(recipeInfo.calculator) <= 1.0d) { textToDraw += String.format(" (%s)", getDurationStringTicks(recipeInfo.calculator)); @@ -81,26 +81,26 @@ public abstract class OverclockDescriber { * * @return If this object can handle the supplied recipe */ - public boolean canHandle(GT_Recipe recipe) { - byte tier = GT_Utility.getTier(recipe.mEUt); + public boolean canHandle(GTRecipe recipe) { + byte tier = GTUtility.getTier(recipe.mEUt); return this.tier >= tier; } - private int getDurationTicks(GT_OverclockCalculator calculator) { + private int getDurationTicks(OverclockCalculator calculator) { return calculator.getDuration(); } - private double getDurationSeconds(GT_OverclockCalculator calculator) { + private double getDurationSeconds(OverclockCalculator calculator) { return 0.05d * getDurationTicks(calculator); } - private String getDurationStringSeconds(GT_OverclockCalculator calculator) { - return GT_Utility.formatNumbers(getDurationSeconds(calculator)) + GT_Utility.trans("161", " secs"); + private String getDurationStringSeconds(OverclockCalculator calculator) { + return GTUtility.formatNumbers(getDurationSeconds(calculator)) + GTUtility.trans("161", " secs"); } - private String getDurationStringTicks(GT_OverclockCalculator calculator) { - String ticksString = getDurationTicks(calculator) == 1 ? GT_Utility.trans("209.1", " tick") - : GT_Utility.trans("209", " ticks"); - return GT_Utility.formatNumbers(getDurationTicks(calculator)) + ticksString; + private String getDurationStringTicks(OverclockCalculator calculator) { + String ticksString = getDurationTicks(calculator) == 1 ? GTUtility.trans("209.1", " tick") + : GTUtility.trans("209", " ticks"); + return GTUtility.formatNumbers(getDurationTicks(calculator)) + ticksString; } } diff --git a/src/main/java/gregtech/api/objects/overclockdescriber/SteamOverclockDescriber.java b/src/main/java/gregtech/api/objects/overclockdescriber/SteamOverclockDescriber.java index 5da64d4028..3a2da01b08 100644 --- a/src/main/java/gregtech/api/objects/overclockdescriber/SteamOverclockDescriber.java +++ b/src/main/java/gregtech/api/objects/overclockdescriber/SteamOverclockDescriber.java @@ -1,16 +1,16 @@ package gregtech.api.objects.overclockdescriber; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.util.StatCollector; import gregtech.api.enums.SteamVariant; -import gregtech.api.util.GT_OverclockCalculator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.api.util.OverclockCalculator; import gregtech.nei.RecipeDisplayInfo; @ParametersAreNonnullByDefault @@ -34,8 +34,8 @@ public class SteamOverclockDescriber extends OverclockDescriber { } @Override - public GT_OverclockCalculator createCalculator(GT_OverclockCalculator template, GT_Recipe recipe) { - return GT_OverclockCalculator.ofNoOverclock(recipe) + public OverclockCalculator createCalculator(OverclockCalculator template, GTRecipe recipe) { + return OverclockCalculator.ofNoOverclock(recipe) .setEUtDiscount(euPerTickMultiplier) .setSpeedBoost(durationMultiplier); } @@ -48,13 +48,13 @@ public class SteamOverclockDescriber extends OverclockDescriber { recipeInfo.drawText(trans("153", "Usage: ") + getSteamUsageString(recipeInfo.calculator)); } - private String getTotalPowerString(GT_OverclockCalculator calculator) { - return GT_Utility.formatNumbers(convertEUToSteam(calculator.getConsumption() * calculator.getDuration())) + private String getTotalPowerString(OverclockCalculator calculator) { + return GTUtility.formatNumbers(convertEUToSteam(calculator.getConsumption() * calculator.getDuration())) + " Steam"; } - private String getSteamUsageString(GT_OverclockCalculator calculator) { - return GT_Utility.formatNumbers(20 * convertEUToSteam(calculator.getConsumption())) + " L/s Steam"; + private String getSteamUsageString(OverclockCalculator calculator) { + return GTUtility.formatNumbers(20 * convertEUToSteam(calculator.getConsumption())) + " L/s Steam"; } private static long convertEUToSteam(long eu) { diff --git a/src/main/java/gregtech/api/recipe/BasicUIPropertiesBuilder.java b/src/main/java/gregtech/api/recipe/BasicUIPropertiesBuilder.java index 7be2c94b23..adb2ee40e8 100644 --- a/src/main/java/gregtech/api/recipe/BasicUIPropertiesBuilder.java +++ b/src/main/java/gregtech/api/recipe/BasicUIPropertiesBuilder.java @@ -20,7 +20,7 @@ import com.gtnewhorizons.modularui.api.math.Size; import com.gtnewhorizons.modularui.common.widget.ProgressBar; import gregtech.api.gui.modularui.FallbackableSteamTexture; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.gui.modularui.SteamTexture; import gregtech.api.util.MethodsReturnNonnullByDefault; import gregtech.common.gui.modularui.UIHelper; @@ -59,7 +59,7 @@ public final class BasicUIPropertiesBuilder { private final ImmutableList.Builder>> specialTexturesSteam = ImmutableList .builder(); - private IDrawable logo = GT_UITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT; + private IDrawable logo = GTUITextures.PICTURE_GT_LOGO_17x17_TRANSPARENT; private Size logoSize = new Size(17, 17); private Pos2d logoPos = new Pos2d(152, 63); diff --git a/src/main/java/gregtech/api/recipe/FindRecipeQuery.java b/src/main/java/gregtech/api/recipe/FindRecipeQuery.java index 77c0648688..16702b6be6 100644 --- a/src/main/java/gregtech/api/recipe/FindRecipeQuery.java +++ b/src/main/java/gregtech/api/recipe/FindRecipeQuery.java @@ -9,7 +9,7 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; // spotless:off spotless likes formatting @code to @code @@ -20,7 +20,7 @@ import gregtech.api.util.MethodsReturnNonnullByDefault; * *
  * {@code
- *     GT_Recipe recipe = recipeMap.findRecipeQuery()
+ *     GTRecipe recipe = recipeMap.findRecipeQuery()
  *         .items(inputItems)
  *         .fluids(inputFluids)
  *         .find();
@@ -33,7 +33,7 @@ import gregtech.api.util.MethodsReturnNonnullByDefault;
 @MethodsReturnNonnullByDefault
 public final class FindRecipeQuery {
 
-    private static final Predicate ALWAYS = r -> true;
+    private static final Predicate ALWAYS = r -> true;
 
     private final RecipeMap recipeMap;
 
@@ -43,10 +43,10 @@ public final class FindRecipeQuery {
     private FluidStack[] fluids;
     @Nullable
     private ItemStack specialSlot;
-    private Predicate filter = ALWAYS;
+    private Predicate filter = ALWAYS;
     private long voltage = Integer.MAX_VALUE;
     @Nullable
-    private GT_Recipe cachedRecipe;
+    private GTRecipe cachedRecipe;
     private boolean notUnificated;
     private boolean dontCheckStackSizes;
     private boolean forCollisionCheck;
@@ -61,7 +61,7 @@ public final class FindRecipeQuery {
      * @return The first matched recipe, or null if not found.
      */
     @Nullable
-    public GT_Recipe find() {
+    public GTRecipe find() {
         return findAll().findFirst()
             .orElse(null);
     }
@@ -69,7 +69,7 @@ public final class FindRecipeQuery {
     /**
      * @return All the matched recipes in the form of Stream.
      */
-    public Stream findAll() {
+    public Stream findAll() {
         if (items == null) {
             items = new ItemStack[0];
         }
@@ -135,7 +135,7 @@ public final class FindRecipeQuery {
      * @param filter Matched recipe will be tested by this function. If it returns false, the query will attempt to
      *               find next recipe.
      */
-    public FindRecipeQuery filter(Predicate filter) {
+    public FindRecipeQuery filter(Predicate filter) {
         this.filter = filter;
         return this;
     }
@@ -152,7 +152,7 @@ public final class FindRecipeQuery {
     /**
      * @param cachedRecipe If this is not null, the query tests it before all other recipes.
      */
-    public FindRecipeQuery cachedRecipe(@Nullable GT_Recipe cachedRecipe) {
+    public FindRecipeQuery cachedRecipe(@Nullable GTRecipe cachedRecipe) {
         this.cachedRecipe = cachedRecipe;
         return this;
     }
diff --git a/src/main/java/gregtech/api/recipe/NEIRecipeProperties.java b/src/main/java/gregtech/api/recipe/NEIRecipeProperties.java
index 2ba49f5da1..1b62ca0390 100644
--- a/src/main/java/gregtech/api/recipe/NEIRecipeProperties.java
+++ b/src/main/java/gregtech/api/recipe/NEIRecipeProperties.java
@@ -12,7 +12,7 @@ import com.gtnewhorizons.modularui.api.math.Size;
 import codechicken.nei.recipe.HandlerInfo;
 import gregtech.api.objects.overclockdescriber.OverclockDescriber;
 import gregtech.api.util.FieldsAreNonnullByDefault;
-import gregtech.api.util.GT_Recipe;
+import gregtech.api.util.GTRecipe;
 import gregtech.api.util.MethodsReturnNonnullByDefault;
 import gregtech.nei.formatter.INEISpecialInfoFormatter;
 
@@ -49,7 +49,7 @@ public final class NEIRecipeProperties {
     public final Pos2d recipeBackgroundOffset;
 
     /**
-     * Formats special description for the recipe, mainly {@link gregtech.api.util.GT_Recipe#mSpecialValue}.
+     * Formats special description for the recipe, mainly {@link GTRecipe#mSpecialValue}.
      */
     public final INEISpecialInfoFormatter neiSpecialInfoFormatter;
 
@@ -68,14 +68,14 @@ public final class NEIRecipeProperties {
     public final boolean renderRealStackSizes;
 
     /**
-     * Comparator for NEI recipe sort. {@link GT_Recipe#compareTo(GT_Recipe)} by default.
+     * Comparator for NEI recipe sort. {@link GTRecipe#compareTo(GTRecipe)} by default.
      */
-    public final Comparator comparator;
+    public final Comparator comparator;
 
     NEIRecipeProperties(boolean registerNEI, @Nullable UnaryOperator handlerInfoCreator,
         Size recipeBackgroundSize, Pos2d recipeBackgroundOffset, INEISpecialInfoFormatter neiSpecialInfoFormatter,
         boolean unificateOutput, boolean useCustomFilter, boolean renderRealStackSizes,
-        Comparator comparator) {
+        Comparator comparator) {
         this.registerNEI = registerNEI;
         this.handlerInfoCreator = handlerInfoCreator;
         this.recipeBackgroundOffset = recipeBackgroundOffset;
diff --git a/src/main/java/gregtech/api/recipe/NEIRecipePropertiesBuilder.java b/src/main/java/gregtech/api/recipe/NEIRecipePropertiesBuilder.java
index 050a1c4920..3b47e9ce13 100644
--- a/src/main/java/gregtech/api/recipe/NEIRecipePropertiesBuilder.java
+++ b/src/main/java/gregtech/api/recipe/NEIRecipePropertiesBuilder.java
@@ -10,7 +10,7 @@ import com.gtnewhorizons.modularui.api.math.Pos2d;
 import com.gtnewhorizons.modularui.api.math.Size;
 
 import codechicken.nei.recipe.HandlerInfo;
-import gregtech.api.util.GT_Recipe;
+import gregtech.api.util.GTRecipe;
 import gregtech.api.util.MethodsReturnNonnullByDefault;
 import gregtech.nei.formatter.DefaultSpecialValueFormatter;
 import gregtech.nei.formatter.INEISpecialInfoFormatter;
@@ -36,7 +36,7 @@ public final class NEIRecipePropertiesBuilder {
     private boolean useCustomFilter;
     private boolean renderRealStackSizes = true;
 
-    private Comparator comparator = GT_Recipe::compareTo;
+    private Comparator comparator = GTRecipe::compareTo;
 
     NEIRecipePropertiesBuilder() {}
 
@@ -93,7 +93,7 @@ public final class NEIRecipePropertiesBuilder {
         return this;
     }
 
-    public NEIRecipePropertiesBuilder recipeComparator(Comparator comparator) {
+    public NEIRecipePropertiesBuilder recipeComparator(Comparator comparator) {
         this.comparator = comparator;
         return this;
     }
diff --git a/src/main/java/gregtech/api/recipe/RecipeMap.java b/src/main/java/gregtech/api/recipe/RecipeMap.java
index 46b32d18dd..669c7de2cf 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMap.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMap.java
@@ -1,6 +1,6 @@
 package gregtech.api.recipe;
 
-import static gregtech.api.util.GT_RecipeBuilder.ENABLE_COLLISION_CHECK;
+import static gregtech.api.util.GTRecipeBuilder.ENABLE_COLLISION_CHECK;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -23,8 +23,8 @@ import org.jetbrains.annotations.Unmodifiable;
 import gregtech.api.interfaces.IRecipeMap;
 import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords;
 import gregtech.api.util.FieldsAreNonnullByDefault;
-import gregtech.api.util.GT_Recipe;
-import gregtech.api.util.GT_RecipeBuilder;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTRecipeBuilder;
 import gregtech.api.util.MethodsReturnNonnullByDefault;
 
 /**
@@ -82,7 +82,7 @@ public final class RecipeMap implements IRecipeMap {
      * @return All the recipes belonging to this recipemap.
      */
     @Unmodifiable
-    public Collection getAllRecipes() {
+    public Collection getAllRecipes() {
         return backend.getAllRecipes();
     }
 
@@ -116,13 +116,13 @@ public final class RecipeMap implements IRecipeMap {
     // region add recipe
     @Deprecated
     @Nullable
-    public GT_Recipe addRecipe(GT_Recipe aRecipe) {
+    public GTRecipe addRecipe(GTRecipe aRecipe) {
         return addRecipe(aRecipe, true, false, false);
     }
 
     @Deprecated
     @Nullable
-    public GT_Recipe addRecipe(GT_Recipe aRecipe, boolean aCheckForCollisions, boolean aFakeRecipe, boolean aHidden) {
+    public GTRecipe addRecipe(GTRecipe aRecipe, boolean aCheckForCollisions, boolean aFakeRecipe, boolean aHidden) {
         aRecipe.mHidden = aHidden;
         aRecipe.mFakeRecipe = aFakeRecipe;
         if (aRecipe.mFluidInputs.length < backend.properties.minFluidInputs
@@ -137,13 +137,13 @@ public final class RecipeMap implements IRecipeMap {
      */
     @Deprecated
     @Nullable
-    public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, @Nullable ItemStack[] aInputs,
+    public GTRecipe addFakeRecipe(boolean aCheckForCollisions, @Nullable ItemStack[] aInputs,
         @Nullable ItemStack[] aOutputs, @Nullable Object aSpecial, @Nullable FluidStack[] aFluidInputs,
         @Nullable FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue, ItemStack[][] aAlt,
         boolean hidden) {
         return addFakeRecipe(
             aCheckForCollisions,
-            new GT_Recipe.GT_Recipe_WithAlt(
+            new GTRecipe.GTRecipe_WithAlt(
                 false,
                 aInputs,
                 aOutputs,
@@ -164,23 +164,23 @@ public final class RecipeMap implements IRecipeMap {
      */
     @Deprecated
     @Nullable
-    public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, GT_Recipe aRecipe) {
+    public GTRecipe addFakeRecipe(boolean aCheckForCollisions, GTRecipe aRecipe) {
         return addRecipe(aRecipe, aCheckForCollisions, true, false);
     }
 
     @Deprecated
     @Nullable
-    public GT_Recipe addFakeRecipe(boolean aCheckForCollisions, GT_Recipe aRecipe, boolean hidden) {
+    public GTRecipe addFakeRecipe(boolean aCheckForCollisions, GTRecipe aRecipe, boolean hidden) {
         return addRecipe(aRecipe, aCheckForCollisions, true, hidden);
     }
 
     @Nonnull
     @Override
-    public Collection doAdd(GT_RecipeBuilder builder) {
+    public Collection doAdd(GTRecipeBuilder builder) {
         return backend.doAdd(builder);
     }
 
-    public GT_Recipe add(GT_Recipe aRecipe) {
+    public GTRecipe add(GTRecipe aRecipe) {
         return backend.compileRecipe(aRecipe);
     }
 
@@ -217,26 +217,26 @@ public final class RecipeMap implements IRecipeMap {
     }
 
     @Nullable
-    public GT_Recipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated, long aVoltage,
+    public GTRecipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated, long aVoltage,
         @Nullable FluidStack[] aFluids, @Nullable ItemStack... aInputs) {
         return findRecipe(aTileEntity, null, aNotUnificated, aVoltage, aFluids, null, aInputs);
     }
 
     @Nullable
-    public GT_Recipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated,
+    public GTRecipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, boolean aNotUnificated,
         boolean aDontCheckStackSizes, long aVoltage, @Nullable FluidStack[] aFluids, @Nullable ItemStack... aInputs) {
         return findRecipe(aTileEntity, null, aNotUnificated, aDontCheckStackSizes, aVoltage, aFluids, null, aInputs);
     }
 
     @Nullable
-    public GT_Recipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, @Nullable GT_Recipe aRecipe,
+    public GTRecipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, @Nullable GTRecipe aRecipe,
         boolean aNotUnificated, long aVoltage, @Nullable FluidStack[] aFluids, @Nullable ItemStack aSpecialSlot,
         @Nullable ItemStack... aInputs) {
         return findRecipe(aTileEntity, aRecipe, aNotUnificated, false, aVoltage, aFluids, aSpecialSlot, aInputs);
     }
 
     @Nullable
-    public GT_Recipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, @Nullable GT_Recipe aRecipe,
+    public GTRecipe findRecipe(@Nullable IHasWorldObjectAndCoords aTileEntity, @Nullable GTRecipe aRecipe,
         boolean aNotUnificated, boolean aDontCheckStackSizes, long aVoltage, @Nullable FluidStack[] aFluids,
         @Nullable ItemStack aSpecialSlot, @Nullable ItemStack... aInputs) {
         return findRecipeQuery().items(aInputs != null ? aInputs : new ItemStack[0])
diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBackend.java b/src/main/java/gregtech/api/recipe/RecipeMapBackend.java
index 8ba0895a7f..f78e367adf 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMapBackend.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMapBackend.java
@@ -1,9 +1,9 @@
 package gregtech.api.recipe;
 
-import static gregtech.api.util.GT_RecipeBuilder.ENABLE_COLLISION_CHECK;
-import static gregtech.api.util.GT_RecipeBuilder.handleInvalidRecipe;
-import static gregtech.api.util.GT_RecipeBuilder.handleRecipeCollision;
-import static gregtech.api.util.GT_Utility.areStacksEqualOrNull;
+import static gregtech.api.util.GTRecipeBuilder.ENABLE_COLLISION_CHECK;
+import static gregtech.api.util.GTRecipeBuilder.handleInvalidRecipe;
+import static gregtech.api.util.GTRecipeBuilder.handleRecipeCollision;
+import static gregtech.api.util.GTUtility.areStacksEqualOrNull;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,13 +28,13 @@ import org.jetbrains.annotations.Unmodifiable;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.SetMultimap;
 
-import gregtech.api.GregTech_API;
+import gregtech.api.GregTechAPI;
 import gregtech.api.interfaces.IRecipeMap;
-import gregtech.api.objects.GT_ItemStack;
-import gregtech.api.util.GT_OreDictUnificator;
-import gregtech.api.util.GT_Recipe;
-import gregtech.api.util.GT_RecipeBuilder;
-import gregtech.api.util.GT_StreamUtil;
+import gregtech.api.objects.GTItemStack;
+import gregtech.api.util.GTOreDictUnificator;
+import gregtech.api.util.GTRecipe;
+import gregtech.api.util.GTRecipeBuilder;
+import gregtech.api.util.GTStreamUtil;
 import gregtech.api.util.MethodsReturnNonnullByDefault;
 
 /**
@@ -52,16 +52,16 @@ public class RecipeMapBackend {
     /**
      * Recipe index based on items.
      */
-    private final SetMultimap itemIndex = HashMultimap.create();
+    private final SetMultimap itemIndex = HashMultimap.create();
     /**
      * Recipe index based on fluids.
      */
-    private final SetMultimap fluidIndex = HashMultimap.create();
+    private final SetMultimap fluidIndex = HashMultimap.create();
 
     /**
      * All the recipes belonging to this backend, indexed by recipe category.
      */
-    private final Map> recipesByCategory = new HashMap<>();
+    private final Map> recipesByCategory = new HashMap<>();
 
     /**
      * List of recipemaps that also receive recipe addition from this backend.
@@ -75,7 +75,7 @@ public class RecipeMapBackend {
 
     public RecipeMapBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) {
         this.properties = propertiesBuilder.build();
-        GregTech_API.itemStackMultiMaps.add(itemIndex);
+        GregTechAPI.itemStackMultiMaps.add(itemIndex);
     }
 
     void setRecipeMap(RecipeMap recipeMap) {
@@ -94,14 +94,14 @@ public class RecipeMapBackend {
      *         use {@link #compileRecipe} to add / {@link #removeRecipes} to remove.
      */
     @Unmodifiable
-    public Collection getAllRecipes() {
+    public Collection getAllRecipes() {
         return Collections.unmodifiableCollection(allRecipes());
     }
 
     /**
      * @return Raw recipe list
      */
-    private Collection allRecipes() {
+    private Collection allRecipes() {
         return recipesByCategory.values()
             .stream()
             .flatMap(Collection::stream)
@@ -112,13 +112,13 @@ public class RecipeMapBackend {
      * @return All the recipes belonging to this backend, indexed by recipe category.
      */
     @Unmodifiable
-    public Collection getRecipesByCategory(RecipeCategory recipeCategory) {
+    public Collection getRecipesByCategory(RecipeCategory recipeCategory) {
         return Collections
             .unmodifiableCollection(recipesByCategory.getOrDefault(recipeCategory, Collections.emptyList()));
     }
 
     @Unmodifiable
-    public Map> getRecipeCategoryMap() {
+    public Map> getRecipeCategoryMap() {
         return Collections.unmodifiableMap(recipesByCategory);
     }
 
@@ -129,7 +129,7 @@ public class RecipeMapBackend {
      *
      * @return Supplied recipe.
      */
-    public GT_Recipe compileRecipe(GT_Recipe recipe) {
+    public GTRecipe compileRecipe(GTRecipe recipe) {
         if (recipe.getRecipeCategory() == null) {
             recipe.setRecipeCategory(recipeMap.getDefaultRecipeCategory());
         }
@@ -148,17 +148,17 @@ public class RecipeMapBackend {
     /**
      * Adds the supplied recipe to the item cache.
      */
-    protected GT_Recipe addToItemMap(GT_Recipe recipe) {
+    protected GTRecipe addToItemMap(GTRecipe recipe) {
         for (ItemStack item : recipe.mInputs) {
             if (item == null) continue;
-            itemIndex.put(new GT_ItemStack(item), recipe);
+            itemIndex.put(new GTItemStack(item), recipe);
         }
-        if (recipe instanceof GT_Recipe.GT_Recipe_WithAlt recipeWithAlt) {
+        if (recipe instanceof GTRecipe.GTRecipe_WithAlt recipeWithAlt) {
             for (ItemStack[] itemStacks : recipeWithAlt.mOreDictAlt) {
                 if (itemStacks == null) continue;
                 for (ItemStack item : itemStacks) {
                     if (item == null) continue;
-                    itemIndex.put(new GT_ItemStack(item), recipe);
+                    itemIndex.put(new GTItemStack(item), recipe);
                 }
             }
         }
@@ -168,10 +168,10 @@ public class RecipeMapBackend {
     /**
      * Builds recipe from supplied recipe builder and adds it.
      */
-    protected Collection doAdd(GT_RecipeBuilder builder) {
-        Iterable recipes = properties.recipeEmitter.apply(builder);
-        Collection ret = new ArrayList<>();
-        for (GT_Recipe recipe : recipes) {
+    protected Collection doAdd(GTRecipeBuilder builder) {
+        Iterable recipes = properties.recipeEmitter.apply(builder);
+        Collection ret = new ArrayList<>();
+        for (GTRecipe recipe : recipes) {
             if (recipe.mFluidInputs.length < properties.minFluidInputs
                 || recipe.mInputs.length < properties.minItemInputs) {
                 return Collections.emptyList();
@@ -199,7 +199,7 @@ public class RecipeMapBackend {
         return ret;
     }
 
-    private void handleCollision(GT_Recipe recipe) {
+    private void handleCollision(GTRecipe recipe) {
         StringBuilder errorInfo = new StringBuilder();
         boolean hasAnEntry = false;
         for (FluidStack fluid : recipe.mFluidInputs) {
@@ -241,11 +241,11 @@ public class RecipeMapBackend {
     /**
      * Removes supplied recipes from recipe list. Do not use unless absolute necessity!
      */
-    public void removeRecipes(Collection recipesToRemove) {
-        for (Collection recipes : recipesByCategory.values()) {
+    public void removeRecipes(Collection recipesToRemove) {
+        for (Collection recipes : recipesByCategory.values()) {
             recipes.removeAll(recipesToRemove);
         }
-        for (GT_ItemStack key : new HashMap<>(itemIndex.asMap()).keySet()) {
+        for (GTItemStack key : new HashMap<>(itemIndex.asMap()).keySet()) {
             itemIndex.get(key)
                 .removeAll(recipesToRemove);
         }
@@ -258,7 +258,7 @@ public class RecipeMapBackend {
     /**
      * Removes supplied recipe from recipe list. Do not use unless absolute necessity!
      */
-    public void removeRecipe(GT_Recipe recipe) {
+    public void removeRecipe(GTRecipe recipe) {
         removeRecipes(Collections.singleton(recipe));
     }
 
@@ -276,9 +276,9 @@ public class RecipeMapBackend {
      */
     public void reInit() {
         itemIndex.clear();
-        for (GT_Recipe recipe : allRecipes()) {
-            GT_OreDictUnificator.setStackArray(true, recipe.mInputs);
-            GT_OreDictUnificator.setStackArray(true, recipe.mOutputs);
+        for (GTRecipe recipe : allRecipes()) {
+            GTOreDictUnificator.setStackArray(true, recipe.mInputs);
+            GTOreDictUnificator.setStackArray(true, recipe.mOutputs);
             addToItemMap(recipe);
         }
     }
@@ -287,7 +287,7 @@ public class RecipeMapBackend {
      * @return If supplied item is a valid input for any of the recipes
      */
     public boolean containsInput(ItemStack item) {
-        return itemIndex.containsKey(new GT_ItemStack(item)) || itemIndex.containsKey(new GT_ItemStack(item, true));
+        return itemIndex.containsKey(new GTItemStack(item)) || itemIndex.containsKey(new GTItemStack(item, true));
     }
 
     /**
@@ -304,7 +304,7 @@ public class RecipeMapBackend {
      *
      * @return True if collision is found.
      */
-    boolean checkCollision(GT_Recipe recipe) {
+    boolean checkCollision(GTRecipe recipe) {
         return matchRecipeStream(recipe.mInputs, recipe.mFluidInputs, null, null, false, true, true).findAny()
             .isPresent();
     }
@@ -313,8 +313,8 @@ public class RecipeMapBackend {
      * Overwrites {@link #matchRecipeStream} method. Also override {@link #doesOverwriteFindRecipe} to make it work.
      */
     @Nullable
-    protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot,
-        @Nullable GT_Recipe cachedRecipe) {
+    protected GTRecipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot,
+        @Nullable GTRecipe cachedRecipe) {
         return null;
     }
 
@@ -329,7 +329,7 @@ public class RecipeMapBackend {
      * Modifies successfully found recipe. Make sure not to mutate the found recipe but use copy!
      */
     @Nullable
-    protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids,
+    protected GTRecipe modifyFoundRecipe(GTRecipe recipe, ItemStack[] items, FluidStack[] fluids,
         @Nullable ItemStack specialSlot) {
         return recipe;
     }
@@ -338,7 +338,7 @@ public class RecipeMapBackend {
      * Called when {@link #matchRecipeStream} cannot find recipe.
      */
     @Nullable
-    protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) {
+    protected GTRecipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) {
         return null;
     }
 
@@ -357,11 +357,11 @@ public class RecipeMapBackend {
      * @param forCollisionCheck   If this method is called to check collision with already registered recipes.
      * @return Stream of matches recipes.
      */
-    Stream matchRecipeStream(ItemStack[] rawItems, FluidStack[] fluids, @Nullable ItemStack specialSlot,
-        @Nullable GT_Recipe cachedRecipe, boolean notUnificated, boolean dontCheckStackSizes,
+    Stream matchRecipeStream(ItemStack[] rawItems, FluidStack[] fluids, @Nullable ItemStack specialSlot,
+        @Nullable GTRecipe cachedRecipe, boolean notUnificated, boolean dontCheckStackSizes,
         boolean forCollisionCheck) {
         if (doesOverwriteFindRecipe()) {
-            return GT_StreamUtil.ofNullable(overwriteFindRecipe(rawItems, fluids, specialSlot, cachedRecipe));
+            return GTStreamUtil.ofNullable(overwriteFindRecipe(rawItems, fluids, specialSlot, cachedRecipe));
         }
 
         if (recipesByCategory.isEmpty()) {
@@ -393,22 +393,22 @@ public class RecipeMapBackend {
         ItemStack[] items;
         // Unification happens here in case the item input isn't already unificated.
         if (notUnificated) {
-            items = GT_OreDictUnificator.getStackArray(true, (Object[]) rawItems);
+            items = GTOreDictUnificator.getStackArray(true, (Object[]) rawItems);
         } else {
             items = rawItems;
         }
 
-        return Stream.>of(
+        return Stream.>of(
             // Check the recipe which has been used last time in order to not have to search for it again, if possible.
-            GT_StreamUtil.ofNullable(cachedRecipe)
+            GTStreamUtil.ofNullable(cachedRecipe)
                 .filter(recipe -> recipe.mCanBeBuffered)
                 .filter(recipe -> filterFindRecipe(recipe, items, fluids, specialSlot, dontCheckStackSizes))
                 .map(recipe -> modifyFoundRecipe(recipe, items, fluids, specialSlot))
                 .filter(Objects::nonNull),
             // Now look for the recipes inside the item index, but only when the recipes actually can have items inputs.
-            GT_StreamUtil.ofConditional(!itemIndex.isEmpty(), items)
+            GTStreamUtil.ofConditional(!itemIndex.isEmpty(), items)
                 .filter(Objects::nonNull)
-                .flatMap(item -> Stream.of(new GT_ItemStack(item), new GT_ItemStack(item, true)))
+                .flatMap(item -> Stream.of(new GTItemStack(item), new GTItemStack(item, true)))
                 .map(itemIndex::get)
                 .flatMap(Collection::stream)
                 .filter(recipe -> filterFindRecipe(recipe, items, fluids, specialSlot, dontCheckStackSizes))
@@ -416,7 +416,7 @@ public class RecipeMapBackend {
                 .filter(Objects::nonNull),
             // If the minimum amount of items required for the recipes is 0, then it could match to fluid-only recipes,
             // so check fluid index too.
-            GT_StreamUtil.ofConditional(properties.minItemInputs == 0, fluids)
+            GTStreamUtil.ofConditional(properties.minItemInputs == 0, fluids)
                 .filter(Objects::nonNull)
                 .map(
                     fluidStack -> fluidIndex.get(
@@ -428,7 +428,7 @@ public class RecipeMapBackend {
                 .filter(Objects::nonNull),
             // Lastly, find fallback.
             forCollisionCheck ? Stream.empty()
-                : GT_StreamUtil.ofSupplier(() -> findFallback(items, fluids, specialSlot))
+                : GTStreamUtil.ofSupplier(() -> findFallback(items, fluids, specialSlot))
                     .filter(Objects::nonNull))
             .flatMap(Function.identity());
     }
@@ -440,7 +440,7 @@ public class RecipeMapBackend {
      * 

* Note that this won't be called if {@link #doesOverwriteFindRecipe} is true. */ - protected boolean filterFindRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + protected boolean filterFindRecipe(GTRecipe recipe, ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, boolean dontCheckStackSizes) { if (recipe.mEnabled && !recipe.mFakeRecipe && recipe.isRecipeInputEqual(false, dontCheckStackSizes, fluids, items)) { diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java b/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java index 0cd08279a7..47c400a3dd 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java +++ b/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java @@ -6,8 +6,8 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import gregtech.api.util.FieldsAreNonnullByDefault; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -44,18 +44,18 @@ public final class RecipeMapBackendProperties { /** * Changes how recipes are emitted by a particular recipe builder. */ - public final Function> recipeEmitter; + public final Function> recipeEmitter; /** * Runs a custom hook on all recipes added via builder. */ @Nullable - public final Function recipeTransformer; + public final Function recipeTransformer; RecipeMapBackendProperties(int minItemInputs, int minFluidInputs, boolean specialSlotSensitive, boolean disableOptimize, - Function> recipeEmitter, - @Nullable Function recipeTransformer) { + Function> recipeEmitter, + @Nullable Function recipeTransformer) { if (minItemInputs < 0 || minFluidInputs < 0) { throw new IllegalArgumentException("minItemInputs and minFluidInputs cannot be negative"); } diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java b/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java index 48a27fa42e..aad0748fa9 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java +++ b/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java @@ -1,6 +1,6 @@ package gregtech.api.recipe; -import static gregtech.api.util.GT_RecipeMapUtil.buildOrEmpty; +import static gregtech.api.util.GTRecipeMapUtil.buildOrEmpty; import java.util.function.Function; @@ -9,8 +9,8 @@ import javax.annotation.ParametersAreNonnullByDefault; import com.google.common.collect.Iterables; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -28,10 +28,10 @@ public final class RecipeMapBackendPropertiesBuilder { private boolean disableOptimize; - private Function> recipeEmitter = this::defaultBuildRecipe; + private Function> recipeEmitter = this::defaultBuildRecipe; @Nullable - private Function recipeTransformer; + private Function recipeTransformer; RecipeMapBackendPropertiesBuilder() {} @@ -66,40 +66,40 @@ public final class RecipeMapBackendPropertiesBuilder { } public RecipeMapBackendPropertiesBuilder recipeEmitter( - Function> recipeEmitter) { + Function> recipeEmitter) { this.recipeEmitter = recipeEmitter; return this; } public RecipeMapBackendPropertiesBuilder combineRecipeEmitter( - Function> func) { + Function> func) { // move recipeEmitter to local variable, so lambda capture the function itself instead of this - Function> cur = this.recipeEmitter; + Function> cur = this.recipeEmitter; return recipeEmitter(b -> Iterables.concat(cur.apply(b), func.apply(b))); } public RecipeMapBackendPropertiesBuilder recipeTransformer( - Function recipeTransformer) { + Function recipeTransformer) { this.recipeTransformer = recipeTransformer; return this; } public RecipeMapBackendPropertiesBuilder chainRecipeTransformer( - Function func) { + Function func) { this.recipeTransformer = this.recipeTransformer == null ? func : this.recipeTransformer.andThen(func); return this; } - private Iterable defaultBuildRecipe(GT_RecipeBuilder builder) { + private Iterable defaultBuildRecipe(GTRecipeBuilder builder) { // TODO sensible validation - GT_RecipeBuilder b = builder; + GTRecipeBuilder b = builder; if (disableOptimize && builder.isOptimize()) { b = copy(builder, b).noOptimize(); } return buildOrEmpty(b); } - private static GT_RecipeBuilder copy(GT_RecipeBuilder original, GT_RecipeBuilder b) { + private static GTRecipeBuilder copy(GTRecipeBuilder original, GTRecipeBuilder b) { return b == original ? b.copy() : b; } } diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java b/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java index a1638a5a34..2b7bc39066 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java +++ b/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java @@ -20,11 +20,11 @@ import com.gtnewhorizons.modularui.common.widget.ProgressBar; import codechicken.nei.recipe.HandlerInfo; import gregtech.api.gui.modularui.FallbackableSteamTexture; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.gui.modularui.SteamTexture; import gregtech.api.objects.overclockdescriber.OverclockDescriber; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; import gregtech.api.util.MethodsReturnNonnullByDefault; import gregtech.nei.formatter.INEISpecialInfoFormatter; @@ -84,7 +84,7 @@ public final class RecipeMapBuilder { this.unlocalizedName = unlocalizedName; this.backendCreator = backendCreator; this.uiPropertiesBuilder = BasicUIProperties.builder() - .progressBarTexture(GT_UITextures.fallbackableProgressbar(unlocalizedName, GT_UITextures.PROGRESSBAR_ARROW)) + .progressBarTexture(GTUITextures.fallbackableProgressbar(unlocalizedName, GTUITextures.PROGRESSBAR_ARROW)) .neiTransferRectId(unlocalizedName); } @@ -119,7 +119,7 @@ public final class RecipeMapBuilder { * Changes how recipes are emitted by a particular recipe builder. Can emit multiple recipe per builder. */ public RecipeMapBuilder recipeEmitter( - Function> recipeEmitter) { + Function> recipeEmitter) { backendPropertiesBuilder.recipeEmitter(recipeEmitter); return this; } @@ -130,7 +130,7 @@ public final class RecipeMapBuilder { * Recipes added via one of the overloads of addRecipe will NOT be affected by this function. */ public RecipeMapBuilder recipeEmitterSingle( - Function recipeEmitter) { + Function recipeEmitter) { return recipeEmitter(recipeEmitter.andThen(Collections::singletonList)); } @@ -142,7 +142,7 @@ public final class RecipeMapBuilder { * Unlike {@link #recipeEmitter(Function)}, this one does not clear the existing recipe being emitted, if any */ public RecipeMapBuilder combineRecipeEmitter( - Function> recipeEmitter) { + Function> recipeEmitter) { backendPropertiesBuilder.combineRecipeEmitter(recipeEmitter); return this; } @@ -156,7 +156,7 @@ public final class RecipeMapBuilder { * Unlike {@link #recipeEmitter(Function)}, this one does not clear the existing recipe being emitted, if any */ public RecipeMapBuilder combineRecipeEmitterSingle( - Function recipeEmitter) { + Function recipeEmitter) { return combineRecipeEmitter(recipeEmitter.andThen(Collections::singletonList)); } @@ -166,7 +166,7 @@ public final class RecipeMapBuilder { *

* Recipes added via one of the overloads of addRecipe will NOT be affected by this function. */ - public RecipeMapBuilder recipeTransformer(Function recipeTransformer) { + public RecipeMapBuilder recipeTransformer(Function recipeTransformer) { backendPropertiesBuilder.recipeTransformer(recipeTransformer); return this; } @@ -177,7 +177,7 @@ public final class RecipeMapBuilder { *

* Recipes added via one of the overloads of addRecipe will NOT be affected by this function. */ - public RecipeMapBuilder recipeTransformer(Consumer recipeTransformer) { + public RecipeMapBuilder recipeTransformer(Consumer recipeTransformer) { return recipeTransformer(withIdentityReturn(recipeTransformer)); } @@ -191,7 +191,7 @@ public final class RecipeMapBuilder { * The supplied function will be given the output of existing handler when a recipe is added. */ public RecipeMapBuilder chainRecipeTransformer( - Function recipeTransformer) { + Function recipeTransformer) { backendPropertiesBuilder.chainRecipeTransformer(recipeTransformer); return this; } @@ -205,7 +205,7 @@ public final class RecipeMapBuilder { * Unlike {@link #recipeTransformer(Function)}, this one will not replace the existing special handler. * The supplied function will be given the output of existing handler when a recipe is added. */ - public RecipeMapBuilder chainRecipeTransformer(Consumer recipeTransformer) { + public RecipeMapBuilder chainRecipeTransformer(Consumer recipeTransformer) { return chainRecipeTransformer(withIdentityReturn(recipeTransformer)); } @@ -250,7 +250,7 @@ public final class RecipeMapBuilder { * By default, it's set to {@code GT_UITextures.PROGRESSBAR_ARROW, ProgressBar.Direction.RIGHT}. */ public RecipeMapBuilder progressBar(UITexture texture, ProgressBar.Direction direction) { - return progressBarWithFallback(GT_UITextures.fallbackableProgressbar(unlocalizedName, texture), direction); + return progressBarWithFallback(GTUITextures.fallbackableProgressbar(unlocalizedName, texture), direction); } /** @@ -438,7 +438,7 @@ public final class RecipeMapBuilder { } /** - * Sets formatter for special description for the recipe, mainly {@link gregtech.api.util.GT_Recipe#mSpecialValue}. + * Sets formatter for special description for the recipe, mainly {@link GTRecipe#mSpecialValue}. */ public RecipeMapBuilder neiSpecialInfoFormatter(INEISpecialInfoFormatter neiSpecialInfoFormatter) { neiPropertiesBuilder.neiSpecialInfoFormatter(neiSpecialInfoFormatter); @@ -478,7 +478,7 @@ public final class RecipeMapBuilder { /** * Sets custom comparator for NEI recipe sort. */ - public RecipeMapBuilder neiRecipeComparator(Comparator comparator) { + public RecipeMapBuilder neiRecipeComparator(Comparator comparator) { neiPropertiesBuilder.recipeComparator(comparator); return this; } diff --git a/src/main/java/gregtech/api/recipe/RecipeMapFrontend.java b/src/main/java/gregtech/api/recipe/RecipeMapFrontend.java index 63daa00dc7..36aee2872f 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMapFrontend.java +++ b/src/main/java/gregtech/api/recipe/RecipeMapFrontend.java @@ -1,6 +1,6 @@ package gregtech.api.recipe; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import static net.minecraft.util.EnumChatFormatting.GRAY; import java.util.ArrayList; @@ -30,15 +30,15 @@ import com.gtnewhorizons.modularui.common.widget.ProgressBar; import com.gtnewhorizons.modularui.common.widget.SlotWidget; import codechicken.nei.PositionedStack; -import gregtech.GT_Mod; +import gregtech.GTMod; import gregtech.api.enums.SteamVariant; -import gregtech.api.gui.GT_GUIColorOverride; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.GUIColorOverride; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.metadata.IRecipeMetadataStorage; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; import gregtech.common.gui.modularui.UIHelper; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.nei.GTNEIDefaultHandler; import gregtech.nei.RecipeDisplayInfo; /** @@ -60,8 +60,8 @@ public class RecipeMapFrontend { */ protected final NEIRecipeProperties neiProperties; - protected final GT_GUIColorOverride colorOverride = GT_GUIColorOverride - .get(GT_UITextures.BACKGROUND_NEI_SINGLE_RECIPE.location); + protected final GUIColorOverride colorOverride = GUIColorOverride + .get(GTUITextures.BACKGROUND_NEI_SINGLE_RECIPE.location); public RecipeMapFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, NEIRecipePropertiesBuilder neiPropertiesBuilder) { @@ -96,7 +96,7 @@ public class RecipeMapFrontend { IItemHandlerModifiable fluidInputsInventory, IItemHandlerModifiable fluidOutputsInventory, Supplier progressSupplier, Pos2d windowOffset) { ModularWindow.Builder builder = ModularWindow.builder(neiProperties.recipeBackgroundSize) - .setBackground(GT_UITextures.BACKGROUND_NEI_SINGLE_RECIPE); + .setBackground(GTUITextures.BACKGROUND_NEI_SINGLE_RECIPE); UIHelper.forEachSlots( (i, backgrounds, pos) -> builder.widget( @@ -245,8 +245,8 @@ public class RecipeMapFrontend { } protected void drawRecipeOwnerInfo(RecipeDisplayInfo recipeInfo) { - GT_Recipe recipe = recipeInfo.recipe; - if (GT_Mod.gregtechproxy.mNEIRecipeOwner) { + GTRecipe recipe = recipeInfo.recipe; + if (GTMod.gregtechproxy.mNEIRecipeOwner) { if (recipe.owners.size() > 1) { recipeInfo.drawText( EnumChatFormatting.ITALIC + trans("273", "Original Recipe by: ") @@ -265,7 +265,7 @@ public class RecipeMapFrontend { .getName()); } } - if (GT_Mod.gregtechproxy.mNEIRecipeOwnerStackTrace && recipe.stackTraces != null + if (GTMod.gregtechproxy.mNEIRecipeOwnerStackTrace && recipe.stackTraces != null && !recipe.stackTraces.isEmpty()) { recipeInfo.drawText("stackTrace:"); // todo: good way to show all stacktraces @@ -276,23 +276,23 @@ public class RecipeMapFrontend { } public List handleNEIItemTooltip(ItemStack stack, List currentTip, - GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { for (PositionedStack pStack : neiCachedRecipe.mInputs) { if (stack == pStack.item) { - if (pStack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { + if (pStack instanceof GTNEIDefaultHandler.FixedPositionedStack) { currentTip = handleNEIItemInputTooltip( currentTip, - (GT_NEI_DefaultHandler.FixedPositionedStack) pStack); + (GTNEIDefaultHandler.FixedPositionedStack) pStack); } break; } } for (PositionedStack pStack : neiCachedRecipe.mOutputs) { if (stack == pStack.item) { - if (pStack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { + if (pStack instanceof GTNEIDefaultHandler.FixedPositionedStack) { currentTip = handleNEIItemOutputTooltip( currentTip, - (GT_NEI_DefaultHandler.FixedPositionedStack) pStack); + (GTNEIDefaultHandler.FixedPositionedStack) pStack); } break; } @@ -301,7 +301,7 @@ public class RecipeMapFrontend { } protected List handleNEIItemInputTooltip(List currentTip, - GT_NEI_DefaultHandler.FixedPositionedStack pStack) { + GTNEIDefaultHandler.FixedPositionedStack pStack) { if (pStack.isNotConsumed()) { currentTip.add(GRAY + trans("151", "Does not get consumed in the process")); } @@ -309,33 +309,33 @@ public class RecipeMapFrontend { } protected List handleNEIItemOutputTooltip(List currentTip, - GT_NEI_DefaultHandler.FixedPositionedStack pStack) { + GTNEIDefaultHandler.FixedPositionedStack pStack) { if (pStack.isChanceBased()) { currentTip.add(GRAY + trans("150", "Chance: ") + pStack.getChanceText()); } return currentTip; } - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { for (PositionedStack stack : neiCachedRecipe.mInputs) { - if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { - drawNEIOverlayForInput((GT_NEI_DefaultHandler.FixedPositionedStack) stack); + if (stack instanceof GTNEIDefaultHandler.FixedPositionedStack) { + drawNEIOverlayForInput((GTNEIDefaultHandler.FixedPositionedStack) stack); } } for (PositionedStack stack : neiCachedRecipe.mOutputs) { - if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack) { - drawNEIOverlayForOutput((GT_NEI_DefaultHandler.FixedPositionedStack) stack); + if (stack instanceof GTNEIDefaultHandler.FixedPositionedStack) { + drawNEIOverlayForOutput((GTNEIDefaultHandler.FixedPositionedStack) stack); } } } - protected void drawNEIOverlayForInput(GT_NEI_DefaultHandler.FixedPositionedStack stack) { + protected void drawNEIOverlayForInput(GTNEIDefaultHandler.FixedPositionedStack stack) { if (stack.isNotConsumed()) { drawNEIOverlayText("NC", stack); } } - protected void drawNEIOverlayForOutput(GT_NEI_DefaultHandler.FixedPositionedStack stack) { + protected void drawNEIOverlayForOutput(GTNEIDefaultHandler.FixedPositionedStack stack) { if (stack.isChanceBased()) { drawNEIOverlayText(stack.getChanceText(), stack); } diff --git a/src/main/java/gregtech/api/recipe/RecipeMaps.java b/src/main/java/gregtech/api/recipe/RecipeMaps.java index 293b4f36b5..b43b1144ee 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipe/RecipeMaps.java @@ -4,18 +4,18 @@ import static gregtech.api.enums.Mods.Avaritia; import static gregtech.api.enums.Mods.GTNHIntergalactic; import static gregtech.api.enums.Mods.NEICustomDiagrams; import static gregtech.api.enums.Mods.Railcraft; -import static gregtech.api.util.GT_ModHandler.getModItem; -import static gregtech.api.util.GT_RecipeConstants.ADDITIVE_AMOUNT; -import static gregtech.api.util.GT_RecipeConstants.FUEL_VALUE; -import static gregtech.api.util.GT_RecipeMapUtil.GT_RecipeTemplate; -import static gregtech.api.util.GT_RecipeMapUtil.asTemplate; -import static gregtech.api.util.GT_RecipeMapUtil.buildOrEmpty; -import static gregtech.api.util.GT_Utility.clamp; -import static gregtech.api.util.GT_Utility.copyAmount; -import static gregtech.api.util.GT_Utility.getFluidForFilledItem; -import static gregtech.api.util.GT_Utility.isArrayEmptyOrNull; -import static gregtech.api.util.GT_Utility.isArrayOfLength; -import static gregtech.api.util.GT_Utility.multiplyStack; +import static gregtech.api.util.GTModHandler.getModItem; +import static gregtech.api.util.GTRecipeConstants.ADDITIVE_AMOUNT; +import static gregtech.api.util.GTRecipeConstants.FUEL_VALUE; +import static gregtech.api.util.GTRecipeMapUtil.GTRecipeTemplate; +import static gregtech.api.util.GTRecipeMapUtil.asTemplate; +import static gregtech.api.util.GTRecipeMapUtil.buildOrEmpty; +import static gregtech.api.util.GTUtility.clamp; +import static gregtech.api.util.GTUtility.copyAmount; +import static gregtech.api.util.GTUtility.getFluidForFilledItem; +import static gregtech.api.util.GTUtility.isArrayEmptyOrNull; +import static gregtech.api.util.GTUtility.isArrayOfLength; +import static gregtech.api.util.GTUtility.multiplyStack; import java.util.ArrayList; import java.util.Collection; @@ -32,11 +32,11 @@ import org.apache.commons.lang3.ArrayUtils; import com.gtnewhorizons.modularui.api.drawable.UITexture; import com.gtnewhorizons.modularui.common.widget.ProgressBar; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.interfaces.IRecipeMap; import gregtech.api.objects.ItemData; import gregtech.api.recipe.maps.AssemblerBackend; @@ -68,12 +68,12 @@ import gregtech.api.recipe.maps.UnpackagerBackend; import gregtech.api.recipe.metadata.CompressionTierKey; import gregtech.api.recipe.metadata.PCBFactoryTierKey; import gregtech.api.recipe.metadata.PurificationPlantBaseChanceKey; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeConstants; -import gregtech.api.util.GT_RecipeMapUtil; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeConstants; +import gregtech.api.util.GTRecipeMapUtil; +import gregtech.api.util.GTUtility; import gregtech.common.tileentities.machines.multi.purification.PurifiedWaterHelpers; import gregtech.nei.formatter.FuelSpecialValueFormatter; import gregtech.nei.formatter.FusionSpecialValueFormatter; @@ -94,12 +94,12 @@ public final class RecipeMaps { return null; } if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; } else { - return GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE; + return GTUITextures.OVERLAY_SLOT_CRUSHED_ORE; } }) - .progressBar(GT_UITextures.PROGRESSBAR_BATH, ProgressBar.Direction.CIRCULAR_CW) + .progressBar(GTUITextures.PROGRESSBAR_BATH, ProgressBar.Direction.CIRCULAR_CW) .build(); public static final RecipeMap thermalCentrifugeRecipes = RecipeMapBuilder .of("gt.recipe.thermalcentrifuge") @@ -111,9 +111,9 @@ public final class RecipeMaps { return null; } if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; } else { - return GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE; + return GTUITextures.OVERLAY_SLOT_CRUSHED_ORE; } }) .build(); @@ -121,17 +121,17 @@ public final class RecipeMaps { .maxIO(1, 1, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_COMPRESSOR + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_COMPRESSOR : null) - .progressBar(GT_UITextures.PROGRESSBAR_COMPRESS) + .progressBar(GTUITextures.PROGRESSBAR_COMPRESS) .slotOverlaysSteam( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_COMPRESSOR_STEAM + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_COMPRESSOR_STEAM : null) - .progressBarSteam(GT_UITextures.PROGRESSBAR_COMPRESS_STEAM) + .progressBarSteam(GTUITextures.PROGRESSBAR_COMPRESS_STEAM) .neiRecipeComparator( Comparator - .comparing(recipe -> recipe.getMetadataOrDefault(CompressionTierKey.INSTANCE, 0)) - .thenComparing(GT_Recipe::compareTo)) + .comparing(recipe -> recipe.getMetadataOrDefault(CompressionTierKey.INSTANCE, 0)) + .thenComparing(GTRecipe::compareTo)) // Avoid steam machine being used as handler icon .neiHandlerInfo(builder -> builder.setDisplayStack(ItemList.Machine_LV_Compressor.get(1))) .build(); @@ -139,27 +139,27 @@ public final class RecipeMaps { .of("gt.recipe.neutroniumcompressor") .maxIO(1, 1, 1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_COMPRESSOR + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_COMPRESSOR : null) - .progressBar(GT_UITextures.PROGRESSBAR_COMPRESS) + .progressBar(GTUITextures.PROGRESSBAR_COMPRESS) .neiHandlerInfo(builder -> builder.setDisplayStack(getModItem(Avaritia.ID, "Singularity", 1L, 0))) .disableOptimize() .neiRecipeComparator( Comparator - .comparing(recipe -> recipe.getMetadataOrDefault(CompressionTierKey.INSTANCE, 0)) - .thenComparing(GT_Recipe::compareTo)) + .comparing(recipe -> recipe.getMetadataOrDefault(CompressionTierKey.INSTANCE, 0)) + .thenComparing(GTRecipe::compareTo)) .build(); public static final RecipeMap extractorRecipes = RecipeMapBuilder.of("gt.recipe.extractor") .maxIO(1, 1, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_CENTRIFUGE + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_CENTRIFUGE : null) - .progressBar(GT_UITextures.PROGRESSBAR_EXTRACT) + .progressBar(GTUITextures.PROGRESSBAR_EXTRACT) .slotOverlaysSteam( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_CENTRIFUGE_STEAM + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_CENTRIFUGE_STEAM : null) - .progressBarSteam(GT_UITextures.PROGRESSBAR_EXTRACT_STEAM) + .progressBarSteam(GTUITextures.PROGRESSBAR_EXTRACT_STEAM) // Avoid steam machine being used as handler icon .neiHandlerInfo(builder -> builder.setDisplayStack(ItemList.Machine_LV_Extractor.get(1))) .build(); @@ -168,8 +168,8 @@ public final class RecipeMaps { .maxIO(1, 1, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_RECYCLE : null) - .progressBar(GT_UITextures.PROGRESSBAR_RECYCLE, ProgressBar.Direction.CIRCULAR_CW) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_RECYCLE : null) + .progressBar(GTUITextures.PROGRESSBAR_RECYCLE, ProgressBar.Direction.CIRCULAR_CW) .neiTransferRectId("ic2.recycler") .disableRegisterNEI() .build(); @@ -178,11 +178,11 @@ public final class RecipeMaps { .maxIO(1, 1, 0, 0) .minInputs(1, 9) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_FURNACE : null) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_FURNACE : null) .slotOverlaysSteam( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_FURNACE_STEAM + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_FURNACE_STEAM : null) - .progressBarSteam(GT_UITextures.PROGRESSBAR_ARROW_STEAM) + .progressBarSteam(GTUITextures.PROGRESSBAR_ARROW_STEAM) .neiTransferRectId("smelting") .disableRegisterNEI() .build(); @@ -191,7 +191,7 @@ public final class RecipeMaps { .maxIO(1, 1, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_FURNACE : null) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_FURNACE : null) .neiTransferRectId("smelting") .disableRegisterNEI() .build(); @@ -201,10 +201,10 @@ public final class RecipeMaps { .useSpecialSlot() .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isSpecial) { - return GT_UITextures.OVERLAY_SLOT_DATA_ORB; + return GTUITextures.OVERLAY_SLOT_DATA_ORB; } if (!isFluid && !isOutput) { - return GT_UITextures.OVERLAY_SLOT_MICROSCOPE; + return GTUITextures.OVERLAY_SLOT_MICROSCOPE; } return null; }) @@ -214,12 +214,12 @@ public final class RecipeMaps { .maxIO(2, 1, 0, 0) .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE; + return GTUITextures.OVERLAY_SLOT_CRUSHED_ORE; } else { - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; } }) - .progressBar(GT_UITextures.PROGRESSBAR_MACERATE) + .progressBar(GTUITextures.PROGRESSBAR_MACERATE) .build(); public static final RecipeMap replicatorRecipes = RecipeMapBuilder .of("gt.recipe.replicator", ReplicatorBackend::new) @@ -228,23 +228,23 @@ public final class RecipeMaps { .useSpecialSlot() .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isSpecial) { - return GT_UITextures.OVERLAY_SLOT_DATA_ORB; + return GTUITextures.OVERLAY_SLOT_DATA_ORB; } if (isFluid && !isOutput) { - return GT_UITextures.OVERLAY_SLOT_UUM; + return GTUITextures.OVERLAY_SLOT_UUM; } return null; }) .build(); /** - * Use {@link GT_RecipeConstants#AssemblyLine} for recipe addition. + * Use {@link GTRecipeConstants#AssemblyLine} for recipe addition. */ public static final RecipeMap assemblylineVisualRecipes = RecipeMapBuilder .of("gt.recipe.fakeAssemblylineProcess") .maxIO(16, 1, 4, 0) .minInputs(1, 0) .useSpecialSlot() - .slotOverlays((index, isFluid, isOutput, isSpecial) -> isSpecial ? GT_UITextures.OVERLAY_SLOT_DATA_ORB : null) + .slotOverlays((index, isFluid, isOutput, isSpecial) -> isSpecial ? GTUITextures.OVERLAY_SLOT_DATA_ORB : null) .disableOptimize() .neiTransferRect(88, 8, 18, 72) .neiTransferRect(124, 8, 18, 72) @@ -252,7 +252,7 @@ public final class RecipeMaps { .frontend(AssemblyLineFrontend::new) .build(); /** - * Usually, but not always, you should use {@link GT_RecipeConstants#UniversalArcFurnace} instead. + * Usually, but not always, you should use {@link GTRecipeConstants#UniversalArcFurnace} instead. */ public static final RecipeMap plasmaArcFurnaceRecipes = RecipeMapBuilder .of("gt.recipe.plasmaarcfurnace") @@ -260,7 +260,7 @@ public final class RecipeMaps { .minInputs(1, 1) .build(); /** - * Usually, but not always, you should use {@link GT_RecipeConstants#UniversalArcFurnace} instead. + * Usually, but not always, you should use {@link GTRecipeConstants#UniversalArcFurnace} instead. */ public static final RecipeMap arcFurnaceRecipes = RecipeMapBuilder.of("gt.recipe.arcfurnace") .maxIO(1, 9, 1, 0) @@ -274,20 +274,20 @@ public final class RecipeMaps { .useSpecialSlot() .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isSpecial) { - return GT_UITextures.OVERLAY_SLOT_DATA_STICK; + return GTUITextures.OVERLAY_SLOT_DATA_STICK; } if (isFluid) { return null; } if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_PAGE_PRINTED; + return GTUITextures.OVERLAY_SLOT_PAGE_PRINTED; } - return GT_UITextures.OVERLAY_SLOT_PAGE_BLANK; + return GTUITextures.OVERLAY_SLOT_PAGE_BLANK; }) .build(); public static final RecipeMap sifterRecipes = RecipeMapBuilder.of("gt.recipe.sifter") .maxIO(1, 9, 1, 1) - .progressBar(GT_UITextures.PROGRESSBAR_SIFT, ProgressBar.Direction.DOWN) + .progressBar(GTUITextures.PROGRESSBAR_SIFT, ProgressBar.Direction.DOWN) .build(); public static final RecipeMap formingPressRecipes = RecipeMapBuilder .of("gt.recipe.press", FormingPressBackend::new) @@ -295,32 +295,32 @@ public final class RecipeMaps { .minInputs(2, 0) .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_PRESS_3; + return GTUITextures.OVERLAY_SLOT_PRESS_3; } if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_PRESS_1; + return GTUITextures.OVERLAY_SLOT_PRESS_1; } - return GT_UITextures.OVERLAY_SLOT_PRESS_2; + return GTUITextures.OVERLAY_SLOT_PRESS_2; }) - .progressBar(GT_UITextures.PROGRESSBAR_COMPRESS) + .progressBar(GTUITextures.PROGRESSBAR_COMPRESS) .build(); public static final RecipeMap laserEngraverRecipes = RecipeMapBuilder .of("gt.recipe.laserengraver") .maxIO(4, 4, 2, 2) .slotOverlays( (index, isFluid, isOutput, - isSpecial) -> !isFluid && !isOutput && index != 0 ? GT_UITextures.OVERLAY_SLOT_LENS : null) + isSpecial) -> !isFluid && !isOutput && index != 0 ? GTUITextures.OVERLAY_SLOT_LENS : null) // Add a simple ordering so lower tier purified water is displayed first, otherwise it gets really confusing .neiRecipeComparator( (a, b) -> Comparator.comparing(PurifiedWaterHelpers::getWaterTierFromRecipe) - .thenComparing(GT_Recipe::compareTo) + .thenComparing(GTRecipe::compareTo) .compare(a, b)) .build(); public static final RecipeMap mixerRecipes = RecipeMapBuilder.of("gt.recipe.mixer") .maxIO(9, 4, 1, 1) .minInputs(1, 0) - .slotOverlays((index, isFluid, isOutput, isSpecial) -> !isFluid ? GT_UITextures.OVERLAY_SLOT_DUST : null) - .progressBar(GT_UITextures.PROGRESSBAR_MIXER, ProgressBar.Direction.CIRCULAR_CW) + .slotOverlays((index, isFluid, isOutput, isSpecial) -> !isFluid ? GTUITextures.OVERLAY_SLOT_DUST : null) + .progressBar(GTUITextures.PROGRESSBAR_MIXER, ProgressBar.Direction.CIRCULAR_CW) .build(); public static final RecipeMap autoclaveRecipes = RecipeMapBuilder.of("gt.recipe.autoclave") .maxIO(2, 4, 1, 1) @@ -331,11 +331,11 @@ public final class RecipeMaps { } if (isOutput) { if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_GEM; + return GTUITextures.OVERLAY_SLOT_GEM; } - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; } - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; }) .build(); public static final RecipeMap electroMagneticSeparatorRecipes = RecipeMapBuilder @@ -343,47 +343,47 @@ public final class RecipeMaps { .maxIO(1, 3, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> isOutput ? GT_UITextures.OVERLAY_SLOT_DUST - : GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) - .progressBar(GT_UITextures.PROGRESSBAR_MAGNET) + (index, isFluid, isOutput, isSpecial) -> isOutput ? GTUITextures.OVERLAY_SLOT_DUST + : GTUITextures.OVERLAY_SLOT_CRUSHED_ORE) + .progressBar(GTUITextures.PROGRESSBAR_MAGNET) .build(); public static final RecipeMap polarizerRecipes = RecipeMapBuilder.of("gt.recipe.polarizer") .maxIO(1, 1, 0, 0) .minInputs(1, 0) - .progressBar(GT_UITextures.PROGRESSBAR_MAGNET) + .progressBar(GTUITextures.PROGRESSBAR_MAGNET) .build(); public static final RecipeMap maceratorRecipes = RecipeMapBuilder.of("gt.recipe.macerator") .maxIO(1, 4, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> isOutput ? GT_UITextures.OVERLAY_SLOT_DUST - : GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE) + (index, isFluid, isOutput, isSpecial) -> isOutput ? GTUITextures.OVERLAY_SLOT_DUST + : GTUITextures.OVERLAY_SLOT_CRUSHED_ORE) .slotOverlaysSteam( - (index, isFluid, isOutput, isSpecial) -> isOutput ? GT_UITextures.OVERLAY_SLOT_DUST_STEAM - : GT_UITextures.OVERLAY_SLOT_CRUSHED_ORE_STEAM) - .progressBar(GT_UITextures.PROGRESSBAR_MACERATE) - .progressBarSteam(GT_UITextures.PROGRESSBAR_MACERATE_STEAM) + (index, isFluid, isOutput, isSpecial) -> isOutput ? GTUITextures.OVERLAY_SLOT_DUST_STEAM + : GTUITextures.OVERLAY_SLOT_CRUSHED_ORE_STEAM) + .progressBar(GTUITextures.PROGRESSBAR_MACERATE) + .progressBarSteam(GTUITextures.PROGRESSBAR_MACERATE_STEAM) // Avoid steam machine being used as handler icon .neiHandlerInfo(builder -> builder.setDisplayStack(ItemList.Machine_LV_Macerator.get(1))) .build(); public static final RecipeMap chemicalBathRecipes = RecipeMapBuilder.of("gt.recipe.chemicalbath") .maxIO(1, 3, 1, 1) .minInputs(1, 1) - .progressBar(GT_UITextures.PROGRESSBAR_BATH, ProgressBar.Direction.CIRCULAR_CW) + .progressBar(GTUITextures.PROGRESSBAR_BATH, ProgressBar.Direction.CIRCULAR_CW) .build(); public static final RecipeMap fluidCannerRecipes = RecipeMapBuilder .of("gt.recipe.fluidcanner", FluidCannerBackend::new) .maxIO(1, 1, 1, 1) .minInputs(1, 0) - .slotOverlays((index, isFluid, isOutput, isSpecial) -> !isFluid ? GT_UITextures.OVERLAY_SLOT_CANISTER : null) - .progressBar(GT_UITextures.PROGRESSBAR_CANNER) + .slotOverlays((index, isFluid, isOutput, isSpecial) -> !isFluid ? GTUITextures.OVERLAY_SLOT_CANISTER : null) + .progressBar(GTUITextures.PROGRESSBAR_CANNER) .build(); public static final RecipeMap brewingRecipes = RecipeMapBuilder.of("gt.recipe.brewer") .maxIO(1, 0, 1, 1) .minInputs(1, 1) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_CAULDRON : null) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_CAULDRON : null) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .build(); public static final RecipeMap fluidHeaterRecipes = RecipeMapBuilder.of("gt.recipe.fluidheater") .maxIO(1, 0, 1, 1) @@ -392,11 +392,11 @@ public final class RecipeMaps { return null; } if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_HEATER_2; + return GTUITextures.OVERLAY_SLOT_HEATER_2; } - return GT_UITextures.OVERLAY_SLOT_HEATER_1; + return GTUITextures.OVERLAY_SLOT_HEATER_1; }) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .build(); public static final RecipeMap distilleryRecipes = RecipeMapBuilder.of("gt.recipe.distillery") .maxIO(1, 1, 1, 1) @@ -406,11 +406,11 @@ public final class RecipeMaps { return null; } if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_BEAKER_2; + return GTUITextures.OVERLAY_SLOT_BEAKER_2; } - return GT_UITextures.OVERLAY_SLOT_BEAKER_1; + return GTUITextures.OVERLAY_SLOT_BEAKER_1; }) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .recipeTransformer(r -> { int aInput = r.mFluidInputs[0].amount, aOutput = r.mFluidOutputs[0].amount, aDuration = r.mDuration; @@ -434,14 +434,14 @@ public final class RecipeMaps { aInput = (aInput + tScale - 1) / tScale; aOutput = aOutput / tScale; if (!isArrayEmptyOrNull(r.mOutputs)) { - ItemData tData = GT_OreDictUnificator.getItemData(r.mOutputs[0]); + ItemData tData = GTOreDictUnificator.getItemData(r.mOutputs[0]); if (tData != null && (tData.mPrefix == OrePrefixes.dust || OrePrefixes.dust.mFamiliarPrefixes.contains(tData.mPrefix))) { - r.mOutputs[0] = GT_OreDictUnificator.getDust( + r.mOutputs[0] = GTOreDictUnificator.getDust( tData.mMaterial.mMaterial, tData.mMaterial.mAmount * r.mOutputs[0].stackSize / tScale); } else { - if (r.mOutputs[0].stackSize / tScale == 0) r.mOutputs[0] = GT_Values.NI; + if (r.mOutputs[0].stackSize / tScale == 0) r.mOutputs[0] = GTValues.NI; else r.mOutputs[0] = copyAmount(r.mOutputs[0].stackSize / tScale, r.mOutputs[0]); } } @@ -455,14 +455,14 @@ public final class RecipeMaps { public static final RecipeMap fermentingRecipes = RecipeMapBuilder.of("gt.recipe.fermenter") .maxIO(0, 0, 1, 1) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .build(); public static final RecipeMap fluidSolidifierRecipes = RecipeMapBuilder .of("gt.recipe.fluidsolidifier") .maxIO(1, 1, 1, 0) .minInputs(1, 1) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_MOLD : null) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_MOLD : null) .recipeTransformer(r -> { if (ArrayUtils.isNotEmpty(r.mFluidInputs)) { if (Materials.PhasedGold.getMolten(1) @@ -479,9 +479,9 @@ public final class RecipeMaps { .maxIO(1, 1, 0, 1) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_CENTRIFUGE + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_CENTRIFUGE : null) - .progressBar(GT_UITextures.PROGRESSBAR_EXTRACT) + .progressBar(GTUITextures.PROGRESSBAR_EXTRACT) .recipeTransformer(r -> { if (ArrayUtils.isNotEmpty(r.mFluidOutputs)) { if (Materials.PhasedGold.getMolten(1) @@ -498,10 +498,10 @@ public final class RecipeMaps { .minInputs(2, 0) .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_BOXED; + return GTUITextures.OVERLAY_SLOT_BOXED; } if (index != 0) { - return GT_UITextures.OVERLAY_SLOT_BOX; + return GTUITextures.OVERLAY_SLOT_BOX; } return null; }) @@ -510,7 +510,7 @@ public final class RecipeMaps { .of("gt.recipe.unpackager", UnpackagerBackend::new) .maxIO(1, 2, 0, 0) .minInputs(1, 0) - .slotOverlays((index, isFluid, isOutput, isSpecial) -> !isOutput ? GT_UITextures.OVERLAY_SLOT_BOXED : null) + .slotOverlays((index, isFluid, isOutput, isSpecial) -> !isOutput ? GTUITextures.OVERLAY_SLOT_BOXED : null) .build(); public static final RecipeMap fusionRecipes = RecipeMapBuilder.of("gt.recipe.fusionreactor") .maxIO(0, 0, 2, 1) @@ -520,9 +520,9 @@ public final class RecipeMaps { .neiSpecialInfoFormatter(FusionSpecialValueFormatter.INSTANCE) .neiRecipeComparator( Comparator - .comparing( + .comparing( recipe -> FusionSpecialValueFormatter.getFusionTier(recipe.mSpecialValue, recipe.mEUt)) - .thenComparing(GT_Recipe::compareTo)) + .thenComparing(GTRecipe::compareTo)) .frontend(FluidOnlyFrontend::new) .build(); public static final RecipeMap centrifugeRecipes = RecipeMapBuilder.of("gt.recipe.centrifuge") @@ -532,15 +532,15 @@ public final class RecipeMaps { return null; } if (isFluid) { - return GT_UITextures.OVERLAY_SLOT_CENTRIFUGE_FLUID; + return GTUITextures.OVERLAY_SLOT_CENTRIFUGE_FLUID; } else { if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_CENTRIFUGE; + return GTUITextures.OVERLAY_SLOT_CENTRIFUGE; } - return GT_UITextures.OVERLAY_SLOT_CANISTER; + return GTUITextures.OVERLAY_SLOT_CANISTER; } }) - .progressBar(GT_UITextures.PROGRESSBAR_EXTRACT) + .progressBar(GTUITextures.PROGRESSBAR_EXTRACT) .build(); public static final RecipeMap electrolyzerRecipes = RecipeMapBuilder.of("gt.recipe.electrolyzer") .maxIO(2, 6, 1, 1) @@ -549,18 +549,18 @@ public final class RecipeMaps { return null; } if (isFluid) { - return GT_UITextures.OVERLAY_SLOT_CHARGER_FLUID; + return GTUITextures.OVERLAY_SLOT_CHARGER_FLUID; } else { if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_CHARGER; + return GTUITextures.OVERLAY_SLOT_CHARGER; } - return GT_UITextures.OVERLAY_SLOT_CANISTER; + return GTUITextures.OVERLAY_SLOT_CANISTER; } }) - .progressBar(GT_UITextures.PROGRESSBAR_EXTRACT) + .progressBar(GTUITextures.PROGRESSBAR_EXTRACT) .build(); /** - * Use {@link GT_RecipeConstants#COIL_HEAT} as heat level. + * Use {@link GTRecipeConstants#COIL_HEAT} as heat level. */ public static final RecipeMap blastFurnaceRecipes = RecipeMapBuilder.of("gt.recipe.blastfurnace") .maxIO(6, 6, 1, 1) @@ -568,7 +568,7 @@ public final class RecipeMaps { .neiSpecialInfoFormatter(HeatingCoilSpecialValueFormatter.INSTANCE) .build(); /** - * Use {@link GT_RecipeConstants#COIL_HEAT} as heat level. + * Use {@link GTRecipeConstants#COIL_HEAT} as heat level. */ public static final RecipeMap plasmaForgeRecipes = RecipeMapBuilder.of("gt.recipe.plasmaforge") .maxIO(9, 9, 9, 9) @@ -606,14 +606,14 @@ public final class RecipeMaps { .disableOptimize() .build(); /** - * Uses {@link GT_RecipeConstants#ADDITIVE_AMOUNT} for coal/charcoal amount. + * Uses {@link GTRecipeConstants#ADDITIVE_AMOUNT} for coal/charcoal amount. */ public static final RecipeMap primitiveBlastRecipes = RecipeMapBuilder .of("gt.recipe.primitiveblastfurnace") .maxIO(3, 3, 0, 0) .minInputs(1, 0) .recipeEmitter(builder -> { - Optional rr = builder.eut(0) + Optional rr = builder.eut(0) .validateInputCount(1, 2) .validateOutputCount(1, 2) .validateNoInputFluid() @@ -629,7 +629,7 @@ public final class RecipeMaps { return Collections.emptyList(); int aCoalAmount = builder.getMetadataOrDefault(ADDITIVE_AMOUNT, 0); if (aCoalAmount <= 0) return Collections.emptyList(); - GT_RecipeTemplate coll = asTemplate(rr.get()); + GTRecipeTemplate coll = asTemplate(rr.get()); for (Materials coal : new Materials[] { Materials.Coal, Materials.Charcoal }) { coll.derive() .setInputs(aInput1, aInput2, coal.getGems(aCoalAmount)) @@ -684,7 +684,7 @@ public final class RecipeMaps { }) .build(); /** - * Uses {@link GT_RecipeConstants#ADDITIVE_AMOUNT} for TNT/ITNT/... amount. Value is truncated to [0, 64] + * Uses {@link GTRecipeConstants#ADDITIVE_AMOUNT} for TNT/ITNT/... amount. Value is truncated to [0, 64] */ public static final RecipeMap implosionRecipes = RecipeMapBuilder .of("gt.recipe.implosioncompressor") @@ -693,13 +693,13 @@ public final class RecipeMaps { .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (!isFluid && !isOutput) { if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_IMPLOSION; + return GTUITextures.OVERLAY_SLOT_IMPLOSION; } - return GT_UITextures.OVERLAY_SLOT_EXPLOSIVE; + return GTUITextures.OVERLAY_SLOT_EXPLOSIVE; } return null; }) - .progressBar(GT_UITextures.PROGRESSBAR_COMPRESS) + .progressBar(GTUITextures.PROGRESSBAR_COMPRESS) .disableOptimize() .recipeEmitter(b -> { switch (b.getItemInputsBasic().length) { @@ -712,7 +712,7 @@ public final class RecipeMaps { .map(Collections::singletonList) .orElse(Collections.emptyList()); } - Optional t = b.noOptimize() + Optional t = b.noOptimize() .duration(20) .eut(30) .validateInputCount(1, 1) @@ -720,7 +720,7 @@ public final class RecipeMaps { .build(); if (!t.isPresent()) return Collections.emptyList(); ItemStack input = b.getItemInputBasic(0); - GT_RecipeTemplate coll = asTemplate(t.get()); + GTRecipeTemplate coll = asTemplate(t.get()); int tExplosives = Math.min(b.getMetadataOrDefault(ADDITIVE_AMOUNT, 0), 64); int tGunpowder = tExplosives << 1; // Worst int tDynamite = Math.max(1, tExplosives >> 1); // good @@ -730,11 +730,11 @@ public final class RecipeMaps { if (tGunpowder < 65) coll.derive() .setInputs(input, ItemList.Block_Powderbarrel.get(tGunpowder)); if (tDynamite < 17) coll.derive() - .setInputs(input, GT_ModHandler.getIC2Item("dynamite", tDynamite, null)); + .setInputs(input, GTModHandler.getIC2Item("dynamite", tDynamite, null)); coll.derive() .setInputs(input, new ItemStack(Blocks.tnt, tTNT)); coll.derive() - .setInputs(input, GT_ModHandler.getIC2Item("industrialTnt", tITNT, null)); + .setInputs(input, GTModHandler.getIC2Item("industrialTnt", tITNT, null)); return coll.getAll(); }) .build(); @@ -749,7 +749,7 @@ public final class RecipeMaps { && isArrayEmptyOrNull(b.getFluidOutputs()) && (in = getFluidForFilledItem(b.getItemInputBasic(0), true)) != null && (out = getFluidForFilledItem(b.getItemOutput(0), true)) != null) { - Collection ret = new ArrayList<>(); + Collection ret = new ArrayList<>(); b.build() .ifPresent(ret::add); b.itemInputs() @@ -765,7 +765,7 @@ public final class RecipeMaps { .build(); /** * Using {@code .addTo(chemicalReactorRecipes)} will cause the recipe to be added to single block recipe map ONLY! - * Use {@link GT_RecipeConstants#UniversalChemical} to add to both. + * Use {@link GTRecipeConstants#UniversalChemical} to add to both. */ public static final RecipeMap chemicalReactorRecipes = RecipeMapBuilder .of("gt.recipe.chemicalreactor") @@ -774,30 +774,30 @@ public final class RecipeMaps { .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isFluid) { if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_VIAL_2; + return GTUITextures.OVERLAY_SLOT_VIAL_2; } - return GT_UITextures.OVERLAY_SLOT_MOLECULAR_3; + return GTUITextures.OVERLAY_SLOT_MOLECULAR_3; } else { if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_VIAL_1; + return GTUITextures.OVERLAY_SLOT_VIAL_1; } if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_MOLECULAR_1; + return GTUITextures.OVERLAY_SLOT_MOLECULAR_1; } - return GT_UITextures.OVERLAY_SLOT_MOLECULAR_2; + return GTUITextures.OVERLAY_SLOT_MOLECULAR_2; } }) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .disableOptimize() .build(); /** * Using {@code .addTo(multiblockChemicalReactorRecipes)} will cause the recipe to be added to - * multiblock recipe map ONLY! Use {@link GT_RecipeConstants#UniversalChemical} to add to both. + * multiblock recipe map ONLY! Use {@link GTRecipeConstants#UniversalChemical} to add to both. */ public static final RecipeMap multiblockChemicalReactorRecipes = RecipeMapBuilder .of("gt.recipe.largechemicalreactor") .maxIO(6, 6, 6, 6) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .disableOptimize() .frontend(LargeNEIFrontend::new) .build(); @@ -809,12 +809,12 @@ public final class RecipeMaps { return null; } if (isFluid) { - return GT_UITextures.OVERLAY_SLOTS_NUMBER[index + 1]; + return GTUITextures.OVERLAY_SLOTS_NUMBER[index + 1]; } else { - return GT_UITextures.OVERLAY_SLOTS_NUMBER[0]; + return GTUITextures.OVERLAY_SLOTS_NUMBER[0]; } }) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .logoPos(80, 62) .frontend(DistillationTowerFrontend::new) .disableOptimize() @@ -823,7 +823,7 @@ public final class RecipeMaps { .of("gt.recipe.craker", OilCrackerBackend::new) .maxIO(1, 1, 2, 1) .minInputs(1, 2) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW_MULTIPLE) + .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) .build(); public static final RecipeMap pyrolyseRecipes = RecipeMapBuilder.of("gt.recipe.pyro") .maxIO(2, 1, 1, 1) @@ -834,26 +834,26 @@ public final class RecipeMaps { .maxIO(2, 1, 0, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_WIREMILL : null) - .progressBar(GT_UITextures.PROGRESSBAR_WIREMILL) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_WIREMILL : null) + .progressBar(GTUITextures.PROGRESSBAR_WIREMILL) .build(); public static final RecipeMap benderRecipes = RecipeMapBuilder.of("gt.recipe.metalbender") .maxIO(2, 1, 0, 0) .minInputs(2, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_BENDER : null) - .progressBar(GT_UITextures.PROGRESSBAR_BENDING) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_BENDER : null) + .progressBar(GTUITextures.PROGRESSBAR_BENDING) .build(); public static final RecipeMap alloySmelterRecipes = RecipeMapBuilder.of("gt.recipe.alloysmelter") .maxIO(2, 1, 0, 0) .minInputs(2, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_FURNACE : null) - .slotOverlaysSteam((index, isFluid, isOutput, isSpecial) -> GT_UITextures.OVERLAY_SLOT_FURNACE_STEAM) - .progressBarSteam(GT_UITextures.PROGRESSBAR_ARROW_STEAM) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_FURNACE : null) + .slotOverlaysSteam((index, isFluid, isOutput, isSpecial) -> GTUITextures.OVERLAY_SLOT_FURNACE_STEAM) + .progressBarSteam(GTUITextures.PROGRESSBAR_ARROW_STEAM) .recipeEmitter(b -> { if (Materials.Graphite.contains(b.getItemInputBasic(0))) return Collections.emptyList(); - if (GT_Utility.isArrayOfLength(b.getItemInputsBasic(), 1)) { + if (GTUtility.isArrayOfLength(b.getItemInputsBasic(), 1)) { ItemStack aInput1 = b.getItemInputBasic(0); if (((OrePrefixes.ingot.contains(aInput1)) || (OrePrefixes.dust.contains(aInput1)) || (OrePrefixes.gem.contains(aInput1)))) return Collections.emptyList(); @@ -872,8 +872,8 @@ public final class RecipeMaps { .maxIO(9, 1, 1, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_CIRCUIT : null) - .progressBar(GT_UITextures.PROGRESSBAR_ASSEMBLE) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_CIRCUIT : null) + .progressBar(GTUITextures.PROGRESSBAR_ASSEMBLE) .disableOptimize() .build(); public static final RecipeMap circuitAssemblerRecipes = RecipeMapBuilder @@ -881,8 +881,8 @@ public final class RecipeMaps { .maxIO(6, 1, 1, 0) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_CIRCUIT : null) - .progressBar(GT_UITextures.PROGRESSBAR_CIRCUIT_ASSEMBLER) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_CIRCUIT : null) + .progressBar(GTUITextures.PROGRESSBAR_CIRCUIT_ASSEMBLER) .unificateOutputNEI(!NEICustomDiagrams.isModLoaded()) .build(); public static final RecipeMap cannerRecipes = RecipeMapBuilder.of("gt.recipe.canner") @@ -893,11 +893,11 @@ public final class RecipeMaps { return null; } if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_CANNER; + return GTUITextures.OVERLAY_SLOT_CANNER; } - return GT_UITextures.OVERLAY_SLOT_CANISTER; + return GTUITextures.OVERLAY_SLOT_CANISTER; }) - .progressBar(GT_UITextures.PROGRESSBAR_CANNER) + .progressBar(GTUITextures.PROGRESSBAR_CANNER) .build(); public static final RecipeMap latheRecipes = RecipeMapBuilder.of("gt.recipe.lathe") .maxIO(1, 2, 0, 0) @@ -905,14 +905,14 @@ public final class RecipeMaps { .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isOutput) { if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_ROD_2; + return GTUITextures.OVERLAY_SLOT_ROD_2; } - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; } - return GT_UITextures.OVERLAY_SLOT_ROD_1; + return GTUITextures.OVERLAY_SLOT_ROD_1; }) - .progressBar(GT_UITextures.PROGRESSBAR_LATHE) - .addSpecialTexture(98, 24, 5, 18, GT_UITextures.PROGRESSBAR_LATHE_BASE) + .progressBar(GTUITextures.PROGRESSBAR_LATHE) + .addSpecialTexture(98, 24, 5, 18, GTUITextures.PROGRESSBAR_LATHE_BASE) .build(); public static final RecipeMap cutterRecipes = RecipeMapBuilder.of("gt.recipe.cuttingsaw") .maxIO(2, 4, 1, 0) @@ -923,13 +923,13 @@ public final class RecipeMaps { } if (isOutput) { if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_CUTTER_SLICED; + return GTUITextures.OVERLAY_SLOT_CUTTER_SLICED; } - return GT_UITextures.OVERLAY_SLOT_DUST; + return GTUITextures.OVERLAY_SLOT_DUST; } - return GT_UITextures.OVERLAY_SLOT_BOX; + return GTUITextures.OVERLAY_SLOT_BOX; }) - .progressBar(GT_UITextures.PROGRESSBAR_CUT) + .progressBar(GTUITextures.PROGRESSBAR_CUT) .recipeEmitter(b -> { b.validateInputCount(1, 2) .validateOutputCount(1, 4) @@ -937,14 +937,14 @@ public final class RecipeMaps { if ((b.getFluidInputs() != null && b.getFluidInputs().length > 0) || !b.isValid()) return buildOrEmpty(b.validateInputFluidCount(1, 1)); int aDuration = b.getDuration(), aEUt = b.getEUt(); - Collection ret = new ArrayList<>(); + Collection ret = new ArrayList<>(); b.copy() .fluidInputs(Materials.Water.getFluid(clamp(aDuration * aEUt / 320, 4, 1000))) .duration(aDuration * 2) .build() .ifPresent(ret::add); b.copy() - .fluidInputs(GT_ModHandler.getDistilledWater(clamp(aDuration * aEUt / 426, 3, 750))) + .fluidInputs(GTModHandler.getDistilledWater(clamp(aDuration * aEUt / 426, 3, 750))) .duration(aDuration * 2) .build() .ifPresent(ret::add); @@ -960,34 +960,34 @@ public final class RecipeMaps { .minInputs(2, 0) .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_SLICER_SLICED; + return GTUITextures.OVERLAY_SLOT_SLICER_SLICED; } if (index == 0) { - return GT_UITextures.OVERLAY_SLOT_SQUARE; + return GTUITextures.OVERLAY_SLOT_SQUARE; } - return GT_UITextures.OVERLAY_SLOT_SLICE_SHAPE; + return GTUITextures.OVERLAY_SLOT_SLICE_SHAPE; }) - .progressBar(GT_UITextures.PROGRESSBAR_SLICE) + .progressBar(GTUITextures.PROGRESSBAR_SLICE) .build(); public static final RecipeMap extruderRecipes = RecipeMapBuilder.of("gt.recipe.extruder") .maxIO(2, 1, 0, 0) .minInputs(2, 0) .slotOverlays( (index, isFluid, isOutput, - isSpecial) -> !isFluid && !isOutput && index != 0 ? GT_UITextures.OVERLAY_SLOT_EXTRUDER_SHAPE : null) - .progressBar(GT_UITextures.PROGRESSBAR_EXTRUDE) + isSpecial) -> !isFluid && !isOutput && index != 0 ? GTUITextures.OVERLAY_SLOT_EXTRUDER_SHAPE : null) + .progressBar(GTUITextures.PROGRESSBAR_EXTRUDE) .build(); public static final RecipeMap hammerRecipes = RecipeMapBuilder.of("gt.recipe.hammer") .maxIO(2, 2, 2, 2) .minInputs(1, 0) .slotOverlays( - (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GT_UITextures.OVERLAY_SLOT_HAMMER : null) - .progressBar(GT_UITextures.PROGRESSBAR_HAMMER, ProgressBar.Direction.DOWN) - .addSpecialTexture(78, 42, 20, 6, GT_UITextures.PROGRESSBAR_HAMMER_BASE) + (index, isFluid, isOutput, isSpecial) -> !isFluid && !isOutput ? GTUITextures.OVERLAY_SLOT_HAMMER : null) + .progressBar(GTUITextures.PROGRESSBAR_HAMMER, ProgressBar.Direction.DOWN) + .addSpecialTexture(78, 42, 20, 6, GTUITextures.PROGRESSBAR_HAMMER_BASE) .slotOverlaysSteam( - (index, isFluid, isOutput, isSpecial) -> !isOutput ? GT_UITextures.OVERLAY_SLOT_HAMMER_STEAM : null) - .progressBarSteam(GT_UITextures.PROGRESSBAR_HAMMER_STEAM) - .addSpecialTextureSteam(78, 42, 20, 6, GT_UITextures.PROGRESSBAR_HAMMER_BASE_STEAM) + (index, isFluid, isOutput, isSpecial) -> !isOutput ? GTUITextures.OVERLAY_SLOT_HAMMER_STEAM : null) + .progressBarSteam(GTUITextures.PROGRESSBAR_HAMMER_STEAM) + .addSpecialTextureSteam(78, 42, 20, 6, GTUITextures.PROGRESSBAR_HAMMER_BASE_STEAM) // Avoid steam machine being used as handler icon .neiHandlerInfo(builder -> builder.setDisplayStack(ItemList.Machine_LV_Hammer.get(1))) .build(); @@ -996,14 +996,14 @@ public final class RecipeMaps { .minInputs(1, 0) .slotOverlays((index, isFluid, isOutput, isSpecial) -> { if (isFluid) { - return GT_UITextures.OVERLAY_SLOT_UUA; + return GTUITextures.OVERLAY_SLOT_UUA; } if (!isOutput) { - return GT_UITextures.OVERLAY_SLOT_CENTRIFUGE; + return GTUITextures.OVERLAY_SLOT_CENTRIFUGE; } return null; }) - .progressBar(GT_UITextures.PROGRESSBAR_EXTRACT) + .progressBar(GTUITextures.PROGRESSBAR_EXTRACT) .build(); public static final RecipeMap massFabFakeRecipes = RecipeMapBuilder.of("gt.recipe.massfab") .maxIO(1, 0, 1, 1) @@ -1014,9 +1014,9 @@ public final class RecipeMaps { return null; } if (isOutput) { - return GT_UITextures.OVERLAY_SLOT_UUM; + return GTUITextures.OVERLAY_SLOT_UUM; } - return GT_UITextures.OVERLAY_SLOT_UUA; + return GTUITextures.OVERLAY_SLOT_UUA; }) .build(); public static final RecipeMap dieselFuels = RecipeMapBuilder @@ -1083,20 +1083,20 @@ public final class RecipeMaps { .of("gt.recipe.largeelectrolyzer") .maxIO(1, 6, 1, 6) .disableRegisterNEI() - .recipeEmitter(GT_RecipeMapUtil::buildRecipeForMultiblock) + .recipeEmitter(GTRecipeMapUtil::buildRecipeForMultiblock) .build(); public static final RecipeMap centrifugeNonCellRecipes = RecipeMapBuilder .of("gt.recipe.largecentrifuge") .maxIO(2, 6, 1, 6) .disableOptimize() .disableRegisterNEI() - .recipeEmitter(GT_RecipeMapUtil::buildRecipeForMultiblock) + .recipeEmitter(GTRecipeMapUtil::buildRecipeForMultiblock) .build(); public static final RecipeMap mixerNonCellRecipes = RecipeMapBuilder.of("gt.recipe.largemixer") .maxIO(9, 4, 6, 4) .disableOptimize() .disableRegisterNEI() - .recipeEmitter(GT_RecipeMapUtil::buildRecipeForMultiblockNoCircuit) + .recipeEmitter(GTRecipeMapUtil::buildRecipeForMultiblockNoCircuit) .build(); public static final RecipeMap largeBoilerFakeFuels = RecipeMapBuilder .of("gt.recipe.largeboilerfakefuels", LargeBoilerFuelBackend::new) @@ -1110,20 +1110,20 @@ public final class RecipeMaps { .minInputs(2, 1) .slotOverlays( (index, isFluid, isOutput, - isSpecial) -> !isFluid && !isOutput && index == 0 ? GT_UITextures.OVERLAY_SLOT_LENS : null) - .progressBar(GT_UITextures.PROGRESSBAR_ASSEMBLE) + isSpecial) -> !isFluid && !isOutput && index == 0 ? GTUITextures.OVERLAY_SLOT_LENS : null) + .progressBar(GTUITextures.PROGRESSBAR_ASSEMBLE) .disableOptimize() .neiSpecialInfoFormatter(new SimpleSpecialValueFormatter("GT5U.nei.tier")) .build(); public static final RecipeMap pcbFactoryRecipes = RecipeMapBuilder.of("gt.recipe.pcbfactory") .maxIO(6, 9, 3, 0) .minInputs(3, 1) - .progressBar(GT_UITextures.PROGRESSBAR_ASSEMBLE) + .progressBar(GTUITextures.PROGRESSBAR_ASSEMBLE) .disableOptimize() .neiRecipeComparator( Comparator - .comparing(recipe -> recipe.getMetadataOrDefault(PCBFactoryTierKey.INSTANCE, 1)) - .thenComparing(GT_Recipe::compareTo)) + .comparing(recipe -> recipe.getMetadataOrDefault(PCBFactoryTierKey.INSTANCE, 1)) + .thenComparing(GTRecipe::compareTo)) .build(); public static final RecipeMap purificationClarifierRecipes = RecipeMapBuilder .of("gt.recipe.purificationplantclarifier") @@ -1136,12 +1136,12 @@ public final class RecipeMaps { .of("gt.recipe.purificationplantozonation") .maxIO(0, 4, 2, 1) .minInputs(0, 2) - .progressBar(GT_UITextures.PROGRESSBAR_BATH) + .progressBar(GTUITextures.PROGRESSBAR_BATH) .neiRecipeComparator( Comparator - .comparing( + .comparing( recipe -> recipe.getMetadataOrDefault(PurificationPlantBaseChanceKey.INSTANCE, 0.0f)) - .thenComparing(GT_Recipe::compareTo)) + .thenComparing(GTRecipe::compareTo)) .frontend(PurificationUnitOzonationFrontend::new) .disableOptimize() .build(); @@ -1149,12 +1149,12 @@ public final class RecipeMaps { .of("gt.recipe.purificationplantflocculation") .maxIO(0, 3, 2, 2) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_BATH) + .progressBar(GTUITextures.PROGRESSBAR_BATH) .neiRecipeComparator( Comparator - .comparing( + .comparing( recipe -> recipe.getMetadataOrDefault(PurificationPlantBaseChanceKey.INSTANCE, 0.0f)) - .thenComparing(GT_Recipe::compareTo)) + .thenComparing(GTRecipe::compareTo)) .frontend(PurificationUnitFlocculatorFrontend::new) .disableOptimize() .build(); @@ -1163,7 +1163,7 @@ public final class RecipeMaps { .of("gt.recipe.purificationplantphadjustment") .maxIO(0, 0, 1, 1) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_MIXER) + .progressBar(GTUITextures.PROGRESSBAR_MIXER) .frontend(PurificationUnitPhAdjustmentFrontend::new) .disableOptimize() .build(); @@ -1172,7 +1172,7 @@ public final class RecipeMaps { .of("gt.recipe.purificationplantplasmaheating") .maxIO(0, 0, 1, 1) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_BOILER_HEAT) + .progressBar(GTUITextures.PROGRESSBAR_BOILER_HEAT) .frontend(PurificationUnitPlasmaHeaterFrontend::new) .disableOptimize() .build(); @@ -1180,7 +1180,7 @@ public final class RecipeMaps { .of("gt.recipe.purificationplantuvtreatment") .maxIO(9, 0, 1, 1) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW) + .progressBar(GTUITextures.PROGRESSBAR_ARROW) .frontend(PurificationUnitLaserFrontend::new) .disableOptimize() .build(); @@ -1188,14 +1188,14 @@ public final class RecipeMaps { .of("gt.recipe.purificationplantdegasifier") .maxIO(0, 3, 1, 2) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW) + .progressBar(GTUITextures.PROGRESSBAR_ARROW) .disableOptimize() .build(); public static final RecipeMap purificationParticleExtractionRecipes = RecipeMapBuilder .of("gt.recipe.purificationplantquarkextractor") .maxIO(2, 2, 1, 2) .minInputs(0, 1) - .progressBar(GT_UITextures.PROGRESSBAR_ARROW) + .progressBar(GTUITextures.PROGRESSBAR_ARROW) .frontend(PurificationUnitParticleExtractorFrontend::new) .disableOptimize() .build(); @@ -1203,10 +1203,10 @@ public final class RecipeMaps { .maxIO(1, 1, 0, 0) .minInputs(1, 0) .disableOptimize() - .logo(GT_UITextures.PICTURE_RADIATION_WARNING) + .logo(GTUITextures.PICTURE_RADIATION_WARNING) .logoPos(152, 41) .neiRecipeBackgroundSize(170, 60) - .neiHandlerInfo(builder -> builder.setDisplayStack(GT_ModHandler.getIC2Item("nuclearReactor", 1, null))) + .neiHandlerInfo(builder -> builder.setDisplayStack(GTModHandler.getIC2Item("nuclearReactor", 1, null))) .build(); static { diff --git a/src/main/java/gregtech/api/recipe/check/ResultInsufficientHeat.java b/src/main/java/gregtech/api/recipe/check/ResultInsufficientHeat.java index 9383abad9d..18edab74e7 100644 --- a/src/main/java/gregtech/api/recipe/check/ResultInsufficientHeat.java +++ b/src/main/java/gregtech/api/recipe/check/ResultInsufficientHeat.java @@ -11,7 +11,7 @@ import net.minecraft.util.StatCollector; import org.jetbrains.annotations.NotNull; import gregtech.api.enums.HeatingCoilLevel; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class ResultInsufficientHeat implements CheckRecipeResult { @@ -38,7 +38,7 @@ public class ResultInsufficientHeat implements CheckRecipeResult { return Objects.requireNonNull( StatCollector.translateToLocalFormatted( "GT5U.gui.text.insufficient_heat", - GT_Utility.formatNumbers(required), + GTUtility.formatNumbers(required), HeatingCoilLevel.getDisplayNameFromHeat(required, true))); } diff --git a/src/main/java/gregtech/api/recipe/check/ResultInsufficientMachineTier.java b/src/main/java/gregtech/api/recipe/check/ResultInsufficientMachineTier.java index 1fb2183edb..2f144049f1 100644 --- a/src/main/java/gregtech/api/recipe/check/ResultInsufficientMachineTier.java +++ b/src/main/java/gregtech/api/recipe/check/ResultInsufficientMachineTier.java @@ -10,7 +10,7 @@ import net.minecraft.util.StatCollector; import org.jetbrains.annotations.NotNull; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class ResultInsufficientMachineTier implements CheckRecipeResult { @@ -37,7 +37,7 @@ public class ResultInsufficientMachineTier implements CheckRecipeResult { return Objects.requireNonNull( StatCollector.translateToLocalFormatted( "GT5U.gui.text.insufficient_machine_tier", - GT_Utility.formatNumbers(required))); + GTUtility.formatNumbers(required))); } @Override diff --git a/src/main/java/gregtech/api/recipe/check/ResultInsufficientPower.java b/src/main/java/gregtech/api/recipe/check/ResultInsufficientPower.java index 45b50aebf6..33b86ecbf8 100644 --- a/src/main/java/gregtech/api/recipe/check/ResultInsufficientPower.java +++ b/src/main/java/gregtech/api/recipe/check/ResultInsufficientPower.java @@ -10,7 +10,7 @@ import net.minecraft.util.StatCollector; import org.jetbrains.annotations.NotNull; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class ResultInsufficientPower implements CheckRecipeResult { @@ -37,8 +37,8 @@ public class ResultInsufficientPower implements CheckRecipeResult { return Objects.requireNonNull( StatCollector.translateToLocalFormatted( "GT5U.gui.text.insufficient_power", - GT_Utility.formatNumbers(required), - GT_Utility.getColoredTierNameFromVoltage(required))); + GTUtility.formatNumbers(required), + GTUtility.getColoredTierNameFromVoltage(required))); } @Override diff --git a/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPower.java b/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPower.java index c33e9bfff1..9adf82aa28 100644 --- a/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPower.java +++ b/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPower.java @@ -10,7 +10,7 @@ import net.minecraft.util.StatCollector; import org.jetbrains.annotations.NotNull; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class ResultInsufficientStartupPower implements CheckRecipeResult { @@ -37,7 +37,7 @@ public class ResultInsufficientStartupPower implements CheckRecipeResult { return Objects.requireNonNull( StatCollector.translateToLocalFormatted( "GT5U.gui.text.insufficient_startup_power", - GT_Utility.formatNumbers(required))); + GTUtility.formatNumbers(required))); } @Override diff --git a/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPowerBigInt.java b/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPowerBigInt.java index f4b186c9a1..32aab79465 100644 --- a/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPowerBigInt.java +++ b/src/main/java/gregtech/api/recipe/check/ResultInsufficientStartupPowerBigInt.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.check; -import static util.Util.toStandardForm; +import static kekztech.util.Util.toStandardForm; import java.math.BigInteger; import java.util.Objects; diff --git a/src/main/java/gregtech/api/recipe/check/SingleRecipeCheck.java b/src/main/java/gregtech/api/recipe/check/SingleRecipeCheck.java index 8683812d84..d339f8acfd 100644 --- a/src/main/java/gregtech/api/recipe/check/SingleRecipeCheck.java +++ b/src/main/java/gregtech/api/recipe/check/SingleRecipeCheck.java @@ -22,11 +22,11 @@ import net.minecraftforge.fluids.FluidStack; import com.google.common.collect.ImmutableMap; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.recipe.RecipeMap; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; -import gregtech.api.util.GT_Utility.ItemId; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; +import gregtech.api.util.GTUtility.ItemId; /** * Used by machines that are locked to a single recipe, for faster recipe check. @@ -37,10 +37,10 @@ import gregtech.api.util.GT_Utility.ItemId; *

    * {@link gregtech.api.recipe.FindRecipeQuery#find Find recipe from recipemap}: O(NCR) * where N = number of machine inputs, C = average amount of recipe candidates found for specific input, - * R = computation time to {@link GT_Recipe#isRecipeInputEqual check if inputs match to recipe} + * R = computation time to {@link GTRecipe#isRecipeInputEqual check if inputs match to recipe} *
*
    - * {@link GT_Recipe#isRecipeInputEqual Check if inputs match to recipe}: O(NM) + * {@link GTRecipe#isRecipeInputEqual Check if inputs match to recipe}: O(NM) * where N = number of machine inputs, M = number of recipe inputs *
* @@ -52,7 +52,7 @@ import gregtech.api.util.GT_Utility.ItemId; public class SingleRecipeCheck { @Nonnull - private final GT_Recipe recipe; + private final GTRecipe recipe; @Nonnull private final RecipeMap recipeMap; @Nonnull @@ -63,7 +63,7 @@ public class SingleRecipeCheck { private final int totalItemCost; private final int totalFluidCost; - private SingleRecipeCheck(@Nonnull GT_Recipe recipe, @Nonnull RecipeMap recipeMap, + private SingleRecipeCheck(@Nonnull GTRecipe recipe, @Nonnull RecipeMap recipeMap, @Nonnull ImmutableMap itemCost, @Nonnull ImmutableMap fluidCost) { this.recipe = recipe; this.recipeMap = recipeMap; @@ -81,7 +81,7 @@ public class SingleRecipeCheck { } @Nonnull - public GT_Recipe getRecipe() { + public GTRecipe getRecipe() { return recipe; } @@ -188,14 +188,14 @@ public class SingleRecipeCheck { // At load time we do a recipe check again, so in case the recipe is gone, we can stop tracking. // Of course the next step would be auto migrating to new recipe (if any), but given // we don't yet have a mean to uniquely name a recipe, this will have to make do. - // Consider move serialization code to GT_Recipe once this has been proven to work + // Consider move serialization code to GTRecipe once this has been proven to work NBTTagCompound tag = new NBTTagCompound(); tag.setString("recipemap", recipeMap.unlocalizedName); if (recipe.mInputs != null) { - tag.setTag("inputs", writeList(recipe.mInputs, GT_Utility::saveItem)); + tag.setTag("inputs", writeList(recipe.mInputs, GTUtility::saveItem)); } if (recipe.mOutputs != null) { - tag.setTag("outputs", writeList(recipe.mOutputs, GT_Utility::saveItem)); + tag.setTag("outputs", writeList(recipe.mOutputs, GTUtility::saveItem)); } if (recipe.mChances != null) { tag.setIntArray("chances", recipe.mChances); @@ -270,45 +270,44 @@ public class SingleRecipeCheck { return null; } - GT_Recipe foundRecipe = tryFindRecipe(mapToUse, tag); + GTRecipe foundRecipe = tryFindRecipe(mapToUse, tag); if (foundRecipe == null) return null; return new SingleRecipeCheck(foundRecipe, mapToUse, loadItemCost(tag), loadFluidCost(tag)); } private static ImmutableMap loadFluidCost(NBTTagCompound tag) { - return GT_Utility.streamCompounds(tag.getTagList("fluidCost", Constants.NBT.TAG_COMPOUND)) + return GTUtility.streamCompounds(tag.getTagList("fluidCost", Constants.NBT.TAG_COMPOUND)) .collect( - GT_Utility + GTUtility .toImmutableMapSerial(t -> FluidRegistry.getFluid(t.getString("id")), t -> t.getInteger("count"))); } private static ImmutableMap loadItemCost(NBTTagCompound tag) { - return GT_Utility.streamCompounds(tag.getTagList("itemCost", Constants.NBT.TAG_COMPOUND)) + return GTUtility.streamCompounds(tag.getTagList("itemCost", Constants.NBT.TAG_COMPOUND)) .collect( - GT_Utility - .toImmutableMapSerial(t -> ItemId.create(t.getCompoundTag("id")), t -> t.getInteger("count"))); + GTUtility.toImmutableMapSerial(t -> ItemId.create(t.getCompoundTag("id")), t -> t.getInteger("count"))); } - private static GT_Recipe tryFindRecipe(@Nonnull RecipeMap recipeMap, NBTTagCompound tag) { - ItemStack[] inputs = GT_Utility.streamCompounds(tag.getTagList("inputs", Constants.NBT.TAG_COMPOUND)) - .map(GT_Utility::loadItem) + private static GTRecipe tryFindRecipe(@Nonnull RecipeMap recipeMap, NBTTagCompound tag) { + ItemStack[] inputs = GTUtility.streamCompounds(tag.getTagList("inputs", Constants.NBT.TAG_COMPOUND)) + .map(GTUtility::loadItem) .toArray(ItemStack[]::new); - ItemStack[] outputs = GT_Utility.streamCompounds(tag.getTagList("outputs", Constants.NBT.TAG_COMPOUND)) - .map(GT_Utility::loadItem) + ItemStack[] outputs = GTUtility.streamCompounds(tag.getTagList("outputs", Constants.NBT.TAG_COMPOUND)) + .map(GTUtility::loadItem) .toArray(ItemStack[]::new); - FluidStack[] fInputs = GT_Utility.streamCompounds(tag.getTagList("fInputs", Constants.NBT.TAG_COMPOUND)) + FluidStack[] fInputs = GTUtility.streamCompounds(tag.getTagList("fInputs", Constants.NBT.TAG_COMPOUND)) .map(FluidStack::loadFluidStackFromNBT) .toArray(FluidStack[]::new); - FluidStack[] fOutputs = GT_Utility.streamCompounds(tag.getTagList("fOutputs", Constants.NBT.TAG_COMPOUND)) + FluidStack[] fOutputs = GTUtility.streamCompounds(tag.getTagList("fOutputs", Constants.NBT.TAG_COMPOUND)) .map(FluidStack::loadFluidStackFromNBT) .toArray(FluidStack[]::new); int eut = tag.getInteger("eut"); - GT_Recipe found = recipeMap.findRecipe(null, false, GT_Values.V[GT_Utility.getTier(eut)], fInputs, inputs); + GTRecipe found = recipeMap.findRecipe(null, false, GTValues.V[GTUtility.getTier(eut)], fInputs, inputs); int[] chances = tag.getIntArray("chances"); if (chances.length == 0) chances = null; - if (found == null || !GT_Utility.equals(inputs, found.mInputs) + if (found == null || !GTUtility.equals(inputs, found.mInputs) || !Arrays.equals(fInputs, found.mFluidInputs) - || !GT_Utility.equals(outputs, found.mOutputs) + || !GTUtility.equals(outputs, found.mOutputs) || !Arrays.equals(fOutputs, found.mFluidOutputs) || !Arrays.equals(chances, found.mChances) || found.mDuration != tag.getInteger("duration") @@ -350,7 +349,7 @@ public class SingleRecipeCheck { private Map afterItems; private Map afterFluids; - private GT_Recipe recipe; + private GTRecipe recipe; private Builder(@Nonnull RecipeMap recipeMap) { this.recipeMap = recipeMap; @@ -368,7 +367,7 @@ public class SingleRecipeCheck { return this; } - public Builder setRecipe(@Nonnull GT_Recipe recipe) { + public Builder setRecipe(@Nonnull GTRecipe recipe) { this.recipe = recipe; return this; } diff --git a/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java b/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java index cfa25e9fe2..8273c895b2 100644 --- a/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java @@ -9,7 +9,7 @@ import net.minecraftforge.fluids.FluidStack; import gregtech.api.enums.ItemList; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; @ParametersAreNonnullByDefault @@ -21,7 +21,7 @@ public class AssemblerBackend extends RecipeMapBackend { } @Override - protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + protected GTRecipe modifyFoundRecipe(GTRecipe recipe, ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { for (ItemStack item : items) { if (ItemList.Paper_Printed_Pages.isStackEqual(item, false, true)) { diff --git a/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java b/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java index 3d56c96b82..4bf3f7f56e 100644 --- a/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java @@ -10,7 +10,7 @@ import com.gtnewhorizons.modularui.api.math.Pos2d; import com.gtnewhorizons.modularui.api.screen.ModularWindow; import com.gtnewhorizons.modularui.common.widget.ProgressBar; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.recipe.RecipeMapFrontend; @@ -52,21 +52,21 @@ public class AssemblyLineFrontend extends RecipeMapFrontend { int bar2Width = 18; List> splitProgress = splitProgress(progressSupplier, bar1Width, bar2Width); builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, bar1Width) + new ProgressBar().setTexture(GTUITextures.PROGRESSBAR_ASSEMBLY_LINE_1, bar1Width) .setDirection(ProgressBar.Direction.RIGHT) .setProgress(splitProgress.get(0)) .setSynced(false, false) .setPos(new Pos2d(88, 8).add(windowOffset)) .setSize(bar1Width, 72)); builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, bar2Width) + new ProgressBar().setTexture(GTUITextures.PROGRESSBAR_ASSEMBLY_LINE_2, bar2Width) .setDirection(ProgressBar.Direction.RIGHT) .setProgress(splitProgress.get(1)) .setSynced(false, false) .setPos(new Pos2d(124, 8).add(windowOffset)) .setSize(bar2Width, 72)); builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_3, 18) + new ProgressBar().setTexture(GTUITextures.PROGRESSBAR_ASSEMBLY_LINE_3, 18) .setDirection(ProgressBar.Direction.UP) .setProgress(progressSupplier) .setSynced(false, false) diff --git a/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java b/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java index e5681f59aa..9bbe087e54 100644 --- a/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java @@ -8,11 +8,11 @@ import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidContainerItem; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; @ParametersAreNonnullByDefault @@ -24,17 +24,17 @@ public class FluidCannerBackend extends RecipeMapBackend { } @Override - protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + protected GTRecipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { if (items.length == 0 || items[0] == null) { return null; } if (fluids.length > 0 && fluids[0] != null) { - ItemStack filledItem = GT_Utility.fillFluidContainer(fluids[0], items[0], false, true); - FluidStack fluidToTake = GT_Utility.getFluidForFilledItem(filledItem, true); + ItemStack filledItem = GTUtility.fillFluidContainer(fluids[0], items[0], false, true); + FluidStack fluidToTake = GTUtility.getFluidForFilledItem(filledItem, true); if (fluidToTake != null) { - return GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])) + return GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])) .itemOutputs(filledItem) .fluidInputs(fluidToTake) .duration(Math.max(fluidToTake.amount / 64, 16)) @@ -45,11 +45,11 @@ public class FluidCannerBackend extends RecipeMapBackend { .orElse(null); } } - FluidStack drainedFluid = GT_Utility.getFluidForFilledItem(items[0], true); + FluidStack drainedFluid = GTUtility.getFluidForFilledItem(items[0], true); if (drainedFluid != null) { - return GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])) - .itemOutputs(GT_Utility.getContainerItem(items[0], true)) + return GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])) + .itemOutputs(GTUtility.getContainerItem(items[0], true)) .fluidOutputs(drainedFluid) .duration(Math.max(drainedFluid.amount / 64, 16)) .eut(1) diff --git a/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java b/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java index ce3ea3e89c..ccf6e63c29 100644 --- a/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java @@ -7,12 +7,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.ItemList; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -27,7 +27,7 @@ public class FormingPressBackend extends RecipeMapBackend { } @Override - protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + protected GTRecipe modifyFoundRecipe(GTRecipe recipe, ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { for (ItemStack mold : items) { if (ItemList.Shape_Mold_Credit.isStackEqual(mold, false, true)) { @@ -46,7 +46,7 @@ public class FormingPressBackend extends RecipeMapBackend { } @Override - protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + protected GTRecipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { if (items.length < 2) { return null; } @@ -54,16 +54,16 @@ public class FormingPressBackend extends RecipeMapBackend { } @Nullable - private GT_Recipe findRenamingRecipe(ItemStack[] inputs) { + private GTRecipe findRenamingRecipe(ItemStack[] inputs) { ItemStack mold = findNameMoldIndex(inputs); if (mold == null) return null; ItemStack input = findStackToRename(inputs, mold); if (input == null) return null; - ItemStack output = GT_Utility.copyAmount(1, input); + ItemStack output = GTUtility.copyAmount(1, input); if (output == null) return null; output.setStackDisplayName(mold.getDisplayName()); - return GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(0, mold), GT_Utility.copyAmount(1, input)) + return GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(0, mold), GTUtility.copyAmount(1, input)) .itemOutputs(output) .duration(128) .eut(8) diff --git a/src/main/java/gregtech/api/recipe/maps/FuelBackend.java b/src/main/java/gregtech/api/recipe/maps/FuelBackend.java index 49c989e174..e5f0ab40d1 100644 --- a/src/main/java/gregtech/api/recipe/maps/FuelBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/FuelBackend.java @@ -12,23 +12,23 @@ import net.minecraftforge.fluids.FluidStack; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class FuelBackend extends RecipeMapBackend { - private final Map recipesByFluidInput = new HashMap<>(); + private final Map recipesByFluidInput = new HashMap<>(); public FuelBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { super(propertiesBuilder.disableOptimize()); } @Override - protected Collection doAdd(GT_RecipeBuilder builder) { + protected Collection doAdd(GTRecipeBuilder builder) { if (builder.getDuration() == -1) { builder.duration(0); } @@ -39,11 +39,11 @@ public class FuelBackend extends RecipeMapBackend { } @Override - public GT_Recipe compileRecipe(GT_Recipe recipe) { + public GTRecipe compileRecipe(GTRecipe recipe) { super.compileRecipe(recipe); - if (recipe.mInputs != null && GT_Utility.getNonnullElementCount(recipe.mInputs) == 1 - && (recipe.mFluidInputs == null || GT_Utility.getNonnullElementCount(recipe.mFluidInputs) == 0)) { - FluidStack fluidStack = GT_Utility.getFluidForFilledItem(recipe.mInputs[0], true); + if (recipe.mInputs != null && GTUtility.getNonnullElementCount(recipe.mInputs) == 1 + && (recipe.mFluidInputs == null || GTUtility.getNonnullElementCount(recipe.mFluidInputs) == 0)) { + FluidStack fluidStack = GTUtility.getFluidForFilledItem(recipe.mInputs[0], true); if (fluidStack != null) { fluidStack.amount = 0; recipesByFluidInput.put( @@ -51,9 +51,9 @@ public class FuelBackend extends RecipeMapBackend { .getName(), recipe); } - } else if ((recipe.mInputs == null || GT_Utility.getNonnullElementCount(recipe.mInputs) == 0) + } else if ((recipe.mInputs == null || GTUtility.getNonnullElementCount(recipe.mInputs) == 0) && recipe.mFluidInputs != null - && GT_Utility.getNonnullElementCount(recipe.mFluidInputs) >= 1 + && GTUtility.getNonnullElementCount(recipe.mFluidInputs) >= 1 && recipe.mFluidInputs[0] != null) { recipesByFluidInput.put( recipe.mFluidInputs[0].getFluid() @@ -64,12 +64,12 @@ public class FuelBackend extends RecipeMapBackend { } @Nullable - public GT_Recipe findFuel(FluidStack fluidStack) { + public GTRecipe findFuel(FluidStack fluidStack) { return findFuel(fluidStack.getFluid()); } @Nullable - public GT_Recipe findFuel(Fluid fluid) { + public GTRecipe findFuel(Fluid fluid) { return recipesByFluidInput.get(fluid.getName()); } } diff --git a/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java b/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java index c4095eeb4e..e501db3c40 100644 --- a/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java @@ -6,11 +6,11 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -25,18 +25,18 @@ public class FurnaceBackend extends NonGTBackend { } @Override - protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, - @Nullable GT_Recipe cachedRecipe) { + protected GTRecipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GTRecipe cachedRecipe) { if (items.length == 0 || items[0] == null) { return null; } if (cachedRecipe != null && cachedRecipe.isRecipeInputEqual(false, true, fluids, items)) { return cachedRecipe; } - ItemStack output = GT_ModHandler.getSmeltingOutput(items[0], false, null); + ItemStack output = GTModHandler.getSmeltingOutput(items[0], false, null); return output == null ? null - : GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])) + : GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])) .itemOutputs(output) .duration(128) .eut(4) @@ -47,6 +47,6 @@ public class FurnaceBackend extends NonGTBackend { @Override public boolean containsInput(ItemStack item) { - return GT_ModHandler.getSmeltingOutput(item, false, null) != null; + return GTModHandler.getSmeltingOutput(item, false, null) != null; } } diff --git a/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java b/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java index b38b66e41b..a27e425efb 100644 --- a/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java @@ -9,11 +9,11 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; @SuppressWarnings({ "unused", "UnusedReturnValue" }) @@ -46,11 +46,11 @@ public class LargeBoilerFuelBackend extends RecipeMapBackend { return ALLOWED_SOLID_FUELS.add(itemregistryName + ":" + meta); } - public GT_Recipe addDenseLiquidRecipe(GT_Recipe recipe) { + public GTRecipe addDenseLiquidRecipe(GTRecipe recipe) { return addRecipe(recipe, ((double) recipe.mSpecialValue) / 10, false); } - public GT_Recipe addDieselRecipe(GT_Recipe recipe) { + public GTRecipe addDieselRecipe(GTRecipe recipe) { return addRecipe(recipe, ((double) recipe.mSpecialValue) / 40, false); } @@ -61,12 +61,12 @@ public class LargeBoilerFuelBackend extends RecipeMapBackend { } @Nullable - public GT_Recipe addSolidRecipe(@Nullable ItemStack fuelItemStack) { + public GTRecipe addSolidRecipe(@Nullable ItemStack fuelItemStack) { if (fuelItemStack == null) { return null; } if (!addedGeneralDesc) { - GT_Values.RA.stdBuilder() + GTValues.RA.stdBuilder() .duration(1) .eut(1) .specialValue(1) @@ -82,17 +82,17 @@ public class LargeBoilerFuelBackend extends RecipeMapBackend { String registryName = Item.itemRegistry.getNameForObject(fuelItemStack.getItem()); boolean isHighTierAllowed = ALLOWED_SOLID_FUELS.contains(registryName + ":" + fuelItemStack.getItemDamage()); - return GT_Values.RA.stdBuilder() + return GTValues.RA.stdBuilder() .itemInputs(fuelItemStack) .duration(1) .eut(0) - .specialValue(GT_ModHandler.getFuelValue(fuelItemStack) / 1600) + .specialValue(GTModHandler.getFuelValue(fuelItemStack) / 1600) .build() - .map(r -> addRecipe(r, ((double) GT_ModHandler.getFuelValue(fuelItemStack)) / 1600, isHighTierAllowed)) + .map(r -> addRecipe(r, ((double) GTModHandler.getFuelValue(fuelItemStack)) / 1600, isHighTierAllowed)) .orElse(null); } - private GT_Recipe addRecipe(GT_Recipe recipe, double baseBurnTime, boolean isHighTierAllowed) { + private GTRecipe addRecipe(GTRecipe recipe, double baseBurnTime, boolean isHighTierAllowed) { // Some recipes will have a burn time like 15.9999999 and % always rounds down double floatErrorCorrection = 0.0001; diff --git a/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java b/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java index 53623cb0c7..ae4b5f5d35 100644 --- a/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java @@ -1,8 +1,8 @@ package gregtech.api.recipe.maps; -import static gregtech.api.enums.GT_Values.W; -import static gregtech.api.util.GT_RecipeConstants.EXPLODE; -import static gregtech.api.util.GT_RecipeConstants.ON_FIRE; +import static gregtech.api.enums.GTValues.W; +import static gregtech.api.util.GTRecipeConstants.EXPLODE; +import static gregtech.api.util.GTRecipeConstants.ON_FIRE; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -13,18 +13,18 @@ import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityFurnace; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.ItemList; import gregtech.api.enums.SubTag; import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_OreDictUnificator; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -39,8 +39,8 @@ public class MicrowaveBackend extends NonGTBackend { } @Override - protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, - @Nullable GT_Recipe cachedRecipe) { + protected GTRecipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GTRecipe cachedRecipe) { if (items.length == 0 || items[0] == null) { return null; } @@ -48,12 +48,12 @@ public class MicrowaveBackend extends NonGTBackend { return cachedRecipe; } - ItemStack output = GT_ModHandler.getSmeltingOutput(items[0], false, null); + ItemStack output = GTModHandler.getSmeltingOutput(items[0], false, null); - if (GT_Utility.areStacksEqual(items[0], new ItemStack(Items.book, 1, W))) { - return GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])) - .itemOutputs(GT_Utility.getWrittenBook("Manual_Microwave", ItemList.Book_Written_03.get(1))) + if (GTUtility.areStacksEqual(items[0], new ItemStack(Items.book, 1, W))) { + return GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])) + .itemOutputs(GTUtility.getWrittenBook("Manual_Microwave", ItemList.Book_Written_03.get(1))) .duration(32) .eut(4) .noOptimize() @@ -63,37 +63,36 @@ public class MicrowaveBackend extends NonGTBackend { // Check Container Item of Input since it is around the Input, then the Input itself, then Container Item of // Output and last check the Output itself - for (ItemStack item : new ItemStack[] { GT_Utility.getContainerItem(items[0], true), items[0], - GT_Utility.getContainerItem(output, true), output }) { + for (ItemStack item : new ItemStack[] { GTUtility.getContainerItem(items[0], true), items[0], + GTUtility.getContainerItem(output, true), output }) { if (item == null) continue; - if (GT_Utility.areStacksEqual(item, new ItemStack(Blocks.netherrack, 1, W), true) - || GT_Utility.areStacksEqual(item, new ItemStack(Blocks.tnt, 1, W), true) - || GT_Utility.areStacksEqual(item, new ItemStack(Items.egg, 1, W), true) - || GT_Utility.areStacksEqual(item, new ItemStack(Items.firework_charge, 1, W), true) - || GT_Utility.areStacksEqual(item, new ItemStack(Items.fireworks, 1, W), true) - || GT_Utility.areStacksEqual(item, new ItemStack(Items.fire_charge, 1, W), true)) { - GT_Log.exp - .println("Microwave Explosion due to TNT || EGG || FIREWORKCHARGE || FIREWORK || FIRE CHARGE"); - return GT_RecipeBuilder.empty() + if (GTUtility.areStacksEqual(item, new ItemStack(Blocks.netherrack, 1, W), true) + || GTUtility.areStacksEqual(item, new ItemStack(Blocks.tnt, 1, W), true) + || GTUtility.areStacksEqual(item, new ItemStack(Items.egg, 1, W), true) + || GTUtility.areStacksEqual(item, new ItemStack(Items.firework_charge, 1, W), true) + || GTUtility.areStacksEqual(item, new ItemStack(Items.fireworks, 1, W), true) + || GTUtility.areStacksEqual(item, new ItemStack(Items.fire_charge, 1, W), true)) { + GTLog.exp.println("Microwave Explosion due to TNT || EGG || FIREWORKCHARGE || FIREWORK || FIRE CHARGE"); + return GTRecipeBuilder.empty() .metadata(EXPLODE, true) .build() .orElse(null); } - ItemData itemData = GT_OreDictUnificator.getItemData(item); + ItemData itemData = GTOreDictUnificator.getItemData(item); if (itemData != null) { if (itemData.mMaterial != null && itemData.mMaterial.mMaterial != null) { if (itemData.mMaterial.mMaterial.contains(SubTag.METAL) || itemData.mMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) { - GT_Log.exp.println("Microwave Explosion due to METAL insertion"); - return GT_RecipeBuilder.empty() + GTLog.exp.println("Microwave Explosion due to METAL insertion"); + return GTRecipeBuilder.empty() .metadata(EXPLODE, true) .build() .orElse(null); } if (itemData.mMaterial.mMaterial.contains(SubTag.FLAMMABLE)) { - GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); - return GT_RecipeBuilder.empty() + GTLog.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); + return GTRecipeBuilder.empty() .metadata(ON_FIRE, true) .build() .orElse(null); @@ -103,15 +102,15 @@ public class MicrowaveBackend extends NonGTBackend { if (materialStack == null) continue; if (materialStack.mMaterial.contains(SubTag.METAL) || materialStack.mMaterial.contains(SubTag.EXPLOSIVE)) { - GT_Log.exp.println("Microwave Explosion due to METAL insertion"); - return GT_RecipeBuilder.empty() + GTLog.exp.println("Microwave Explosion due to METAL insertion"); + return GTRecipeBuilder.empty() .metadata(EXPLODE, true) .build() .orElse(null); } if (materialStack.mMaterial.contains(SubTag.FLAMMABLE)) { - GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); - return GT_RecipeBuilder.empty() + GTLog.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); + return GTRecipeBuilder.empty() .metadata(ON_FIRE, true) .build() .orElse(null); @@ -119,8 +118,8 @@ public class MicrowaveBackend extends NonGTBackend { } } if (TileEntityFurnace.getItemBurnTime(item) > 0) { - GT_Log.exp.println("Microwave INFLAMMATION due to BURNABLE insertion"); - return GT_RecipeBuilder.empty() + GTLog.exp.println("Microwave INFLAMMATION due to BURNABLE insertion"); + return GTRecipeBuilder.empty() .metadata(ON_FIRE, true) .build() .orElse(null); @@ -128,8 +127,8 @@ public class MicrowaveBackend extends NonGTBackend { } return output == null ? null - : GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])) + : GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])) .itemOutputs(output) .duration(32) .eut(4) @@ -140,6 +139,6 @@ public class MicrowaveBackend extends NonGTBackend { @Override public boolean containsInput(ItemStack item) { - return GT_ModHandler.getSmeltingOutput(item, false, null) != null; + return GTModHandler.getSmeltingOutput(item, false, null) != null; } } diff --git a/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java b/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java index 1e871df372..3a66a1c980 100644 --- a/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java @@ -9,7 +9,7 @@ import net.minecraftforge.fluids.FluidStack; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -24,8 +24,8 @@ public abstract class NonGTBackend extends RecipeMapBackend { } @Override - protected abstract GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, - @Nullable ItemStack specialSlot, @Nullable GT_Recipe cachedRecipe); + protected abstract GTRecipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, + @Nullable ItemStack specialSlot, @Nullable GTRecipe cachedRecipe); @Override protected boolean doesOverwriteFindRecipe() { @@ -46,7 +46,7 @@ public abstract class NonGTBackend extends RecipeMapBackend { public void reInit() {} @Override - protected GT_Recipe addToItemMap(GT_Recipe recipe) { + protected GTRecipe addToItemMap(GTRecipe recipe) { return recipe; } } diff --git a/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java b/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java index c2c312a48a..6417334d34 100644 --- a/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java @@ -9,7 +9,7 @@ import net.minecraftforge.fluids.FluidStack; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; @ParametersAreNonnullByDefault @@ -23,7 +23,7 @@ public class OilCrackerBackend extends RecipeMapBackend { } @Override - public GT_Recipe compileRecipe(GT_Recipe recipe) { + public GTRecipe compileRecipe(GTRecipe recipe) { super.compileRecipe(recipe); if (recipe.mFluidInputs != null && recipe.mFluidInputs.length > 1 && recipe.mFluidInputs[1] != null) { validCatalystFluidNames.add( diff --git a/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java b/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java index a933886447..788828df52 100644 --- a/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.maps; -import static gregtech.api.enums.GT_Values.L; +import static gregtech.api.enums.GTValues.L; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -12,13 +12,13 @@ import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import gregtech.api.enums.Dyes; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.ItemList; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -33,14 +33,14 @@ public class PrinterBackend extends RecipeMapBackend { } @Override - protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + protected GTRecipe modifyFoundRecipe(GTRecipe recipe, ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { if (items[0].getItem() == Items.paper) { assert specialSlot != null; if (!ItemList.Tool_DataStick.isStackEqual(specialSlot, false, true)) return null; NBTTagCompound nbt = specialSlot.getTagCompound(); - if (nbt == null || GT_Utility.isStringInvalid(nbt.getString("title")) - || GT_Utility.isStringInvalid(nbt.getString("author"))) return null; + if (nbt == null || GTUtility.isStringInvalid(nbt.getString("title")) + || GTUtility.isStringInvalid(nbt.getString("author"))) return null; recipe = recipe.copy(); recipe.mCanBeBuffered = false; @@ -67,7 +67,7 @@ public class PrinterBackend extends RecipeMapBackend { recipe = recipe.copy(); recipe.mCanBeBuffered = false; recipe.mOutputs[0].setTagCompound( - GT_Utility.getNBTContainingString( + GTUtility.getNBTContainingString( new NBTTagCompound(), "GT.PunchCardData", nbt.getString("GT.PunchCardData"))); @@ -77,7 +77,7 @@ public class PrinterBackend extends RecipeMapBackend { } @Override - protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + protected GTRecipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { if (items.length == 0 || items[0] == null || fluids.length == 0 || fluids[0] == null) { return null; } @@ -88,7 +88,7 @@ public class PrinterBackend extends RecipeMapBackend { } if (dye == null) return null; - ItemStack batchRecolorOutput = GT_ModHandler.getAllRecipeOutput( + ItemStack batchRecolorOutput = GTModHandler.getAllRecipeOutput( null, items[0], items[0], @@ -100,8 +100,8 @@ public class PrinterBackend extends RecipeMapBackend { items[0], items[0]); if (batchRecolorOutput != null) { - return GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(8, items[0])) + return GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(8, items[0])) .itemOutputs(batchRecolorOutput) .fluidInputs(new FluidStack(fluids[0].getFluid(), (int) L)) .duration(256) @@ -112,11 +112,11 @@ public class PrinterBackend extends RecipeMapBackend { .orElse(null); } - ItemStack singleRecolorOutput = GT_ModHandler + ItemStack singleRecolorOutput = GTModHandler .getAllRecipeOutput(null, items[0], ItemList.DYE_ONLY_ITEMS[dye.mIndex].get(1)); if (singleRecolorOutput != null) { - return GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])) + return GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])) .itemOutputs(singleRecolorOutput) .fluidInputs(new FluidStack(fluids[0].getFluid(), (int) L)) .duration(32) diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitClarifierFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitClarifierFrontend.java index c7dad7ea3a..e681c95403 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitClarifierFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitClarifierFrontend.java @@ -11,13 +11,13 @@ import com.gtnewhorizons.modularui.api.math.Size; import codechicken.nei.PositionedStack; import gregtech.api.enums.ItemList; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.util.MethodsReturnNonnullByDefault; import gregtech.common.gui.modularui.UIHelper; -import gregtech.common.tileentities.machines.multi.purification.GT_MetaTileEntity_PurificationUnitClarifier; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.common.tileentities.machines.multi.purification.MTEPurificationUnitClarifier; +import gregtech.nei.GTNEIDefaultHandler; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @@ -28,7 +28,7 @@ public class PurificationUnitClarifierFrontend extends PurificationUnitRecipeMap super( 80, uiPropertiesBuilder.logoPos(new Pos2d(160, 100)) - .progressBarTexture(new FallbackableUITexture(GT_UITextures.PROGRESSBAR_CLARIFIER)) + .progressBarTexture(new FallbackableUITexture(GTUITextures.PROGRESSBAR_CLARIFIER)) .logoPos(new Pos2d(152, 90)), neiPropertiesBuilder.recipeBackgroundSize(new Size(170, 120))); } @@ -60,12 +60,12 @@ public class PurificationUnitClarifierFrontend extends PurificationUnitRecipeMap } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { super.drawNEIOverlays(neiCachedRecipe); for (PositionedStack stack : neiCachedRecipe.mInputs) { if (stack.item.isItemEqual(ItemList.ActivatedCarbonFilterMesh.get(1))) { - drawNEIOverlayText((int) (GT_MetaTileEntity_PurificationUnitClarifier.FILTER_DAMAGE_RATE) + "%", stack); + drawNEIOverlayText((int) (MTEPurificationUnitClarifier.FILTER_DAMAGE_RATE) + "%", stack); } } } diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitFlocculatorFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitFlocculatorFrontend.java index 9366237b67..d0373d4310 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitFlocculatorFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitFlocculatorFrontend.java @@ -15,14 +15,14 @@ import com.gtnewhorizons.modularui.api.math.Size; import codechicken.nei.PositionedStack; import gregtech.api.enums.Materials; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; import gregtech.common.gui.modularui.UIHelper; -import gregtech.common.tileentities.machines.multi.purification.GT_MetaTileEntity_PurificationUnitFlocculation; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.common.tileentities.machines.multi.purification.MTEPurificationUnitFlocculation; +import gregtech.nei.GTNEIDefaultHandler; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @@ -33,7 +33,7 @@ public class PurificationUnitFlocculatorFrontend extends PurificationUnitRecipeM super( 80, uiPropertiesBuilder.logoPos(new Pos2d(160, 100)) - .progressBarTexture(new FallbackableUITexture(GT_UITextures.PROGRESSBAR_FLOCCULATION)) + .progressBarTexture(new FallbackableUITexture(GTUITextures.PROGRESSBAR_FLOCCULATION)) .logoPos(new Pos2d(152, 100)), neiPropertiesBuilder.recipeBackgroundSize(new Size(170, 120))); } @@ -60,30 +60,29 @@ public class PurificationUnitFlocculatorFrontend extends PurificationUnitRecipeM @Override @NotNull public List handleNEIItemTooltip(ItemStack stack, List currentTip, - GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { - if (stack - .isItemEqual(GT_Utility.getFluidDisplayStack(Materials.PolyAluminiumChloride.getFluid(1000L), false))) { + GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + if (stack.isItemEqual(GTUtility.getFluidDisplayStack(Materials.PolyAluminiumChloride.getFluid(1000L), false))) { currentTip.add("Consumed during operation"); currentTip.add( - "+" + GT_MetaTileEntity_PurificationUnitFlocculation.SUCCESS_PER_LEVEL + "+" + MTEPurificationUnitFlocculation.SUCCESS_PER_LEVEL + "%/" - + GT_MetaTileEntity_PurificationUnitFlocculation.INPUT_CHEMICAL_PER_LEVEL + + MTEPurificationUnitFlocculation.INPUT_CHEMICAL_PER_LEVEL + "L"); } else if (stack - .isItemEqual(GT_Utility.getFluidDisplayStack(Materials.FlocculationWasteLiquid.getFluid(1000L), false))) { + .isItemEqual(GTUtility.getFluidDisplayStack(Materials.FlocculationWasteLiquid.getFluid(1000L), false))) { currentTip.add("Returned in amount equivalent to consumed flocculant."); } return super.handleNEIItemTooltip(stack, currentTip, neiCachedRecipe); } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { super.drawNEIOverlays(neiCachedRecipe); // Display flocculation chemical neiCachedRecipe.mInputs.add( new PositionedStack( - GT_Utility.getFluidDisplayStack(Materials.PolyAluminiumChloride.getFluid(100000L), true), + GTUtility.getFluidDisplayStack(Materials.PolyAluminiumChloride.getFluid(100000L), true), 5, -1, false)); @@ -91,7 +90,7 @@ public class PurificationUnitFlocculatorFrontend extends PurificationUnitRecipeM // Display waste output neiCachedRecipe.mOutputs.add( new PositionedStack( - GT_Utility.getFluidDisplayStack(Materials.FlocculationWasteLiquid.getFluid(100000L), true), + GTUtility.getFluidDisplayStack(Materials.FlocculationWasteLiquid.getFluid(100000L), true), 147, 48, false)); diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitLaserFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitLaserFrontend.java index df42259864..9c90acd8ad 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitLaserFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitLaserFrontend.java @@ -11,8 +11,8 @@ import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.recipe.RecipeMapFrontend; import gregtech.common.gui.modularui.UIHelper; -import gregtech.common.tileentities.machines.multi.purification.GT_MetaTileEntity_PurificationUnitUVTreatment; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.common.tileentities.machines.multi.purification.MTEPurificationUnitUVTreatment; +import gregtech.nei.GTNEIDefaultHandler; public class PurificationUnitLaserFrontend extends RecipeMapFrontend { @@ -22,13 +22,13 @@ public class PurificationUnitLaserFrontend extends RecipeMapFrontend { } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { - final int numLenses = GT_MetaTileEntity_PurificationUnitUVTreatment.LENS_ITEMS.size(); + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + final int numLenses = MTEPurificationUnitUVTreatment.LENS_ITEMS.size(); List positions = UIHelper.getGridPositions(numLenses, 12, -4, 3, 3); // Put in lens items for (int i = 0; i < numLenses; ++i) { Pos2d position = positions.get(i); - ItemStack lens = GT_MetaTileEntity_PurificationUnitUVTreatment.LENS_ITEMS.get(i); + ItemStack lens = MTEPurificationUnitUVTreatment.LENS_ITEMS.get(i); neiCachedRecipe.mInputs.add(new PositionedStack(lens, position.x, position.y, false)); } super.drawNEIOverlays(neiCachedRecipe); diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitOzonationFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitOzonationFrontend.java index cdfd41b78c..e9c1277cb3 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitOzonationFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitOzonationFrontend.java @@ -9,7 +9,7 @@ import com.gtnewhorizons.modularui.api.drawable.FallbackableUITexture; import com.gtnewhorizons.modularui.api.math.Pos2d; import com.gtnewhorizons.modularui.api.math.Size; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.util.MethodsReturnNonnullByDefault; @@ -24,7 +24,7 @@ public class PurificationUnitOzonationFrontend extends PurificationUnitRecipeMap super( 120, uiPropertiesBuilder.logoPos(new Pos2d(160, 100)) - .progressBarTexture(new FallbackableUITexture(GT_UITextures.PROGRESSBAR_OZONATION)) + .progressBarTexture(new FallbackableUITexture(GTUITextures.PROGRESSBAR_OZONATION)) .logoPos(new Pos2d(152, 97)), neiPropertiesBuilder.recipeBackgroundSize(new Size(170, 180))); } diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitParticleExtractorFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitParticleExtractorFrontend.java index bbbd88fd5f..d738ce0750 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitParticleExtractorFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitParticleExtractorFrontend.java @@ -12,7 +12,7 @@ import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.recipe.RecipeMapFrontend; import gregtech.common.gui.modularui.UIHelper; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.nei.GTNEIDefaultHandler; public class PurificationUnitParticleExtractorFrontend extends RecipeMapFrontend { @@ -25,7 +25,7 @@ public class PurificationUnitParticleExtractorFrontend extends RecipeMapFrontend } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { List positions = UIHelper.getGridPositions(2, 30, 14, 2, 1); Pos2d pos1 = positions.get(0); Pos2d pos2 = positions.get(1); diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitPhAdjustmentFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitPhAdjustmentFrontend.java index 7e9eded675..e78d2a395a 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitPhAdjustmentFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitPhAdjustmentFrontend.java @@ -15,13 +15,13 @@ import com.gtnewhorizons.modularui.api.math.Size; import codechicken.nei.PositionedStack; import gregtech.api.enums.Materials; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; -import gregtech.common.tileentities.machines.multi.purification.GT_MetaTileEntity_PurificationUnitPhAdjustment; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.common.tileentities.machines.multi.purification.MTEPurificationUnitPhAdjustment; +import gregtech.nei.GTNEIDefaultHandler; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @@ -32,7 +32,7 @@ public class PurificationUnitPhAdjustmentFrontend extends PurificationUnitRecipe super( 80, uiPropertiesBuilder.logoPos(new Pos2d(160, 100)) - .progressBarTexture(new FallbackableUITexture(GT_UITextures.PROGRESSBAR_PH_NEUTRALIZATION)) + .progressBarTexture(new FallbackableUITexture(GTUITextures.PROGRESSBAR_PH_NEUTRALIZATION)) .logoPos(new Pos2d(152, 90)), neiPropertiesBuilder.recipeBackgroundSize(new Size(170, 120))); } @@ -54,24 +54,23 @@ public class PurificationUnitPhAdjustmentFrontend extends PurificationUnitRecipe @Override @NotNull public List handleNEIItemTooltip(ItemStack stack, List currentTip, - GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { // Add pH adjustment values if (stack.isItemEqual(Materials.SodiumHydroxide.getDust(1))) { - currentTip - .add("+" + GT_MetaTileEntity_PurificationUnitPhAdjustment.PH_PER_ALKALINE_DUST * 64 + " pH/stack"); + currentTip.add("+" + MTEPurificationUnitPhAdjustment.PH_PER_ALKALINE_DUST * 64 + " pH/stack"); } else - if (stack.isItemEqual(GT_Utility.getFluidDisplayStack(Materials.HydrochloricAcid.getFluid(1000L), false))) { - currentTip.add(GT_MetaTileEntity_PurificationUnitPhAdjustment.PH_PER_10_ACID_LITER * 100 + " pH/1000L"); + if (stack.isItemEqual(GTUtility.getFluidDisplayStack(Materials.HydrochloricAcid.getFluid(1000L), false))) { + currentTip.add(MTEPurificationUnitPhAdjustment.PH_PER_10_ACID_LITER * 100 + " pH/1000L"); } return super.handleNEIItemTooltip(stack, currentTip, neiCachedRecipe); } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { neiCachedRecipe.mInputs.add(new PositionedStack(Materials.SodiumHydroxide.getDust(64), 3, 1, false)); neiCachedRecipe.mInputs.add( new PositionedStack( - GT_Utility.getFluidDisplayStack(Materials.HydrochloricAcid.getFluid(1000L), true), + GTUtility.getFluidDisplayStack(Materials.HydrochloricAcid.getFluid(1000L), true), 147, 1, false)); diff --git a/src/main/java/gregtech/api/recipe/maps/PurificationUnitPlasmaHeaterFrontend.java b/src/main/java/gregtech/api/recipe/maps/PurificationUnitPlasmaHeaterFrontend.java index 5c63353b98..a7f35c86a5 100644 --- a/src/main/java/gregtech/api/recipe/maps/PurificationUnitPlasmaHeaterFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/PurificationUnitPlasmaHeaterFrontend.java @@ -11,12 +11,12 @@ import com.gtnewhorizons.modularui.api.math.Size; import codechicken.nei.PositionedStack; import gregtech.api.enums.Materials; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.nei.GTNEIDefaultHandler; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @@ -27,7 +27,7 @@ public class PurificationUnitPlasmaHeaterFrontend extends PurificationUnitRecipe super( 120, uiPropertiesBuilder.logoPos(new Pos2d(152, 90)) - .progressBarTexture(new FallbackableUITexture(GT_UITextures.PROGRESSBAR_PLASMA_HEATER)), + .progressBarTexture(new FallbackableUITexture(GTUITextures.PROGRESSBAR_PLASMA_HEATER)), neiPropertiesBuilder.recipeBackgroundSize(new Size(170, 120))); } @@ -46,12 +46,12 @@ public class PurificationUnitPlasmaHeaterFrontend extends PurificationUnitRecipe } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { neiCachedRecipe.mInputs.add( - new PositionedStack(GT_Utility.getFluidDisplayStack(Materials.Helium.getPlasma(10L), true), 26, 53, false)); + new PositionedStack(GTUtility.getFluidDisplayStack(Materials.Helium.getPlasma(10L), true), 26, 53, false)); neiCachedRecipe.mInputs.add( new PositionedStack( - GT_Utility.getFluidDisplayStack(Materials.SuperCoolant.getFluid(100L), true), + GTUtility.getFluidDisplayStack(Materials.SuperCoolant.getFluid(100L), true), 107, 52, false)); diff --git a/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java b/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java index 55fb9b4cc4..c149be4219 100644 --- a/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java @@ -6,12 +6,12 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; /** @@ -26,17 +26,17 @@ public class RecyclerBackend extends NonGTBackend { } @Override - protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, - @Nullable GT_Recipe cachedRecipe) { + protected GTRecipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GTRecipe cachedRecipe) { if (items.length == 0 || items[0] == null) { return null; } if (cachedRecipe != null && cachedRecipe.isRecipeInputEqual(false, true, fluids, items)) { return cachedRecipe; } - GT_RecipeBuilder builder = GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, items[0])); - ItemStack output = GT_ModHandler.getRecyclerOutput(items[0], 0); + GTRecipeBuilder builder = GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, items[0])); + ItemStack output = GTModHandler.getRecyclerOutput(items[0], 0); if (output != null) { builder.itemOutputs(output) .outputChances(1250); @@ -50,6 +50,6 @@ public class RecyclerBackend extends NonGTBackend { @Override public boolean containsInput(ItemStack item) { - return GT_ModHandler.getRecyclerOutput(item, 0) != null; + return GTModHandler.getRecyclerOutput(item, 0) != null; } } diff --git a/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java b/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java index f201698457..b40b3dd082 100644 --- a/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java @@ -12,34 +12,34 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import gregtech.GT_Mod; +import gregtech.GTMod; import gregtech.api.enums.Element; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.enums.TierEU; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_Recipe; -import gregtech.api.util.GT_RecipeBuilder; -import gregtech.api.util.GT_RecipeConstants; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeBuilder; +import gregtech.api.util.GTRecipeConstants; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; -import gregtech.common.items.behaviors.Behaviour_DataOrb; +import gregtech.common.items.behaviors.BehaviourDataOrb; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class ReplicatorBackend extends RecipeMapBackend { - private final Map recipesByMaterial = new HashMap<>(); + private final Map recipesByMaterial = new HashMap<>(); public ReplicatorBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { super(propertiesBuilder.recipeEmitter(ReplicatorBackend::replicatorRecipeEmitter)); } @Override - public GT_Recipe compileRecipe(GT_Recipe recipe) { + public GTRecipe compileRecipe(GTRecipe recipe) { super.compileRecipe(recipe); - Materials material = recipe.getMetadata(GT_RecipeConstants.MATERIAL); + Materials material = recipe.getMetadata(GTRecipeConstants.MATERIAL); assert material != null; // checked by replicatorRecipeEmitter recipesByMaterial.put(material, recipe); return recipe; @@ -51,8 +51,8 @@ public class ReplicatorBackend extends RecipeMapBackend { } @Override - protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, - @Nullable GT_Recipe cachedRecipe) { + protected GTRecipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GTRecipe cachedRecipe) { if (specialSlot == null) { return null; } @@ -65,19 +65,19 @@ public class ReplicatorBackend extends RecipeMapBackend { @Nullable private static Materials getMaterialFromDataOrb(ItemStack stack) { - if (ItemList.Tool_DataOrb.isStackEqual(stack, false, true) && Behaviour_DataOrb.getDataTitle(stack) + if (ItemList.Tool_DataOrb.isStackEqual(stack, false, true) && BehaviourDataOrb.getDataTitle(stack) .equals("Elemental-Scan")) { - return Element.get(Behaviour_DataOrb.getDataName(stack)).mLinkedMaterials.stream() + return Element.get(BehaviourDataOrb.getDataName(stack)).mLinkedMaterials.stream() .findFirst() .orElse(null); } return null; } - private static Collection replicatorRecipeEmitter(GT_RecipeBuilder builder) { - Materials material = builder.getMetadata(GT_RecipeConstants.MATERIAL); + private static Collection replicatorRecipeEmitter(GTRecipeBuilder builder) { + Materials material = builder.getMetadata(GTRecipeConstants.MATERIAL); if (material == null) { - throw new IllegalStateException("GT_RecipeConstants.MATERIAL must be set for replicator recipe"); + throw new IllegalStateException("GTRecipeConstants.MATERIAL must be set for replicator recipe"); } return Optional.of(material) .map(material1 -> material1.mElement) @@ -85,7 +85,7 @@ public class ReplicatorBackend extends RecipeMapBackend { .map(ReplicatorBackend::getUUMAmountFromMass) .flatMap( uum -> builder.fluidInputs(Materials.UUMatter.getFluid(uum)) - .duration(GT_Utility.safeInt(uum * 512L, 1)) + .duration(GTUtility.safeInt(uum * 512L, 1)) .eut(TierEU.RECIPE_LV) .ignoreCollision() .noOptimize() @@ -95,6 +95,6 @@ public class ReplicatorBackend extends RecipeMapBackend { } private static int getUUMAmountFromMass(long mass) { - return GT_Utility.safeInt((long) Math.pow(mass, GT_Mod.gregtechproxy.replicatorExponent), 1); + return GTUtility.safeInt((long) Math.pow(mass, GTMod.gregtechproxy.replicatorExponent), 1); } } diff --git a/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java b/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java index 98463dcc4d..70c9605e1b 100644 --- a/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.maps; -import static gregtech.api.util.GT_Utility.formatNumbers; +import static gregtech.api.util.GTUtility.formatNumbers; import static net.minecraft.util.EnumChatFormatting.GRAY; import static net.minecraft.util.StatCollector.translateToLocal; @@ -22,7 +22,7 @@ import com.gtnewhorizons.modularui.common.widget.ProgressBar; import appeng.util.ReadableNumberConverter; import codechicken.lib.gui.GuiDraw; import codechicken.nei.PositionedStack; -import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.modularui.GTUITextures; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.recipe.RecipeMapFrontend; @@ -31,7 +31,7 @@ import gregtech.common.gui.modularui.UIHelper; import gregtech.common.misc.spaceprojects.SpaceProjectManager; import gregtech.common.misc.spaceprojects.SpaceProjectManager.FakeSpaceProjectRecipe; import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject; -import gregtech.nei.GT_NEI_DefaultHandler; +import gregtech.nei.GTNEIDefaultHandler; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @@ -76,7 +76,7 @@ public class SpaceProjectFrontend extends RecipeMapFrontend { @Override protected List handleNEIItemInputTooltip(List currentTip, - GT_NEI_DefaultHandler.FixedPositionedStack pStack) { + GTNEIDefaultHandler.FixedPositionedStack pStack) { super.handleNEIItemOutputTooltip(currentTip, pStack); if (pStack.isFluid()) return currentTip; currentTip.add(GRAY + translateToLocal("Item Count: ") + formatNumbers(pStack.realStackSize)); @@ -84,11 +84,11 @@ public class SpaceProjectFrontend extends RecipeMapFrontend { } @Override - public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) { for (PositionedStack stack : neiCachedRecipe.mInputs) { - if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack pStack && stack.item != null + if (stack instanceof GTNEIDefaultHandler.FixedPositionedStack pStack && stack.item != null && !pStack.isFluid()) { - int stackSize = ((GT_NEI_DefaultHandler.FixedPositionedStack) stack).realStackSize; + int stackSize = ((GTNEIDefaultHandler.FixedPositionedStack) stack).realStackSize; String displayString; if (stack.item.stackSize > 9999) { displayString = ReadableNumberConverter.INSTANCE.toWideReadableForm(stackSize); @@ -114,14 +114,14 @@ public class SpaceProjectFrontend extends RecipeMapFrontend { int bar2Width = 18; List> splitProgress = splitProgress(progressSupplier, bar1Width, bar2Width); builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, 17) + new ProgressBar().setTexture(GTUITextures.PROGRESSBAR_ASSEMBLY_LINE_1, 17) .setDirection(ProgressBar.Direction.RIGHT) .setProgress(splitProgress.get(0)) .setSynced(false, false) .setPos(new Pos2d(70, 28).add(windowOffset)) .setSize(bar1Width, 72)); builder.widget( - new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, 18) + new ProgressBar().setTexture(GTUITextures.PROGRESSBAR_ASSEMBLY_LINE_2, 18) .setDirection(ProgressBar.Direction.RIGHT) .setProgress(splitProgress.get(1)) .setSynced(false, false) diff --git a/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java b/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java index 7a5d7ff164..7a4036e7ba 100644 --- a/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java +++ b/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.maps; -import static gregtech.api.util.GT_Utility.formatNumbers; +import static gregtech.api.util.GTUtility.formatNumbers; import java.util.List; @@ -11,7 +11,7 @@ import com.gtnewhorizons.modularui.api.math.Pos2d; import gregtech.api.recipe.BasicUIPropertiesBuilder; import gregtech.api.recipe.NEIRecipePropertiesBuilder; import gregtech.api.recipe.RecipeMapFrontend; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; import gregtech.api.util.MethodsReturnNonnullByDefault; import gregtech.common.gui.modularui.UIHelper; import gregtech.nei.RecipeDisplayInfo; @@ -45,12 +45,12 @@ public class TranscendentPlasmaMixerFrontend extends RecipeMapFrontend { // These look odd because recipeInfo.recipe.mEUt is actually the EU per litre of fluid processed, not // the EU/t. recipeInfo.drawText( - GT_Utility.trans("152", "Total: ") + GTUtility.trans("152", "Total: ") + formatNumbers(1000L * recipeInfo.recipe.mDuration / 100L * recipeInfo.recipe.mEUt) + " EU"); // 1000 / (20 ticks * 5 seconds) = 10L/t. 10L/t * x EU/L = 10 * x EU/t. long averageUsage = 10L * recipeInfo.recipe.mEUt; recipeInfo.drawText( - "Average: " + formatNumbers(averageUsage) + " EU/t" + GT_Utility.getTierNameWithParentheses(averageUsage)); + "Average: " + formatNumbers(averageUsage) + " EU/t" + GTUtility.getTierNameWithParentheses(averageUsage)); } } diff --git a/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java b/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java index e7297f0609..9ea34609f6 100644 --- a/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java +++ b/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java @@ -6,12 +6,12 @@ import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.ItemList; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; -import gregtech.api.util.GT_ModHandler; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTRecipe; import gregtech.api.util.MethodsReturnNonnullByDefault; @ParametersAreNonnullByDefault @@ -23,16 +23,16 @@ public class UnpackagerBackend extends RecipeMapBackend { } @Override - protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + protected GTRecipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { if (items.length == 0 || !ItemList.IC2_Scrapbox.isStackEqual(items[0], false, true)) { return null; } - ItemStack output = GT_ModHandler.getRandomScrapboxDrop(); + ItemStack output = GTModHandler.getRandomScrapboxDrop(); if (output == null) { return null; } - return GT_Values.RA.stdBuilder() + return GTValues.RA.stdBuilder() .itemInputs(ItemList.IC2_Scrapbox.get(1)) .itemOutputs(output) .duration(16) diff --git a/src/main/java/gregtech/api/recipe/metadata/CompressionTierKey.java b/src/main/java/gregtech/api/recipe/metadata/CompressionTierKey.java index 384b5ce2d9..88bd3d6664 100644 --- a/src/main/java/gregtech/api/recipe/metadata/CompressionTierKey.java +++ b/src/main/java/gregtech/api/recipe/metadata/CompressionTierKey.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.metadata; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/gregtech/api/recipe/metadata/PCBFactoryTierKey.java b/src/main/java/gregtech/api/recipe/metadata/PCBFactoryTierKey.java index 05db919b57..ada5574b01 100644 --- a/src/main/java/gregtech/api/recipe/metadata/PCBFactoryTierKey.java +++ b/src/main/java/gregtech/api/recipe/metadata/PCBFactoryTierKey.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.metadata; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/gregtech/api/recipe/metadata/PCBFactoryUpgradeKey.java b/src/main/java/gregtech/api/recipe/metadata/PCBFactoryUpgradeKey.java index 8257f1e6ef..4891c88848 100644 --- a/src/main/java/gregtech/api/recipe/metadata/PCBFactoryUpgradeKey.java +++ b/src/main/java/gregtech/api/recipe/metadata/PCBFactoryUpgradeKey.java @@ -1,6 +1,6 @@ package gregtech.api.recipe.metadata; -import static gregtech.api.util.GT_Utility.trans; +import static gregtech.api.util.GTUtility.trans; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/gregtech/api/registries/LHECoolantRegistry.java b/src/main/java/gregtech/api/registries/LHECoolantRegistry.java index 7944132572..084086c841 100644 --- a/src/main/java/gregtech/api/registries/LHECoolantRegistry.java +++ b/src/main/java/gregtech/api/registries/LHECoolantRegistry.java @@ -7,6 +7,8 @@ import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; +import gregtech.common.tileentities.machines.multi.MTEHeatExchanger; + public class LHECoolantRegistry { private static final Map lheCoolants = new HashMap<>(); @@ -15,9 +17,9 @@ public class LHECoolantRegistry { * Registers a coolant for use in Large Heat Exchangers and Whakawhiti Weras. * See the constants in {@link #registerBaseCoolants()} as a reference for what the multipliers should be. * The multipliers are used in - * {@link gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_HeatExchanger#checkProcessing()} - * and {@link gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_HeatExchanger#onRunningTick()}. - * + * {@link MTEHeatExchanger#checkProcessing()} + * and {@link MTEHeatExchanger#onRunningTick()}. + * * @param coldFluidName The fluid name of the resulting cold coolant * @param hotFluidName The fluid name of the input hot coolant * @param steamMultiplier The steam multiplier diff --git a/src/main/java/gregtech/api/render/TextureFactory.java b/src/main/java/gregtech/api/render/TextureFactory.java index 26142fd606..a87b20ccb4 100644 --- a/src/main/java/gregtech/api/render/TextureFactory.java +++ b/src/main/java/gregtech/api/render/TextureFactory.java @@ -6,7 +6,7 @@ import net.minecraftforge.common.util.ForgeDirection; import gregtech.api.interfaces.IIconContainer; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.ITextureBuilder; -import gregtech.common.render.GT_TextureBuilder; +import gregtech.common.render.GTTextureBuilder; /** *

@@ -152,6 +152,6 @@ public final class TextureFactory { * @return An instance of the {@link ITextureBuilder} implementation */ public static ITextureBuilder builder() { - return new GT_TextureBuilder(); + return new GTTextureBuilder(); } } diff --git a/src/main/java/gregtech/api/task/tasks/PollutionTask.java b/src/main/java/gregtech/api/task/tasks/PollutionTask.java index 060a91acab..3770409fb1 100644 --- a/src/main/java/gregtech/api/task/tasks/PollutionTask.java +++ b/src/main/java/gregtech/api/task/tasks/PollutionTask.java @@ -8,7 +8,7 @@ import gregtech.api.enums.TickTime; import gregtech.api.interfaces.tileentity.IMachineProgress; import gregtech.api.task.TaskHost; import gregtech.api.task.TickableTask; -import gregtech.common.GT_Pollution; +import gregtech.common.Pollution; public class PollutionTask extends TickableTask { @@ -38,7 +38,7 @@ public class PollutionTask extends Tickab public void update(long tick, boolean isServerSide) { if (isServerSide && tick % POLLUTION_TICK == 0 && taskHost.hasThingsToDo()) { if (taskHost instanceof final TileEntity entity) { - GT_Pollution.addPollution(entity, getPollutionPerSecond()); + Pollution.addPollution(entity, getPollutionPerSecond()); } } } diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java deleted file mode 100644 index 5e3b36f473..0000000000 --- a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java +++ /dev/null @@ -1,87 +0,0 @@ -package gregtech.api.threads; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizon.gtnhlib.util.CoordinatePacker; - -import gregtech.GT_Mod; -import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; -import gregtech.api.metatileentity.BaseMetaPipeEntity; -import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; -import gregtech.common.GT_Proxy; - -public class GT_Runnable_Cable_Update extends GT_Runnable_MachineBlockUpdate { - - protected GT_Runnable_Cable_Update(World aWorld, int posX, int posY, int posZ) { - super(aWorld, posX, posY, posZ); - } - - public static void setCableUpdateValues(World aWorld, int posX, int posY, int posZ) { - if (isEnabled) { - EXECUTOR_SERVICE.submit(new GT_Runnable_Cable_Update(aWorld, posX, posY, posZ)); - } - } - - @Override - public void run() { - int posX, posY, posZ; - try { - while (!tQueue.isEmpty()) { - final long packedCoords = tQueue.dequeueLong(); - posX = CoordinatePacker.unpackX(packedCoords); - posY = CoordinatePacker.unpackY(packedCoords); - posZ = CoordinatePacker.unpackZ(packedCoords); - - final TileEntity tTileEntity; - - GT_Proxy.TICK_LOCK.lock(); - try { - // we dont want to go over cables that are in unloaded chunks - // keeping the lock just to make sure no CME happens - if (world.blockExists(posX, posY, posZ)) { - tTileEntity = world.getTileEntity(posX, posY, posZ); - } else { - tTileEntity = null; - } - } finally { - GT_Proxy.TICK_LOCK.unlock(); - } - - // See if the block itself needs an update - if (tTileEntity instanceof IMachineBlockUpdateable) - ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); - - // Now see if we should add the nearby blocks to the queue: - // only add blocks the cable is connected to - if (tTileEntity instanceof BaseMetaPipeEntity metaPipe - && metaPipe.getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable cable) { - for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) { - final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i]; - if (cable.isConnectedAtSide(side)) { - final long tCoords = CoordinatePacker - .pack(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ); - if (visited.add(tCoords)) { - tQueue.enqueue(tCoords); - } - } - } - } - } - } catch (Exception e) { - GT_Mod.GT_FML_LOGGER.error( - "Well this update was broken... " + initialX - + ", " - + initialY - + ", " - + initialZ - + ", mWorld={" - + world.getProviderName() - + " @dimId " - + world.provider.dimensionId - + "}", - e); - } - } -} diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java deleted file mode 100644 index 339556e246..0000000000 --- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java +++ /dev/null @@ -1,184 +0,0 @@ -package gregtech.api.threads; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizon.gtnhlib.util.CoordinatePacker; - -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; -import gregtech.common.GT_Proxy; -import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; - -public class GT_Runnable_MachineBlockUpdate implements Runnable { - - // used by runner thread - protected final int initialX, initialY, initialZ; - protected final World world; - protected final LongSet visited = new LongOpenHashSet(); - protected final LongArrayFIFOQueue tQueue = new LongArrayFIFOQueue(); - - // Threading - private static final ThreadFactory THREAD_FACTORY = r -> { - Thread thread = new Thread(r); - thread.setName("GT_MachineBlockUpdate"); - return thread; - }; - protected static ExecutorService EXECUTOR_SERVICE; - - // This class should never be initiated outside of this class! - protected GT_Runnable_MachineBlockUpdate(World aWorld, int posX, int posY, int posZ) { - this.world = aWorld; - this.initialX = posX; - this.initialY = posY; - this.initialZ = posZ; - final long coords = CoordinatePacker.pack(posX, posY, posZ); - visited.add(coords); - tQueue.enqueue(coords); - } - - public static boolean isEnabled() { - return isEnabled; - } - - public static void setEnabled() { - GT_Runnable_MachineBlockUpdate.isEnabled = true; - } - - public static void setDisabled() { - GT_Runnable_MachineBlockUpdate.isEnabled = false; - } - - public static void setEnabled(boolean isEnabled) { - GT_Runnable_MachineBlockUpdate.isEnabled = isEnabled; - } - - public static boolean isCurrentThreadEnabled() { - return perThreadEnable.get(); - } - - public static void setCurrentThreadEnabled(boolean perThreadEnable) { - GT_Runnable_MachineBlockUpdate.perThreadEnable.set(perThreadEnable); - } - - protected static boolean isEnabled = true; - protected static final ThreadLocal perThreadEnable = ThreadLocal.withInitial(() -> true); - - public static void setMachineUpdateValues(World aWorld, int posX, int posY, int posZ) { - if (isEnabled() && isCurrentThreadEnabled()) { - EXECUTOR_SERVICE.submit(new GT_Runnable_MachineBlockUpdate(aWorld, posX, posY, posZ)); - } - } - - public static void initExecutorService() { - EXECUTOR_SERVICE = Executors.newFixedThreadPool( - Math.max( - 1, - (Runtime.getRuntime() - .availableProcessors() * 2 - / 3)), - THREAD_FACTORY); - } - - public static void shutdownExecutorService() { - try { - GT_Mod.GT_FML_LOGGER.info("Shutting down Machine block update executor service"); - EXECUTOR_SERVICE.shutdown(); // Disable new tasks from being submitted - // Wait a while for existing tasks to terminate - if (!EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS)) { - EXECUTOR_SERVICE.shutdownNow(); // Cancel currently executing tasks - // Wait a while for tasks to respond to being cancelled - if (!EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS)) { - GT_Mod.GT_FML_LOGGER.error( - "Well this didn't terminated well... GT_Runnable_MachineBlockUpdate.shutdownExecutorService"); - } - } - } catch (InterruptedException ie) { - GT_Mod.GT_FML_LOGGER.error("Well this interruption got interrupted...", ie); - // (Re-)Cancel if current thread also interrupted - EXECUTOR_SERVICE.shutdownNow(); - // Preserve interrupt status - Thread.currentThread() - .interrupt(); - } catch (Exception e) { - GT_Mod.GT_FML_LOGGER.error("Well this didn't terminated well...", e); - // (Re-)Cancel in case - EXECUTOR_SERVICE.shutdownNow(); - } finally { - GT_Mod.GT_FML_LOGGER.info("Leaving... GT_Runnable_MachineBlockUpdate.shutdownExecutorService"); - } - } - - @Override - public void run() { - int posX, posY, posZ; - try { - while (!tQueue.isEmpty()) { - final long packedCoords = tQueue.dequeueLong(); - posX = CoordinatePacker.unpackX(packedCoords); - posY = CoordinatePacker.unpackY(packedCoords); - posZ = CoordinatePacker.unpackZ(packedCoords); - - final TileEntity tTileEntity; - final boolean isMachineBlock; - - // This might load a chunk... which might load a TileEntity... which might get added to - // `loadedTileEntityList`... which might be in the process - // of being iterated over during `UpdateEntities()`... which might cause a - // ConcurrentModificationException. So, lock that shit. - GT_Proxy.TICK_LOCK.lock(); - try { - tTileEntity = world.getTileEntity(posX, posY, posZ); - isMachineBlock = GregTech_API - .isMachineBlock(world.getBlock(posX, posY, posZ), world.getBlockMetadata(posX, posY, posZ)); - } finally { - GT_Proxy.TICK_LOCK.unlock(); - } - - // See if the block itself needs an update - if (tTileEntity instanceof IMachineBlockUpdateable) - ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); - - // Now see if we should add the nearby blocks to the queue: - // 1) If we've visited less than 5 blocks, then yes - // 2) If the tile says we should recursively updated (pipes don't, machine blocks do) - // 3) If the block at the coordinates is marked as a machine block - if (visited.size() < 5 - || (tTileEntity instanceof IMachineBlockUpdateable - && ((IMachineBlockUpdateable) tTileEntity).isMachineBlockUpdateRecursive()) - || isMachineBlock) { - for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) { - final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i]; - final long tCoords = CoordinatePacker - .pack(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ); - if (visited.add(tCoords)) { - tQueue.enqueue(tCoords); - } - } - } - } - } catch (Exception e) { - GT_Mod.GT_FML_LOGGER.error( - "Well this update was broken... " + initialX - + ", " - + initialY - + ", " - + initialZ - + ", mWorld={" - + world.getProviderName() - + " @dimId " - + world.provider.dimensionId - + "}", - e); - } - } -} diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_Sound.java b/src/main/java/gregtech/api/threads/GT_Runnable_Sound.java deleted file mode 100644 index 9021a60e89..0000000000 --- a/src/main/java/gregtech/api/threads/GT_Runnable_Sound.java +++ /dev/null @@ -1,41 +0,0 @@ -package gregtech.api.threads; - -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; - -import gregtech.api.util.GT_PlayedSound; -import gregtech.api.util.GT_Utility; - -public class GT_Runnable_Sound implements Runnable { - - private final double mX, mY, mZ; - private final int mTimeUntilNextSound; - private final World mWorld; - private final ResourceLocation mSoundResourceLocation; - private final float mSoundStrength, mSoundModulation; - - public GT_Runnable_Sound(World aWorld, double aX, double aY, double aZ, int aTimeUntilNextSound, - ResourceLocation aSoundResourceLocation, float aSoundStrength, float aSoundModulation) { - mWorld = aWorld; - mX = aX; - mY = aY; - mZ = aZ; - mTimeUntilNextSound = aTimeUntilNextSound; - mSoundResourceLocation = aSoundResourceLocation; - mSoundStrength = aSoundStrength; - mSoundModulation = aSoundModulation; - } - - @Override - public void run() { - try { - GT_PlayedSound tSound; - if (GT_Utility.sPlayedSoundMap.containsKey(tSound = new GT_PlayedSound(mSoundResourceLocation, mX, mY, mZ))) - return; - mWorld.playSound(mX, mY, mZ, mSoundResourceLocation.toString(), mSoundStrength, mSoundModulation, false); - GT_Utility.sPlayedSoundMap.put(tSound, mTimeUntilNextSound); - } catch (Throwable e) { - /**/ - } - } -} diff --git a/src/main/java/gregtech/api/threads/RunnableCableUpdate.java b/src/main/java/gregtech/api/threads/RunnableCableUpdate.java new file mode 100644 index 0000000000..7ed4e28554 --- /dev/null +++ b/src/main/java/gregtech/api/threads/RunnableCableUpdate.java @@ -0,0 +1,87 @@ +package gregtech.api.threads; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.gtnhlib.util.CoordinatePacker; + +import gregtech.GTMod; +import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; +import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gregtech.api.metatileentity.implementations.MTECable; +import gregtech.common.GTProxy; + +public class RunnableCableUpdate extends RunnableMachineUpdate { + + protected RunnableCableUpdate(World aWorld, int posX, int posY, int posZ) { + super(aWorld, posX, posY, posZ); + } + + public static void setCableUpdateValues(World aWorld, int posX, int posY, int posZ) { + if (isEnabled) { + EXECUTOR_SERVICE.submit(new RunnableCableUpdate(aWorld, posX, posY, posZ)); + } + } + + @Override + public void run() { + int posX, posY, posZ; + try { + while (!tQueue.isEmpty()) { + final long packedCoords = tQueue.dequeueLong(); + posX = CoordinatePacker.unpackX(packedCoords); + posY = CoordinatePacker.unpackY(packedCoords); + posZ = CoordinatePacker.unpackZ(packedCoords); + + final TileEntity tTileEntity; + + GTProxy.TICK_LOCK.lock(); + try { + // we dont want to go over cables that are in unloaded chunks + // keeping the lock just to make sure no CME happens + if (world.blockExists(posX, posY, posZ)) { + tTileEntity = world.getTileEntity(posX, posY, posZ); + } else { + tTileEntity = null; + } + } finally { + GTProxy.TICK_LOCK.unlock(); + } + + // See if the block itself needs an update + if (tTileEntity instanceof IMachineBlockUpdateable) + ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); + + // Now see if we should add the nearby blocks to the queue: + // only add blocks the cable is connected to + if (tTileEntity instanceof BaseMetaPipeEntity metaPipe + && metaPipe.getMetaTileEntity() instanceof MTECable cable) { + for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) { + final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i]; + if (cable.isConnectedAtSide(side)) { + final long tCoords = CoordinatePacker + .pack(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ); + if (visited.add(tCoords)) { + tQueue.enqueue(tCoords); + } + } + } + } + } + } catch (Exception e) { + GTMod.GT_FML_LOGGER.error( + "Well this update was broken... " + initialX + + ", " + + initialY + + ", " + + initialZ + + ", mWorld={" + + world.getProviderName() + + " @dimId " + + world.provider.dimensionId + + "}", + e); + } + } +} diff --git a/src/main/java/gregtech/api/threads/RunnableMachineUpdate.java b/src/main/java/gregtech/api/threads/RunnableMachineUpdate.java new file mode 100644 index 0000000000..d11e176f3d --- /dev/null +++ b/src/main/java/gregtech/api/threads/RunnableMachineUpdate.java @@ -0,0 +1,184 @@ +package gregtech.api.threads; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.gtnhlib.util.CoordinatePacker; + +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; +import gregtech.common.GTProxy; +import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; + +public class RunnableMachineUpdate implements Runnable { + + // used by runner thread + protected final int initialX, initialY, initialZ; + protected final World world; + protected final LongSet visited = new LongOpenHashSet(); + protected final LongArrayFIFOQueue tQueue = new LongArrayFIFOQueue(); + + // Threading + private static final ThreadFactory THREAD_FACTORY = r -> { + Thread thread = new Thread(r); + thread.setName("GT_MachineBlockUpdate"); + return thread; + }; + protected static ExecutorService EXECUTOR_SERVICE; + + // This class should never be initiated outside of this class! + protected RunnableMachineUpdate(World aWorld, int posX, int posY, int posZ) { + this.world = aWorld; + this.initialX = posX; + this.initialY = posY; + this.initialZ = posZ; + final long coords = CoordinatePacker.pack(posX, posY, posZ); + visited.add(coords); + tQueue.enqueue(coords); + } + + public static boolean isEnabled() { + return isEnabled; + } + + public static void setEnabled() { + RunnableMachineUpdate.isEnabled = true; + } + + public static void setDisabled() { + RunnableMachineUpdate.isEnabled = false; + } + + public static void setEnabled(boolean isEnabled) { + RunnableMachineUpdate.isEnabled = isEnabled; + } + + public static boolean isCurrentThreadEnabled() { + return perThreadEnable.get(); + } + + public static void setCurrentThreadEnabled(boolean perThreadEnable) { + RunnableMachineUpdate.perThreadEnable.set(perThreadEnable); + } + + protected static boolean isEnabled = true; + protected static final ThreadLocal perThreadEnable = ThreadLocal.withInitial(() -> true); + + public static void setMachineUpdateValues(World aWorld, int posX, int posY, int posZ) { + if (isEnabled() && isCurrentThreadEnabled()) { + EXECUTOR_SERVICE.submit(new RunnableMachineUpdate(aWorld, posX, posY, posZ)); + } + } + + public static void initExecutorService() { + EXECUTOR_SERVICE = Executors.newFixedThreadPool( + Math.max( + 1, + (Runtime.getRuntime() + .availableProcessors() * 2 + / 3)), + THREAD_FACTORY); + } + + public static void shutdownExecutorService() { + try { + GTMod.GT_FML_LOGGER.info("Shutting down Machine block update executor service"); + EXECUTOR_SERVICE.shutdown(); // Disable new tasks from being submitted + // Wait a while for existing tasks to terminate + if (!EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS)) { + EXECUTOR_SERVICE.shutdownNow(); // Cancel currently executing tasks + // Wait a while for tasks to respond to being cancelled + if (!EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS)) { + GTMod.GT_FML_LOGGER.error( + "Well this didn't terminated well... GT_Runnable_MachineBlockUpdate.shutdownExecutorService"); + } + } + } catch (InterruptedException ie) { + GTMod.GT_FML_LOGGER.error("Well this interruption got interrupted...", ie); + // (Re-)Cancel if current thread also interrupted + EXECUTOR_SERVICE.shutdownNow(); + // Preserve interrupt status + Thread.currentThread() + .interrupt(); + } catch (Exception e) { + GTMod.GT_FML_LOGGER.error("Well this didn't terminated well...", e); + // (Re-)Cancel in case + EXECUTOR_SERVICE.shutdownNow(); + } finally { + GTMod.GT_FML_LOGGER.info("Leaving... GT_Runnable_MachineBlockUpdate.shutdownExecutorService"); + } + } + + @Override + public void run() { + int posX, posY, posZ; + try { + while (!tQueue.isEmpty()) { + final long packedCoords = tQueue.dequeueLong(); + posX = CoordinatePacker.unpackX(packedCoords); + posY = CoordinatePacker.unpackY(packedCoords); + posZ = CoordinatePacker.unpackZ(packedCoords); + + final TileEntity tTileEntity; + final boolean isMachineBlock; + + // This might load a chunk... which might load a TileEntity... which might get added to + // `loadedTileEntityList`... which might be in the process + // of being iterated over during `UpdateEntities()`... which might cause a + // ConcurrentModificationException. So, lock that shit. + GTProxy.TICK_LOCK.lock(); + try { + tTileEntity = world.getTileEntity(posX, posY, posZ); + isMachineBlock = GregTechAPI + .isMachineBlock(world.getBlock(posX, posY, posZ), world.getBlockMetadata(posX, posY, posZ)); + } finally { + GTProxy.TICK_LOCK.unlock(); + } + + // See if the block itself needs an update + if (tTileEntity instanceof IMachineBlockUpdateable) + ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); + + // Now see if we should add the nearby blocks to the queue: + // 1) If we've visited less than 5 blocks, then yes + // 2) If the tile says we should recursively updated (pipes don't, machine blocks do) + // 3) If the block at the coordinates is marked as a machine block + if (visited.size() < 5 + || (tTileEntity instanceof IMachineBlockUpdateable + && ((IMachineBlockUpdateable) tTileEntity).isMachineBlockUpdateRecursive()) + || isMachineBlock) { + for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) { + final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i]; + final long tCoords = CoordinatePacker + .pack(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ); + if (visited.add(tCoords)) { + tQueue.enqueue(tCoords); + } + } + } + } + } catch (Exception e) { + GTMod.GT_FML_LOGGER.error( + "Well this update was broken... " + initialX + + ", " + + initialY + + ", " + + initialZ + + ", mWorld={" + + world.getProviderName() + + " @dimId " + + world.provider.dimensionId + + "}", + e); + } + } +} diff --git a/src/main/java/gregtech/api/threads/RunnableSound.java b/src/main/java/gregtech/api/threads/RunnableSound.java new file mode 100644 index 0000000000..30704f2a97 --- /dev/null +++ b/src/main/java/gregtech/api/threads/RunnableSound.java @@ -0,0 +1,41 @@ +package gregtech.api.threads; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import gregtech.api.util.GTPlayedSound; +import gregtech.api.util.GTUtility; + +public class RunnableSound implements Runnable { + + private final double mX, mY, mZ; + private final int mTimeUntilNextSound; + private final World mWorld; + private final ResourceLocation mSoundResourceLocation; + private final float mSoundStrength, mSoundModulation; + + public RunnableSound(World aWorld, double aX, double aY, double aZ, int aTimeUntilNextSound, + ResourceLocation aSoundResourceLocation, float aSoundStrength, float aSoundModulation) { + mWorld = aWorld; + mX = aX; + mY = aY; + mZ = aZ; + mTimeUntilNextSound = aTimeUntilNextSound; + mSoundResourceLocation = aSoundResourceLocation; + mSoundStrength = aSoundStrength; + mSoundModulation = aSoundModulation; + } + + @Override + public void run() { + try { + GTPlayedSound tSound; + if (GTUtility.sPlayedSoundMap.containsKey(tSound = new GTPlayedSound(mSoundResourceLocation, mX, mY, mZ))) + return; + mWorld.playSound(mX, mY, mZ, mSoundResourceLocation.toString(), mSoundStrength, mSoundModulation, false); + GTUtility.sPlayedSoundMap.put(tSound, mTimeUntilNextSound); + } catch (Throwable e) { + /**/ + } + } +} diff --git a/src/main/java/gregtech/api/util/AssemblyLineServer.java b/src/main/java/gregtech/api/util/AssemblyLineServer.java new file mode 100644 index 0000000000..49e3882982 --- /dev/null +++ b/src/main/java/gregtech/api/util/AssemblyLineServer.java @@ -0,0 +1,297 @@ +package gregtech.api.util; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Materials; +import gregtech.api.enums.MaterialsBotania; + +public class AssemblyLineServer { + + public static LinkedHashMap lServerNames = new LinkedHashMap<>(); + private static LinkedHashMap internal2 = new LinkedHashMap<>(), internal3 = new LinkedHashMap<>(), + internal4 = new LinkedHashMap<>(); + private static HashMap internal = new HashMap<>(); + + public static void fillMap(FMLPreInitializationEvent aEvent) { + Configuration conf = GTLanguageManager.sEnglishFile; + + ConfigCategory cat = conf.getCategory("languagefile"); + internal.putAll(cat.getValues()); + for (Map.Entry entry : internal.entrySet()) { + try { + String s = entry.getValue() + .getString() + .replaceAll("%", ""); + + if (entry.getKey() + .contains("metaitem") && s.contains("material")) internal2.put(entry.getKey(), s); + else if (entry.getKey() + .contains("blockmachines") && s.contains("material")) internal3.put(entry.getKey(), s); + else if ((entry.getKey() + .contains("blockores") + || (entry.getKey() + .contains("blockmetal") + || entry.getKey() + .contains("blockgem"))) + && s.contains("material")) internal4.put(entry.getKey(), s); + else lServerNames.put(entry.getKey(), s); + } catch (Exception ignored) {} + } + for (Map.Entry entry : internal2.entrySet()) { + try { + if (entry.getKey() + .contains("name")) { + int i = Integer.parseInt( + entry.getKey() + .substring( + "gt.metaitem.01.".length(), + entry.getKey() + .length() - ".name".length())); + i = i % 1000; + if (GregTechAPI.sGeneratedMaterials[i] != null) lServerNames.put( + entry.getKey(), + entry.getValue() + .replace("material", GregTechAPI.sGeneratedMaterials[i].toString())); + else lServerNames.put(entry.getKey(), null); + } + } catch (Exception ignored) {} + } + for (Map.Entry entry : internal3.entrySet()) { + try { + if (entry.getKey() + .contains("cable")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.cable.".length(), + entry.getKey() + .length() - ".01.name".length()))); + else if (entry.getKey() + .contains("gt_frame_")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.gt_frame_".length(), + entry.getKey() + .length() - ".name".length()))); + else if (entry.getKey() + .contains("gt_pipe_")) { + if (!entry.getKey() + .contains("_huge") + && !entry.getKey() + .contains("_large") + && !entry.getKey() + .contains("_nonuple") + && !entry.getKey() + .contains("_quadruple") + && !entry.getKey() + .contains("_small") + && !entry.getKey() + .contains("_tiny")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.gt_pipe_".length(), + entry.getKey() + .length() - ".name".length()))); + else if (entry.getKey() + .contains("_huge") + || entry.getKey() + .contains("_tiny")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.gt_pipe_".length(), + entry.getKey() + .length() - "_tiny.name".length()))); + else if (entry.getKey() + .contains("_large") + || entry.getKey() + .contains("_small")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.gt_pipe_".length(), + entry.getKey() + .length() - "_large.name".length()))); + else if (entry.getKey() + .contains("_nonuple")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.gt_pipe_".length(), + entry.getKey() + .length() - "_nonuple.name".length()))); + else if (entry.getKey() + .contains("_quadruple")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.gt_pipe_".length(), + entry.getKey() + .length() - "_quadruple.name".length()))); + } else if (entry.getKey() + .contains("wire")) + lServerNames.put( + entry.getKey(), + entry.getValue() + .replace( + "material", + entry.getKey() + .substring( + "gt.blockmachines.wire.".length(), + entry.getKey() + .length() - ".01.name".length()))); + else lServerNames.put(entry.getKey(), entry.getValue()); + } catch (Exception ignored) {} + } + for (Map.Entry entry : internal4.entrySet()) { + try { + if (entry.getKey() + .contains("blockores")) { + int i = Integer.parseInt( + entry.getKey() + .substring( + "gt.blockores.".length(), + entry.getKey() + .length() - ".name".length())); + i = i % 1000; + if (GregTechAPI.sGeneratedMaterials[i] != null) lServerNames.put( + entry.getKey(), + entry.getValue() + .replace("material", GregTechAPI.sGeneratedMaterials[i].toString())); + else lServerNames.put(entry.getKey(), null); + } else if (entry.getKey() + .contains("blockmetal")) { + Materials[] mMats = null; + String t = entry.getKey() + .substring("gt.blockmetal".length()); + t = t.substring(0, 1); + int i = Integer.parseInt(t); + switch (i) { + case 1 -> mMats = new Materials[] { Materials.Adamantium, Materials.Aluminium, + Materials.Americium, Materials.AnnealedCopper, Materials.Antimony, Materials.Arsenic, + Materials.AstralSilver, Materials.BatteryAlloy, Materials.Beryllium, Materials.Bismuth, + Materials.BismuthBronze, Materials.BlackBronze, Materials.BlackSteel, + Materials.BlueAlloy, Materials.BlueSteel, Materials.Brass }; + case 2 -> mMats = new Materials[] { Materials.Bronze, Materials.Caesium, Materials.Cerium, + Materials.Chrome, Materials.ChromiumDioxide, Materials.Cobalt, Materials.CobaltBrass, + Materials.Copper, Materials.Cupronickel, Materials.DamascusSteel, Materials.DarkIron, + Materials.DeepIron, Materials.Desh, Materials.Duranium, Materials.Dysprosium, + Materials.Electrum }; + case 3 -> mMats = new Materials[] { Materials.ElectrumFlux, Materials.Enderium, + Materials.Erbium, Materials.Europium, Materials.FierySteel, Materials.Gadolinium, + Materials.Gallium, Materials.Holmium, Materials.HSLA, Materials.Indium, + Materials.InfusedGold, Materials.Invar, Materials.Iridium, Materials.IronMagnetic, + Materials.IronWood, Materials.Kanthal }; + case 4 -> mMats = new Materials[] { Materials.Knightmetal, Materials.Lanthanum, + Materials.Lead, Materials.Lutetium, Materials.Magnalium, Materials.Magnesium, + Materials.Manganese, Materials.MeteoricIron, Materials.MeteoricSteel, Materials.Trinium, + Materials.Mithril, Materials.Molybdenum, Materials.Naquadah, Materials.NaquadahAlloy, + Materials.NaquadahEnriched, Materials.Naquadria }; + case 5 -> mMats = new Materials[] { Materials.Neodymium, Materials.NeodymiumMagnetic, + Materials.Neutronium, Materials.Nichrome, Materials.Nickel, Materials.Niobium, + Materials.NiobiumNitride, Materials.NiobiumTitanium, Materials.Osmiridium, + Materials.Osmium, Materials.Palladium, Materials.PigIron, Materials.Platinum, + Materials.Plutonium, Materials.Plutonium241, Materials.Praseodymium }; + case 6 -> mMats = new Materials[] { Materials.Promethium, Materials.RedAlloy, + Materials.RedSteel, Materials.RoseGold, Materials.Rubidium, Materials.Samarium, + Materials.Scandium, Materials.ShadowIron, Materials.ShadowSteel, Materials.Silicon, + Materials.Silver, Materials.SolderingAlloy, Materials.StainlessSteel, Materials.Steel, + Materials.SteelMagnetic, Materials.SterlingSilver }; + case 7 -> mMats = new Materials[] { Materials.Sunnarium, Materials.Tantalum, + Materials.Tellurium, Materials.Terbium, Materials.Thaumium, Materials.Thorium, + Materials.Thulium, Materials.Tin, Materials.TinAlloy, Materials.Titanium, + Materials.Tritanium, Materials.Tungsten, Materials.TungstenSteel, Materials.Ultimet, + Materials.Uranium, Materials.Uranium235 }; + case 8 -> mMats = new Materials[] { Materials.Vanadium, Materials.VanadiumGallium, + Materials.WroughtIron, Materials.Ytterbium, Materials.Yttrium, + Materials.YttriumBariumCuprate, Materials.Zinc, Materials.TungstenCarbide, + Materials.VanadiumSteel, Materials.HSSG, Materials.HSSE, Materials.HSSS, + Materials.Steeleaf, Materials.Ichorium, Materials.Firestone }; + } + t = entry.getKey() + .substring( + "gt.blockmetal1.".length(), + entry.getKey() + .length() - ".name".length()); + i = Integer.parseInt(t); + lServerNames.put(entry.getKey(), "Block of " + mMats[i].toString()); + mMats = null; + } else if (entry.getKey() + .contains("blockgem")) { + Materials[] mMats = null; + String t = entry.getKey() + .substring("gt.blockgem".length()); + t = t.substring(0, 1); + int i = Integer.parseInt(t); + switch (i) { + case 1 -> mMats = new Materials[] { Materials.InfusedAir, Materials.Amber, + Materials.Amethyst, Materials.InfusedWater, Materials.BlueTopaz, + Materials.CertusQuartz, Materials.Dilithium, Materials.EnderEye, + Materials.EnderPearl, Materials.FoolsRuby, Materials.Force, Materials.Forcicium, + Materials.Forcillium, Materials.GreenSapphire, Materials.InfusedFire, + Materials.Jasper, MaterialsBotania.ManaDiamond, + MaterialsBotania.BotaniaDragonstone }; + case 2 -> mMats = new Materials[] { Materials.Lazurite, Materials.Lignite, + Materials.Monazite, Materials.Niter, Materials.Olivine, Materials.Opal, + Materials.InfusedOrder, Materials.InfusedEntropy, Materials.Phosphorus, + Materials.Quartzite, Materials.GarnetRed, Materials.Ruby, Materials.Sapphire, + Materials.Sodalite, Materials.Tanzanite, Materials.InfusedEarth }; + case 3 -> mMats = new Materials[] { Materials.Topaz, Materials.Vinteum, + Materials.GarnetYellow, Materials.NetherStar, Materials.Charcoal, Materials.Blaze }; + } + t = entry.getKey() + .substring( + "gt.blockgem1.".length(), + entry.getKey() + .length() - ".name".length()); + i = Integer.parseInt(t); + lServerNames.put(entry.getKey(), "Block of " + mMats[i].toString()); + mMats = null; + } + } catch (Exception ignored) {} + } + + internal = null; + internal2 = null; + internal3 = null; + internal4 = null; + } +} diff --git a/src/main/java/gregtech/api/util/AssemblyLineUtils.java b/src/main/java/gregtech/api/util/AssemblyLineUtils.java new file mode 100644 index 0000000000..22bed1884b --- /dev/null +++ b/src/main/java/gregtech/api/util/AssemblyLineUtils.java @@ -0,0 +1,561 @@ +package gregtech.api.util; + +import static gregtech.GTMod.GT_FML_LOGGER; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; + +import javax.annotation.Nonnull; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; +import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.fluids.FluidStack; + +import cpw.mods.fml.common.FMLCommonHandler; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.objects.GTItemStack; +import gregtech.api.util.GTRecipe.RecipeAssemblyLine; + +public class AssemblyLineUtils { + + /** + * A cache of Recipes using the Output as Key. + */ + private static final HashMap sRecipeCacheByOutput = new HashMap<>(); + /** + * A cache of Recipes using the Recipe Hash String as Key. + */ + private static final HashMap sRecipeCacheByRecipeHash = new HashMap<>(); + + /** + * Checks the DataStick for deprecated/invalid recipes, updating them as required. + * + * @param aDataStick - The DataStick to process + * @return Is this DataStick now valid with a current recipe? + */ + public static GTRecipe.RecipeAssemblyLine processDataStick(ItemStack aDataStick) { + if (!isItemDataStick(aDataStick)) { + return null; + } + if (doesDataStickNeedUpdate(aDataStick)) { + ItemStack aStickOutput = getDataStickOutput(aDataStick); + if (aStickOutput != null) { + GTRecipe.RecipeAssemblyLine aIntendedRecipe = findAssemblyLineRecipeByOutput(aStickOutput); + if (aIntendedRecipe != null && setAssemblyLineRecipeOnDataStick(aDataStick, aIntendedRecipe)) + return aIntendedRecipe; + } + } + return null; + } + + /** + * Finds an Assembly Line recipe from a DataStick. + * + * @param aDataStick - The DataStick to check. + * @return The GTRecipe_AssemblyLine recipe contained on the DataStick, if any. + */ + public static RecipeAssemblyLine findAssemblyLineRecipeFromDataStick(ItemStack aDataStick) { + return findAssemblyLineRecipeFromDataStick(aDataStick, false).getRecipe(); + } + + /** + * Finds an Assembly Line recipe from a DataStick. + * + * @param aDataStick - The DataStick to check. + * @param aReturnBuiltRecipe - Do we return a GTRecipe_AssemblyLine built from the data on the Data Stick instead + * of searching the Recipe Map? + * @return The GTRecipe_AssemblyLine recipe contained on the DataStick, if any. + */ + @Nonnull + public static LookupResult findAssemblyLineRecipeFromDataStick(ItemStack aDataStick, boolean aReturnBuiltRecipe) { + if (!isItemDataStick(aDataStick) || !doesDataStickHaveOutput(aDataStick)) { + return LookupResultType.INVALID_STICK.getResult(); + } + List aInputs = new ArrayList<>(16); + ItemStack aOutput = getDataStickOutput(aDataStick); + List> mOreDictAlt = new ArrayList<>(16); + List aFluidInputs = new ArrayList<>(4); + + NBTTagCompound aTag = aDataStick.getTagCompound(); + if (aTag == null) { + return LookupResultType.INVALID_STICK.getResult(); + } + + // Get From Cache + if (doesDataStickHaveRecipeHash(aDataStick)) { + GTRecipe.RecipeAssemblyLine aRecipeFromCache = sRecipeCacheByRecipeHash + .get(getHashFromDataStack(aDataStick)); + if (aRecipeFromCache != null && GTUtility.areStacksEqual(aOutput, aRecipeFromCache.mOutput)) { + return LookupResultType.VALID_STACK_AND_VALID_HASH.getResult(aRecipeFromCache); + } // else: no cache, or the old recipe run into a hash collision with a different new recipe + } + + for (int i = 0; i < 16; i++) { + int count = aTag.getInteger("a" + i); + if (!aTag.hasKey("" + i) && count <= 0) { + continue; + } + + List tAltCurrent = new ArrayList<>(); + for (int j = 0; j < count; j++) { + ItemStack tLoaded = GTUtility.loadItem(aTag, "a" + i + ":" + j); + if (tLoaded == null) { + continue; + } + tAltCurrent.add(tLoaded); + if (GTValues.D1) { + GT_FML_LOGGER.info("Item Alt " + i + " : " + tLoaded.getUnlocalizedName()); + } + } + mOreDictAlt.add(tAltCurrent); + ItemStack tLoaded = GTUtility.loadItem(aTag, "" + i); + if (tLoaded == null) { + continue; + } + aInputs.add(tLoaded); + if (GTValues.D1) { + GT_FML_LOGGER.info("Item " + i + " : " + tLoaded.getUnlocalizedName()); + } + } + + if (GTValues.D1) { + GT_FML_LOGGER.info("All Items done, start fluid check"); + } + for (int i = 0; i < 4; i++) { + if (!aTag.hasKey("f" + i)) continue; + FluidStack tLoaded = GTUtility.loadFluid(aTag, "f" + i); + if (tLoaded == null) continue; + aFluidInputs.add(tLoaded); + if (GTValues.D1) { + GT_FML_LOGGER.info("Fluid " + i + " " + tLoaded.getUnlocalizedName()); + } + } + if (!aTag.hasKey("output") || !aTag.hasKey("time") + || aTag.getInteger("time") <= 0 + || !aTag.hasKey("eu") + || !GTUtility.isStackValid(aOutput)) { + return LookupResultType.INVALID_STICK.getResult(); + } + if (GTValues.D1) { + GT_FML_LOGGER.info("Found Data Stick recipe"); + } + + int aTime = aTag.getInteger("time"); + int aEU = aTag.getInteger("eu"); + + // Try build a recipe instance + if (aReturnBuiltRecipe) { + return LookupResultType.VALID_STACK_AND_VALID_HASH.getResult( + new GTRecipe.RecipeAssemblyLine( + null, + 0, + aInputs.toArray(new ItemStack[0]), + aFluidInputs.toArray(new FluidStack[0]), + aOutput, + aTime, + aEU)); + } + + for (GTRecipe.RecipeAssemblyLine aRecipe : RecipeAssemblyLine.sAssemblylineRecipes) { + if (aRecipe.mEUt != aEU || aRecipe.mDuration != aTime) continue; + if (!GTUtility.areStacksEqual(aOutput, aRecipe.mOutput, true)) continue; + if (!GTUtility.areStackListsEqual(Arrays.asList(aRecipe.mInputs), aInputs, false, true)) continue; + if (!Objects.equals(Arrays.asList(aRecipe.mFluidInputs), aFluidInputs)) continue; + if (!areStacksEqual(aRecipe.mOreDictAlt, mOreDictAlt)) continue; + + // Cache it + String aRecipeHash = generateRecipeHash(aRecipe); + sRecipeCacheByRecipeHash.put(aRecipeHash, aRecipe); + sRecipeCacheByOutput.put(new GTItemStack(aRecipe.mOutput), aRecipe); + if (doesDataStickHaveRecipeHash(aDataStick)) { + String aStickHash = getHashFromDataStack(aDataStick); + if (aRecipeHash.equals(aStickHash)) + return LookupResultType.VALID_STACK_AND_VALID_HASH.getResult(aRecipe); + } + return LookupResultType.VALID_STACK_AND_VALID_RECIPE.getResult(aRecipe); + } + return LookupResultType.VALID_STACK_BUT_INVALID_RECIPE.getResult(); + } + + private static boolean areStacksEqual(ItemStack[][] lhs, List> rhs) { + for (int i = 0; i < lhs.length; i++) { + if (!areStacksEqual(lhs[i], rhs.get(i))) return false; + } + return true; + } + + private static boolean areStacksEqual(ItemStack[] lhs, List rhs) { + return lhs == null ? rhs.isEmpty() + : !rhs.isEmpty() && GTUtility.areStackListsEqual(Arrays.asList(lhs), rhs, false, true); + } + + /** + * Finds a GTRecipe_AssemblyLine based on the expected output ItemStack. + * + * @param aOutput - The Output of a GTRecipe_AssemblyLine. + * @return First found GTRecipe_AssemblyLine with matching output. + */ + public static GTRecipe.RecipeAssemblyLine findAssemblyLineRecipeByOutput(ItemStack aOutput) { + if (aOutput == null) { + return null; + } + + // Check the cache + GTItemStack aCacheStack = new GTItemStack(aOutput); + RecipeAssemblyLine aRecipeFromCache = sRecipeCacheByOutput.get(aCacheStack); + if (aRecipeFromCache != null) { + return aRecipeFromCache; + } + + // Iterate all recipes and return the first matching based on Output. + for (RecipeAssemblyLine aRecipe : GTRecipe.RecipeAssemblyLine.sAssemblylineRecipes) { + ItemStack aRecipeOutput = aRecipe.mOutput; + if (GTUtility.areStacksEqual(aRecipeOutput, aOutput)) { + // Cache it to prevent future iterations of all recipes + sRecipeCacheByOutput.put(aCacheStack, aRecipe); + sRecipeCacheByRecipeHash.put(generateRecipeHash(aRecipe), aRecipe); + return aRecipe; + } + } + return null; + } + + /** + * @param aRecipe - The recipe to generate a Recipe Hash String from. + * @return The Recipe Hash String. + */ + public static String generateRecipeHash(GTRecipe.RecipeAssemblyLine aRecipe) { + String aHash = "Invalid.Recipe.Hash"; + if (aRecipe != null) { + aHash = "Hash." + aRecipe.getPersistentHash(); + } + return aHash; + } + + /** + * @param aRecipe - The recipe to add to internal caches + * @throws IllegalArgumentException if given recipe collide with any existing recipe in the cache + */ + public static void addRecipeToCache(RecipeAssemblyLine aRecipe) { + if (aRecipe != null) { + String aHash = "Hash." + aRecipe.getPersistentHash(); + GTRecipe.RecipeAssemblyLine existing = sRecipeCacheByOutput.put(new GTItemStack(aRecipe.mOutput), aRecipe); + if (existing != null) throw new IllegalArgumentException("Duplicate assline recipe for " + aRecipe.mOutput); + existing = sRecipeCacheByRecipeHash.put(aHash, aRecipe); + if (existing != null && !existing.equals(aRecipe)) + throw new IllegalArgumentException("Recipe hash collision for " + aRecipe + " and " + existing); + } + } + + /** + * @param aHash - Recipe hash String, may be null but will just be treated as invalid. + * @return Is this Recipe Hash String valid? + */ + public static boolean isValidHash(String aHash) { + if (aHash != null && aHash.length() > 0) { + // persistent hash can never be 0 + return !aHash.equals("Invalid.Recipe.Hash") && !aHash.equals("Hash.0"); + } + return false; + } + + /** + * @param aStack - The ItemStack to check. + * @return Is this ItemStack a Data Stick? + */ + public static boolean isItemDataStick(ItemStack aStack) { + return GTUtility.isStackValid(aStack) && ItemList.Tool_DataStick.isStackEqual(aStack, false, true); + } + + /** + * @param aDataStick - The Data Stick to check. + * @return Does this Data Stick have a valid output ItemStack? + */ + public static boolean doesDataStickHaveOutput(ItemStack aDataStick) { + return isItemDataStick(aDataStick) && aDataStick.hasTagCompound() + && aDataStick.getTagCompound() + .hasKey("output"); + } + + /** + * @param aDataStick - The Data Stick to check. + * @return Does this Data Stick need recipe data updated. + */ + public static boolean doesDataStickNeedUpdate(ItemStack aDataStick) { + if (isItemDataStick(aDataStick) && doesDataStickHaveRecipeHash(aDataStick)) { + String aStickHash = getHashFromDataStack(aDataStick); + if (isValidHash(aStickHash) && doesDataStickHaveOutput(aDataStick)) { + ItemStack aStickOutput = getDataStickOutput(aDataStick); + GTRecipe.RecipeAssemblyLine aIntendedRecipe = findAssemblyLineRecipeByOutput(aStickOutput); + return !aStickHash.equals(generateRecipeHash(aIntendedRecipe)); + } + } + return true; + } + + /** + * @param aDataStick - The Data Stick to check. + * @return Does this have a Recipe Hash String at all? + */ + public static boolean doesDataStickHaveRecipeHash(ItemStack aDataStick) { + if (isItemDataStick(aDataStick) && aDataStick.hasTagCompound()) { + NBTTagCompound aNBT = aDataStick.getTagCompound(); + return aNBT.hasKey("Data.Recipe.Hash") && !aNBT.getString("Data.Recipe.Hash") + .equals("Hash.0"); + } + return false; + } + + /** + * Get the Output ItemStack from a Data Stick. + * + * @param aDataStick - The Data Stick to check. + * @return Output ItemStack contained on the Data Stick. + */ + public static ItemStack getDataStickOutput(ItemStack aDataStick) { + if (doesDataStickHaveOutput(aDataStick)) { + return GTUtility.loadItem(aDataStick.getTagCompound(), "output"); + } + return null; + } + + /** + * @param aDataStick - The Data Stick to process. + * @return The stored Recipe Hash String on the Data Stick, will return an invalid Hash if one is not found. + *

+ * The hash will be guaranteed to pass isValidHash(). + *

+ * Will not return Null. + */ + public static String getHashFromDataStack(ItemStack aDataStick) { + if (isItemDataStick(aDataStick) && aDataStick.hasTagCompound()) { + NBTTagCompound aNBT = aDataStick.getTagCompound(); + if (aNBT.hasKey("Data.Recipe.Hash", NBT.TAG_STRING)) { + String hash = aNBT.getString("Data.Recipe.Hash"); + if (isValidHash(hash)) return hash; + } + } + return "Invalid.Recipe.Hash"; + } + + /** + * + * @param aDataStick - The Data Stick to update. + * @param aRecipeHash - The Recipe Hash String to update with. + * @return Did we update the Recipe Hash String on the Data Stick? + */ + public static boolean setRecipeHashOnDataStick(ItemStack aDataStick, String aRecipeHash) { + if (isItemDataStick(aDataStick) && aDataStick.hasTagCompound()) { + NBTTagCompound aNBT = aDataStick.getTagCompound(); + aNBT.setString("Data.Recipe.Hash", aRecipeHash); + aDataStick.setTagCompound(aNBT); + return true; + } + return false; + } + + /** + * + * @param aDataStick - The Data Stick to update. + * @param aNewRecipe - The New GTRecipe_AssemblyLine recipe to update it with. + * @return Did we set the new recipe data & Recipe Hash String on the Data Stick? + */ + public static boolean setAssemblyLineRecipeOnDataStick(ItemStack aDataStick, + GTRecipe.RecipeAssemblyLine aNewRecipe) { + return setAssemblyLineRecipeOnDataStick(aDataStick, aNewRecipe, true); + } + + public static boolean setAssemblyLineRecipeOnDataStick(ItemStack aDataStick, GTRecipe.RecipeAssemblyLine aNewRecipe, + boolean setUpdateTime) { + if (isItemDataStick(aDataStick) && aNewRecipe.mOutput != null) { + String s = aNewRecipe.mOutput.getDisplayName(); + if (FMLCommonHandler.instance() + .getEffectiveSide() + .isServer()) { + s = AssemblyLineServer.lServerNames.get(aNewRecipe.mOutput.getDisplayName()); + if (s == null) { + s = aNewRecipe.mOutput.getDisplayName(); + } + } + + String aHash = generateRecipeHash(aNewRecipe); + if (GTValues.D1) { + GTRecipe.RecipeAssemblyLine aOldRecipe = findAssemblyLineRecipeFromDataStick(aDataStick, true).recipe; + GT_FML_LOGGER.info( + "Updating data stick: " + aDataStick.getDisplayName() + + " | Old Recipe Hash: " + + generateRecipeHash(aOldRecipe) + + ", New Recipe Hash: " + + aHash); + } + + String author = "Assembling Line Recipe Generator"; + String displayName = null; + if (aDataStick.hasTagCompound()) { + NBTTagCompound tag = aDataStick.getTagCompound(); + if (tag.hasKey("author", NBT.TAG_STRING)) { + author = tag.getString("author"); + } + if (tag.hasKey("display", NBT.TAG_COMPOUND)) { + NBTTagCompound displayTag = tag.getCompoundTag("display"); + if (displayTag.hasKey("Name", NBT.TAG_STRING)) displayName = displayTag.getString("Name"); + } + } + + // remove possible old NBTTagCompound + aDataStick.setTagCompound(new NBTTagCompound()); + if (displayName != null) aDataStick.setStackDisplayName(displayName); + if (GTValues.D1) { + GTUtility.ItemNBT.setBookTitle(aDataStick, s + " Construction Data (" + aHash + ")"); + } else { + GTUtility.ItemNBT.setBookTitle(aDataStick, s + " Construction Data"); + } + + NBTTagCompound tNBT = aDataStick.getTagCompound(); + if (tNBT == null) { + tNBT = new NBTTagCompound(); + } + + tNBT.setTag("output", aNewRecipe.mOutput.writeToNBT(new NBTTagCompound())); + tNBT.setInteger("time", aNewRecipe.mDuration); + tNBT.setInteger("eu", aNewRecipe.mEUt); + tNBT.setString("author", author); + NBTTagList tNBTList = new NBTTagList(); + tNBTList.appendTag( + new NBTTagString( + "Construction plan for " + aNewRecipe.mOutput.stackSize + + " " + + s + + ". Needed EU/t: " + + aNewRecipe.mEUt + + " Production time: " + + (aNewRecipe.mDuration / 20))); + for (int i = 0; i < aNewRecipe.mInputs.length; i++) { + boolean hasSetOreDictAlt = false; + + if (aNewRecipe.mOreDictAlt[i] != null && aNewRecipe.mOreDictAlt[i].length > 0) { + tNBT.setInteger("a" + i, aNewRecipe.mOreDictAlt[i].length); + int count = 0; + StringBuilder tBuilder = new StringBuilder("Input Bus " + (i + 1) + ": "); + for (int j = 0; j < aNewRecipe.mOreDictAlt[i].length; j++) { + ItemStack tStack = aNewRecipe.mOreDictAlt[i][j]; + if (tStack != null) { + tNBT.setTag("a" + i + ":" + j, tStack.writeToNBT(new NBTTagCompound())); + + s = tStack.getDisplayName(); + if (FMLCommonHandler.instance() + .getEffectiveSide() + .isServer()) { + s = AssemblyLineServer.lServerNames.get(tStack.getDisplayName()); + if (s == null) s = tStack.getDisplayName(); + } + + tBuilder.append(count == 0 ? "" : "\nOr ") + .append(tStack.stackSize) + .append(" ") + .append(s); + count++; + } + } + if (count > 0) { + tNBTList.appendTag(new NBTTagString(tBuilder.toString())); + hasSetOreDictAlt = true; + } + } + + if (aNewRecipe.mInputs[i] != null) { + tNBT.setTag("" + i, aNewRecipe.mInputs[i].writeToNBT(new NBTTagCompound())); + + if (!hasSetOreDictAlt) { + s = aNewRecipe.mInputs[i].getDisplayName(); + if (FMLCommonHandler.instance() + .getEffectiveSide() + .isServer()) { + s = AssemblyLineServer.lServerNames.get(aNewRecipe.mInputs[i].getDisplayName()); + if (s == null) s = aNewRecipe.mInputs[i].getDisplayName(); + } + tNBTList.appendTag( + new NBTTagString( + "Input Bus " + (i + 1) + ": " + aNewRecipe.mInputs[i].stackSize + " " + s)); + } + } + } + for (int i = 0; i < aNewRecipe.mFluidInputs.length; i++) { + if (aNewRecipe.mFluidInputs[i] != null) { + tNBT.setTag("f" + i, aNewRecipe.mFluidInputs[i].writeToNBT(new NBTTagCompound())); + + s = aNewRecipe.mFluidInputs[i].getLocalizedName(); + if (FMLCommonHandler.instance() + .getEffectiveSide() + .isServer()) { + s = AssemblyLineServer.lServerNames.get(aNewRecipe.mFluidInputs[i].getLocalizedName()); + if (s == null) s = aNewRecipe.mFluidInputs[i].getLocalizedName(); + } + tNBTList.appendTag( + new NBTTagString( + "Input Hatch " + (i + 1) + ": " + aNewRecipe.mFluidInputs[i].amount + "L " + s)); + } + } + tNBT.setTag("pages", tNBTList); + if (setUpdateTime) tNBT.setLong("lastUpdate", System.currentTimeMillis()); + aDataStick.setTagCompound(tNBT); + // Set recipe hash + setRecipeHashOnDataStick(aDataStick, aHash); + return true; + } + return false; + } + + public enum LookupResultType { + + INVALID_STICK(true), + VALID_STACK_BUT_INVALID_RECIPE(true), + VALID_STACK_AND_VALID_RECIPE(false), + VALID_STACK_AND_VALID_HASH(false); + + private final boolean recipeNull; + private LookupResult singletonResult; + + LookupResultType(boolean recipeNull) { + this.recipeNull = recipeNull; + } + + public LookupResult getResult() { + if (!recipeNull) throw new IllegalArgumentException("This result type require a nonnull recipe"); + if (singletonResult == null) singletonResult = new LookupResult(null, this); + return singletonResult; + } + + public LookupResult getResult(GTRecipe.RecipeAssemblyLine recipe) { + if ((recipe == null) != recipeNull) + throw new IllegalArgumentException("This result type does not allow given input"); + return new LookupResult(recipe, this); + } + } + + public static class LookupResult { + + private final GTRecipe.RecipeAssemblyLine recipe; + private final LookupResultType type; + + LookupResult(GTRecipe.RecipeAssemblyLine recipe, LookupResultType type) { + this.recipe = recipe; + this.type = type; + } + + public GTRecipe.RecipeAssemblyLine getRecipe() { + return recipe; + } + + public LookupResultType getType() { + return type; + } + } +} diff --git a/src/main/java/gregtech/api/util/BlastFurnaceGasStat.java b/src/main/java/gregtech/api/util/BlastFurnaceGasStat.java index ac1601e846..822e2f036e 100644 --- a/src/main/java/gregtech/api/util/BlastFurnaceGasStat.java +++ b/src/main/java/gregtech/api/util/BlastFurnaceGasStat.java @@ -6,9 +6,8 @@ import java.util.List; import net.minecraftforge.fluids.FluidStack; -import com.github.bartimaeusnek.bartworks.system.material.Werkstoff; -import com.github.bartimaeusnek.bartworks.system.material.WerkstoffLoader; - +import bartworks.system.material.Werkstoff; +import bartworks.system.material.WerkstoffLoader; import gregtech.api.enums.Materials; public class BlastFurnaceGasStat { diff --git a/src/main/java/gregtech/api/util/CircuitryBehavior.java b/src/main/java/gregtech/api/util/CircuitryBehavior.java new file mode 100644 index 0000000000..3859be590a --- /dev/null +++ b/src/main/java/gregtech/api/util/CircuitryBehavior.java @@ -0,0 +1,212 @@ +package gregtech.api.util; + +import net.minecraftforge.common.util.ForgeDirection; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; +import gregtech.api.interfaces.IRedstoneCircuitBlock; + +/** + * Redstone Circuit Control Code + *

+ * This should make everything possible what a Redstone Computer or BuildCraft Gate could do. It is intended to use this + * similar to BC-Gates (for acquiring Data) and RP Logic Gates. You could write an extremely specified and complex Logic + * Gate, which works only for you Setup, like with ComputerCraft, but you would have to write an extra Mod to add that, + * as it doesn't work Ingame. + *

+ * One can make use of the fact, that ItemStacks can be stored as Integer, so that you can scan Inventories for specific + * Items using that. Luckily the Buttons in the GUI enable Copy/Paste of ItemID+MetaData to Integer, including the + * WildCard Damage Value when you use rightclick to place it. You just need to use @GT_Utility.stackToInt(ItemStack + * aStack) to get it. + *

+ * All Functions run usually in a seperate try/catch Block, so that failed Logic won't crash the TileEntity. + */ +public abstract class CircuitryBehavior { + + /** + * @param aIndex 0 - 1023 are my own Indices, so use other Numbers! + */ + public CircuitryBehavior(int aIndex) { + GregTechAPI.sCircuitryBehaviors.put(aIndex, this); + } + + /** + * returns if there is Redstone applied to any of the valid Inputs (OR) + */ + public static boolean getAnyRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) + .letsRedstoneGoIn( + side, + aRedstoneCircuitBlock.getCoverID(side), + aRedstoneCircuitBlock.getCoverVariable(side), + aRedstoneCircuitBlock.getOwnTileEntity())) { + if (aRedstoneCircuitBlock.getInputRedstone(side) > 0) { + return true; + } + } + } + return false; + } + + /** + * returns if there is Redstone applied to all the valid Inputs (AND) + */ + public static boolean getAllRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) + .letsRedstoneGoIn( + side, + aRedstoneCircuitBlock.getCoverID(side), + aRedstoneCircuitBlock.getCoverVariable(side), + aRedstoneCircuitBlock.getOwnTileEntity())) { + if (aRedstoneCircuitBlock.getInputRedstone(side) == 0) { + return false; + } + } + } + return true; + } + + /** + * returns if there is Redstone applied to exactly one of the valid Inputs (XOR) + */ + public static boolean getOneRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { + int tRedstoneAmount = 0; + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) + .letsRedstoneGoIn( + side, + aRedstoneCircuitBlock.getCoverID(side), + aRedstoneCircuitBlock.getCoverVariable(side), + aRedstoneCircuitBlock.getOwnTileEntity())) { + if (aRedstoneCircuitBlock.getInputRedstone(side) > 0) { + tRedstoneAmount++; + } + } + } + return tRedstoneAmount == 1; + } + + /** + * returns the strongest incoming RS-Power + */ + public static byte getStrongestRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { + byte tRedstoneAmount = 0; + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) + .letsRedstoneGoIn( + side, + aRedstoneCircuitBlock.getCoverID(side), + aRedstoneCircuitBlock.getCoverVariable(side), + aRedstoneCircuitBlock.getOwnTileEntity())) { + tRedstoneAmount = (byte) Math.max(tRedstoneAmount, aRedstoneCircuitBlock.getInputRedstone(side)); + } + } + return tRedstoneAmount; + } + + // region GUI Functions + + /** + * returns the weakest incoming non-zero RS-Power + */ + public static byte getWeakestNonZeroRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { + if (!getAnyRedstone(aRedstoneCircuitBlock)) return 0; + byte tRedstoneAmount = 15; + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) + .letsRedstoneGoIn( + side, + aRedstoneCircuitBlock.getCoverID(side), + aRedstoneCircuitBlock.getCoverVariable(side), + aRedstoneCircuitBlock.getOwnTileEntity())) { + if (aRedstoneCircuitBlock.getInputRedstone(side) > 0) + tRedstoneAmount = (byte) Math.min(tRedstoneAmount, aRedstoneCircuitBlock.getInputRedstone(side)); + } + } + return tRedstoneAmount; + } + + /** + * returns the weakest incoming RS-Power + */ + public static byte getWeakestRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { + if (!getAnyRedstone(aRedstoneCircuitBlock)) return 0; + byte tRedstoneAmount = 15; + for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) + .letsRedstoneGoIn( + side, + aRedstoneCircuitBlock.getCoverID(side), + aRedstoneCircuitBlock.getCoverVariable(side), + aRedstoneCircuitBlock.getOwnTileEntity())) { + tRedstoneAmount = (byte) Math.min(tRedstoneAmount, aRedstoneCircuitBlock.getInputRedstone(side)); + } + } + return tRedstoneAmount; + } + + /** + * Initializes the Parameters of this Circuit, all Parameters have been set to 0 right before calling this + * + * @param aCircuitData, The Data Storage you can use (8 Slots) + * @param aRedstoneCircuitBlock, The Circuit Block MetaTileEntity itself + */ + public abstract void initParameters(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock); + + /** + * Validates the Parameters of this Circuit when a value has been changed by the GUI Also called right + * after @initParameters and when the Chunk reloads + * + * @param aCircuitData, The Data Storage you can use (8 Slots and only the first 4 are User definable) + * @param aRedstoneCircuitBlock, The Circuit Block MetaTileEntity itself + */ + public abstract void validateParameters(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock); + + // endregion + + // region Utility Functions + + /** + * Called every tick if the Block has enough Energy and if the Block is Active + * + * @param aCircuitData, The Data Storage you can use (8 Slots) + * @param aRedstoneCircuitBlock, The Circuit Block MetaTileEntity itself + */ + public abstract void onTick(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock); + + /** + * If the ItemStack should be displayed. Parameters are between 0 and 3. + */ + public abstract boolean displayItemStack(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock, + int aIndex); + + /** + * The Name of the Gate for the GUI + */ + @SideOnly(Side.CLIENT) + public abstract String getName(); + + /** + * The Description of the Gate for the GUI + */ + @SideOnly(Side.CLIENT) + public abstract String getDescription(); + + /** + * The Description of the Data Field for the GUI + */ + @SideOnly(Side.CLIENT) + public abstract String getDataDescription(int[] aCircuitData, int aCircuitDataIndex); + + /** + * How the Integer should be displayed in the GUI. null means, that it just displays as regular Number. + */ + @SideOnly(Side.CLIENT) + public String getDataDisplay(int[] aCircuitData, int aCircuitDataIndex) { + return null; + } + // endregion +} diff --git a/src/main/java/gregtech/api/util/ColorsMetadataSection.java b/src/main/java/gregtech/api/util/ColorsMetadataSection.java index fb9cc6dd56..7e420f3451 100644 --- a/src/main/java/gregtech/api/util/ColorsMetadataSection.java +++ b/src/main/java/gregtech/api/util/ColorsMetadataSection.java @@ -37,7 +37,7 @@ public class ColorsMetadataSection implements IMetadataSection { try { if (!hex.isEmpty()) colorValue = Integer.parseUnsignedInt(hex, 16); } catch (final NumberFormatException e) { - GT_Log.err.println("Couldn't format color correctly of " + key + " -> " + hex); + GTLog.err.println("Couldn't format color correctly of " + key + " -> " + hex); } intMap.put(key, colorValue); } diff --git a/src/main/java/gregtech/api/util/ColorsMetadataSectionSerializer.java b/src/main/java/gregtech/api/util/ColorsMetadataSectionSerializer.java index 389662d041..8eb91802cb 100644 --- a/src/main/java/gregtech/api/util/ColorsMetadataSectionSerializer.java +++ b/src/main/java/gregtech/api/util/ColorsMetadataSectionSerializer.java @@ -14,8 +14,8 @@ import com.google.gson.JsonSerializationContext; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; import gregtech.api.enums.Dyes; @SideOnly(Side.CLIENT) @@ -24,7 +24,7 @@ public class ColorsMetadataSectionSerializer extends BaseMetadataSectionSerializ public ColorsMetadataSection deserialize(JsonElement metadataColors, Type type, JsonDeserializationContext context) { // Default values - boolean enableGuiTint = GregTech_API.sColoredGUI; + boolean enableGuiTint = GregTechAPI.sColoredGUI; Map hexGuiTintMap = new HashMap<>(); Map hexTextColorMap = new HashMap<>(); @@ -39,7 +39,7 @@ public class ColorsMetadataSectionSerializer extends BaseMetadataSectionSerializ entry.getValue() .getAsString()); } else { - GT_Mod.GT_FML_LOGGER.warn("ColorOverride expects primitive value for key `textColor`"); + GTMod.GT_FML_LOGGER.warn("ColorOverride expects primitive value for key `textColor`"); } } } @@ -50,7 +50,7 @@ public class ColorsMetadataSectionSerializer extends BaseMetadataSectionSerializ .getJsonObjectBooleanFieldValueOrDefault(guiTints, "enableGuiTintWhenPainted", true); for (Dyes dye : Dyes.values()) { - hexGuiTintMap.put(dye.mName, GT_Util.toHexString(dye.getRGBA())); + hexGuiTintMap.put(dye.mName, GTUtil.toHexString(dye.getRGBA())); } for (String key : hexGuiTintMap.keySet()) { @@ -59,7 +59,7 @@ public class ColorsMetadataSectionSerializer extends BaseMetadataSectionSerializ key, JsonUtils.getJsonObjectStringFieldValueOrDefault(guiTints, key, hexGuiTintMap.get(key))); } else { - hexGuiTintMap.replace(key, GT_Util.toHexString(Dyes.dyeWhite.getRGBA())); + hexGuiTintMap.replace(key, GTUtil.toHexString(Dyes.dyeWhite.getRGBA())); } } } diff --git a/src/main/java/gregtech/api/util/CoverBehavior.java b/src/main/java/gregtech/api/util/CoverBehavior.java new file mode 100644 index 0000000000..7e6f1049e9 --- /dev/null +++ b/src/main/java/gregtech/api/util/CoverBehavior.java @@ -0,0 +1,402 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.E; + +import java.lang.ref.WeakReference; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; + +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.ICoverable; + +/** + * For Covers with a special behavior. Has fixed storage format of 4 byte. Not very convenient... + */ +public abstract class CoverBehavior extends CoverBehaviorBase { + + public boolean mPlayerNotified = false; + + public CoverBehavior() { + this(null); + } + + public CoverBehavior(ITexture coverTexture) { + super(ISerializableObject.LegacyCoverData.class, coverTexture); + } + + protected static int convert(ISerializableObject.LegacyCoverData data) { + return data == null ? 0 : data.get(); + } + + // region bridge the parent call to legacy calls + + @Override + public final ISerializableObject.LegacyCoverData createDataObject() { + return new ISerializableObject.LegacyCoverData(); + } + + @Override + public ISerializableObject.LegacyCoverData createDataObject(int aLegacyData) { + return new ISerializableObject.LegacyCoverData(aLegacyData); + } + + @Override + protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { + return isRedstoneSensitive(side, aCoverID, aCoverVariable.get(), aTileEntity, aTimer); + } + + @Override + protected ISerializableObject.LegacyCoverData doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, + int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { + if (aCoverVariable == null) aCoverVariable = new ISerializableObject.LegacyCoverData(); + aCoverVariable.set(doCoverThings(side, aInputRedstone, aCoverID, aCoverVariable.get(), aTileEntity, aTimer)); + return aCoverVariable; + } + + @Override + protected boolean onCoverRightClickImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, + float aY, float aZ) { + return onCoverRightclick(side, aCoverID, convert(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ); + } + + @Override + protected ISerializableObject.LegacyCoverData onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, + float aY, float aZ) { + if (aCoverVariable == null) aCoverVariable = new ISerializableObject.LegacyCoverData(); + aCoverVariable + .set(onCoverScrewdriverclick(side, aCoverID, convert(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ)); + return aCoverVariable; + } + + @Override + protected boolean onCoverShiftRightClickImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer) { + return onCoverShiftRightclick(side, aCoverID, convert(aCoverVariable), aTileEntity, aPlayer); + } + + @Override + protected boolean onCoverRemovalImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, boolean aForced) { + return onCoverRemoval(side, aCoverID, convert(aCoverVariable), aTileEntity, aForced); + } + + @Override + protected void onBaseTEDestroyedImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + onBaseTEDestroyed(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected void onCoverUnloadImpl(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + onCoverUnload(aTileEntity); + } + + @Override + protected String getDescriptionImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return getDescription(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected float getBlastProofLevelImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return getBlastProofLevel(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean letsRedstoneGoInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return letsRedstoneGoIn(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean letsRedstoneGoOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return letsRedstoneGoOut(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return letsEnergyIn(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return letsEnergyOut(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { + return letsFluidIn(side, aCoverID, convert(aCoverVariable), aFluid, aTileEntity); + } + + @Override + protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { + return letsFluidOut(side, aCoverID, convert(aCoverVariable), aFluid, aTileEntity); + } + + @Override + protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { + return letsItemsIn(side, aCoverID, convert(aCoverVariable), aSlot, aTileEntity); + } + + @Override + protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { + return letsItemsOut(side, aCoverID, convert(aCoverVariable), aSlot, aTileEntity); + } + + @Override + protected boolean isGUIClickableImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return isGUIClickable(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return manipulatesSidedRedstoneOutput(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected boolean alwaysLookConnectedImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return alwaysLookConnected(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected byte getRedstoneInputImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return getRedstoneInput(side, aInputRedstone, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected int getTickRateImpl(ForgeDirection side, int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, + ICoverable aTileEntity) { + return getTickRate(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected byte getLensColorImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return getLensColor(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + @Override + protected ItemStack getDropImpl(ForgeDirection side, int aCoverID, + ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { + return getDrop(side, aCoverID, convert(aCoverVariable), aTileEntity); + } + + // endregion + + public boolean isRedstoneSensitive(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + long aTimer) { + return true; + } + + /** + * Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time. + */ + public int doCoverThings(ForgeDirection side, byte aInputRedstone, int aCoverID, int aCoverVariable, + ICoverable aTileEntity, long aTimer) { + return aCoverVariable; + } + + /** + * Called when someone rightclicks this Cover. + *

+ * return true, if something actually happens. + */ + public boolean onCoverRightclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer, float aX, float aY, float aZ) { + return false; + } + + /** + * Called when someone rightclicks this Cover with a Screwdriver. Doesn't call @onCoverRightclick in this Case. + *

+ * return the new Value of the Cover Variable + */ + public int onCoverScrewdriverclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer, float aX, float aY, float aZ) { + return aCoverVariable; + } + + /** + * Called when someone shift-rightclicks this Cover with no tool. Doesn't call @onCoverRightclick in this Case. + */ + public boolean onCoverShiftRightclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer) { + if (hasCoverGUI() && aPlayer instanceof EntityPlayerMP) { + lastPlayer = new WeakReference<>(aPlayer); + mPlayerNotified = false; + GTUIInfos.openCoverUI(aTileEntity, aPlayer, side); + return true; + } + return false; + } + + /** + * Removes the Cover if this returns true, or if aForced is true. Doesn't get called when the Machine Block is + * getting broken, only if you break the Cover away from the Machine. + */ + public boolean onCoverRemoval(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, + boolean aForced) { + return true; + } + + public void onCoverUnload(ICoverable aTileEntity) { + + } + + public void onBaseTEDestroyed(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) {} + + /** + * Gives a small Text for the status of the Cover. + */ + public String getDescription(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return E; + } + + /** + * How Blast Proof the Cover is. 30 is normal. + */ + public float getBlastProofLevel(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return 10.0F; + } + + /** + * If it lets RS-Signals into the Block + *

+ * This is just Informative so that Machines know if their Redstone Input is blocked or not + */ + public boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * If it lets RS-Signals out of the Block + */ + public boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Energy into the Block + */ + public boolean letsEnergyIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Energy out of the Block + */ + public boolean letsEnergyOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Liquids into the Block, aFluid can be null meaning if this is generally allowing Fluids or not. + */ + public boolean letsFluidIn(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Liquids out of the Block, aFluid can be null meaning if this is generally allowing Fluids or not. + */ + public boolean letsFluidOut(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Items into the Block, aSlot = -1 means if it is generally accepting Items (return false for no + * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each + * Slot). + */ + public boolean letsItemsIn(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Items out of the Block, aSlot = -1 means if it is generally accepting Items (return false for no + * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each + * Slot). + */ + public boolean letsItemsOut(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets you rightclick the Machine normally + */ + public boolean isGUIClickable(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return true; + } + + /** + * Needs to return true for Covers, which have a Redstone Output on their Facing. + */ + public boolean manipulatesSidedRedstoneOutput(ForgeDirection side, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + /** + * if this Cover should let Pipe Connections look connected even if it is not the case. + */ + public boolean alwaysLookConnected(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * Called to determine the incoming Redstone Signal of a Machine. Returns the original Redstone per default. The + * Cover should @letsRedstoneGoIn or the aInputRedstone Parameter is always 0. + */ + public byte getRedstoneInput(ForgeDirection side, byte aInputRedstone, int aCoverID, int aCoverVariable, + ICoverable aTileEntity) { + return letsRedstoneGoIn(side, aCoverID, aCoverVariable, aTileEntity) ? aInputRedstone : 0; + } + + /** + * Gets the Tick Rate for doCoverThings of the Cover + *

+ * 0 = No Ticks! Yes, 0 is Default, you have to override this + */ + public int getTickRate(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return 0; + } + + /** + * The MC Color of this Lens. -1 for no Color (meaning this isn't a Lens then). + */ + public byte getLensColor(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return -1; + } + + /** + * @return the ItemStack dropped by this Cover + */ + public ItemStack getDrop(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { + return GTOreDictUnificator.get(true, aTileEntity.getCoverItemAtSide(side)); + } +} diff --git a/src/main/java/gregtech/api/util/CoverBehaviorBase.java b/src/main/java/gregtech/api/util/CoverBehaviorBase.java new file mode 100644 index 0000000000..0c8ef81533 --- /dev/null +++ b/src/main/java/gregtech/api/util/CoverBehaviorBase.java @@ -0,0 +1,839 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.E; + +import java.lang.ref.WeakReference; +import java.util.List; +import java.util.function.Supplier; + +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagInt; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; + +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.ModularUITextures; +import com.gtnewhorizons.modularui.api.drawable.ItemDrawable; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import gregtech.api.GregTechAPI; +import gregtech.api.gui.GUIColorOverride; +import gregtech.api.gui.modularui.CoverUIBuildContext; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GUITextureSet; +import gregtech.api.gui.widgets.CoverTickRateButton; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.common.covers.CoverInfo; + +/** + * For Covers with a special behavior. + * + * @author glease + */ +public abstract class CoverBehaviorBase { + + public WeakReference lastPlayer = null; + private final Class typeToken; + private final ITexture coverFGTexture; + + protected CoverBehaviorBase(Class typeToken) { + this(typeToken, null); + } + + protected CoverBehaviorBase(Class typeToken, ITexture coverTexture) { + this.typeToken = typeToken; + this.coverFGTexture = coverTexture; + reloadColorOverride(); + } + + public void reloadColorOverride() { + this.colorOverride = GUIColorOverride.get(guiTexturePath); + } + + public abstract T createDataObject(int aLegacyData); + + public abstract T createDataObject(); + + public final T createDataObject(NBTBase aNBT) { + // Handle legacy data (migrating from GT_CoverBehavior to GT_CoverBehaviorBase) + if (aNBT instanceof NBTTagInt) { + return createDataObject(((NBTTagInt) aNBT).func_150287_d()); + } + + final T ret = createDataObject(); + ret.loadDataFromNBT(aNBT); + return ret; + } + + public final T cast(ISerializableObject aData) { + if (typeToken.isInstance(aData)) return forceCast(aData); + return null; + } + + private T forceCast(ISerializableObject aData) { + try { + return typeToken.cast(aData); + } catch (Exception e) { + throw new RuntimeException("Casting data in " + this.getClass() + ", data " + aData, e); + } + } + + // region facade + + /** + * Get target facade block. Does not affect rendering of **this** block. It is only used as a hint for other block + * in case of CTM + * + * @return null if none, otherwise return facade target block + */ + public final Block getFacadeBlock(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getFacadeBlockImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Get target facade block. Does not affect rendering of **this** block. It is only used as a hint for other block + * in case of CTM + * + * @return 0 if none, otherwise return facade target meta + */ + public final int getFacadeMeta(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getFacadeMetaImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Get the display stack. Default to {@code int2Stack(aCoverID)} + */ + public final ItemStack getDisplayStack(int aCoverID, ISerializableObject aCoverVariable) { + return getDisplayStackImpl(aCoverID, forceCast(aCoverVariable)); + } + + /** + * Get the special foreground cover texture associated with this cover. Return null if one should use the texture + * passed to {@link GregTechAPI#registerCover(ItemStack, ITexture, CoverBehaviorBase)} or its + * overloads. + */ + public final ITexture getSpecialCoverFGTexture(ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return getSpecialCoverFGTextureImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Get the special cover texture associated with this cover. Return null if one should use the texture passed to + * {@link GregTechAPI#registerCover(ItemStack, ITexture, CoverBehaviorBase)} or its overloads. + */ + public final ITexture getSpecialCoverTexture(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getSpecialCoverTextureImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Return whether cover data needs to be synced to client upon tile entity creation or cover placement. + *

+ * Note if you want to sync the data afterwards you will have to manually do it by calling + * {@link ICoverable#issueCoverUpdate(ForgeDirection)} This option only affects the initial sync. + */ + public final boolean isDataNeededOnClient(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return isDataNeededOnClientImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Called upon receiving data from network. Use {@link ICoverable#isClientSide()} to determine the side. + */ + public final void onDataChanged(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + onDataChangedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Called before receiving data from network. Use {@link ICoverable#isClientSide()} to determine the side. + */ + public final void preDataChanged(ForgeDirection side, int aCoverID, int aNewCoverId, + ISerializableObject aCoverVariable, ISerializableObject aNewCoverVariable, ICoverable aTileEntity) { + preDataChangedImpl( + side, + aCoverID, + aNewCoverId, + forceCast(aCoverVariable), + forceCast(aNewCoverVariable), + aTileEntity); + } + + /** + * Called upon cover being removed. Called on both server and client. + */ + public final void onDropped(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + onDroppedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + public final boolean isRedstoneSensitive(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity, long aTimer) { + return isRedstoneSensitiveImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aTimer); + } + + /** + * Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time. + */ + public final T doCoverThings(ForgeDirection side, byte aInputRedstone, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity, long aTimer) { + return doCoverThingsImpl(side, aInputRedstone, aCoverID, forceCast(aCoverVariable), aTileEntity, aTimer); + } + + /** + * Called when someone rightclicks this Cover. + *

+ * return true, if something actually happens. + */ + public final boolean onCoverRightClick(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { + return onCoverRightClickImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ); + } + + /** + * Called when someone rightclicks this Cover with a Screwdriver. Doesn't call @onCoverRightclick in this Case. + *

+ * return the new Value of the Cover Variable + */ + public final T onCoverScrewdriverClick(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { + return onCoverScrewdriverClickImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ); + } + + /** + * Called when someone shift-rightclicks this Cover with no tool. Doesn't call @onCoverRightclick in this Case. + */ + public final boolean onCoverShiftRightClick(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity, EntityPlayer aPlayer) { + return onCoverShiftRightClickImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aPlayer); + } + + /** + * Removes the Cover if this returns true, or if aForced is true. Doesn't get called when the Machine Block is + * getting broken, only if you break the Cover away from the Machine. + */ + public final boolean onCoverRemoval(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity, boolean aForced) { + return onCoverRemovalImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aForced); + } + + /** + * Called upon Base TE being destroyed (once getDrops is called), thus getting called only when destroyed in + * survival. + */ + public final void onBaseTEDestroyed(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + onBaseTEDestroyedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Gives a small Text for the status of the Cover. + */ + public final String getDescription(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getDescriptionImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Called when Base TE being unloaded. + */ + public void onCoverUnload(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + onCoverUnloadImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * How Blast Proof the Cover is. 30 is normal. + */ + public final float getBlastProofLevel(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getBlastProofLevelImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * If it lets RS-Signals into the Block + *

+ * This is just Informative so that Machines know if their Redstone Input is blocked or not + */ + public final boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return letsRedstoneGoInImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * If it lets RS-Signals out of the Block + */ + public final boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return letsRedstoneGoOutImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * If it lets Energy into the Block + */ + public final boolean letsEnergyIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return letsEnergyInImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * If it lets Energy out of the Block + */ + public final boolean letsEnergyOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return letsEnergyOutImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * If it lets Liquids into the Block, aFluid can be null meaning if this is generally allowing Fluids or not. + */ + public final boolean letsFluidIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + Fluid aFluid, ICoverable aTileEntity) { + return letsFluidInImpl(side, aCoverID, forceCast(aCoverVariable), aFluid, aTileEntity); + } + + /** + * If it lets Liquids out of the Block, aFluid can be null meaning if this is generally allowing Fluids or not. + */ + public final boolean letsFluidOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + Fluid aFluid, ICoverable aTileEntity) { + return letsFluidOutImpl(side, aCoverID, forceCast(aCoverVariable), aFluid, aTileEntity); + } + + /** + * If it lets Items into the Block, aSlot = -1 means if it is generally accepting Items (return false for no + * reaction at all), aSlot = -2 means if it would accept for all Slots Impl(return true to skip the Checks for each + * Slot). + */ + public final boolean letsItemsIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return letsItemsInImpl(side, aCoverID, forceCast(aCoverVariable), aSlot, aTileEntity); + } + + /** + * If it lets Items out of the Block, aSlot = -1 means if it is generally accepting Items (return false for no + * reaction at all), aSlot = -2 means if it would accept for all Slots Impl(return true to skip the Checks for each + * Slot). + */ + public final boolean letsItemsOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return letsItemsOutImpl(side, aCoverID, forceCast(aCoverVariable), aSlot, aTileEntity); + } + + /** + * If it lets you rightclick the Machine normally + */ + public final boolean isGUIClickable(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return isGUIClickableImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Needs to return true for Covers, which have a Redstone Output on their Facing. + */ + public final boolean manipulatesSidedRedstoneOutput(ForgeDirection side, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return manipulatesSidedRedstoneOutputImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * if this Cover should let Pipe Connections look connected even if it is not the case. + */ + public final boolean alwaysLookConnected(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return alwaysLookConnectedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Called to determine the incoming Redstone Signal of a Machine. Returns the original Redstone per default. The + * Cover should @letsRedstoneGoIn or the aInputRedstone Parameter is always 0. + */ + public final byte getRedstoneInput(ForgeDirection side, byte aInputRedstone, int aCoverID, + ISerializableObject aCoverVariable, ICoverable aTileEntity) { + return getRedstoneInputImpl(side, aInputRedstone, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Gets the Tick Rate for doCoverThings of the Cover + *

+ * 0 = No Ticks! Yes, 0 is Default, you have to override this + */ + public final int getTickRate(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getTickRateImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * The MC Color of this Lens. -1 for no Color (meaning this isn't a Lens then). + */ + public final byte getLensColor(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getLensColorImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * @return the ItemStack dropped by this Cover + */ + public final ItemStack getDrop(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) { + return getDropImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); + } + + /** + * Called when the cover is initially attached to a machine. + * + * @param player The attaching player + * @param aCover An {@link ItemStack} containing the cover + * @param aTileEntity The machine receiving the cover + * @param side Which side the cover is attached to + */ + public void onPlayerAttach(EntityPlayer player, ItemStack aCover, ICoverable aTileEntity, ForgeDirection side) { + // Do nothing by default. + } + + // endregion + + // region UI stuff + + protected GT_TooltipDataCache mTooltipCache = new GT_TooltipDataCache(); + protected GUIColorOverride colorOverride; + private static final String guiTexturePath = "gregtech:textures/gui/GuiCover.png"; + + public ModularWindow createWindow(CoverUIBuildContext buildContext) { + return new UIFactory(buildContext).createWindow(); + } + + /** + * Creates {@link ModularWindow} for this cover. This is separated from base class, as attaching the same covers in + * different sides of the same tile needs different UI with different context. + */ + protected class UIFactory { + + private final CoverUIBuildContext uiBuildContext; + + public UIFactory(CoverUIBuildContext buildContext) { + this.uiBuildContext = buildContext; + } + + public ModularWindow createWindow() { + ModularWindow.Builder builder = ModularWindow.builder(getGUIWidth(), getGUIHeight()); + builder.setBackground(ModularUITextures.VANILLA_BACKGROUND); + builder.setGuiTint(getUIBuildContext().getGuiColorization()); + maybeBindPlayerInventory(builder); + addTitleToUI(builder); + addUIWidgets(builder); + if (getUIBuildContext().isAnotherWindow()) { + builder.widget( + ButtonWidget.closeWindowButton(true) + .setPos(getGUIWidth() - 15, 3)); + } + + final CoverInfo coverInfo = uiBuildContext.getTile() + .getCoverInfoAtSide(uiBuildContext.getCoverSide()); + final CoverBehaviorBase behavior = coverInfo.getCoverBehavior(); + if (coverInfo.getMinimumTickRate() > 0 && behavior.allowsTickRateAddition()) { + builder.widget( + new CoverTickRateButton(coverInfo, builder).setPos(getGUIWidth() - 24, getGUIHeight() - 24)); + } + + return builder.build(); + } + + protected void maybeBindPlayerInventory(ModularWindow.Builder builder) { + if (doesBindPlayerInventory() && !getUIBuildContext().isAnotherWindow()) { + builder.bindPlayerInventory(getUIBuildContext().getPlayer(), 7, GUITextureSet.DEFAULT.getItemSlot()); + } + } + + /** + * Override this to add widgets for your UI. + */ + protected void addUIWidgets(ModularWindow.Builder builder) {} + + public CoverUIBuildContext getUIBuildContext() { + return uiBuildContext; + } + + /** + * Can return null when cover data is invalid e.g. tile is broken or cover is removed + */ + @Nullable + public T getCoverData() { + if (isCoverValid()) { + return forceCast( + getUIBuildContext().getTile() + .getComplexCoverDataAtSide(getUIBuildContext().getCoverSide())); + } else { + return null; + } + } + + public boolean setCoverData(T data) { + if (isCoverValid()) { + getUIBuildContext().getTile() + .receiveCoverData( + getUIBuildContext().getCoverSide(), + getUIBuildContext().getCoverID(), + data, + getUIBuildContext().getPlayer() instanceof EntityPlayerMP + ? (EntityPlayerMP) getUIBuildContext().getPlayer() + : null); + return true; + } else { + return false; + } + } + + public boolean isCoverValid() { + return !getUIBuildContext().getTile() + .isDead() + && getUIBuildContext().getTile() + .getCoverBehaviorAtSideNew(getUIBuildContext().getCoverSide()) != GregTechAPI.sNoBehavior; + } + + protected void addTitleToUI(ModularWindow.Builder builder) { + ItemStack coverItem = GTUtility.intToStack(getUIBuildContext().getCoverID()); + if (coverItem != null) { + builder.widget( + new ItemDrawable(coverItem).asWidget() + .setPos(5, 5) + .setSize(16, 16)) + .widget( + new TextWidget(coverItem.getDisplayName()).setDefaultColor(COLOR_TITLE.get()) + .setPos(25, 9)); + } + } + + protected int getGUIWidth() { + return 176; + } + + protected int getGUIHeight() { + return 107; + } + + protected boolean doesBindPlayerInventory() { + return false; + } + + protected int getTextColorOrDefault(String textType, int defaultColor) { + return colorOverride.getTextColorOrDefault(textType, defaultColor); + } + + protected final Supplier COLOR_TITLE = () -> getTextColorOrDefault("title", 0x222222); + protected final Supplier COLOR_TEXT_GRAY = () -> getTextColorOrDefault("text_gray", 0x555555); + protected final Supplier COLOR_TEXT_WARN = () -> getTextColorOrDefault("text_warn", 0xff0000); + } + + // endregion + + // region impl + + protected Block getFacadeBlockImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return null; + } + + protected int getFacadeMetaImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return 0; + } + + protected ItemStack getDisplayStackImpl(int aCoverID, T aCoverVariable) { + return GTUtility.intToStack(aCoverID); + } + + protected ITexture getSpecialCoverFGTextureImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return coverFGTexture; + } + + protected ITexture getSpecialCoverTextureImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return null; + } + + protected boolean isDataNeededOnClientImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + protected void onDataChangedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {} + + protected void preDataChangedImpl(ForgeDirection side, int aCoverID, int aNewCoverId, T aCoverVariable, + T aNewCoverVariable, ICoverable aTileEntity) {} + + protected void onDroppedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {} + + protected void onBaseTEDestroyedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {} + + protected void onCoverUnloadImpl(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, + ICoverable aTileEntity) {} + + protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity, long aTimer) { + return false; + } + + /** + * Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time. + */ + protected T doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, T aCoverVariable, + ICoverable aTileEntity, long aTimer) { + return aCoverVariable; + } + + /** + * Called when someone rightclicks this Cover. + *

+ * return true, if something actually happens. + */ + protected boolean onCoverRightClickImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer, float aX, float aY, float aZ) { + return false; + } + + /** + * Called when someone rightclicks this Cover with a Screwdriver. Doesn't call @onCoverRightclick in this Case. + *

+ * return the new Value of the Cover Variable + */ + protected T onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity, + EntityPlayer aPlayer, float aX, float aY, float aZ) { + return aCoverVariable; + } + + /** + * Called when someone shift-rightclicks this Cover with no tool. Doesn't call @onCoverRightclick in this Case. + */ + protected boolean onCoverShiftRightClickImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity, EntityPlayer aPlayer) { + if (hasCoverGUI() && aPlayer instanceof EntityPlayerMP) { + lastPlayer = new WeakReference<>(aPlayer); + GTUIInfos.openCoverUI(aTileEntity, aPlayer, side); + return true; + } + return false; + } + + /** + * Removes the Cover if this returns true, or if aForced is true. Doesn't get called when the Machine Block is + * getting broken, only if you break the Cover away from the Machine. + */ + protected boolean onCoverRemovalImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity, + boolean aForced) { + return true; + } + + /** + * Gives a small Text for the status of the Cover. + */ + protected String getDescriptionImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return E; + } + + /** + * How Blast Proof the Cover is. 30 is normal. + */ + protected float getBlastProofLevelImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return 10.0F; + } + + /** + * If it lets RS-Signals into the Block + *

+ * This is just Informative so that Machines know if their Redstone Input is blocked or not + */ + protected boolean letsRedstoneGoInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets RS-Signals out of the Block + */ + protected boolean letsRedstoneGoOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Energy into the Block + */ + protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Energy out of the Block + */ + protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Liquids into the Block, aFluid can be null meaning if this is generally allowing Fluids or not. + */ + protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Liquids out of the Block, aFluid can be null meaning if this is generally allowing Fluids or not. + */ + protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, Fluid aFluid, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Items into the Block, aSlot = -1 means if it is generally accepting Items (return false for no + * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each + * Slot). + */ + protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets Items out of the Block, aSlot = -1 means if it is generally accepting Items (return false for no + * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each + * Slot). + */ + protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, int aSlot, + ICoverable aTileEntity) { + return false; + } + + /** + * If it lets you rightclick the Machine normally + */ + protected boolean isGUIClickableImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return true; + } + + /** + * Needs to return true for Covers, which have a Redstone Output on their Facing. + */ + protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + /** + * if this Cover should let Pipe Connections look connected even if it is not the case. + */ + protected boolean alwaysLookConnectedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return false; + } + + /** + * Called to determine the incoming Redstone Signal of a Machine. Returns the original Redstone per default. The + * Cover should @letsRedstoneGoIn or the aInputRedstone Parameter is always 0. + */ + protected byte getRedstoneInputImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, T aCoverVariable, + ICoverable aTileEntity) { + return letsRedstoneGoIn(side, aCoverID, aCoverVariable, aTileEntity) ? aInputRedstone : 0; + } + + /** + * Gets the Tick Rate for doCoverThings of the Cover + *

+ * 0 = No Ticks! Yes, 0 is Default, you have to override this + */ + protected int getTickRateImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return 0; + } + + /** + * The MC Color of this Lens. -1 for no Color (meaning this isn't a Lens then). + */ + protected byte getLensColorImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return -1; + } + + /** + * @return the ItemStack dropped by this Cover + */ + protected ItemStack getDropImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { + return GTOreDictUnificator.get(true, aTileEntity.getCoverItemAtSide(side)); + } + + // endregion + + // region no data + + /** + * Checks if the Cover can be placed on this. + */ + public boolean isCoverPlaceable(ForgeDirection side, ItemStack aStack, ICoverable aTileEntity) { + return true; + } + + public boolean hasCoverGUI() { + return false; + } + + /** + * Called when someone rightclicks this Cover Client Side + *

+ * return true, if something actually happens. + */ + public boolean onCoverRightclickClient(ForgeDirection side, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, + float aY, float aZ) { + return false; + } + + /** + * If this is a simple Cover, which can also be used on Bronze Machines and similar. + */ + public boolean isSimpleCover() { + return false; + } + + /** + * sets the Cover upon placement. + */ + public void placeCover(ForgeDirection side, ItemStack aCover, ICoverable aTileEntity) { + aTileEntity.setCoverIDAtSide(side, GTUtility.stackToInt(aCover)); + } + + public boolean allowsCopyPasteTool() { + return true; + } + + public boolean allowsTickRateAddition() { + return true; + } + + @NotNull + public final List getAdditionalTooltip(ISerializableObject coverData) { + return getAdditionalTooltipImpl(forceCast(coverData)); + } + + /** + * Override to add to the tooltip generated when a user hovers over the cover on the left side of a machine's UI. + * + * @param coverData The cover data associated with the cover on a particular side. + * @return A list of new tooltip entries. Entries are inserted at the top, just after the name and direction line. + */ + protected List getAdditionalTooltipImpl(T coverData) { + return ImmutableList.of(); + } + // endregion +} diff --git a/src/main/java/gregtech/api/util/ExoticEnergyInputHelper.java b/src/main/java/gregtech/api/util/ExoticEnergyInputHelper.java new file mode 100644 index 0000000000..6640f03835 --- /dev/null +++ b/src/main/java/gregtech/api/util/ExoticEnergyInputHelper.java @@ -0,0 +1,103 @@ +package gregtech.api.util; + +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatch; +import tectech.thing.metaTileEntity.hatch.MTEHatchEnergyMulti; +import tectech.thing.metaTileEntity.hatch.MTEHatchEnergyTunnel; + +public class ExoticEnergyInputHelper { + + /** + * The Valid Types of TecTech Hatch List. + */ + private static final List> sExoticEnergyHatchType = new ArrayList<>(); + + static { + register(MTEHatchEnergyMulti.class); + register(MTEHatchEnergyTunnel.class); + } + + public static void register(Class clazz) { + if (!MTEHatch.class.isAssignableFrom(clazz)) + throw new IllegalArgumentException(clazz.getName() + " is not a subclass of " + MTEHatch.class.getName()); + sExoticEnergyHatchType.add(clazz); + } + + public static boolean drainEnergy(long aEU, Collection hatches) { + for (MTEHatch tHatch : hatches) { + long tDrain = Math.min( + tHatch.getBaseMetaTileEntity() + .getStoredEU(), + aEU); + tHatch.getBaseMetaTileEntity() + .decreaseStoredEnergyUnits(tDrain, false); + aEU -= tDrain; + } + return aEU <= 0; + } + + public static boolean isExoticEnergyInput(IMetaTileEntity aHatch) { + for (Class clazz : sExoticEnergyHatchType) { + if (clazz.isInstance(aHatch)) return true; + } + return false; + } + + public static long getTotalEuMulti(Collection hatches) { + long rEU = 0L; + for (MTEHatch tHatch : filterValidMTEs(hatches)) { + rEU += tHatch.getBaseMetaTileEntity() + .getInputVoltage() * tHatch.maxWorkingAmperesIn(); + } + return rEU; + } + + public static long getMaxInputVoltageMulti(Collection hatches) { + long rVoltage = 0; + for (MTEHatch tHatch : filterValidMTEs(hatches)) { + rVoltage += tHatch.getBaseMetaTileEntity() + .getInputVoltage(); + } + return rVoltage; + } + + public static long getAverageInputVoltageMulti(Collection hatches) { + long rVoltage = 0; + for (MTEHatch tHatch : filterValidMTEs(hatches)) { + rVoltage += tHatch.getBaseMetaTileEntity() + .getInputVoltage(); + } + if (hatches.isEmpty()) { + return 0; + } + return rVoltage / hatches.size(); + } + + public static long getMaxInputAmpsMulti(Collection hatches) { + long rAmp = 0; + for (MTEHatch tHatch : filterValidMTEs(hatches)) { + rAmp += tHatch.getBaseMetaTileEntity() + .getInputAmperage(); + } + return rAmp; + } + + public static long getMaxWorkingInputAmpsMulti(Collection hatches) { + long rAmp = 0; + for (MTEHatch tHatch : filterValidMTEs(hatches)) { + rAmp += tHatch.maxWorkingAmperesIn(); + } + return rAmp; + } + + public static List> getAllClasses() { + return Collections.unmodifiableList(sExoticEnergyHatchType); + } +} diff --git a/src/main/java/gregtech/api/util/FishPondFakeRecipe.java b/src/main/java/gregtech/api/util/FishPondFakeRecipe.java index b5bfff9e29..8f36600e2a 100644 --- a/src/main/java/gregtech/api/util/FishPondFakeRecipe.java +++ b/src/main/java/gregtech/api/util/FishPondFakeRecipe.java @@ -1,6 +1,6 @@ package gregtech.api.util; -import static gregtech.api.util.GT_RecipeBuilder.SECONDS; +import static gregtech.api.util.GTRecipeBuilder.SECONDS; import static gtPlusPlus.api.recipe.GTPPRecipeMaps.fishPondRecipes; import java.util.ArrayList; @@ -9,7 +9,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.WeightedRandomFishable; import net.minecraftforge.common.FishingHooks; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gtPlusPlus.api.objects.Logger; import gtPlusPlus.api.objects.data.AutoMap; import gtPlusPlus.core.util.minecraft.ItemUtils; @@ -50,8 +50,8 @@ public class FishPondFakeRecipe { ItemStack t = (ItemStack) ReflectionUtils .getField(WeightedRandomFishable.class, "field_150711_b") .get(u); - GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.getIntegratedCircuit(mType)) + GTValues.RA.stdBuilder() + .itemInputs(GTUtility.getIntegratedCircuit(mType)) .itemOutputs(t) .duration(5 * SECONDS) .eut(0) diff --git a/src/main/java/gregtech/api/util/GTApiaryModifier.java b/src/main/java/gregtech/api/util/GTApiaryModifier.java new file mode 100644 index 0000000000..955b2e60f9 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTApiaryModifier.java @@ -0,0 +1,24 @@ +package gregtech.api.util; + +import net.minecraft.world.biome.BiomeGenBase; + +public class GTApiaryModifier { + + public float territory = 1f; + public float mutation = 1f; + public float lifespan = 1f; + public float production = 2f; + public float flowering = 1f; + public float geneticDecay = 1f; + public boolean isSealed = false; + public boolean isSelfLighted = false; + public boolean isSelfUnlighted = false; + public boolean isSunlightSimulated = false; + public boolean isAutomated = false; + public boolean isCollectingPollen = false; + public BiomeGenBase biomeOverride = null; + public float energy = 1f; + public float temperature = 0f; + public float humidity = 0f; + public int maxSpeed = 0; +} diff --git a/src/main/java/gregtech/api/util/GTApiaryUpgrade.java b/src/main/java/gregtech/api/util/GTApiaryUpgrade.java new file mode 100644 index 0000000000..5de373a57e --- /dev/null +++ b/src/main/java/gregtech/api/util/GTApiaryUpgrade.java @@ -0,0 +1,224 @@ +package gregtech.api.util; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.biome.BiomeGenBase; + +import gregtech.api.enums.OrePrefixes; +import gregtech.common.items.MetaGeneratedItem03; + +/** + * Actual items are defined in {@link MetaGeneratedItem03} + */ +public enum GTApiaryUpgrade { + + speed1(UNIQUE_INDEX.SPEED_UPGRADE, 32200, 1, (mods, n) -> mods.maxSpeed = 1), + speed2(UNIQUE_INDEX.SPEED_UPGRADE, 32201, 1, (mods, n) -> mods.maxSpeed = 2), + speed3(UNIQUE_INDEX.SPEED_UPGRADE, 32202, 1, (mods, n) -> mods.maxSpeed = 3), + speed4(UNIQUE_INDEX.SPEED_UPGRADE, 32203, 1, (mods, n) -> mods.maxSpeed = 4), + speed5(UNIQUE_INDEX.SPEED_UPGRADE, 32204, 1, (mods, n) -> mods.maxSpeed = 5), + speed6(UNIQUE_INDEX.SPEED_UPGRADE, 32205, 1, (mods, n) -> mods.maxSpeed = 6), + speed7(UNIQUE_INDEX.SPEED_UPGRADE, 32206, 1, (mods, n) -> mods.maxSpeed = 7), + speed8(UNIQUE_INDEX.SPEED_UPGRADE, 32207, 1, (mods, n) -> mods.maxSpeed = 8), + speed8upgraded(UNIQUE_INDEX.SPEED_UPGRADE, 32208, 1, (mods, n) -> { + mods.maxSpeed = 8; + mods.production = 17.19926784f; + mods.energy *= 14.75; + }), + production(UNIQUE_INDEX.PRODUCTION_UPGRADE, 32209, 8, (mods, n) -> { + mods.production = 4.f * (float) Math.pow(1.2d, n); + mods.energy *= Math.pow(1.4f, n); + }), + plains(UNIQUE_INDEX.PLAINS_UPGRADE, 32210, 1, (mods, n) -> { + mods.biomeOverride = BiomeGenBase.plains; + mods.energy *= 1.2f; + }), + light(UNIQUE_INDEX.LIGHT_UPGRADE, 32211, 1, (mods, n) -> { + mods.isSelfLighted = true; + mods.energy *= 1.05f; + }), + flowering(UNIQUE_INDEX.FLOWERING_UPGRADE, 32212, 8, (mods, n) -> { + mods.flowering *= Math.pow(1.2f, n); + mods.energy *= Math.pow(1.1f, n); + }), + winter(UNIQUE_INDEX.WINTER_UPGRADE, 32213, 1, (mods, n) -> { + mods.biomeOverride = BiomeGenBase.taiga; + mods.energy *= 1.5f; + }), + dryer(UNIQUE_INDEX.DRYER_UPGRADE, 32214, 16, (mods, n) -> { + mods.humidity -= 0.125f * n; + mods.energy *= Math.pow(1.025f, n); + }), + automation(UNIQUE_INDEX.AUTOMATION_UPGRADE, 32215, 1, (mods, n) -> { + mods.isAutomated = true; + mods.energy *= 1.1f; + }), + humidifier(UNIQUE_INDEX.HUMIDIFIER_UPGRADE, 32216, 16, (mods, n) -> { + mods.humidity += 0.125f * n; + mods.energy *= Math.pow(1.05f, n); + }), + hell(UNIQUE_INDEX.HELL_UPGRADE, 32217, 1, (mods, n) -> { + mods.biomeOverride = BiomeGenBase.hell; + mods.energy *= 1.5f; + }), + pollen(UNIQUE_INDEX.POLLEN_UPGRADE, 32218, 1, (mods, n) -> { + mods.flowering = 0f; + mods.energy *= 1.3f; + }), + desert(UNIQUE_INDEX.DESERT_UPGRADE, 32219, 1, (mods, n) -> { + mods.biomeOverride = BiomeGenBase.desert; + mods.energy *= 1.2f; + }), + cooler(UNIQUE_INDEX.COOLER_UPGRADE, 32220, 16, (mods, n) -> { + mods.temperature -= 0.125f * n; + mods.energy *= Math.pow(1.025f, n); + }), + lifespan(UNIQUE_INDEX.LIFESPAN_UPGRADE, 32221, 4, (mods, n) -> { + mods.lifespan /= Math.pow(1.5f, n); + mods.energy *= Math.pow(1.05f, n); + }), + seal(UNIQUE_INDEX.SEAL_UPGRADE, 32222, 1, (mods, n) -> { + mods.isSealed = true; + mods.energy *= 1.05f; + }), + stabilizer(UNIQUE_INDEX.STABILIZER_UPGRADE, 32223, 1, (mods, n) -> { + mods.geneticDecay = 0f; + mods.energy *= 2.50f; + }), + jungle(UNIQUE_INDEX.JUNGLE_UPGRADE, 32224, 1, (mods, n) -> { + mods.biomeOverride = BiomeGenBase.jungle; + mods.energy *= 1.20f; + }), + territory(UNIQUE_INDEX.TERRITORY_UPGRADE, 32225, 4, (mods, n) -> { + mods.territory *= Math.pow(1.5f, n); + mods.energy *= Math.pow(1.05f, n); + }), + ocean(UNIQUE_INDEX.OCEAN_UPGRADE, 32226, 1, (mods, n) -> { + mods.biomeOverride = BiomeGenBase.ocean; + mods.energy *= 1.20f; + }), + sky(UNIQUE_INDEX.SKY_UPGRADE, 32227, 1, (mods, n) -> { + mods.isSunlightSimulated = true; + mods.energy *= 1.05f; + }), + heater(UNIQUE_INDEX.HEATER_UPGRADE, 32228, 16, (mods, n) -> { + mods.temperature += 0.125f * n; + mods.energy *= Math.pow(1.025f, n); + }), + sieve(UNIQUE_INDEX.SIEVE_UPGRADE, 32229, 1, (mods, n) -> { + mods.isCollectingPollen = true; + mods.energy *= 1.05f; + }), + unlight(UNIQUE_INDEX.LIGHT_UPGRADE, 32231, 1, (mods, n) -> { + mods.isSelfUnlighted = true; + mods.energy *= 1.05f; + }),; + + private enum UNIQUE_INDEX { + + SPEED_UPGRADE, + PRODUCTION_UPGRADE, + PLAINS_UPGRADE, + LIGHT_UPGRADE, // also unlight + FLOWERING_UPGRADE, + WINTER_UPGRADE, + DRYER_UPGRADE, + AUTOMATION_UPGRADE, + HUMIDIFIER_UPGRADE, + HELL_UPGRADE, + POLLEN_UPGRADE, + DESERT_UPGRADE, + COOLER_UPGRADE, + LIFESPAN_UPGRADE, + SEAL_UPGRADE, + STABILIZER_UPGRADE, + JUNGLE_UPGRADE, + TERRITORY_UPGRADE, + OCEAN_UPGRADE, + SKY_UPGRADE, + HEATER_UPGRADE, + SIEVE_UPGRADE,; + + void apply(Consumer fn) { + UNIQUE_UPGRADE_LIST.get(this) + .forEach(fn); + } + } + + private static final EnumMap> UNIQUE_UPGRADE_LIST = new EnumMap<>( + UNIQUE_INDEX.class); + + private int meta = 0; + private int maxnumber = 1; + + private final GTUtility.ItemId id; + private final UNIQUE_INDEX unique_index; + private final BiConsumer applier; + + private final HashSet blacklistedUpgrades = new HashSet<>(); + + GTApiaryUpgrade(UNIQUE_INDEX unique_index, int meta, int maxnumber, BiConsumer applier) { + this.unique_index = unique_index; + this.meta = meta; + this.maxnumber = maxnumber; + this.applier = applier; + this.id = GTUtility.ItemId.createNoCopy(get(1)); + } + + private void setup_static_variables() { + quickLookup.put(this.meta, this); + ArrayList un = UNIQUE_UPGRADE_LIST.get(this.unique_index); + if (un != null) un.forEach((u) -> { + u.blacklistedUpgrades.add(this.id); + this.blacklistedUpgrades.add(u.id); + }); + else { + un = new ArrayList<>(1); + UNIQUE_UPGRADE_LIST.put(this.unique_index, un); + } + un.add(this); + } + + public static GTApiaryUpgrade getUpgrade(ItemStack s) { + if (s == null) return null; + if (!isUpgrade(s)) return null; + return quickLookup.get(s.getItemDamage()); + } + + public boolean isAllowedToWorkWith(ItemStack s) { + GTUtility.ItemId id = GTUtility.ItemId.createNoCopy(s); + return !blacklistedUpgrades.contains(id); + } + + public int getMaxNumber() { + return maxnumber; + } + + public void applyModifiers(GTApiaryModifier mods, ItemStack stack) { + if (applier != null) applier.accept(mods, stack.stackSize); + } + + public ItemStack get(int count) { + return new ItemStack(MetaGeneratedItem03.INSTANCE, count, meta); + } + + public static boolean isUpgrade(ItemStack s) { + return OrePrefixes.apiaryUpgrade.contains(s); + } + + private static final HashMap quickLookup = new HashMap<>(); + + static { + EnumSet.allOf(GTApiaryUpgrade.class) + .forEach(GTApiaryUpgrade::setup_static_variables); + speed8upgraded.blacklistedUpgrades.add(production.id); + production.blacklistedUpgrades.add(speed8upgraded.id); + } +} diff --git a/src/main/java/gregtech/api/util/GTBaseCrop.java b/src/main/java/gregtech/api/util/GTBaseCrop.java new file mode 100644 index 0000000000..2ddf37bbeb --- /dev/null +++ b/src/main/java/gregtech/api/util/GTBaseCrop.java @@ -0,0 +1,311 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.E; +import static gregtech.api.enums.Mods.IC2CropPlugin; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.ConfigCategories; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.objects.ItemData; +import gregtech.common.blocks.BlockOresAbstract; +import gregtech.common.blocks.TileEntityOres; +import ic2.api.crops.CropCard; +import ic2.api.crops.Crops; +import ic2.api.crops.ICropTile; +import speiger.src.crops.api.ICropCardInfo; + +public class GTBaseCrop extends CropCard implements ICropCardInfo { + + public static ArrayList sCropList = new ArrayList<>(); + private String mName = E; + private String mDiscoveredBy = "Gregorius Techneticies"; + private String[] mAttributes; + private int mTier = 0; + private int mMaxSize = 0; + private int mAfterHarvestSize = 0; + private int mHarvestSize = 0; + private final int[] mStats = new int[5]; + private final int mGrowthSpeed = 0; + private ItemStack mDrop = null; + private ItemStack[] mSpecialDrops = null; + private Materials mBlock = null; + private static boolean bIc2NeiLoaded = IC2CropPlugin.isModLoaded(); + + /** + * To create new Crops + * + * @param aID Default ID + * @param aCropName Name of the Crop + * @param aDiscoveredBy The one who discovered the Crop + * @param aDrop The Item which is dropped by the Crop. must be != null + * @param aBaseSeed Baseseed to plant this Crop. null == crossbreed only + * @param aTier tier of the Crop. forced to be >= 1 + * @param aMaxSize maximum Size of the Crop. forced to be >= 3 + * @param aGrowthSpeed how fast the Crop grows. if < 0 then its set to Tier*300 + * @param aHarvestSize the size the Crop needs to be harvested. forced to be between 2 and max size + */ + public GTBaseCrop(int aID, String aCropName, String aDiscoveredBy, ItemStack aBaseSeed, int aTier, int aMaxSize, + int aGrowthSpeed, int aAfterHarvestSize, int aHarvestSize, int aStatChemical, int aStatFood, int aStatDefensive, + int aStatColor, int aStatWeed, String[] aAttributes, ItemStack aDrop, ItemStack[] aSpecialDrops) { + new GTBaseCrop( + aID, + aCropName, + aDiscoveredBy, + aBaseSeed, + aTier, + aMaxSize, + aGrowthSpeed, + aAfterHarvestSize, + aHarvestSize, + aStatChemical, + aStatFood, + aStatDefensive, + aStatColor, + aStatWeed, + aAttributes, + null, + aDrop, + aSpecialDrops); + } + + /** + * To create new Crops + * + * @param aID Default ID + * @param aCropName Name of the Crop + * @param aDiscoveredBy The one who discovered the Crop + * @param aDrop The Item which is dropped by the Crop. must be != null + * @param aBaseSeed Baseseed to plant this Crop. null == crossbreed only + * @param aTier tier of the Crop. forced to be >= 1 + * @param aMaxSize maximum Size of the Crop. forced to be >= 3 + * @param aGrowthSpeed how fast the Crop grows. if < 0 then its set to Tier*300 + * @param aHarvestSize the size the Crop needs to be harvested. forced to be between 2 and max size + * @param aBlock the block below needed for crop to grow. If null no block needed + */ + public GTBaseCrop(int aID, String aCropName, String aDiscoveredBy, ItemStack aBaseSeed, int aTier, int aMaxSize, + int aGrowthSpeed, int aAfterHarvestSize, int aHarvestSize, int aStatChemical, int aStatFood, int aStatDefensive, + int aStatColor, int aStatWeed, String[] aAttributes, Materials aBlock, ItemStack aDrop, + ItemStack[] aSpecialDrops) { + mName = aCropName; + aID = GTConfig.addIDConfig(ConfigCategories.IDs.crops, mName.replaceAll(" ", "_"), aID); + if (aDiscoveredBy != null && !aDiscoveredBy.equals(E)) mDiscoveredBy = aDiscoveredBy; + if (aDrop != null && aID > 0 && aID < 256) { + mDrop = GTUtility.copyOrNull(aDrop); + mSpecialDrops = aSpecialDrops; + mTier = Math.max(1, aTier); + mMaxSize = Math.max(3, aMaxSize); + mHarvestSize = Math.min(Math.max(aHarvestSize, 2), mMaxSize); + mAfterHarvestSize = Math.min(Math.max(aAfterHarvestSize, 1), mMaxSize - 1); + mStats[0] = aStatChemical; + mStats[1] = aStatFood; + mStats[2] = aStatDefensive; + mStats[3] = aStatColor; + mStats[4] = aStatWeed; + mAttributes = aAttributes; + mBlock = aBlock; + if (!Crops.instance.registerCrop(this, aID)) + throw new GTItsNotMyFaultException("Make sure the Crop ID is valid!"); + if (aBaseSeed != null) Crops.instance.registerBaseSeed(aBaseSeed, this, 1, 1, 1, 1); + sCropList.add(this); + } + if (bIc2NeiLoaded) { + try { + Class.forName("speiger.src.crops.api.CropPluginAPI") + .getMethod("registerCropInfo", Class.forName("speiger.src.crops.api.ICropCardInfo")) + .invoke( + Class.forName("speiger.src.crops.api.CropPluginAPI") + .getField("instance"), + this); + } catch (IllegalAccessException | ClassNotFoundException | SecurityException | NoSuchMethodException + | NoSuchFieldException | InvocationTargetException | IllegalArgumentException ex) { + bIc2NeiLoaded = false; + } + } + } + + @Override + public byte getSizeAfterHarvest(ICropTile crop) { + return (byte) mAfterHarvestSize; + } + + @Override + public int growthDuration(ICropTile aCrop) { + if (mGrowthSpeed < 200) return super.growthDuration(aCrop); + return tier() * mGrowthSpeed; + } + + @Override + public int getrootslength(ICropTile crop) { + return 5; + } + + @Override + public String[] attributes() { + return mAttributes; + } + + @Override + public String discoveredBy() { + return mDiscoveredBy; + } + + @Override + public final boolean canGrow(ICropTile aCrop) { + // block check is only performed at the last stage of growth + if (this.needsBlockBelow() && aCrop.getSize() == mMaxSize - 1) { + return isBlockBelow(aCrop); + } + return aCrop.getSize() < maxSize(); + } + + @Override + public final boolean canBeHarvested(ICropTile aCrop) { + return aCrop.getSize() >= mHarvestSize; + } + + @Override + public boolean canCross(ICropTile aCrop) { + return aCrop.getSize() + 2 > maxSize(); + } + + @Override + public int stat(int n) { + if (n < 0 || n >= mStats.length) return 0; + return mStats[n]; + } + + @Override + public String name() { + return mName; + } + + @Override + public int tier() { + return mTier; + } + + @Override + public int maxSize() { + return mMaxSize; + } + + @Override + public ItemStack getGain(ICropTile aCrop) { + int tDrop = 0; + if (mSpecialDrops != null && (tDrop = java.util.concurrent.ThreadLocalRandom.current() + .nextInt(0, (mSpecialDrops.length * 2) + 2)) < mSpecialDrops.length && mSpecialDrops[tDrop] != null) { + return GTUtility.copyOrNull(mSpecialDrops[tDrop]); + } + return GTUtility.copyOrNull(mDrop); + } + + @Override + public boolean rightclick(ICropTile aCrop, EntityPlayer aPlayer) { + if (!canBeHarvested(aCrop)) return false; + return aCrop.harvest(aPlayer instanceof EntityPlayerMP); + } + + @Override + public int getOptimalHavestSize(ICropTile crop) { + return maxSize(); + } + + /** + * Checks if the crop needs a block below it + * + * @return True if the crop needs a block below it to grow to its max size + */ + public boolean needsBlockBelow() { + return GTMod.gregtechproxy.mCropNeedBlock && this.mBlock != null; + } + + public boolean isBlockBelow(ICropTile aCrop) { + if (aCrop == null) { + return false; + } + for (int i = 1; i < this.getrootslength(aCrop); i++) { + Block tBlock = aCrop.getWorld() + .getBlock(aCrop.getLocation().posX, aCrop.getLocation().posY - i, aCrop.getLocation().posZ); + if ((tBlock instanceof BlockOresAbstract)) { + TileEntity tTileEntity = aCrop.getWorld() + .getTileEntity(aCrop.getLocation().posX, aCrop.getLocation().posY - i, aCrop.getLocation().posZ); + if ((tTileEntity instanceof TileEntityOres)) { + Materials tMaterial = GregTechAPI.sGeneratedMaterials[(((TileEntityOres) tTileEntity).mMetaData + % 1000)]; + if ((tMaterial != null) && (tMaterial != Materials._NULL)) { + return tMaterial == mBlock; + } + } + } else { + int tMetaID = aCrop.getWorld() + .getBlockMetadata(aCrop.getLocation().posX, aCrop.getLocation().posY - i, aCrop.getLocation().posZ); + if (isBlockBelow(new ItemStack(tBlock, 1, tMetaID))) { + return true; + } + } + } + return false; + } + + /** + * An isolated function to check if an item stack is a block that should be below this crop + * + * @param aItem a stack of the block placed under the crop + * @return The result of the check + */ + public boolean isBlockBelow(ItemStack aItem) { + // safety in case someone calls this without checking if we have a block + if (!this.needsBlockBelow()) return true; + + // get material from stack + ItemData tAssociation = GTOreDictUnificator.getAssociation(aItem); + if (tAssociation == null) return false; + + // return true if it's an ore of the material + // note: some ores don't appear to have associations in testing, naq ore is an example of that + if (tAssociation.mPrefix.toString() + .startsWith("ore") && tAssociation.mMaterial.mMaterial == mBlock) { + return true; + } + + // return true if it's a block of the material + if (tAssociation.mPrefix == OrePrefixes.block && tAssociation.mMaterial.mMaterial == mBlock) { + return true; + } + return false; + } + + @Override + public List getCropInformation() { + if (mBlock != null) { + ArrayList result = new ArrayList<>(1); + result.add( + String.format( + "Requires %s Ore or Block of %s as soil block to reach full growth.", + mBlock.mName, + mBlock.mName)); + return result; + } + return null; + } + + @Override + public ItemStack getDisplayItem() { + if (mSpecialDrops != null && mSpecialDrops[mSpecialDrops.length - 1] != null) { + return GTUtility.copyOrNull(mSpecialDrops[mSpecialDrops.length - 1]); + } + return GTUtility.copyOrNull(mDrop); + } +} diff --git a/src/main/java/gregtech/api/util/GTBlockMap.java b/src/main/java/gregtech/api/util/GTBlockMap.java new file mode 100644 index 0000000000..a5ac98d427 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTBlockMap.java @@ -0,0 +1,134 @@ +package gregtech.api.util; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiFunction; + +import net.minecraft.block.Block; + +import gnu.trove.map.TByteObjectMap; +import gnu.trove.map.hash.TByteObjectHashMap; + +public class GTBlockMap { + + public static final byte WILDCARD = -1; + private final ConcurrentHashMap> backing = new ConcurrentHashMap<>(); + private int size = 0; + + private TByteObjectMap getSubmap(Block block) { + return backing.computeIfAbsent(block, b -> new TByteObjectHashMap<>()); + } + + /** + * Associate a value with that union key + * + * @param block block + * @param meta meta + * @return old mapping, or null if that doesn't exist + */ + public V put(Block block, byte meta, V value) { + V v = getSubmap(block).put(meta, value); + if (v == null) size++; + return v; + } + + /** + * Associate a value with that union key ONLY IF there isn't a prior EXACT mapping + * + * @param block block + * @param meta meta + * @return old mapping, or null if that doesn't exist + */ + public V putIfAbsent(Block block, byte meta, V value) { + V v = getSubmap(block).putIfAbsent(meta, value); + if (v == null) size++; + return v; + } + + /** + * Associate a value with that union key ONLY IF there isn't a prior EXACT mapping + * + * @param block block + * @param meta meta + * @return old mapping, or null if that doesn't exist + */ + public V computeIfAbsent(Block block, byte meta, BiFunction function) { + TByteObjectMap submap = getSubmap(block); + V v = submap.get(meta); + if (v == null) { + v = function.apply(block, meta); + submap.put(meta, v); + size++; + } + return v; + } + + /** + * Contains an associated value + * + * @param block block + * @param meta meta + * @return current mapping OR wildcard of that mapping exists + */ + public boolean containsKey(Block block, byte meta) { + TByteObjectMap submap = backing.get(block); + if (submap == null) return false; + return submap.containsKey(meta) || submap.containsKey(WILDCARD); + } + + /** + * Get the associated value + * + * @param block block + * @param meta meta + * @return current mapping OR wildcard of that block. null if neither exists + */ + public V get(Block block, byte meta) { + TByteObjectMap submap = backing.get(block); + if (submap == null) return null; + V v = submap.get(meta); + if (v != null) return v; + return submap.get(WILDCARD); + } + + /** + * Remove a mapping + * + * @param block block + * @param meta meta + * @return old value, or null if none + */ + public V remove(Block block, byte meta) { + TByteObjectMap submap = backing.get(block); + if (submap == null) return null; + V v = submap.remove(meta); + if (v != null) { + size--; + if (submap.isEmpty()) backing.remove(block); + } + return v; + } + + /** + * Size of all mappings + * + * @return size + */ + public int size() { + return size; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GTBlockMap that = (GTBlockMap) o; + + return backing.equals(that.backing); + } + + @Override + public int hashCode() { + return backing.hashCode(); + } +} diff --git a/src/main/java/gregtech/api/util/GTBlockSet.java b/src/main/java/gregtech/api/util/GTBlockSet.java new file mode 100644 index 0000000000..6c91193832 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTBlockSet.java @@ -0,0 +1,39 @@ +package gregtech.api.util; + +import net.minecraft.block.Block; + +public class GTBlockSet { + + private final GTBlockMap backing = new GTBlockMap<>(); + + public boolean add(Block block, byte meta) { + return backing.put(block, meta, this) != this; + } + + public boolean contains(Block block, byte meta) { + return backing.get(block, meta) == this; + } + + public boolean remove(Block block, byte meta) { + return backing.remove(block, meta) == this; + } + + public int size() { + return backing.size(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GTBlockSet that = (GTBlockSet) o; + + return backing.equals(that.backing); + } + + @Override + public int hashCode() { + return backing.hashCode(); + } +} diff --git a/src/main/java/gregtech/api/util/GTCLSCompat.java b/src/main/java/gregtech/api/util/GTCLSCompat.java new file mode 100644 index 0000000000..823a7b850e --- /dev/null +++ b/src/main/java/gregtech/api/util/GTCLSCompat.java @@ -0,0 +1,157 @@ +package gregtech.api.util; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; + +import cpw.mods.fml.common.ProgressManager; +import gregtech.GTMod; +import gregtech.api.enums.Materials; +import gregtech.common.GTProxy; +import gregtech.loaders.postload.GTPostLoad; + +@SuppressWarnings("rawtypes, unchecked, deprecation") +public class GTCLSCompat { + + private static Class alexiilMinecraftDisplayer; + private static Class alexiilProgressDisplayer; + private static Class cpwProgressBar; + + private static Method getLastPercent; + private static Method displayProgress; + + private static Field isReplacingVanillaMaterials; + private static Field isRegisteringGTmaterials; + private static Field progressBarStep; + + static { + // CLS + try { + alexiilMinecraftDisplayer = Class.forName("alexiil.mods.load.MinecraftDisplayer"); + alexiilProgressDisplayer = Class.forName("alexiil.mods.load.ProgressDisplayer"); + } catch (ClassNotFoundException ex) { + GTMod.GT_FML_LOGGER.catching(ex); + } + + try { + cpwProgressBar = Class.forName("cpw.mods.fml.common.ProgressManager$ProgressBar"); + } catch (ClassNotFoundException ex) { + GTMod.GT_FML_LOGGER.catching(ex); + } + + Optional.ofNullable(alexiilMinecraftDisplayer) + .ifPresent(e -> { + try { + getLastPercent = e.getMethod("getLastPercent"); + isReplacingVanillaMaterials = e.getField("isReplacingVanillaMaterials"); + isRegisteringGTmaterials = e.getField("isRegisteringGTmaterials"); + } catch (NoSuchMethodException | NoSuchFieldException ex) { + GTMod.GT_FML_LOGGER.catching(ex); + } + }); + + Optional.ofNullable(alexiilProgressDisplayer) + .ifPresent(e -> { + try { + displayProgress = e.getMethod("displayProgress", String.class, float.class); + } catch (NoSuchMethodException ex) { + GTMod.GT_FML_LOGGER.catching(ex); + } + }); + + try { + progressBarStep = cpwProgressBar.getDeclaredField("step"); + progressBarStep.setAccessible(true); + } catch (NoSuchFieldException ex) { + GTMod.GT_FML_LOGGER.catching(ex); + } + } + + private GTCLSCompat() {} + + private static void registerAndReportProgression(String materialsType, Collection materials, + ProgressManager.ProgressBar progressBar, Function getName, Consumer action) { + int sizeStep = materials.size(); + final long progressionReportsEvery = 100; + final long bakingMsgEvery = 1000; + long nextProgressionReportAt = 0; + long nextBakingMsgAt = 0; + int currentStep = 0; + + for (T m : materials) { + long now = System.currentTimeMillis(); + + if (nextProgressionReportAt < now) { + nextProgressionReportAt = now + progressionReportsEvery; + String materialName = getName.apply(m) + .toString(); + try { + displayProgress.invoke(null, materialName, (float) currentStep / sizeStep); + } catch (IllegalAccessException | InvocationTargetException iae) { + GTMod.GT_FML_LOGGER.error("While updating progression", iae); + } + try { + progressBarStep.set(progressBar, currentStep); + } catch (IllegalAccessException iae) { + GTMod.GT_FML_LOGGER.error("While updating intermediate progression steps number", iae); + } + progressBar.step(materialName); + } + if (nextBakingMsgAt < now) { + nextBakingMsgAt = now + bakingMsgEvery; + GTMod.GT_FML_LOGGER + .info(String.format("%s - Baking: %d%%", materialsType, currentStep * 100 / sizeStep)); + } + action.accept(m); + currentStep += 1; + } + GTMod.GT_FML_LOGGER.info(String.format("%s - Baking: Done", materialsType)); + try { + progressBarStep.set(progressBar, currentStep); + } catch (IllegalAccessException iae) { + GTMod.GT_FML_LOGGER.error("While updating final progression steps number", iae); + } + } + + public static void stepMaterialsCLS(Collection mEvents, + ProgressManager.ProgressBar progressBar) throws IllegalAccessException { + try { + isRegisteringGTmaterials.set(null, true); + } catch (IllegalArgumentException | IllegalAccessException e) { + GTMod.GT_FML_LOGGER.catching(e); + } + registerAndReportProgression( + "GregTech materials", + mEvents, + progressBar, + m -> m.mMaterial, + GTProxy::registerRecipes); + ProgressManager.pop(progressBar); + isRegisteringGTmaterials.set(null, false); + } + + public static void doActualRegistrationCLS(ProgressManager.ProgressBar progressBar, + Set replacedVanillaItemsSet) { + try { + isReplacingVanillaMaterials.set(null, true); + } catch (IllegalArgumentException | IllegalAccessException e) { + GTMod.GT_FML_LOGGER.catching(e); + } + registerAndReportProgression( + "Vanilla materials", + replacedVanillaItemsSet, + progressBar, + m -> m.mDefaultLocalName, + GTPostLoad::doActualRegistration); + } + + public static void pushToDisplayProgress() throws InvocationTargetException, IllegalAccessException { + isReplacingVanillaMaterials.set(null, false); + displayProgress.invoke(null, "Post Initialization: loading GregTech", getLastPercent.invoke(null)); + } +} diff --git a/src/main/java/gregtech/api/util/GTChunkAssociatedData.java b/src/main/java/gregtech/api/util/GTChunkAssociatedData.java new file mode 100644 index 0000000000..7a81c715cb --- /dev/null +++ b/src/main/java/gregtech/api/util/GTChunkAssociatedData.java @@ -0,0 +1,494 @@ +package gregtech.api.util; + +import static gregtech.api.enums.Mods.GregTech; + +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.ref.WeakReference; +import java.lang.reflect.Array; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.WorldEvent; + +import org.apache.commons.io.FileUtils; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gregtech.api.enums.GTValues; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +/** + * A utility to save all kinds of data that is a function of any chunk. + *

+ * GregTech takes care of saving and loading the data from disk, and an efficient mechanism to locate it. Subclass only + * need to define the exact scheme of each element data (by overriding the three protected abstract method) + *

+ * Oh, there is no limit on how large your data is, though you'd not have the familiar NBT interface, but DataOutput + * should be reasonably common anyway. + *

+ * It should be noted this class is NOT thread safe. + *

+ * Element cannot be null. + *

+ * TODO: Implement automatic region unloading. + * + * @param data element type + * @author glease + */ +@ParametersAreNonnullByDefault +public abstract class GTChunkAssociatedData { + + private static final Map> instances = new ConcurrentHashMap<>(); + private static final int IO_PARALLELISM = Math.min( + 8, + Math.max( + 1, + Runtime.getRuntime() + .availableProcessors() * 2 + / 3)); + private static final ExecutorService IO_WORKERS = Executors.newWorkStealingPool(IO_PARALLELISM); + private static final Pattern FILE_PATTERN = Pattern.compile("(.+)\\.(-?\\d+)\\.(-?\\d+)\\.dat"); + + static { + // register event handler + new EventHandler(); + } + + protected final String mId; + protected final Class elementtype; + private final int regionLength; + private final int version; + private final boolean saveDefaults; + /** + * Data is stored as a `(world id -> (super region id -> super region data))` hash map. where super region's size is + * determined by regionSize. Here it is called super region, to not confuse with vanilla's regions. + */ + private final Map> masterMap = new ConcurrentHashMap<>(); + + /** + * Initialize this instance. + * + * @param aId An arbitrary, but globally unique identifier for what this data is + * @param elementType The class of this element type. Used to create arrays. + * @param regionLength The length of one super region. Each super region will contain + * {@code regionLength * regionLength} chunks + * @param version An integer marking the version of this data. Useful later when the data's serialized form + * changed. + */ + protected GTChunkAssociatedData(String aId, Class elementType, int regionLength, byte version, + boolean saveDefaults) { + if (regionLength * regionLength > Short.MAX_VALUE || regionLength <= 0) + throw new IllegalArgumentException("Region invalid: " + regionLength); + if (!IData.class.isAssignableFrom(elementType)) throw new IllegalArgumentException("Data type invalid"); + if (aId.contains(".")) throw new IllegalArgumentException("ID cannot contains dot"); + this.mId = aId; + this.elementtype = elementType; + this.regionLength = regionLength; + this.version = version; + this.saveDefaults = saveDefaults; + if (instances.putIfAbsent(aId, this) != null) + throw new IllegalArgumentException("Duplicate GT_ChunkAssociatedData: " + aId); + } + + private ChunkCoordIntPair getRegionID(int aChunkX, int aChunkZ) { + return new ChunkCoordIntPair(Math.floorDiv(aChunkX, regionLength), Math.floorDiv(aChunkZ, regionLength)); + } + + /** + * Get a reference to data of the chunk that tile entity is in. The returned reference should be mutable. + */ + public final T get(IGregTechTileEntity tileEntity) { + return get(tileEntity.getWorld(), tileEntity.getXCoord() >> 4, tileEntity.getZCoord() >> 4); + } + + public final T get(Chunk chunk) { + return get(chunk.worldObj, chunk.xPosition, chunk.zPosition); + } + + public final T get(World world, ChunkCoordIntPair coord) { + return get(world, coord.chunkXPos, coord.chunkZPos); + } + + public final T get(World world, int chunkX, int chunkZ) { + SuperRegion region = masterMap.computeIfAbsent(world.provider.dimensionId, ignored -> new ConcurrentHashMap<>()) + .computeIfAbsent(getRegionID(chunkX, chunkZ), c -> new SuperRegion(world, c)); + return region.get(Math.floorMod(chunkX, regionLength), Math.floorMod(chunkZ, regionLength)); + } + + protected final void set(World world, int chunkX, int chunkZ, T data) { + SuperRegion region = masterMap.computeIfAbsent(world.provider.dimensionId, ignored -> new ConcurrentHashMap<>()) + .computeIfAbsent(getRegionID(chunkX, chunkZ), c -> new SuperRegion(world, c)); + region.set(Math.floorMod(chunkX, regionLength), Math.floorMod(chunkZ, regionLength), data); + } + + protected final boolean isCreated(int dimId, int chunkX, int chunkZ) { + Map dimData = masterMap.getOrDefault(dimId, null); + if (dimData == null) return false; + + SuperRegion region = dimData.getOrDefault(getRegionID(chunkX, chunkZ), null); + if (region == null) return false; + + return region.isCreated(Math.floorMod(chunkX, regionLength), Math.floorMod(chunkZ, regionLength)); + } + + public void clear() { + if (GTValues.debugWorldData) { + long dirtyRegionCount = masterMap.values() + .stream() + .flatMap( + m -> m.values() + .stream()) + .filter(SuperRegion::isDirty) + .count(); + if (dirtyRegionCount > 0) GTLog.out.println( + "Clearing ChunkAssociatedData with " + dirtyRegionCount + " regions dirty. Data might have been lost!"); + } + masterMap.clear(); + } + + public void save() { + saveRegions( + masterMap.values() + .stream() + .flatMap( + m -> m.values() + .stream())); + } + + public void save(World world) { + Map map = masterMap.get(world.provider.dimensionId); + if (map != null) saveRegions( + map.values() + .stream()); + } + + private void saveRegions(Stream stream) { + stream.filter(SuperRegion::isDirty) + .map(c -> (Runnable) c::save) + .map(r -> CompletableFuture.runAsync(r, IO_WORKERS)) + .reduce(CompletableFuture::allOf) + .ifPresent(f -> { + try { + f.get(); + } catch (Exception e) { + GTLog.err.println("Data save error: " + mId); + e.printStackTrace(GTLog.err); + } + }); + } + + protected abstract void writeElement(DataOutput output, T element, World world, int chunkX, int chunkZ) + throws IOException; + + protected abstract T readElement(DataInput input, int version, World world, int chunkX, int chunkZ) + throws IOException; + + protected abstract T createElement(World world, int chunkX, int chunkZ); + + /** + * Clear all mappings, regardless of whether they are dirty + */ + public static void clearAll() { + for (GTChunkAssociatedData d : instances.values()) d.clear(); + } + + /** + * Save all mappings + */ + public static void saveAll() { + for (GTChunkAssociatedData d : instances.values()) d.save(); + } + + /** + * Load data for all chunks for a given world. Current data for that world will be discarded. If this is what you + * intended, call {@link #save(World)} beforehand. + *

+ * Be aware of the memory consumption though. + */ + protected void loadAll(World w) { + if (GTValues.debugWorldData && masterMap.containsKey(w.provider.dimensionId)) GTLog.err.println( + "Reloading ChunkAssociatedData " + mId + " for world " + w.provider.dimensionId + " discards old data!"); + if (!getSaveDirectory(w).isDirectory()) + // nothing to load... + return; + try (Stream stream = Files.list(getSaveDirectory(w).toPath())) { + Map worldData = stream.map(f -> { + Matcher matcher = FILE_PATTERN.matcher( + f.getFileName() + .toString()); + return matcher.matches() ? matcher : null; + }) + .filter(Objects::nonNull) + .filter(m -> mId.equals(m.group(1))) + .map( + m -> CompletableFuture.supplyAsync( + () -> new SuperRegion(w, Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3))), + IO_WORKERS)) + .map(f -> { + try { + return f.get(); + } catch (Exception e) { + GTLog.err.println("Error loading region"); + e.printStackTrace(GTLog.err); + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toMap(SuperRegion::getCoord, Function.identity())); + masterMap.put(w.provider.dimensionId, worldData); + } catch (IOException | UncheckedIOException e) { + GTLog.err.println("Error loading all region"); + e.printStackTrace(GTLog.err); + } + } + + protected File getSaveDirectory(World w) { + File base; + if (w.provider.getSaveFolder() == null) base = w.getSaveHandler() + .getWorldDirectory(); + else base = new File( + w.getSaveHandler() + .getWorldDirectory(), + w.provider.getSaveFolder()); + return new File(base, GregTech.ID); + } + + public interface IData { + + /** + * @return Whether the data is different from chunk default + */ + boolean isSameAsDefault(); + } + + protected final class SuperRegion { + + private final T[] data = createData(); + private final File backingStorage; + private final WeakReference world; + /** + * Be aware, this means region coord, not bottom-left chunk coord + */ + private final ChunkCoordIntPair coord; + + private SuperRegion(World world, int regionX, int regionZ) { + this.world = new WeakReference<>(world); + this.coord = new ChunkCoordIntPair(regionX, regionZ); + backingStorage = new File(getSaveDirectory(world), String.format("%s.%d.%d.dat", mId, regionX, regionZ)); + if (backingStorage.isFile()) load(); + } + + private SuperRegion(World world, ChunkCoordIntPair regionCoord) { + this.world = new WeakReference<>(world); + this.coord = regionCoord; + backingStorage = new File( + getSaveDirectory(world), + String.format("%s.%d.%d.dat", mId, regionCoord.chunkXPos, regionCoord.chunkZPos)); + if (backingStorage.isFile()) load(); + } + + @SuppressWarnings("unchecked") + private T[] createData() { + return (T[]) Array.newInstance(elementtype, regionLength * regionLength); + } + + public T get(int subRegionX, int subRegionZ) { + int index = getIndex(subRegionX, subRegionZ); + T datum = data[index]; + if (datum == null) { + World world = Objects.requireNonNull(this.world.get()); + T newElem = createElement( + world, + coord.chunkXPos * regionLength + subRegionX, + coord.chunkZPos * regionLength + subRegionZ); + data[index] = newElem; + return newElem; + } + return datum; + } + + public void set(int subRegionX, int subRegionZ, T data) { + this.data[getIndex(subRegionX, subRegionZ)] = data; + } + + public boolean isCreated(int subRegionX, int subRegionZ) { + return this.data[getIndex(subRegionX, subRegionZ)] != null; + } + + public ChunkCoordIntPair getCoord() { + return coord; + } + + private int getIndex(int subRegionX, int subRegionY) { + return subRegionX * regionLength + subRegionY; + } + + private int getChunkX(int index) { + return index / regionLength + coord.chunkXPos * regionLength; + } + + private int getChunkZ(int index) { + return index % regionLength + coord.chunkZPos * regionLength; + } + + public boolean isDirty() { + for (T datum : data) { + if (datum != null && !datum.isSameAsDefault()) return true; + } + return false; + } + + public void save() { + try { + save0(); + } catch (IOException e) { + GTLog.err.println("Error saving data " + backingStorage.getPath()); + e.printStackTrace(GTLog.err); + } + } + + private void save0() throws IOException { + // noinspection ResultOfMethodCallIgnored + backingStorage.getParentFile() + .mkdirs(); + File tmpFile = getTmpFile(); + World world = Objects.requireNonNull(this.world.get(), "Attempting to save region of another world!"); + try (DataOutputStream output = new DataOutputStream(new FileOutputStream(tmpFile))) { + int ptr = 0; + boolean nullRange = data[0] == null; + // write a magic byte as storage format version + output.writeByte(0); + // write a magic byte as data format version + output.writeByte(version); + output.writeBoolean(nullRange); + while (ptr < data.length) { + // work out how long is this range + int rangeStart = ptr; + while (ptr < data.length + && (data[ptr] == null || (!saveDefaults && data[ptr].isSameAsDefault())) == nullRange) ptr++; + // write range length + output.writeShort(ptr - rangeStart); + if (!nullRange) + // write element data + for (int i = rangeStart; i < ptr; i++) + writeElement(output, data[i], world, getChunkX(ptr), getChunkZ(ptr)); + // or not + nullRange = !nullRange; + } + } + // first try to replace the destination file + // since atomic operation, no need to keep the backup in place + try { + Files.move( + tmpFile.toPath(), + backingStorage.toPath(), + StandardCopyOption.REPLACE_EXISTING, + StandardCopyOption.ATOMIC_MOVE); + } catch (AtomicMoveNotSupportedException ignored) { + // in case some dumb system/jre combination would cause this + // or if **somehow** two file inside the same directory belongs two separate filesystem + FileUtils.copyFile(tmpFile, backingStorage); + } + } + + public void load() { + try { + loadFromFile(backingStorage); + } catch (IOException | RuntimeException e) { + GTLog.err.println("Primary storage file broken in " + backingStorage.getPath()); + e.printStackTrace(GTLog.err); + // in case the primary storage is broken + try { + loadFromFile(getTmpFile()); + } catch (IOException | RuntimeException e2) { + GTLog.err.println("Backup storage file broken in " + backingStorage.getPath()); + e2.printStackTrace(GTLog.err); + } + } + } + + private void loadFromFile(File file) throws IOException { + World world = Objects.requireNonNull(this.world.get(), "Attempting to load region of another world!"); + try (DataInputStream input = new DataInputStream(new FileInputStream(file))) { + byte b = input.readByte(); + if (b == 0) { + loadV0(input, world); + } else { + GTLog.err.printf("Unknown ChunkAssociatedData version %d\n", b); + } + } + } + + private void loadV0(DataInput input, World world) throws IOException { + int version = input.readByte(); + boolean nullRange = input.readBoolean(); + int ptr = 0; + while (ptr != data.length) { + int rangeEnd = ptr + input.readUnsignedShort(); + if (!nullRange) { + for (; ptr < rangeEnd; ptr++) { + data[ptr] = readElement(input, version, world, getChunkX(ptr), getChunkZ(ptr)); + } + } else { + Arrays.fill(data, ptr, rangeEnd, null); + ptr = rangeEnd; + } + nullRange = !nullRange; + } + } + + private File getTmpFile() { + return new File(backingStorage.getParentFile(), backingStorage.getName() + ".tmp"); + } + } + + public static class EventHandler { + + private EventHandler() { + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onWorldSave(WorldEvent.Save e) { + for (GTChunkAssociatedData d : instances.values()) { + d.save(e.world); + } + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload e) { + for (GTChunkAssociatedData d : instances.values()) { + // there is no need to explicitly do a save here + // forge will send a WorldEvent.Save on server thread before this event is distributed + d.masterMap.remove(e.world.provider.dimensionId); + } + } + } +} diff --git a/src/main/java/gregtech/api/util/GTClientPreference.java b/src/main/java/gregtech/api/util/GTClientPreference.java new file mode 100644 index 0000000000..f265094ca3 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTClientPreference.java @@ -0,0 +1,43 @@ +package gregtech.api.util; + +import gregtech.common.config.client.ConfigPreference; +import gregtech.common.config.client.ConfigWaila; + +public class GTClientPreference { + + private final boolean mSingleBlockInitialFilter; + private final boolean mSingleBlockInitialMultiStack; + private final boolean mInputBusInitialFilter; + private final boolean wailaAverageNS; + + public GTClientPreference(boolean mSingleBlockInitialFilter, boolean mSingleBlockInitialMultiStack, + boolean mInputBusInitialFilter, boolean wailaAverageNS) { + this.mSingleBlockInitialFilter = mSingleBlockInitialFilter; + this.mSingleBlockInitialMultiStack = mSingleBlockInitialMultiStack; + this.mInputBusInitialFilter = mInputBusInitialFilter; + this.wailaAverageNS = wailaAverageNS; + } + + public GTClientPreference() { + this.mSingleBlockInitialFilter = ConfigPreference.singleBlockInitialFilter; + this.mSingleBlockInitialMultiStack = ConfigPreference.singleBlockInitialAllowMultiStack; + this.mInputBusInitialFilter = ConfigPreference.inputBusInitialFilter; + this.wailaAverageNS = ConfigWaila.wailaAverageNS; + } + + public boolean isSingleBlockInitialFilterEnabled() { + return mSingleBlockInitialFilter; + } + + public boolean isSingleBlockInitialMultiStackEnabled() { + return mSingleBlockInitialMultiStack; + } + + public boolean isInputBusInitialFilterEnabled() { + return mInputBusInitialFilter; + } + + public boolean isWailaAverageNSEnabled() { + return wailaAverageNS; + } +} diff --git a/src/main/java/gregtech/api/util/GTConfig.java b/src/main/java/gregtech/api/util/GTConfig.java new file mode 100644 index 0000000000..68ff810414 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTConfig.java @@ -0,0 +1,162 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.E; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; + +public class GTConfig implements Runnable { + + public static boolean troll = false; + + public static Configuration sConfigFileIDs; + public static Configuration cleanroomFile; + public static Configuration undergroundFluidsFile; + public final Configuration mConfig; + + public GTConfig(Configuration aConfig) { + mConfig = aConfig; + mConfig.load(); + mConfig.save(); + GregTechAPI.sAfterGTPreload.add(this); // in case of crash on startup + GregTechAPI.sAfterGTLoad.add(this); // in case of crash on startup + GregTechAPI.sAfterGTPostload.add(this); + if (GTValues.lateConfigSave) GregTechAPI.sFirstWorldTick.add(this); + } + + private static boolean shouldSave() { + return GTValues.lateConfigSave ? GTValues.worldTickHappened : GregTechAPI.sPostloadFinished; + } + + public static int addIDConfig(Object aCategory, String aName, int aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = sConfigFileIDs.get( + aCategory.toString() + .replaceAll("\\|", "."), + aName.replaceAll("\\|", "."), + aDefault); + int rResult = tProperty.getInt(aDefault); + sConfigFileIDs.save(); + return rResult; + } + + public static String getStackConfigName(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return E; + Object rName = GTOreDictUnificator.getAssociation(aStack); + if (rName != null) return rName.toString(); + try { + if (GTUtility.isStringValid(rName = aStack.getUnlocalizedName())) return rName.toString(); + } catch (Throwable e) { + /* Do nothing */ + } + String sName = aStack.getItem() + .toString(); + String[] tmp = sName.split("@"); + if (tmp.length > 0) sName = tmp[0]; + return sName + "." + aStack.getItemDamage(); + } + + public boolean get(Object aCategory, ItemStack aStack, boolean aDefault) { + String aName = getStackConfigName(aStack); + return get(aCategory, aName, aDefault); + } + + public boolean get(Object aCategory, String aName, boolean aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + (aName + "_" + aDefault).replaceAll("\\|", "_"), + aDefault); + boolean rResult = tProperty.getBoolean(aDefault); + if (!tProperty.wasRead() && shouldSave()) mConfig.save(); + return rResult; + } + + public int get(Object aCategory, ItemStack aStack, int aDefault) { + return get(aCategory, getStackConfigName(aStack), aDefault); + } + + public int get(Object aCategory, String aName, int aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + (aName + "_" + aDefault).replaceAll("\\|", "_"), + aDefault); + int rResult = tProperty.getInt(aDefault); + if (!tProperty.wasRead() && shouldSave()) mConfig.save(); + return rResult; + } + + public double get(Object aCategory, ItemStack aStack, double aDefault) { + return get(aCategory, getStackConfigName(aStack), aDefault); + } + + public double get(Object aCategory, String aName, double aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + (aName + "_" + aDefault).replaceAll("\\|", "_"), + aDefault); + double rResult = tProperty.getDouble(aDefault); + if (!tProperty.wasRead() && shouldSave()) mConfig.save(); + return rResult; + } + + public String get(Object aCategory, ItemStack aStack, String aDefault) { + return get(aCategory, getStackConfigName(aStack), aDefault); + } + + public String get(Object aCategory, String aName, String aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + (aName + "_" + aDefault).replaceAll("\\|", "_"), + aDefault); + String rResult = tProperty.getString(); + if (!tProperty.wasRead() && shouldSave()) mConfig.save(); + return rResult; + } + + public String[] get(Object aCategory, ItemStack aStack, String... aDefault) { + return get(aCategory, getStackConfigName(aStack), aDefault); + } + + public String[] get(Object aCategory, String aName, String... aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + aName.replaceAll("\\|", "_"), + aDefault); + String[] rResult = tProperty.getStringList(); + if (!tProperty.wasRead() && GregTechAPI.sPostloadFinished) mConfig.save(); + return rResult; + } + + public String getWithValidValues(Object aCategory, String aName, String[] validValues, String aDefault) { + if (GTUtility.isStringInvalid(aName)) return aDefault; + Property tProperty = mConfig.get( + aCategory.toString() + .replaceAll("\\|", "_"), + aName.replaceAll("\\|", "_"), + aDefault, + null, + validValues); + String rResult = tProperty.getString(); + if (!tProperty.wasRead() && GregTechAPI.sPostloadFinished) mConfig.save(); + return rResult; + } + + @Override + public void run() { + mConfig.save(); + } +} diff --git a/src/main/java/gregtech/api/util/GTCreativeTab.java b/src/main/java/gregtech/api/util/GTCreativeTab.java new file mode 100644 index 0000000000..54d8877a83 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTCreativeTab.java @@ -0,0 +1,26 @@ +package gregtech.api.util; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.ItemList; + +public class GTCreativeTab extends CreativeTabs { + + public GTCreativeTab(String aName, String aLocalName) { + super("GregTech." + aName); + GTLanguageManager.addStringLocalization("itemGroup.GregTech." + aName, aLocalName); + } + + @Override + public ItemStack getIconItemStack() { + return ItemList.Tool_Cheat.get(1, new ItemStack(Blocks.iron_block, 1)); + } + + @Override + public Item getTabIconItem() { + return ItemList.Circuit_Integrated.getItem(); + } +} diff --git a/src/main/java/gregtech/api/util/GTFoodStat.java b/src/main/java/gregtech/api/util/GTFoodStat.java new file mode 100644 index 0000000000..51e8818f62 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTFoodStat.java @@ -0,0 +1,122 @@ +package gregtech.api.util; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.PotionEffect; + +import gregtech.api.damagesources.GTDamageSources; +import gregtech.api.enums.SoundResource; +import gregtech.api.interfaces.IFoodStat; +import gregtech.api.items.MetaBaseItem; + +public class GTFoodStat implements IFoodStat { + + private final int mFoodLevel; + private final int[] mPotionEffects; + private final float mSaturation; + private final EnumAction mAction; + private final ItemStack mEmptyContainer; + private final boolean mAlwaysEdible, mInvisibleParticles, mIsRotten; + private boolean mExplosive = false, mMilk = false; + + /** + * @param aFoodLevel Amount of Food in Half Bacon [0 - 20] + * @param aSaturation Amount of Saturation [0.0F - 1.0F] + * @param aAction The Action to be used. If this is null, it uses the Eating Action + * @param aEmptyContainer An empty Container (Optional) + * @param aAlwaysEdible If this Item is always edible, like Golden Apples or Potions + * @param aInvisibleParticles If the Particles of the Potion Effects are invisible + * @param aPotionEffects An Array of Potion Effects with %4==0 Elements as follows ID of a Potion Effect. 0 for + * none Duration of the Potion in Ticks Level of the Effect. [0, 1, 2] are for [I, II, + * III] The likelihood that this Potion Effect takes place upon being eaten [1 - 100] + */ + public GTFoodStat(int aFoodLevel, float aSaturation, EnumAction aAction, ItemStack aEmptyContainer, + boolean aAlwaysEdible, boolean aInvisibleParticles, boolean aIsRotten, int... aPotionEffects) { + mFoodLevel = aFoodLevel; + mSaturation = aSaturation; + mAction = aAction == null ? EnumAction.eat : aAction; + mPotionEffects = aPotionEffects; + mEmptyContainer = GTUtility.copyOrNull(aEmptyContainer); + mInvisibleParticles = aInvisibleParticles; + mAlwaysEdible = aAlwaysEdible; + mIsRotten = aIsRotten; + } + + public GTFoodStat setExplosive() { + mExplosive = true; + return this; + } + + public GTFoodStat setMilk() { + mMilk = true; + return this; + } + + @Override + public int getFoodLevel(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer) { + return mFoodLevel; + } + + @Override + public float getSaturation(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer) { + return mSaturation; + } + + @Override + public void onEaten(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer) { + aStack.stackSize--; + ItemStack tStack = GTOreDictUnificator.get(GTUtility.copyOrNull(mEmptyContainer)); + if (tStack != null && !aPlayer.inventory.addItemStackToInventory(tStack)) + aPlayer.dropPlayerItemWithRandomChoice(tStack, true); + + new WorldSpawnedEventBuilder.SoundAtEntityEventBuilder().setIdentifier(SoundResource.RANDOM_BURP) + .setVolume(0.5F) + .setPitch(aPlayer.worldObj.rand.nextFloat() * 0.1F + 0.9F) + .setEntity(aPlayer) + .setWorld(aPlayer.worldObj) + .run(); + + if (!aPlayer.worldObj.isRemote) { + if (mMilk) { + aPlayer.curePotionEffects(new ItemStack(Items.milk_bucket, 1, 0)); + } + for (int i = 3; i < mPotionEffects.length; i += 4) { + if (aPlayer.worldObj.rand.nextInt(100) < mPotionEffects[i]) { + aPlayer.addPotionEffect( + new PotionEffect( + mPotionEffects[i - 3], + mPotionEffects[i - 2], + mPotionEffects[i - 1], + mInvisibleParticles)); + } + } + if (mExplosive) { + new WorldSpawnedEventBuilder.ExplosionEffectEventBuilder().setSmoking(true) + .setFlaming(true) + .setStrength(4f) + .setPosition(aPlayer.posX, aPlayer.posY, aPlayer.posZ) + .setEntity(aPlayer) + .setWorld(aPlayer.worldObj) + .run(); + aPlayer.attackEntityFrom(GTDamageSources.getExplodingDamage(), Float.MAX_VALUE); + } + } + } + + @Override + public EnumAction getFoodAction(MetaBaseItem aItem, ItemStack aStack) { + return mAction; + } + + @Override + public boolean alwaysEdible(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer) { + return mAlwaysEdible; + } + + @Override + public boolean isRotten(MetaBaseItem aItem, ItemStack aStack, EntityPlayer aPlayer) { + return mIsRotten; + } +} diff --git a/src/main/java/gregtech/api/util/GTForestryCompat.java b/src/main/java/gregtech/api/util/GTForestryCompat.java new file mode 100644 index 0000000000..379604205a --- /dev/null +++ b/src/main/java/gregtech/api/util/GTForestryCompat.java @@ -0,0 +1,193 @@ +package gregtech.api.util; + +import static gregtech.api.recipe.RecipeMaps.centrifugeNonCellRecipes; +import static gregtech.api.recipe.RecipeMaps.centrifugeRecipes; +import static gregtech.api.recipe.RecipeMaps.scannerFakeRecipes; +import static gregtech.api.util.GTRecipeBuilder.SECONDS; +import static gregtech.api.util.GTRecipeBuilder.TICKS; + +import java.util.Map; + +import net.minecraft.item.ItemStack; + +import forestry.api.recipes.ICentrifugeRecipe; +import forestry.api.recipes.ISqueezerRecipe; +import forestry.api.recipes.RecipeManagers; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.recipe.RecipeMaps; + +public class GTForestryCompat { + + public static void populateFakeNeiRecipes() { + if (ItemList.FR_Bee_Drone.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Bee_Drone.getWildcard(1L)) + .itemOutputs(ItemList.FR_Bee_Drone.getWithName(1L, "Scanned Drone")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Bee_Princess.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Bee_Princess.getWildcard(1L)) + .itemOutputs(ItemList.FR_Bee_Princess.getWithName(1L, "Scanned Princess")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Bee_Queen.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Bee_Queen.getWildcard(1L)) + .itemOutputs(ItemList.FR_Bee_Queen.getWithName(1L, "Scanned Queen")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Tree_Sapling.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Tree_Sapling.getWildcard(1L)) + .itemOutputs(ItemList.FR_Tree_Sapling.getWithName(1L, "Scanned Sapling")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Butterfly.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Butterfly.getWildcard(1L)) + .itemOutputs(ItemList.FR_Butterfly.getWithName(1L, "Scanned Butterfly")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Larvae.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Larvae.getWildcard(1L)) + .itemOutputs(ItemList.FR_Larvae.getWithName(1L, "Scanned Larvae")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Serum.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Serum.getWildcard(1L)) + .itemOutputs(ItemList.FR_Serum.getWithName(1L, "Scanned Serum")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_Caterpillar.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_Caterpillar.getWildcard(1L)) + .itemOutputs(ItemList.FR_Caterpillar.getWithName(1L, "Scanned Caterpillar")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + if (ItemList.FR_PollenFertile.get(1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(ItemList.FR_PollenFertile.getWildcard(1L)) + .itemOutputs(ItemList.FR_PollenFertile.getWithName(1L, "Scanned Pollen")) + .fluidInputs(Materials.Honey.getFluid(100L)) + .duration(25 * SECONDS) + .eut(2) + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes); + } + } + + public static void transferCentrifugeRecipes() { + try { + for (ICentrifugeRecipe tRecipe : RecipeManagers.centrifugeManager.recipes()) { + Map outputs = tRecipe.getAllProducts(); + ItemStack[] tOutputs = new ItemStack[outputs.size()]; + int[] tChances = new int[outputs.size()]; + int i = 0; + for (Map.Entry entry : outputs.entrySet()) { + tChances[i] = (int) (entry.getValue() * 10000); + tOutputs[i] = entry.getKey() + .copy(); + i++; + } + GTValues.RA.stdBuilder() + .itemInputs(tRecipe.getInput()) + .itemOutputs(tOutputs) + .outputChances(tChances) + .duration(6 * SECONDS + 8 * TICKS) + .eut(5) + .addTo(centrifugeRecipes); + + GTValues.RA.stdBuilder() + .itemInputs(tRecipe.getInput()) + .itemOutputs(tOutputs) + .outputChances(tChances) + .duration(6 * SECONDS + 8 * TICKS) + .eut(5) + .addTo(centrifugeNonCellRecipes); + } + } catch (Throwable e) { + if (GTValues.D1) { + e.printStackTrace(GTLog.err); + } + } + } + + public static void transferSqueezerRecipes() { + try { + for (ISqueezerRecipe tRecipe : RecipeManagers.squeezerManager.recipes()) { + if ((tRecipe.getResources().length == 1) && (tRecipe.getFluidOutput() != null) + && (tRecipe.getResources()[0] != null)) { + GTRecipeBuilder recipeBuilder = GTValues.RA.stdBuilder(); + recipeBuilder.itemInputs(tRecipe.getResources()[0]); + if (tRecipe.getRemnants() != null) { + recipeBuilder.itemOutputs(tRecipe.getRemnants()) + .outputChances((int) (tRecipe.getRemnantsChance() * 10000)); + } + recipeBuilder.fluidOutputs(tRecipe.getFluidOutput()) + .duration(1 * SECONDS + 12 * TICKS) + .eut(8) + .addTo(RecipeMaps.fluidExtractionRecipes); + } + } + } catch (Throwable e) { + if (GTValues.D1) { + e.printStackTrace(GTLog.err); + } + } + } +} diff --git a/src/main/java/gregtech/api/util/GTGCCompat.java b/src/main/java/gregtech/api/util/GTGCCompat.java new file mode 100644 index 0000000000..0491d0f9f4 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTGCCompat.java @@ -0,0 +1,52 @@ +package gregtech.api.util; + +import static gregtech.api.enums.Mods.GalacticraftCore; + +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; + +import micdoodle8.mods.galacticraft.api.power.EnergySource; +import micdoodle8.mods.galacticraft.api.power.EnergySource.EnergySourceAdjacent; +import micdoodle8.mods.galacticraft.api.power.IEnergyHandlerGC; +import micdoodle8.mods.galacticraft.api.transmission.NetworkType; +import micdoodle8.mods.galacticraft.api.transmission.tile.IConnector; +import micdoodle8.mods.galacticraft.core.energy.EnergyConfigHandler; + +public class GTGCCompat { + + public static long insertEnergyInto(TileEntity tTileEntity, long aVoltage, ForgeDirection tDirection) { + // GC Compat + if (GalacticraftCore.isModLoaded() && tTileEntity instanceof IEnergyHandlerGC) { + if (!(tTileEntity instanceof IConnector) + || ((IConnector) tTileEntity).canConnect(tDirection, NetworkType.POWER)) { + EnergySource eSource = new EnergySourceAdjacent(tDirection); + + float tSizeToReceive = aVoltage * EnergyConfigHandler.IC2_RATIO, + tStored = ((IEnergyHandlerGC) tTileEntity).getEnergyStoredGC(eSource); + if (tSizeToReceive >= tStored + || tSizeToReceive <= ((IEnergyHandlerGC) tTileEntity).getMaxEnergyStoredGC(eSource) - tStored) { + float tReceived = ((IEnergyHandlerGC) tTileEntity).receiveEnergyGC(eSource, tSizeToReceive, false); + if (tReceived > 0) { + tSizeToReceive -= tReceived; + while (tSizeToReceive > 0) { + tReceived = ((IEnergyHandlerGC) tTileEntity) + .receiveEnergyGC(eSource, tSizeToReceive, false); + if (tReceived < 1) break; + tSizeToReceive -= tReceived; + } + return 1; + } + } + } + return 0; + } + return 2; + } + + public static boolean canConnect(TileEntity tTileEntity, ForgeDirection tDirection) { + // GC Compat + return GalacticraftCore.isModLoaded() && tTileEntity instanceof IEnergyHandlerGC + && (!(tTileEntity instanceof IConnector) + || ((IConnector) tTileEntity).canConnect(tDirection, NetworkType.POWER)); + } +} diff --git a/src/main/java/gregtech/api/util/GTIBoxableWrapper.java b/src/main/java/gregtech/api/util/GTIBoxableWrapper.java new file mode 100644 index 0000000000..fcb7846a20 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTIBoxableWrapper.java @@ -0,0 +1,13 @@ +package gregtech.api.util; + +import net.minecraft.item.ItemStack; + +import ic2.api.item.IBoxable; + +public class GTIBoxableWrapper implements IBoxable { + + @Override + public boolean canBeStoredInToolbox(ItemStack itemstack) { + return GTUtility.isStackInList(itemstack, GTModHandler.sBoxableItems); + } +} diff --git a/src/main/java/gregtech/api/util/GTItsNotMyFaultException.java b/src/main/java/gregtech/api/util/GTItsNotMyFaultException.java new file mode 100644 index 0000000000..5d21fd2420 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTItsNotMyFaultException.java @@ -0,0 +1,18 @@ +package gregtech.api.util; + +public class GTItsNotMyFaultException extends RuntimeException { + + private static final long serialVersionUID = -8752778866486460495L; + + private final String mError; + + public GTItsNotMyFaultException(String aError) { + mError = aError; + } + + @Override + public String toString() { + return "The GregTech-Addon has a Problem.\nIT'S NOT MY FAULT!!! Below is how to fix it.\n" + mError + + "\nDO NOT COME TO ME WITH THIS CRASH. YOU CAUSED IT YOURSELF, AND I TOLD YOU HOW TO FIX IT!!!"; + } +} diff --git a/src/main/java/gregtech/api/util/GTLanguageManager.java b/src/main/java/gregtech/api/util/GTLanguageManager.java new file mode 100644 index 0000000000..d68b438027 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTLanguageManager.java @@ -0,0 +1,603 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.E; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import cpw.mods.fml.common.registry.LanguageRegistry; +import cpw.mods.fml.relauncher.ReflectionHelper; +import gregtech.api.GregTechAPI; + +public class GTLanguageManager { + + /** + * Buffer to reduce memory allocation when injecting data to LanguageRegistry. + */ + private static final HashMap TEMPMAP = new HashMap<>(); + /** + * Buffer used when something is trying to add new lang entry while config file is not set up yet. + */ + public static final Map BUFFERMAP = new HashMap<>(); + /** + * Map containing all the translation data coming into this class. + */ + private static final Map LANGMAP = new HashMap<>(); + /** + * Config file handler bound to GregTech.lang or GregTech_(locale_name).lang. Even though it says English file, + * it's not necessarily English, but on system it's always treated as English (as in, "default" language.) + */ + public static Configuration sEnglishFile; + /** + * If the game is running with en_US language. This does not get updated when user changes language in game; + * GT lang system cannot handle that anyway. + */ + public static boolean isEN_US; + /** + * If placeholder like %material should be used for writing lang entries to file. + */ + public static boolean i18nPlaceholder = true; + /** + * If there's any lang entry that is not found on lang file and waiting to be written. + */ + private static boolean hasUnsavedEntry = false; + + // TODO: convert to enum + public static String FACE_ANY = "gt.lang.face.any", FACE_BOTTOM = "gt.lang.face.bottom", + FACE_TOP = "gt.lang.face.top", FACE_LEFT = "gt.lang.face.left", FACE_FRONT = "gt.lang.face.front", + FACE_RIGHT = "gt.lang.face.right", FACE_BACK = "gt.lang.face.back", FACE_NONE = "gt.lang.face.none"; + + public static String[] FACES = { FACE_BOTTOM, FACE_TOP, FACE_LEFT, FACE_FRONT, FACE_RIGHT, FACE_BACK, FACE_NONE }; + + /** + * Map referencing private field of StringTranslate, used by StatCollector. Used to inject lang entries there. + */ + private static final Map stringTranslateLanguageList; + + static { + try { + Field fieldStringTranslateLanguageList = ReflectionHelper + .findField(net.minecraft.util.StringTranslate.class, "languageList", "field_74816_c"); + Field fieldStringTranslateInstance = ReflectionHelper + .findField(net.minecraft.util.StringTranslate.class, "instance", "field_74817_a"); + // noinspection unchecked + stringTranslateLanguageList = (Map) fieldStringTranslateLanguageList + .get(fieldStringTranslateInstance.get(null)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * @deprecated Parameter aWriteIntoLangFile is no longer used, + * use {@link #addStringLocalization(String, String)} or consider migrating to MC lang system instead. + */ + @Deprecated + public static synchronized String addStringLocalization(String aKey, String aEnglish, boolean aWriteIntoLangFile) { + return addStringLocalization(aKey, aEnglish); + } + + /** + * If you newly use this method, please consider using MC lang system instead. + */ + public static synchronized String addStringLocalization(String aKey, String aEnglish) { + String trimmedKey = aKey != null ? aKey.trim() : ""; + if (trimmedKey.isEmpty()) return E; // RIP cascading class loading, don't use GT_Utility here + if (sEnglishFile == null) { + // Lang file is not set up yet + BUFFERMAP.put(trimmedKey, aEnglish); + return aEnglish; + } + if (!BUFFERMAP.isEmpty()) { + // Lang file is now set up, resolve all the buffers + // This won't be visited twice + for (Entry tEntry : BUFFERMAP.entrySet()) { + storeTranslation(tEntry.getKey(), tEntry.getValue()); + } + BUFFERMAP.clear(); + } + + if (!LANGMAP.containsKey(trimmedKey)) { + return storeTranslation(trimmedKey, aEnglish); + } + return LANGMAP.get(trimmedKey); + } + + private static synchronized String storeTranslation(String trimmedKey, String english) { + String translation = writeToLangFile(trimmedKey, english); + LANGMAP.put(trimmedKey, translation); + addToMCLangList(trimmedKey, translation); + TEMPMAP.put(trimmedKey, translation); + LanguageRegistry.instance() + // If we use the actual user configured locale here, switching lang to others while running game + // turns everything into unlocalized string. So we make it "default" and call it a day. + .injectLanguage("en_US", TEMPMAP); + TEMPMAP.clear(); + return translation; + } + + private static synchronized String writeToLangFile(String trimmedKey, String aEnglish) { + Property tProperty = sEnglishFile.get("LanguageFile", trimmedKey, aEnglish); + if (hasUnsavedEntry && GregTechAPI.sPostloadFinished) { + sEnglishFile.save(); + hasUnsavedEntry = false; + } + String translation = tProperty.getString(); + if (tProperty.wasRead()) { + if (isEN_US && !aEnglish.equals(translation)) { + tProperty.set(aEnglish); + markFileDirty(); + return aEnglish; + } + } else { + markFileDirty(); + } + return translation; + } + + private static synchronized void markFileDirty() { + if (GregTechAPI.sPostloadFinished) { + sEnglishFile.save(); + } else { + hasUnsavedEntry = true; + } + } + + public static String getTranslation(String aKey) { + String tTrimmedKey = aKey != null ? aKey.trim() : ""; + if (tTrimmedKey.isEmpty()) return E; + + if (StatCollector.canTranslate(tTrimmedKey)) { + return StatCollector.translateToLocal(tTrimmedKey); + } + String anotherKeyToTry; + if (tTrimmedKey.endsWith(".name")) { + anotherKeyToTry = tTrimmedKey.substring(0, tTrimmedKey.length() - 5); + } else { + anotherKeyToTry = tTrimmedKey + ".name"; + } + if (StatCollector.canTranslate(anotherKeyToTry)) { + return StatCollector.translateToLocal(anotherKeyToTry); + } + return tTrimmedKey; + } + + public static String getTranslation(String aKey, String aSeperator) { + if (aKey == null) return E; + String rTranslation = E; + StringBuilder rTranslationSB = new StringBuilder(rTranslation); + for (String tString : aKey.split(aSeperator)) { + rTranslationSB.append(getTranslation(tString)); + } + rTranslation = String.valueOf(rTranslationSB); + return rTranslation; + } + + @SuppressWarnings("unused") + public static String getTranslateableItemStackName(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return "null"; + NBTTagCompound tNBT = aStack.getTagCompound(); + if (tNBT != null && tNBT.hasKey("display")) { + String tName = tNBT.getCompoundTag("display") + .getString("Name"); + if (GTUtility.isStringValid(tName)) { + return tName; + } + } + return aStack.getUnlocalizedName() + ".name"; + } + + public static void writePlaceholderStrings() { + addStringLocalization("Interaction_DESCRIPTION_Index_001", "Puts out into adjacent Slot #"); + addStringLocalization("Interaction_DESCRIPTION_Index_002", "Grabs in for own Slot #"); + addStringLocalization("Interaction_DESCRIPTION_Index_003", "Enable with Signal"); + addStringLocalization("Interaction_DESCRIPTION_Index_004", "Disable with Signal"); + addStringLocalization("Interaction_DESCRIPTION_Index_005", "Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_006", "Export"); + addStringLocalization("Interaction_DESCRIPTION_Index_007", "Import"); + addStringLocalization("Interaction_DESCRIPTION_Index_008", "Export (conditional)"); + addStringLocalization("Interaction_DESCRIPTION_Index_009", "Import (conditional)"); + addStringLocalization("Interaction_DESCRIPTION_Index_010", "Export (invert cond)"); + addStringLocalization("Interaction_DESCRIPTION_Index_011", "Import (invert cond)"); + addStringLocalization("Interaction_DESCRIPTION_Index_012", "Export allow Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_013", "Import allow Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_014", "Export allow Input (conditional)"); + addStringLocalization("Interaction_DESCRIPTION_Index_015", "Import allow Output (conditional)"); + addStringLocalization("Interaction_DESCRIPTION_Index_016", "Export allow Input (invert cond)"); + addStringLocalization("Interaction_DESCRIPTION_Index_017", "Import allow Output (invert cond)"); + addStringLocalization("Interaction_DESCRIPTION_Index_018", "Normal"); + addStringLocalization("Interaction_DESCRIPTION_Index_019", "Inverted"); + addStringLocalization("Interaction_DESCRIPTION_Index_020", "Ready to work"); + addStringLocalization("Interaction_DESCRIPTION_Index_021", "Not ready to work"); + addStringLocalization("Interaction_DESCRIPTION_Index_022", "Import"); + addStringLocalization("Interaction_DESCRIPTION_Index_023", "Import (conditional)"); + addStringLocalization("Interaction_DESCRIPTION_Index_024", "Import (invert cond)"); + addStringLocalization("Interaction_DESCRIPTION_Index_025", "Keep Liquids Away"); + addStringLocalization("Interaction_DESCRIPTION_Index_026", "Keep Liquids Away (conditional)"); + addStringLocalization("Interaction_DESCRIPTION_Index_027", "Keep Liquids Away (invert cond)"); + addStringLocalization("Interaction_DESCRIPTION_Index_031", "Normal Universal Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_032", "Inverted Universal Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_033", "Normal Electricity Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_034", "Inverted Electricity Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_035", "Normal Steam Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_036", "Inverted Steam Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_037", "Normal Average Electric Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_038", "Inverted Average Electric Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_039", "Normal Average Electric Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_040", "Inverted Average Electric Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_041", "Normal Electricity Storage(Including Batteries)"); + addStringLocalization("Interaction_DESCRIPTION_Index_042", "Inverted Electricity Storage(Including Batteries)"); + addStringLocalization("Interaction_DESCRIPTION_Index_043", "Filter input, Deny output"); + addStringLocalization("Interaction_DESCRIPTION_Index_044", "Invert input, Deny output"); + addStringLocalization("Interaction_DESCRIPTION_Index_045", "Filter input, Permit any output"); + addStringLocalization("Interaction_DESCRIPTION_Index_046", "Invert input, Permit any output"); + addStringLocalization("Interaction_DESCRIPTION_Index_047", "Filter Fluid: "); + addStringLocalization("Interaction_DESCRIPTION_Index_048", "Pump speed: "); + addStringLocalization("Interaction_DESCRIPTION_Index_049", "L/tick "); + addStringLocalization("Interaction_DESCRIPTION_Index_050", "L/sec"); + addStringLocalization("Interaction_DESCRIPTION_Index_053", "Slot: "); + addStringLocalization("Interaction_DESCRIPTION_Index_054", "Inverted"); + addStringLocalization("Interaction_DESCRIPTION_Index_055", "Normal"); + addStringLocalization("Interaction_DESCRIPTION_Index_056", "Emit if 1 Maintenance Needed"); + addStringLocalization("Interaction_DESCRIPTION_Index_057", "Emit if 1 Maintenance Needed(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_058", "Emit if 2 Maintenance Needed"); + addStringLocalization("Interaction_DESCRIPTION_Index_059", "Emit if 2 Maintenance Needed(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_060", "Emit if 3 Maintenance Needed"); + addStringLocalization("Interaction_DESCRIPTION_Index_061", "Emit if 3 Maintenance Needed(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_062", "Emit if 4 Maintenance Needed"); + addStringLocalization("Interaction_DESCRIPTION_Index_063", "Emit if 4 Maintenance Needed(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_064", "Emit if 5 Maintenance Needed"); + addStringLocalization("Interaction_DESCRIPTION_Index_065", "Emit if 5 Maintenance Needed(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_066", "Emit if rotor needs maintenance low accuracy mod"); + addStringLocalization( + "Interaction_DESCRIPTION_Index_067", + "Emit if rotor needs maintenance low accuracy mod(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_068", "Emit if rotor needs maintenance high accuracy mod"); + addStringLocalization("Interaction_DESCRIPTION_Index_068.1", "Emit if any Player is close"); + addStringLocalization( + "Interaction_DESCRIPTION_Index_069", + "Emit if rotor needs maintenance high accuracy mod(inverted)"); + addStringLocalization("Interaction_DESCRIPTION_Index_069.1", "Emit if other Player is close"); + addStringLocalization("Interaction_DESCRIPTION_Index_070", "Emit if you are close"); + addStringLocalization("Interaction_DESCRIPTION_Index_071", "Conducts strongest Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_072", "Conducts from bottom Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_073", "Conducts from top Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_074", "Conducts from north Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_075", "Conducts from south Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_076", "Conducts from west Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_077", "Conducts from east Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_078", "Signal = "); + addStringLocalization("Interaction_DESCRIPTION_Index_079", "Conditional Signal = "); + addStringLocalization("Interaction_DESCRIPTION_Index_080", "Inverted Conditional Signal = "); + addStringLocalization("Interaction_DESCRIPTION_Index_081", "Frequency: "); + addStringLocalization("Interaction_DESCRIPTION_Index_082", "Open if work enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_083", "Open if work disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_084", "Only Output allowed"); + addStringLocalization("Interaction_DESCRIPTION_Index_085", "Only Input allowed"); + addStringLocalization("Interaction_DESCRIPTION_Index_086", "Auto-Input: "); + addStringLocalization("Interaction_DESCRIPTION_Index_087", "Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_088", "Enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_089", " Auto-Output: "); + addStringLocalization("Interaction_DESCRIPTION_Index_090", "Machine Processing: "); + addStringLocalization("Interaction_DESCRIPTION_Index_091", "Redstone Output at Side "); + addStringLocalization("Interaction_DESCRIPTION_Index_092", " set to: "); + addStringLocalization("Interaction_DESCRIPTION_Index_093", "Strong"); + addStringLocalization("Interaction_DESCRIPTION_Index_094", "Weak"); + addStringLocalization("Interaction_DESCRIPTION_Index_094.1", "Not enough soldering material!"); + addStringLocalization("Interaction_DESCRIPTION_Index_095", "Input from Output Side allowed"); + addStringLocalization("Interaction_DESCRIPTION_Index_096", "Input from Output Side forbidden"); + addStringLocalization("Interaction_DESCRIPTION_Index_098", "Do not regulate Item Stack Size"); + addStringLocalization("Interaction_DESCRIPTION_Index_099", "Regulate Item Stack Size to: "); + addStringLocalization("Interaction_DESCRIPTION_Index_100", "This is "); + addStringLocalization("Interaction_DESCRIPTION_Index_101", " Ore."); + addStringLocalization("Interaction_DESCRIPTION_Index_102", "There is Lava behind this Rock."); + addStringLocalization("Interaction_DESCRIPTION_Index_103", "There is a Liquid behind this Rock."); + addStringLocalization("Interaction_DESCRIPTION_Index_104", "There is an Air Pocket behind this Rock."); + addStringLocalization("Interaction_DESCRIPTION_Index_105", "Material is changing behind this Rock."); + addStringLocalization("Interaction_DESCRIPTION_Index_106", "Found traces of "); + addStringLocalization("Interaction_DESCRIPTION_Index_107", "No Ores found."); + addStringLocalization("Interaction_DESCRIPTION_Index_108", "Outputs misc. Fluids, Steam and Items"); + addStringLocalization("Interaction_DESCRIPTION_Index_109", "Outputs Steam and Items"); + addStringLocalization("Interaction_DESCRIPTION_Index_110", "Outputs Steam and misc. Fluids"); + addStringLocalization("Interaction_DESCRIPTION_Index_111", "Outputs Steam"); + addStringLocalization("Interaction_DESCRIPTION_Index_112", "Outputs misc. Fluids and Items"); + addStringLocalization("Interaction_DESCRIPTION_Index_113", "Outputs only Items"); + addStringLocalization("Interaction_DESCRIPTION_Index_114", "Outputs only misc. Fluids"); + addStringLocalization("Interaction_DESCRIPTION_Index_115", "Outputs nothing"); + // 116 moved to lang files + // 117 obsolete + // 118 moved to lang files + // 119 obsolete + // 120 moved to lang files + // 121 obsolete + addStringLocalization("Interaction_DESCRIPTION_Index_122", "Emit Redstone if slots contain something"); + addStringLocalization("Interaction_DESCRIPTION_Index_123", "Don't emit Redstone"); + // 124 moved to lang files + addStringLocalization("Interaction_DESCRIPTION_Index_124.1", "Blacklist Mode"); + // 125 obsolete + addStringLocalization("Interaction_DESCRIPTION_Index_125.1", "Whitelist Mode"); + // 126 moved to lang files + // 127 obsolete + addStringLocalization("Interaction_DESCRIPTION_Index_128", "Redstone"); + addStringLocalization("Interaction_DESCRIPTION_Index_128.1", "Redstone "); + addStringLocalization("Interaction_DESCRIPTION_Index_129", "Energy"); + addStringLocalization("Interaction_DESCRIPTION_Index_129.1", "Energy "); + addStringLocalization("Interaction_DESCRIPTION_Index_130", "Fluids"); + addStringLocalization("Interaction_DESCRIPTION_Index_130.1", "Fluids "); + addStringLocalization("Interaction_DESCRIPTION_Index_131", "Items"); + addStringLocalization("Interaction_DESCRIPTION_Index_131.1", "Items "); + addStringLocalization("Interaction_DESCRIPTION_Index_132", "Pipe is loose."); + addStringLocalization("Interaction_DESCRIPTION_Index_133", "Screws are loose."); + addStringLocalization("Interaction_DESCRIPTION_Index_134", "Something is stuck."); + addStringLocalization("Interaction_DESCRIPTION_Index_135", "Platings are dented."); + addStringLocalization("Interaction_DESCRIPTION_Index_136", "Circuitry burned out."); + addStringLocalization("Interaction_DESCRIPTION_Index_137", "That doesn't belong there."); + addStringLocalization("Interaction_DESCRIPTION_Index_138", "Incomplete Structure."); + addStringLocalization("Interaction_DESCRIPTION_Index_139", "Hit with Soft Mallet"); + addStringLocalization("Interaction_DESCRIPTION_Index_140", "to (re-)start the Machine"); + addStringLocalization("Interaction_DESCRIPTION_Index_141", "if it doesn't start."); + addStringLocalization("Interaction_DESCRIPTION_Index_142", "Running perfectly."); + addStringLocalization("Interaction_DESCRIPTION_Index_143", "Missing Mining Pipe"); + addStringLocalization("Interaction_DESCRIPTION_Index_144", "Missing Turbine Rotor"); + addStringLocalization("Interaction_DESCRIPTION_Index_145", "Step Down, In: "); + addStringLocalization("Interaction_DESCRIPTION_Index_146", "Step Up, In: "); + addStringLocalization("Interaction_DESCRIPTION_Index_147", "A, Out: "); + addStringLocalization("Interaction_DESCRIPTION_Index_148", "V "); + addStringLocalization("Interaction_DESCRIPTION_Index_149", "A"); + addStringLocalization("Interaction_DESCRIPTION_Index_150", "Chance: "); + addStringLocalization("Interaction_DESCRIPTION_Index_151", "Does not get consumed in the process"); + addStringLocalization("Interaction_DESCRIPTION_Index_151.1", "Outputs items and 1 specific Fluid"); + addStringLocalization("Interaction_DESCRIPTION_Index_151.2", "Outputs 1 specific Fluid"); + addStringLocalization("Interaction_DESCRIPTION_Index_151.4", "Successfully locked Fluid to %s"); + addStringLocalization("Interaction_DESCRIPTION_Index_152", "Total: "); + addStringLocalization("Interaction_DESCRIPTION_Index_153", "Usage: "); + addStringLocalization("Interaction_DESCRIPTION_Index_154", "Voltage: "); + addStringLocalization("Interaction_DESCRIPTION_Index_155", "Amperage: "); + addStringLocalization("Interaction_DESCRIPTION_Index_156", "Voltage: unspecified"); + addStringLocalization("Interaction_DESCRIPTION_Index_157", "Amperage: unspecified"); + addStringLocalization("Interaction_DESCRIPTION_Index_158", "Time: "); + addStringLocalization("Interaction_DESCRIPTION_Index_159", "Needs Low Gravity"); + addStringLocalization("Interaction_DESCRIPTION_Index_160", "Needs Cleanroom"); + addStringLocalization("Interaction_DESCRIPTION_Index_160.1", "Needs Cleanroom & LowGrav"); + addStringLocalization("Interaction_DESCRIPTION_Index_161", " secs"); + addStringLocalization("Interaction_DESCRIPTION_Index_162", "Name: "); + addStringLocalization("Interaction_DESCRIPTION_Index_163", " MetaData: "); + addStringLocalization("Interaction_DESCRIPTION_Index_164", "Hardness: "); + addStringLocalization("Interaction_DESCRIPTION_Index_165", " Blast Resistance: "); + addStringLocalization("Interaction_DESCRIPTION_Index_166", "Is valid Beacon Pyramid Material"); + addStringLocalization("Interaction_DESCRIPTION_Index_167", "Tank "); + addStringLocalization("Interaction_DESCRIPTION_Index_168", "Heat: "); + addStringLocalization("Interaction_DESCRIPTION_Index_169", "HEM: "); + addStringLocalization("Interaction_DESCRIPTION_Index_170", " Base EU Output: "); + addStringLocalization("Interaction_DESCRIPTION_Index_171", "Facing: "); + addStringLocalization("Interaction_DESCRIPTION_Index_172", " / Chance: "); + addStringLocalization("Interaction_DESCRIPTION_Index_173", "You can remove this with a Wrench"); + addStringLocalization("Interaction_DESCRIPTION_Index_174", "You can NOT remove this with a Wrench"); + addStringLocalization("Interaction_DESCRIPTION_Index_175", "Conduction Loss: "); + addStringLocalization("Interaction_DESCRIPTION_Index_176", "Contained Energy: "); + addStringLocalization("Interaction_DESCRIPTION_Index_177", "Has Muffler Upgrade"); + addStringLocalization("Interaction_DESCRIPTION_Index_178", "Progress/Load: "); + addStringLocalization("Interaction_DESCRIPTION_Index_179", "Max IN: "); + addStringLocalization("Interaction_DESCRIPTION_Index_181", "Max OUT: "); + addStringLocalization("Interaction_DESCRIPTION_Index_182", " EU at "); + addStringLocalization("Interaction_DESCRIPTION_Index_183", " A"); + addStringLocalization("Interaction_DESCRIPTION_Index_184", "Energy: "); + addStringLocalization("Interaction_DESCRIPTION_Index_186", "Owned by: "); + addStringLocalization("Interaction_DESCRIPTION_Index_187", "Type -- Crop-Name: "); + addStringLocalization("Interaction_DESCRIPTION_Index_188", " Growth: "); + addStringLocalization("Interaction_DESCRIPTION_Index_189", " Gain: "); + addStringLocalization("Interaction_DESCRIPTION_Index_190", " Resistance: "); + addStringLocalization("Interaction_DESCRIPTION_Index_191", "Plant -- Fertilizer: "); + addStringLocalization("Interaction_DESCRIPTION_Index_192", " Water: "); + addStringLocalization("Interaction_DESCRIPTION_Index_193", " Weed-Ex: "); + addStringLocalization("Interaction_DESCRIPTION_Index_194", " Scan-Level: "); + addStringLocalization("Interaction_DESCRIPTION_Index_195", "Environment -- Nutrients: "); + addStringLocalization("Interaction_DESCRIPTION_Index_196", " Humidity: "); + addStringLocalization("Interaction_DESCRIPTION_Index_197", " Air-Quality: "); + addStringLocalization("Interaction_DESCRIPTION_Index_198", "Attributes:"); + addStringLocalization("Interaction_DESCRIPTION_Index_199", "Discovered by: "); + addStringLocalization("Interaction_DESCRIPTION_Index_200", "Sort mode: "); + addStringLocalization("Interaction_DESCRIPTION_Index_200.1", "Automatic Item Shuffling: "); + addStringLocalization("Interaction_DESCRIPTION_Index_201", "Nothing"); + addStringLocalization("Interaction_DESCRIPTION_Index_202", "Pollution in Chunk: "); + addStringLocalization("Interaction_DESCRIPTION_Index_203", " gibbl"); + addStringLocalization("Interaction_DESCRIPTION_Index_204", "No Pollution in Chunk! HAYO!"); + addStringLocalization("Interaction_DESCRIPTION_Index_206", "Scan for Assembly Line"); + addStringLocalization( + "Interaction_DESCRIPTION_Index_207", + "Pump speed: %dL every %d ticks, %.2f L/sec on average"); + addStringLocalization("Interaction_DESCRIPTION_Index_208", " L"); + addStringLocalization("Interaction_DESCRIPTION_Index_209", " ticks"); + addStringLocalization("Interaction_DESCRIPTION_Index_209.1", " tick"); + addStringLocalization("Interaction_DESCRIPTION_Index_210", "Average: %.2f L/sec"); + addStringLocalization("Interaction_DESCRIPTION_Index_211", "Items per side: "); + addStringLocalization("Interaction_DESCRIPTION_Index_212", "Input enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_213", "Input disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_214", "Connected"); + addStringLocalization("Interaction_DESCRIPTION_Index_215", "Disconnected"); + addStringLocalization("Interaction_DESCRIPTION_Index_216", "Deprecated Recipe"); + addStringLocalization("Interaction_DESCRIPTION_Index_219", "Extended Facing: "); + addStringLocalization("Interaction_DESCRIPTION_Index_220", "Single recipe locking disabled."); + addStringLocalization("Interaction_DESCRIPTION_Index_221", "Item threshold"); + addStringLocalization("Interaction_DESCRIPTION_Index_222", "Fluid threshold"); + addStringLocalization("Interaction_DESCRIPTION_Index_222.1", "Energy threshold"); + addStringLocalization( + "Interaction_DESCRIPTION_Index_223", + "Single recipe locking enabled. Will lock to next recipe."); + addStringLocalization("Interaction_DESCRIPTION_Index_224", "Always On"); + addStringLocalization("Interaction_DESCRIPTION_Index_225", "Active with Redstone Signal"); + addStringLocalization("Interaction_DESCRIPTION_Index_226", "Inactive with Redstone Signal"); + addStringLocalization("Interaction_DESCRIPTION_Index_227", "Allow Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_228", "Block Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_229", "Export/Import"); + addStringLocalization("Interaction_DESCRIPTION_Index_230", "Conditional"); + addStringLocalization("Interaction_DESCRIPTION_Index_231", "Enable Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_232", "Filter Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_233", "Filter Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_234", "Block Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_235", "Allow Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_236", "Whitelist Fluid"); + addStringLocalization("Interaction_DESCRIPTION_Index_237", "Blacklist Fluid"); + addStringLocalization("Interaction_DESCRIPTION_Index_238", "Filter Direction"); + addStringLocalization("Interaction_DESCRIPTION_Index_239", "Filter Type"); + addStringLocalization("Interaction_DESCRIPTION_Index_240", "Block Flow"); + addStringLocalization("Interaction_DESCRIPTION_Index_241", "Recipe progress"); + addStringLocalization("Interaction_DESCRIPTION_Index_242", "Machine idle"); + addStringLocalization("Interaction_DESCRIPTION_Index_243", "Enable with Redstone"); + addStringLocalization("Interaction_DESCRIPTION_Index_244", "Disable with Redstone"); + addStringLocalization("Interaction_DESCRIPTION_Index_245", "Disable machine"); + addStringLocalization("Interaction_DESCRIPTION_Index_246", "Frequency"); + addStringLocalization("Interaction_DESCRIPTION_Index_247", "1 Issue"); + addStringLocalization("Interaction_DESCRIPTION_Index_248", "2 Issues"); + addStringLocalization("Interaction_DESCRIPTION_Index_249", "3 Issues"); + addStringLocalization("Interaction_DESCRIPTION_Index_250", "4 Issues"); + addStringLocalization("Interaction_DESCRIPTION_Index_251", "5 Issues"); + addStringLocalization("Interaction_DESCRIPTION_Index_252", "Rotor < 20%"); + addStringLocalization("Interaction_DESCRIPTION_Index_253", "Rotor ≈ 0%"); + addStringLocalization("Interaction_DESCRIPTION_Index_254", "Detect slot#"); + addStringLocalization("Interaction_DESCRIPTION_Index_254.0", "Detect Slot"); + addStringLocalization("Interaction_DESCRIPTION_Index_254.1", "Internal slot#"); + addStringLocalization("Interaction_DESCRIPTION_Index_255", "Adjacent slot#"); + addStringLocalization("Interaction_DESCRIPTION_Index_256", "Universal Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_257", "Electricity Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_258", "Steam Storage"); + addStringLocalization("Interaction_DESCRIPTION_Index_259", "Average Electric Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_260", "Average Electric Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_261", "Electricity Storage(Including Batteries)"); + addStringLocalization("Interaction_DESCRIPTION_Index_262", "Fluid Auto Output Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_263", "Fluid Auto Output Enabled"); + addStringLocalization( + "Interaction_DESCRIPTION_Index_264", + "currently none, will be locked to the next that is put in"); + addStringLocalization("Interaction_DESCRIPTION_Index_265", "1 specific Fluid"); + addStringLocalization("Interaction_DESCRIPTION_Index_266", "Lock Fluid Mode Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_267", "Overflow Voiding Mode Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_268", "Overflow Voiding Mode Enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_269", "Void Full Mode Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_270", "Void Full Mode Enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_271", "unspecified"); + addStringLocalization("Interaction_DESCRIPTION_Index_272", "Recipe by: "); + addStringLocalization("Interaction_DESCRIPTION_Index_273", "Original Recipe by: "); + addStringLocalization("Interaction_DESCRIPTION_Index_274", "Modified by: "); + addStringLocalization("Interaction_DESCRIPTION_Index_275", "Original voltage: "); + addStringLocalization("Interaction_DESCRIPTION_Index_299", "Item Filter: "); + addStringLocalization("Interaction_DESCRIPTION_Index_300", "Filter Cleared!"); + addStringLocalization("Interaction_DESCRIPTION_Index_300.1", "Fluid Lock Cleared."); + addStringLocalization("Interaction_DESCRIPTION_Index_301", "Universal"); + addStringLocalization("Interaction_DESCRIPTION_Index_302", "Int. EU"); + addStringLocalization("Interaction_DESCRIPTION_Index_303", "Steam"); + addStringLocalization("Interaction_DESCRIPTION_Index_304", "Avg. Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_305", "Avg. Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_306", "EU stored"); + addStringLocalization("Interaction_DESCRIPTION_Index_307", "Deny input, Filter output"); + addStringLocalization("Interaction_DESCRIPTION_Index_308", "Deny input, Invert output"); + addStringLocalization("Interaction_DESCRIPTION_Index_309", "Permit any input, Filter output"); + addStringLocalization("Interaction_DESCRIPTION_Index_310", "Permit any input, Invert output"); + addStringLocalization("Interaction_DESCRIPTION_Index_311", "Block Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_312", "Allow Output"); + addStringLocalization("Interaction_DESCRIPTION_Index_313", "Block Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_314", "Allow Input"); + addStringLocalization("Interaction_DESCRIPTION_Index_315", "Filter Empty"); + addStringLocalization("Interaction_DESCRIPTION_Index_316", "Pump speed limit reached!"); + addStringLocalization("Interaction_DESCRIPTION_Index_317", "Filter: "); + addStringLocalization("Interaction_DESCRIPTION_Index_318", "Check Mode"); + addStringLocalization("Interaction_DESCRIPTION_Index_319", "Any player"); + addStringLocalization("Interaction_DESCRIPTION_Index_320", "Other players"); + addStringLocalization("Interaction_DESCRIPTION_Index_321", "Only owner"); + addStringLocalization("Interaction_DESCRIPTION_Index_322", "Overflow point: "); + addStringLocalization("Interaction_DESCRIPTION_Index_323", "L"); + addStringLocalization("Interaction_DESCRIPTION_Index_324", "Now"); + addStringLocalization("Interaction_DESCRIPTION_Index_325", "Max"); + addStringLocalization("Interaction_DESCRIPTION_Index_326", "Public"); + addStringLocalization("Interaction_DESCRIPTION_Index_327", "Private"); + addStringLocalization("Interaction_DESCRIPTION_Index_328", "Channel"); + addStringLocalization("Interaction_DESCRIPTION_Index_329", "Public/Private"); + addStringLocalization("Interaction_DESCRIPTION_Index_330", "Sneak Rightclick to switch Mode"); + addStringLocalization("Interaction_DESCRIPTION_Index_331", "AND Gate"); + addStringLocalization("Interaction_DESCRIPTION_Index_332", "NAND Gate"); + addStringLocalization("Interaction_DESCRIPTION_Index_333", "OR Gate"); + addStringLocalization("Interaction_DESCRIPTION_Index_334", "NOR Gate"); + addStringLocalization("Interaction_DESCRIPTION_Index_335", "Gate Mode"); + addStringLocalization("Interaction_DESCRIPTION_Index_336", "PCB Factory Tier: "); + addStringLocalization("Interaction_DESCRIPTION_Index_337", "Upgrade Required: "); + addStringLocalization("Interaction_DESCRIPTION_Index_338", "Bio"); + addStringLocalization("Interaction_DESCRIPTION_Index_339", "Biochamber Upgrade Enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_339.1", "Biochamber Upgrade Disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_340", "Rotated biochamber enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_340.1", "Rotated biochamber disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_341", "Tier 1 cooling enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_341.1", "Tier 1 cooling disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_342", "Tier 2 cooling enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_342.1", "Tier 2 cooling disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_343", "Use Machine Processing State"); + addStringLocalization("Interaction_DESCRIPTION_Index_343.1", "Use Inverted Machine Processing State"); + addStringLocalization("Interaction_DESCRIPTION_Index_344", "Input Blocking"); + addStringLocalization("Interaction_DESCRIPTION_Index_344.1", "Output Blocking"); + addStringLocalization("Interaction_DESCRIPTION_Index_400", "Running mode: "); + addStringLocalization("Interaction_DESCRIPTION_Index_500", "Fitting: Loose - More Flow"); + addStringLocalization("Interaction_DESCRIPTION_Index_501", "Fitting: Tight - More Efficiency"); + addStringLocalization("Interaction_DESCRIPTION_Index_502", "Mining chunk loading enabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_503", "Mining chunk loading disabled"); + addStringLocalization("Interaction_DESCRIPTION_Index_505", "Enable with Signal (Safe)"); + addStringLocalization("Interaction_DESCRIPTION_Index_506", "Disable with Signal (Safe)"); + addStringLocalization("Interaction_DESCRIPTION_Index_507", "Safe Mode"); + addStringLocalization("Interaction_DESCRIPTION_Index_508", "Needs Stabilized Black Hole"); + addStringLocalization("Interaction_DESCRIPTION_Index_509", "Requires HIP Unit"); + addStringLocalization("Interaction_DESCRIPTION_Index_602", "Use Private Frequency"); + addStringLocalization("Interaction_DESCRIPTION_Index_756", "Connectable: "); + addStringLocalization("Interaction_DESCRIPTION_Index_ALL", "All"); + addStringLocalization("Interaction_DESCRIPTION_Index_ANY", "Any"); + addStringLocalization("Interaction_DESCRIPTION_Index_INVERTED", "Inverted"); + addStringLocalization("Interaction_DESCRIPTION_Index_NORMAL", "Normal"); + addStringLocalization("Interaction_DESCRIPTION_Index_SIDE", "Side: "); + + addStringLocalization("Item_DESCRIPTION_Index_000", "Stored Heat: %s"); + addStringLocalization("Item_DESCRIPTION_Index_001", "Durability: %s/%s"); + addStringLocalization("Item_DESCRIPTION_Index_002", "%s lvl %s"); + addStringLocalization("Item_DESCRIPTION_Index_003", "Attack Damage: %s"); + addStringLocalization("Item_DESCRIPTION_Index_004", "Mining Speed: %s"); + addStringLocalization("Item_DESCRIPTION_Index_005", "Turbine Efficiency: %s"); + addStringLocalization("Item_DESCRIPTION_Index_006", "Optimal Steam flow: %s L/t"); + addStringLocalization("Item_DESCRIPTION_Index_007", "Energy from Optimal Gas Flow: %s EU/t"); + addStringLocalization("Item_DESCRIPTION_Index_008", "Energy from Optimal Plasma Flow: %s EU/t"); + addStringLocalization("Item_DESCRIPTION_Index_009", "Contains %s EU Tier: %s"); + addStringLocalization("Item_DESCRIPTION_Index_010", "Empty. You should recycle it properly."); + addStringLocalization("Item_DESCRIPTION_Index_011", "%s / %s EU - Voltage: %s"); + addStringLocalization("Item_DESCRIPTION_Index_012", "No Fluids Contained"); + addStringLocalization("Item_DESCRIPTION_Index_013", "%sL / %sL"); + addStringLocalization("Item_DESCRIPTION_Index_014", "Missing Coodinates!"); + addStringLocalization("Item_DESCRIPTION_Index_015", "Device at:"); + addStringLocalization("Item_DESCRIPTION_Index_018", "State: %s"); + addStringLocalization("Item_DESCRIPTION_Index_019", "Bath with neutron in a hot reactor"); + addStringLocalization("Item_DESCRIPTION_Index_020", "Progress: %s/%s"); + addStringLocalization("Item_DESCRIPTION_Index_021", "Radiation Hazard"); + addStringLocalization("Item_DESCRIPTION_Index_500", "Turbine Efficiency (Loose): %s"); + addStringLocalization("Item_DESCRIPTION_Index_501", "Optimal Steam flow (Loose): %s L/t"); + addStringLocalization("Item_DESCRIPTION_Index_502", "Overflow Efficiency Tier: %s"); + addStringLocalization("Item_DESCRIPTION_Index_900", "Energy from Optimal Steam Flow: %s EU/t"); + addStringLocalization("Item_DESCRIPTION_Index_901", "Energy from Optimal Steam Flow (Loose): %s EU/t"); + + addStringLocalization(FACE_ANY, "Any Side"); + addStringLocalization(FACE_BOTTOM, "Bottom"); + addStringLocalization(FACE_TOP, "Top"); + addStringLocalization(FACE_LEFT, "Left"); + addStringLocalization(FACE_FRONT, "Front"); + addStringLocalization(FACE_RIGHT, "Right"); + addStringLocalization(FACE_BACK, "Back"); + addStringLocalization(FACE_NONE, "None"); + } + + private static void addToMCLangList(String aKey, String translation) { + if (stringTranslateLanguageList != null) { + stringTranslateLanguageList.put(aKey, translation); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTLog.java b/src/main/java/gregtech/api/util/GTLog.java new file mode 100644 index 0000000000..eba6b0fe50 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTLog.java @@ -0,0 +1,45 @@ +package gregtech.api.util; + +import java.io.File; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * Just a simple Logging Function. If on Server, then this will point to System.out and System.err + */ +public class GTLog { + + public static PrintStream out = System.out; + public static PrintStream err = System.err; + public static PrintStream ore = new LogBuffer(); + public static PrintStream pal = null; + public static PrintStream exp = new LogBuffer(); + public static File mLogFile; + public static File mOreDictLogFile; + public static File mPlayerActivityLogFile; + public static File mExplosionLog; + + public static class LogBuffer extends PrintStream { + + public final List mBufferedOreDictLog = new ArrayList<>(); + + public LogBuffer() { + super(new OutputStream() { + + @Override + public void write(int arg0) { + /* Do nothing */ + } + }); + } + + @Override + public void println(String aString) { + mBufferedOreDictLog.add(aString); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTModHandler.java b/src/main/java/gregtech/api/util/GTModHandler.java new file mode 100644 index 0000000000..8c06f2ad47 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTModHandler.java @@ -0,0 +1,2435 @@ +package gregtech.api.util; + +import static gregtech.GTMod.GT_FML_LOGGER; +import static gregtech.api.enums.GTValues.B; +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.GTValues.DW; +import static gregtech.api.enums.GTValues.E; +import static gregtech.api.enums.GTValues.M; +import static gregtech.api.enums.GTValues.RA; +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.GTValues.VN; +import static gregtech.api.enums.GTValues.W; +import static gregtech.api.recipe.RecipeMaps.alloySmelterRecipes; +import static gregtech.api.recipe.RecipeMaps.oreWasherRecipes; +import static gregtech.api.util.GTRecipeBuilder.SECONDS; +import static gregtech.api.util.GTRecipeBuilder.TICKS; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.item.crafting.ShapelessRecipes; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.oredict.ShapedOreRecipe; +import net.minecraftforge.oredict.ShapelessOreRecipe; + +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OreDictNames; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.Tier; +import gregtech.api.enums.ToolDictNames; +import gregtech.api.interfaces.IDamagableItem; +import gregtech.api.interfaces.IItemContainer; +import gregtech.api.interfaces.internal.IGTCraftingRecipe; +import gregtech.api.items.MetaBaseItem; +import gregtech.api.metatileentity.implementations.MTEBasicMachineWithRecipe; +import gregtech.api.objects.GTHashSet; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeCategories; +import gregtech.api.recipe.RecipeMap; +import ic2.api.item.IBoxable; +import ic2.api.item.IC2Items; +import ic2.api.item.IElectricItem; +import ic2.api.reactor.IReactorComponent; +import ic2.api.recipe.IRecipeInput; +import ic2.api.recipe.RecipeInputItemStack; +import ic2.api.recipe.RecipeOutput; +import ic2.core.item.ItemToolbox; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the Interface I use for interacting with other Mods. + *

+ * Due to the many imports, this File can cause compile Problems if not all the APIs are installed + */ +public class GTModHandler { + + public static final List sSingleNonBlockDamagableRecipeList = new ArrayList<>(1000); + private static final Map sIC2ItemMap = new HashMap<>(); + + // public for bartworks + public static final List sAllRecipeList = new ArrayList<>(5000), sBufferRecipeList = new ArrayList<>(1000); + private static final List delayedRemovalByOutput = new ArrayList<>(); + private static final List delayedRemovalByRecipe = new ArrayList<>(); + + public static Collection sNativeRecipeClasses = new HashSet<>(), sSpecialRecipeClasses = new HashSet<>(); + public static GTHashSet sNonReplaceableItems = new GTHashSet<>(); + public static Object sBoxableWrapper = new GTIBoxableWrapper(); + public static Collection sBoxableItems = new ArrayList<>(); + private static final Map emptyRecipeMap = new HashMap<>(); + private static Set recyclerWhitelist; + private static Set recyclerBlacklist; + + private static boolean sBufferCraftingRecipes = true; + public static List sSingleNonBlockDamagableRecipeList_list = new ArrayList<>(100); + private static final boolean sSingleNonBlockDamagableRecipeList_create = true; + private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0); + private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R"; + private static final ItemStack[][] sShapes1 = new ItemStack[][] { + { sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null }, + { sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1 }, + { null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1 }, + { sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null }, + { sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1 }, + { sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1 }, + { null, null, null, sMt1, null, sMt1, sMt1, null, sMt1 }, + { null, sMt1, null, null, sMt1, null, null, sMt2, null }, + { sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null }, + { null, sMt1, null, null, sMt2, null, null, sMt2, null }, + { sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null }, + { null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null }, + { sMt1, sMt1, null, null, sMt2, null, null, sMt2, null }, + { null, sMt1, sMt1, null, sMt2, null, null, sMt2, null }, + { null, sMt1, null, sMt1, null, null, null, sMt1, sMt2 }, + { null, sMt1, null, null, null, sMt1, sMt2, sMt1, null }, + { null, sMt1, null, sMt1, null, sMt1, null, null, sMt2 }, + { null, sMt1, null, sMt1, null, sMt1, sMt2, null, null }, + { null, sMt2, null, null, sMt1, null, null, sMt1, null }, + { null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1 }, + { null, sMt2, null, null, sMt2, null, null, sMt1, null }, + { null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null }, + { null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1 }, + { null, sMt2, null, null, sMt2, null, sMt1, sMt1, null }, + { sMt1, null, null, null, sMt2, null, null, null, sMt2 }, + { null, null, sMt1, null, sMt2, null, sMt2, null, null }, + { sMt1, null, null, null, sMt2, null, null, null, null }, + { null, null, sMt1, null, sMt2, null, null, null, null }, + { sMt1, sMt2, null, null, null, null, null, null, null }, + { sMt2, sMt1, null, null, null, null, null, null, null }, + { sMt1, null, null, sMt2, null, null, null, null, null }, + { sMt2, null, null, sMt1, null, null, null, null, null }, + { sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null }, + { sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null }, + { null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1 }, + { null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1 }, + { sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null }, + { sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null }, + { null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1 }, + { null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1 }, + { sMt1, null, null, null, sMt1, null, null, null, null }, + { null, sMt1, null, sMt1, null, null, null, null, null }, + { sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null }, + { null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2 } }; + public static List sSingleNonBlockDamagableRecipeList_validsShapes1 = new ArrayList<>(44); + public static boolean sSingleNonBlockDamagableRecipeList_validsShapes1_update = false; + public static List sSingleNonBlockDamagableRecipeList_warntOutput = new ArrayList<>(50); + public static List sVanillaRecipeList_warntOutput = new ArrayList<>(50); + public static final List sSingleNonBlockDamagableRecipeList_verified = new ArrayList<>(1000); + public static List sAnySteamFluidIDs = new ArrayList<>(); + public static List sSuperHeatedSteamFluidIDs = new ArrayList<>(); + + static { + sNativeRecipeClasses.add(ShapedRecipes.class.getName()); + sNativeRecipeClasses.add(ShapedOreRecipe.class.getName()); + sNativeRecipeClasses.add(GTShapedRecipe.class.getName()); + sNativeRecipeClasses.add(ShapelessRecipes.class.getName()); + sNativeRecipeClasses.add(ShapelessOreRecipe.class.getName()); + sNativeRecipeClasses.add(GTShapelessRecipe.class.getName()); + sNativeRecipeClasses.add(ic2.core.AdvRecipe.class.getName()); + sNativeRecipeClasses.add(ic2.core.AdvShapelessRecipe.class.getName()); + sNativeRecipeClasses.add("appeng.recipes.game.ShapedRecipe"); + sNativeRecipeClasses.add("appeng.recipes.game.ShapelessRecipe"); + sNativeRecipeClasses.add("forestry.core.utils.ShapedRecipeCustom"); + + // Recipe Classes, which should never be removed. + sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipeFireworks.class.getName()); + sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesArmorDyes.class.getName()); + sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipeBookCloning.class.getName()); + sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesMapCloning.class.getName()); + sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesMapExtending.class.getName()); + sSpecialRecipeClasses.add("jds.bibliocraft.BiblioSpecialRecipes"); + sSpecialRecipeClasses.add("dan200.qcraft.shared.EntangledQBlockRecipe"); + sSpecialRecipeClasses.add("dan200.qcraft.shared.EntangledQuantumComputerRecipe"); + sSpecialRecipeClasses.add("dan200.qcraft.shared.QBlockRecipe"); + sSpecialRecipeClasses.add("appeng.recipes.game.FacadeRecipe"); + sSpecialRecipeClasses.add("appeng.recipes.game.DisassembleRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.carts.LocomotivePaintingRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RotorRepairRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RoutingTableCopyRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RoutingTicketCopyRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.TankCartFilterRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.emblems.LocomotiveEmblemRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.emblems.EmblemPostColorRecipe"); + sSpecialRecipeClasses.add("mods.railcraft.common.emblems.EmblemPostEmblemRecipe"); + sSpecialRecipeClasses.add("mods.immibis.redlogic.interaction.RecipeDyeLumarButton"); + sSpecialRecipeClasses.add("thaumcraft.common.items.armor.RecipesRobeArmorDyes"); + sSpecialRecipeClasses.add("thaumcraft.common.items.armor.RecipesVoidRobeArmorDyes"); + sSpecialRecipeClasses.add("thaumcraft.common.lib.crafting.ShapelessNBTOreRecipe"); + sSpecialRecipeClasses.add("twilightforest.item.TFMapCloningRecipe"); + sSpecialRecipeClasses.add("forestry.lepidopterology.MatingRecipe"); + sSpecialRecipeClasses.add("micdoodle8.mods.galacticraft.planets.asteroids.recipe.CanisterRecipes"); + sSpecialRecipeClasses.add("shedar.mods.ic2.nuclearcontrol.StorageArrayRecipe"); + } + + /** + * Returns if that Liquid is Water or Distilled Water + */ + public static boolean isWater(FluidStack aFluid) { + if (aFluid == null) return false; + return aFluid.isFluidEqual(getWater(1)) || aFluid.isFluidEqual(getDistilledWater(1)); + } + + /** + * Returns a Liquid Stack with given amount of Water. + */ + public static FluidStack getWater(long aAmount) { + return FluidRegistry.getFluidStack("water", (int) aAmount); + } + + /** + * Returns a Liquid Stack with given amount of distilled Water. + */ + public static FluidStack getDistilledWater(long aAmount) { + FluidStack tFluid = FluidRegistry.getFluidStack("ic2distilledwater", (int) aAmount); + if (tFluid == null) tFluid = getWater(aAmount); + return tFluid; + } + + /** + * Returns if that Liquid is Lava + */ + public static boolean isLava(FluidStack aFluid) { + if (aFluid == null) return false; + return aFluid.isFluidEqual(getLava(1)); + } + + /** + * Returns a Liquid Stack with given amount of Lava. + */ + public static FluidStack getLava(long aAmount) { + return FluidRegistry.getFluidStack("lava", (int) aAmount); + } + + /** + * Returns if that Liquid is Steam + */ + public static boolean isSteam(FluidStack aFluid) { + if (aFluid == null) return false; + return aFluid.isFluidEqual(getSteam(1)); + } + + /** + * Returns if that Liquid is Any Steam (including other mods) + */ + public static boolean isAnySteam(FluidStack aFluid) { + return (aFluid != null && (isSteam(aFluid) || sAnySteamFluidIDs.contains(aFluid.getFluidID()))); + } + + /** + * Returns if that Liquid is Super Heated Steam (including other mods) + */ + public static boolean isSuperHeatedSteam(FluidStack aFluid) { + return (aFluid != null && sSuperHeatedSteamFluidIDs.contains(aFluid.getFluidID())); + } + + /** + * Returns a Liquid Stack with given amount of Steam. + */ + public static FluidStack getSteam(long aAmount) { + return FluidRegistry.getFluidStack("steam", (int) aAmount); + } + + /** + * Returns if that Liquid is Milk + */ + public static boolean isMilk(FluidStack aFluid) { + if (aFluid == null) return false; + return aFluid.isFluidEqual(getMilk(1)); + } + + /** + * Returns a Liquid Stack with given amount of Milk. + */ + public static FluidStack getMilk(long aAmount) { + return FluidRegistry.getFluidStack("milk", (int) aAmount); + } + + public static ItemStack getEmptyCell(long aAmount) { + return ItemList.Cell_Empty.get(aAmount); + } + + public static ItemStack getAirCell(long aAmount) { + return ItemList.Cell_Air.get(aAmount); + } + + public static ItemStack getWaterCell(long aAmount) { + return ItemList.Cell_Water.get(aAmount); + } + + public static ItemStack getLavaCell(long aAmount) { + return ItemList.Cell_Lava.get(aAmount); + } + + /** + * @param aValue the Value of this Stack, when burning inside a Furnace (200 = 1 Burn Process = 500 EU, max = 32767 + * (that is 81917.5 EU)), limited to Short because the vanilla Furnace otherwise can't handle it + * properly, stupid Mojang... + */ + public static ItemStack setFuelValue(ItemStack aStack, short aValue) { + aStack.setTagCompound(GTUtility.getNBTContainingShort(aStack.getTagCompound(), "GT.ItemFuelValue", aValue)); + return aStack; + } + + /** + * @return the Value of this Stack, when burning inside a Furnace (200 = 1 Burn Process = 500 EU, max = 32767 (that + * is 81917.5 EU)), limited to Short because the vanilla Furnace otherwise can't handle it properly, stupid + * Mojang... + */ + public static int getFuelValue(ItemStack aStack) { + return TileEntityFurnace.getItemBurnTime(aStack); + } + + /** + * Gets an Item from IndustrialCraft, and returns a Replacement Item if not possible + */ + public static ItemStack getIC2Item(String aItem, long aAmount, ItemStack aReplacement) { + if (GTUtility.isStringInvalid(aItem) || !GregTechAPI.sPreloadStarted) return null; + // if (D1) GTLog.out.println("Requested the Item '" + aItem + "' from the IC2-API"); + if (!sIC2ItemMap.containsKey(aItem)) try { + ItemStack tStack = IC2Items.getItem(aItem); + sIC2ItemMap.put(aItem, tStack); + if (tStack == null && D1) GTLog.err.println(aItem + " is not found in the IC2 Items!"); + } catch (Throwable e) { + /* Do nothing */ + } + return GTUtility.copyAmount(aAmount, sIC2ItemMap.get(aItem), aReplacement); + } + + /** + * Gets an Item from IndustrialCraft, but the Damage Value can be specified, and returns a Replacement Item with the + * same Damage if not possible + */ + public static ItemStack getIC2Item(String aItem, long aAmount, int aMeta, ItemStack aReplacement) { + ItemStack rStack = getIC2Item(aItem, aAmount, aReplacement); + if (rStack == null) return null; + Items.feather.setDamage(rStack, aMeta); + return rStack; + } + + /** + * Gets an Item from IndustrialCraft, but the Damage Value can be specified + */ + public static ItemStack getIC2Item(String aItem, long aAmount, int aMeta) { + return getIC2Item(aItem, aAmount, aMeta, null); + } + + /** + * Gets an Item from IndustrialCraft + */ + public static ItemStack getIC2Item(String aItem, long aAmount) { + return getIC2Item(aItem, aAmount, null); + } + + /** + * Gets an Item from the specified mod + */ + public static ItemStack getModItem(String aModID, String aItem, long aAmount) { + return getModItem(aModID, aItem, aAmount, null); + } + + /** + * Gets an Item from the specified mod, and returns a Replacement Item if not possible + */ + public static ItemStack getModItem(String aModID, String aItem, long aAmount, ItemStack aReplacement) { + ItemStack result; + if (GTUtility.isStringInvalid(aItem) || !GregTechAPI.sPreloadStarted) { + result = null; + } else { + result = GTUtility + .copyAmount(aAmount, GameRegistry.findItemStack(aModID, aItem, (int) aAmount), aReplacement); + } + + if (result == null) { + String reason; + if (GTUtility.isStringInvalid(aItem)) { + reason = "the name of the item is an invalid string"; + } else if (!GregTechAPI.sPreloadStarted) { + reason = "the GT5U preloading phase has not yet started"; + } else { + reason = "the item was not found in the game registry"; + } + String log_message = "getModItem call: object \"" + aItem + + "\" with mod id \"" + + aModID + + "\" has returned null because " + + reason; + GTLog.out.println(log_message); + new Exception().printStackTrace(GTLog.out); + } + return result; + } + + /** + * Gets an Item from the specified mod, but the Damage Value can be specified + */ + public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta) { + ItemStack rStack = getModItem(aModID, aItem, aAmount); + if (rStack == null) return null; + Items.feather.setDamage(rStack, aMeta); + return rStack; + } + + /** + * Gets an Item from the specified mod, but the Damage Value can be specified, and returns a Replacement Item with + * the same Damage if not possible + */ + public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta, ItemStack aReplacement) { + ItemStack rStack = getModItem(aModID, aItem, aAmount, aReplacement); + if (rStack == null) return null; + Items.feather.setDamage(rStack, aMeta); + return rStack; + } + + /** + * OUT OF ORDER + */ + @Deprecated + public static boolean getModeKeyDown(EntityPlayer aPlayer) { + return false; + } + + /** + * OUT OF ORDER + */ + @Deprecated + public static boolean getBoostKeyDown(EntityPlayer aPlayer) { + return false; + } + + /** + * OUT OF ORDER + */ + @Deprecated + public static boolean getJumpKeyDown(EntityPlayer aPlayer) { + return false; + } + + /** + * Adds a Valuable Ore to the Miner + */ + public static boolean addValuableOre(Block aBlock, int aMeta, int aValue) { + if (aValue <= 0) return false; + try { + Class.forName("ic2.core.IC2") + .getMethod("addValuableOre", IRecipeInput.class, int.class) + .invoke(null, new RecipeInputItemStack(new ItemStack(aBlock, 1, aMeta)), aValue); + } catch (Throwable e) { + /* Do nothing */ + } + return true; + } + + /** + * Adds a Scrapbox Drop. Fails at April first for the "suddenly Hoes"-Feature of IC2 + */ + public static boolean addScrapboxDrop(float aChance, ItemStack aOutput) { + aOutput = GTOreDictUnificator.get(true, aOutput); + if (aOutput == null || aChance <= 0) return false; + aOutput.stackSize = 1; + if (GTConfig.troll && !GTUtility.areStacksEqual(aOutput, new ItemStack(Items.wooden_hoe, 1, 0))) return false; + try { + GTUtility.callMethod( + GTUtility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), + "addDrop", + true, + false, + true, + GTUtility.copyOrNull(aOutput), + aChance); + GTUtility.callMethod( + GTUtility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), + "addRecipe", + true, + true, + false, + GTUtility.copyOrNull(aOutput), + aChance); + } catch (Throwable e) { + /* Do nothing */ + } + return true; + } + + /** + * Adds an Item to the Recycler Blacklist + */ + public static boolean addToRecyclerBlackList(ItemStack aRecycledStack) { + if (aRecycledStack == null) return false; + try { + ic2.api.recipe.Recipes.recyclerBlacklist.add(new RecipeInputItemStack(aRecycledStack)); + } catch (Throwable e) { + /* Do nothing */ + } + return true; + } + + /** + * Just simple Furnace smelting. Unbelievable how Minecraft fails at making a simple ItemStack->ItemStack mapping... + */ + public static boolean addSmeltingRecipe(ItemStack aInput, ItemStack aOutput) { + aOutput = GTOreDictUnificator.get(true, aOutput); + if (aInput == null || aOutput == null) return false; + FurnaceRecipes.smelting() + .func_151394_a(aInput, GTUtility.copyOrNull(aOutput), 0.0F); + return true; + } + + /** + * Adds to Furnace AND Alloy Smelter + */ + public static boolean addSmeltingAndAlloySmeltingRecipe(ItemStack aInput, ItemStack aOutput, boolean hidden) { + if (aInput == null || aOutput == null) { + return false; + } + boolean temp = aInput.stackSize == 1 && addSmeltingRecipe(aInput, aOutput); + ItemStack input2 = OrePrefixes.ingot.contains(aOutput) ? ItemList.Shape_Mold_Ingot.get(0) + : OrePrefixes.block.contains(aOutput) ? ItemList.Shape_Mold_Block.get(0) + : OrePrefixes.nugget.contains(aOutput) ? ItemList.Shape_Mold_Nugget.get(0) : null; + if (Materials.Graphite.contains(aInput)) { + return false; + } + if ((input2 == null) && ((OrePrefixes.ingot.contains(aInput)) || (OrePrefixes.dust.contains(aInput)) + || (OrePrefixes.gem.contains(aInput)))) { + return false; + } + GTRecipeBuilder recipeBuilder = GTValues.RA.stdBuilder(); + if (input2 == null) { + recipeBuilder.itemInputs(aInput); + } else { + recipeBuilder.itemInputs(aInput, input2); + } + recipeBuilder.itemOutputs(aOutput) + .duration(6 * SECONDS + 10 * TICKS) + .eut(3) + .recipeCategory(RecipeCategories.alloySmelterRecycling); + if (hidden) { + recipeBuilder.hidden(); + } + recipeBuilder.addTo(alloySmelterRecipes); + return true; + } + + /** + * Removes IC2 recipes. + */ + public static void removeAllIC2Recipes() { + getMaceratorRecipeList().entrySet() + .clear(); + getCompressorRecipeList().entrySet() + .clear(); + getExtractorRecipeList().entrySet() + .clear(); + getOreWashingRecipeList().entrySet() + .clear(); + getThermalCentrifugeRecipeList().entrySet() + .clear(); + } + + /** + * Adds GT versions of the IC2 recipes from the supplied IC2RecipeList. Deprecated because all IC2 recipes + * have been manually added to GT. + */ + @Deprecated + public static void addIC2RecipesToGT(Map aIC2RecipeList, RecipeMap aGTRecipeMap, + boolean aAddGTRecipe, boolean aRemoveIC2Recipe, boolean aExcludeGTIC2Items) { + Map aRecipesToRemove = new HashMap<>(); + for (Entry iRecipeInputRecipeOutputEntry : aIC2RecipeList.entrySet()) { + if (iRecipeInputRecipeOutputEntry.getValue().items.isEmpty()) { + continue; + } + + for (ItemStack tStack : (iRecipeInputRecipeOutputEntry.getKey()).getInputs()) { + if (!GTUtility.isStackValid(tStack)) { + continue; + } + + if (aAddGTRecipe) { + try { + if (aExcludeGTIC2Items && ((tStack.getUnlocalizedName() + .contains("gt.metaitem.01") + || tStack.getUnlocalizedName() + .contains("gt.blockores") + || tStack.getUnlocalizedName() + .contains("ic2.itemCrushed") + || tStack.getUnlocalizedName() + .contains("ic2.itemPurifiedCrushed")))) + continue; + switch (aGTRecipeMap.unlocalizedName) { + case "gt.recipe.macerator", "gt.recipe.extractor", "gt.recipe.compressor" -> GTValues.RA + .stdBuilder() + .itemInputs( + GTUtility.copyAmount( + iRecipeInputRecipeOutputEntry.getKey() + .getAmount(), + tStack)) + .itemOutputs(iRecipeInputRecipeOutputEntry.getValue().items.toArray(new ItemStack[0])) + .duration(15 * SECONDS) + .eut(2) + .addTo(aGTRecipeMap); + case "gt.recipe.thermalcentrifuge" -> GTValues.RA.stdBuilder() + .itemInputs( + GTUtility.copyAmount( + iRecipeInputRecipeOutputEntry.getKey() + .getAmount(), + tStack)) + .itemOutputs(iRecipeInputRecipeOutputEntry.getValue().items.toArray(new ItemStack[0])) + .duration(25 * SECONDS) + .eut(48) + .addTo(aGTRecipeMap); + } + } catch (Exception e) { + e.printStackTrace(GTLog.err); + } + } + if (aRemoveIC2Recipe) { + aRecipesToRemove.put(tStack, iRecipeInputRecipeOutputEntry.getValue().items.get(0)); + } + + } + + } + GTUtility.bulkRemoveSimpleIC2MachineRecipe(aRecipesToRemove, aIC2RecipeList); + } + + public static Map getExtractorRecipeList() { + try { + return ic2.api.recipe.Recipes.extractor.getRecipes(); + } catch (Throwable e) { + /* Do nothing */ + } + return emptyRecipeMap; + } + + public static Map getCompressorRecipeList() { + try { + return ic2.api.recipe.Recipes.compressor.getRecipes(); + } catch (Throwable e) { + /* Do nothing */ + } + return emptyRecipeMap; + } + + public static Map getMaceratorRecipeList() { + try { + return ic2.api.recipe.Recipes.macerator.getRecipes(); + } catch (Throwable e) { + /* Do nothing */ + } + return emptyRecipeMap; + } + + public static Map getThermalCentrifugeRecipeList() { + try { + return ic2.api.recipe.Recipes.centrifuge.getRecipes(); + } catch (Throwable e) { + /* Do nothing */ + } + return emptyRecipeMap; + } + + public static Map getOreWashingRecipeList() { + try { + return ic2.api.recipe.Recipes.oreWashing.getRecipes(); + } catch (Throwable e) { + /* Do nothing */ + } + return emptyRecipeMap; + } + + /** + * IC2-OreWasher Recipe. Overloads old Recipes automatically + */ + @Deprecated + public static boolean addOreWasherRecipe(ItemStack aInput, int[] aChances, int aWaterAmount, Object... aOutput) { + if (aInput == null || aOutput == null || aOutput.length == 0 || aOutput[0] == null) return false; + RA.stdBuilder() + .itemInputs(aInput) + .itemOutputs((ItemStack) aOutput[0], (ItemStack) aOutput[1], (ItemStack) aOutput[2]) + .outputChances(aChances) + .fluidInputs(GTModHandler.getWater(aWaterAmount)) + .duration(25 * SECONDS) + .eut(16) + .addTo(oreWasherRecipes); + + RA.stdBuilder() + .itemInputs(aInput) + .itemOutputs((ItemStack) aOutput[0], (ItemStack) aOutput[1], (ItemStack) aOutput[2]) + .outputChances(aChances) + .fluidInputs(GTModHandler.getDistilledWater(aWaterAmount / 5)) + .duration(15 * SECONDS) + .eut(16) + .addTo(oreWasherRecipes); + return true; + } + + public static void stopBufferingCraftingRecipes() { + sBufferCraftingRecipes = false; + + bulkRemoveRecipeByOutput(delayedRemovalByOutput); + bulkRemoveByRecipe(delayedRemovalByRecipe); + sBufferRecipeList.forEach(GameRegistry::addRecipe); + + delayedRemovalByOutput.clear(); + delayedRemovalByRecipe.clear(); + sBufferRecipeList.clear(); + } + + /** + * Shapeless Crafting Recipes. Deletes conflicting Recipes too. + */ + public static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, + int[] aEnchantmentLevelsAdded, Object[] aRecipe) { + return addCraftingRecipe( + aResult, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + false, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + aRecipe); + } + + /** + * Regular Crafting Recipes. Deletes conflicting Recipes too. + *

+ * You can insert instances of IItemContainer into the Recipe Input Array directly without having to call "get(1)" + * on them. + *

+ * Enums are automatically getting their "name()"-Method called in order to deliver an OreDict String. + *

+ * Lowercase Letters are reserved for Tools. They are as follows: + *

+ * 'b' ToolDictNames.craftingToolBlade 'c' ToolDictNames.craftingToolCrowbar, 'd' + * ToolDictNames.craftingToolScrewdriver, 'f' ToolDictNames.craftingToolFile, 'h' + * ToolDictNames.craftingToolHardHammer, 'i' ToolDictNames.craftingToolSolderingIron, 'j' + * ToolDictNames.craftingToolSolderingMetal, 'k' ToolDictNames.craftingToolKnive 'm' + * ToolDictNames.craftingToolMortar, 'p' ToolDictNames.craftingToolDrawplate, 'r' + * ToolDictNames.craftingToolSoftHammer, 's' ToolDictNames.craftingToolSaw, 'w' ToolDictNames.craftingToolWrench, + * 'x' ToolDictNames.craftingToolWireCutter, + */ + public static boolean addCraftingRecipe(ItemStack aResult, Object[] aRecipe) { + return addCraftingRecipe(aResult, 0, aRecipe); + } + + /** + * Regular Crafting Recipes. Deletes conflicting Recipes too. + *

+ * You can insert instances of IItemContainer into the Recipe Input Array directly without having to call "get(1)" + * on them. + *

+ * Enums are automatically getting their "name()"-Method called in order to deliver an OreDict String. + *

+ * Lowercase Letters are reserved for Tools. They are as follows: + *

+ * 'b' ToolDictNames.craftingToolBlade 'c' ToolDictNames.craftingToolCrowbar, 'd' + * ToolDictNames.craftingToolScrewdriver, 'f' ToolDictNames.craftingToolFile, 'h' + * ToolDictNames.craftingToolHardHammer, 'i' ToolDictNames.craftingToolSolderingIron, 'j' + * ToolDictNames.craftingToolSolderingMetal, 'k' ToolDictNames.craftingToolKnive 'm' + * ToolDictNames.craftingToolMortar, 'p' ToolDictNames.craftingToolDrawplate, 'r' + * ToolDictNames.craftingToolSoftHammer, 's' ToolDictNames.craftingToolSaw, 'w' ToolDictNames.craftingToolWrench, + * 'x' ToolDictNames.craftingToolWireCutter, + */ + public static boolean addCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) { + return addCraftingRecipe( + aResult, + new Enchantment[0], + new int[0], + (aBitMask & RecipeBits.MIRRORED) != 0, + (aBitMask & RecipeBits.BUFFERED) != 0, + (aBitMask & RecipeBits.KEEPNBT) != 0, + (aBitMask & RecipeBits.DISMANTLEABLE) != 0, + (aBitMask & RecipeBits.NOT_REMOVABLE) == 0, + (aBitMask & RecipeBits.REVERSIBLE) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_SHAPED_RECIPES) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_NATIVE_RECIPES) != 0, + (aBitMask & RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS) == 0, + (aBitMask & RecipeBits.ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT) != 0, + (aBitMask & RecipeBits.ONLY_ADD_IF_RESULT_IS_NOT_NULL) != 0, + aRecipe); + } + + public static boolean addMachineCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe, + int machineTier) { + if (aRecipe != null) { + for (int i = 3; i < aRecipe.length; i++) { + if (!(aRecipe[i] instanceof MTEBasicMachineWithRecipe.X)) continue; + + // spotless:off + aRecipe[i] = switch ((MTEBasicMachineWithRecipe.X) aRecipe[i]) { + case CIRCUIT -> Tier.ELECTRIC[machineTier].mManagingObject; + case BETTER_CIRCUIT -> Tier.ELECTRIC[machineTier].mBetterManagingObject; + case HULL -> Tier.ELECTRIC[machineTier].mHullObject; + case WIRE -> Tier.ELECTRIC[machineTier].mConductingObject; + case WIRE4 -> Tier.ELECTRIC[machineTier].mLargerConductingObject; + case STICK_DISTILLATION -> OrePrefixes.stick.get(Materials.Blaze); + + case GLASS -> switch (machineTier) { + case 0, 1, 2, 3 -> new ItemStack(Blocks.glass, 1, W); + case 4, 5, 6, 7, 8 -> "blockGlass" + VN[machineTier]; + default -> "blockGlass" + VN[8]; + }; + + case PLATE -> switch (machineTier) { + case 0, 1 -> OrePrefixes.plate.get(Materials.Steel); + case 2 -> OrePrefixes.plate.get(Materials.Aluminium); + case 3 -> OrePrefixes.plate.get(Materials.StainlessSteel); + case 4 -> OrePrefixes.plate.get(Materials.Titanium); + case 5 -> OrePrefixes.plate.get(Materials.TungstenSteel); + case 6 -> OrePrefixes.plate.get(Materials.HSSG); + case 7 -> OrePrefixes.plate.get(Materials.HSSE); + default -> OrePrefixes.plate.get(Materials.Neutronium); + }; + + case PIPE -> switch (machineTier) { + case 0, 1 -> OrePrefixes.pipeMedium.get(Materials.Bronze); + case 2 -> OrePrefixes.pipeMedium.get(Materials.Steel); + case 3 -> OrePrefixes.pipeMedium.get(Materials.StainlessSteel); + case 4 -> OrePrefixes.pipeMedium.get(Materials.Titanium); + case 5 -> OrePrefixes.pipeMedium.get(Materials.TungstenSteel); + case 6 -> OrePrefixes.pipeSmall.get(Materials.Ultimate); + case 7 -> OrePrefixes.pipeMedium.get(Materials.Ultimate); + case 8 -> OrePrefixes.pipeLarge.get(Materials.Ultimate); + default -> OrePrefixes.pipeHuge.get(Materials.Ultimate); + }; + + case COIL_HEATING -> switch (machineTier) { + case 0, 1 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); + case 2 -> OrePrefixes.wireGt02.get(Materials.Cupronickel); + case 3 -> OrePrefixes.wireGt02.get(Materials.Kanthal); + case 4 -> OrePrefixes.wireGt02.get(Materials.Nichrome); + case 5 -> OrePrefixes.wireGt02.get(Materials.TPV); + case 6 -> OrePrefixes.wireGt02.get(Materials.HSSG); + case 7 -> OrePrefixes.wireGt02.get(Materials.Naquadah); + case 8 -> OrePrefixes.wireGt02.get(Materials.NaquadahAlloy); + case 9 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); + default -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); + }; + + case COIL_HEATING_DOUBLE -> switch (machineTier) { + case 0, 1 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); + case 2 -> OrePrefixes.wireGt04.get(Materials.Cupronickel); + case 3 -> OrePrefixes.wireGt04.get(Materials.Kanthal); + case 4 -> OrePrefixes.wireGt04.get(Materials.Nichrome); + case 5 -> OrePrefixes.wireGt04.get(Materials.TPV); + case 6 -> OrePrefixes.wireGt04.get(Materials.HSSG); + case 7 -> OrePrefixes.wireGt04.get(Materials.Naquadah); + case 8 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); + case 9 -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); + default -> OrePrefixes.wireGt16.get(Materials.NaquadahAlloy); + }; + + case STICK_MAGNETIC -> switch (machineTier) { + case 0, 1 -> OrePrefixes.stick.get(Materials.IronMagnetic); + case 2, 3 -> OrePrefixes.stick.get(Materials.SteelMagnetic); + case 4, 5 -> OrePrefixes.stick.get(Materials.NeodymiumMagnetic); + case 6, 7, 8, 9 -> OrePrefixes.stick.get(Materials.SamariumMagnetic); + default -> OrePrefixes.stick.get(Materials.TengamAttuned); + }; + + case STICK_ELECTROMAGNETIC -> switch (machineTier) { + case 0, 1 -> OrePrefixes.stick.get(Materials.AnyIron); + case 2, 3 -> OrePrefixes.stick.get(Materials.Steel); + case 4 -> OrePrefixes.stick.get(Materials.Neodymium); + default -> OrePrefixes.stick.get(Materials.VanadiumGallium); + }; + + case COIL_ELECTRIC -> switch (machineTier) { + case 0 -> OrePrefixes.wireGt01.get(Materials.Lead); + case 1 -> OrePrefixes.wireGt02.get(Materials.Tin); + case 2 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); + case 3 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); + case 4 -> OrePrefixes.wireGt08.get(Materials.AnnealedCopper); + case 5 -> OrePrefixes.wireGt16.get(Materials.AnnealedCopper); + case 6 -> OrePrefixes.wireGt04.get(Materials.YttriumBariumCuprate); + case 7 -> OrePrefixes.wireGt08.get(Materials.Iridium); + default -> OrePrefixes.wireGt16.get(Materials.Osmium); + }; + + case ROBOT_ARM -> switch (machineTier) { + case 0, 1 -> ItemList.Robot_Arm_LV; + case 2 -> ItemList.Robot_Arm_MV; + case 3 -> ItemList.Robot_Arm_HV; + case 4 -> ItemList.Robot_Arm_EV; + case 5 -> ItemList.Robot_Arm_IV; + case 6 -> ItemList.Robot_Arm_LuV; + case 7 -> ItemList.Robot_Arm_ZPM; + case 8 -> ItemList.Robot_Arm_UV; + case 9 -> ItemList.Robot_Arm_UHV; + case 10 -> ItemList.Robot_Arm_UEV; + case 11 -> ItemList.Robot_Arm_UIV; + case 12 -> ItemList.Robot_Arm_UMV; + case 13 -> ItemList.Robot_Arm_UXV; + default -> ItemList.Robot_Arm_MAX; + }; + + case PUMP -> switch (machineTier) { + case 0, 1 -> ItemList.Electric_Pump_LV; + case 2 -> ItemList.Electric_Pump_MV; + case 3 -> ItemList.Electric_Pump_HV; + case 4 -> ItemList.Electric_Pump_EV; + case 5 -> ItemList.Electric_Pump_IV; + case 6 -> ItemList.Electric_Pump_LuV; + case 7 -> ItemList.Electric_Pump_ZPM; + case 8 -> ItemList.Electric_Pump_UV; + case 9 -> ItemList.Electric_Pump_UHV; + case 10 -> ItemList.Electric_Pump_UEV; + case 11 -> ItemList.Electric_Pump_UIV; + case 12 -> ItemList.Electric_Pump_UMV; + case 13 -> ItemList.Electric_Pump_UXV; + default -> ItemList.Electric_Pump_MAX; + }; + + case MOTOR -> switch (machineTier) { + case 0, 1 -> ItemList.Electric_Motor_LV; + case 2 -> ItemList.Electric_Motor_MV; + case 3 -> ItemList.Electric_Motor_HV; + case 4 -> ItemList.Electric_Motor_EV; + case 5 -> ItemList.Electric_Motor_IV; + case 6 -> ItemList.Electric_Motor_LuV; + case 7 -> ItemList.Electric_Motor_ZPM; + case 8 -> ItemList.Electric_Motor_UV; + case 9 -> ItemList.Electric_Motor_UHV; + case 10 -> ItemList.Electric_Motor_UEV; + case 11 -> ItemList.Electric_Motor_UIV; + case 12 -> ItemList.Electric_Motor_UMV; + case 13 -> ItemList.Electric_Motor_UXV; + default -> ItemList.Electric_Motor_MAX; + }; + + case PISTON -> switch (machineTier) { + case 0, 1 -> ItemList.Electric_Piston_LV; + case 2 -> ItemList.Electric_Piston_MV; + case 3 -> ItemList.Electric_Piston_HV; + case 4 -> ItemList.Electric_Piston_EV; + case 5 -> ItemList.Electric_Piston_IV; + case 6 -> ItemList.Electric_Piston_LuV; + case 7 -> ItemList.Electric_Piston_ZPM; + case 8 -> ItemList.Electric_Piston_UV; + case 9 -> ItemList.Electric_Piston_UHV; + case 10 -> ItemList.Electric_Piston_UEV; + case 11 -> ItemList.Electric_Piston_UIV; + case 12 -> ItemList.Electric_Piston_UMV; + case 13 -> ItemList.Electric_Piston_UXV; + default -> ItemList.Electric_Piston_MAX; + }; + + case CONVEYOR -> switch (machineTier) { + case 0, 1 -> ItemList.Conveyor_Module_LV; + case 2 -> ItemList.Conveyor_Module_MV; + case 3 -> ItemList.Conveyor_Module_HV; + case 4 -> ItemList.Conveyor_Module_EV; + case 5 -> ItemList.Conveyor_Module_IV; + case 6 -> ItemList.Conveyor_Module_LuV; + case 7 -> ItemList.Conveyor_Module_ZPM; + case 8 -> ItemList.Conveyor_Module_UV; + case 9 -> ItemList.Conveyor_Module_UHV; + case 10 -> ItemList.Conveyor_Module_UEV; + case 11 -> ItemList.Conveyor_Module_UIV; + case 12 -> ItemList.Conveyor_Module_UMV; + case 13 -> ItemList.Conveyor_Module_UXV; + default -> ItemList.Conveyor_Module_MAX; + }; + + case EMITTER -> switch (machineTier) { + case 0, 1 -> ItemList.Emitter_LV; + case 2 -> ItemList.Emitter_MV; + case 3 -> ItemList.Emitter_HV; + case 4 -> ItemList.Emitter_EV; + case 5 -> ItemList.Emitter_IV; + case 6 -> ItemList.Emitter_LuV; + case 7 -> ItemList.Emitter_ZPM; + case 8 -> ItemList.Emitter_UV; + case 9 -> ItemList.Emitter_UHV; + case 10 -> ItemList.Emitter_UEV; + case 11 -> ItemList.Emitter_UIV; + case 12 -> ItemList.Emitter_UMV; + case 13 -> ItemList.Emitter_UXV; + default -> ItemList.Emitter_MAX; + }; + + case SENSOR -> switch (machineTier) { + case 0, 1 -> ItemList.Sensor_LV; + case 2 -> ItemList.Sensor_MV; + case 3 -> ItemList.Sensor_HV; + case 4 -> ItemList.Sensor_EV; + case 5 -> ItemList.Sensor_IV; + case 6 -> ItemList.Sensor_LuV; + case 7 -> ItemList.Sensor_ZPM; + case 8 -> ItemList.Sensor_UV; + case 9 -> ItemList.Sensor_UHV; + case 10 -> ItemList.Sensor_UEV; + case 11 -> ItemList.Sensor_UIV; + case 12 -> ItemList.Sensor_UMV; + case 13 -> ItemList.Sensor_UXV; + default -> ItemList.Sensor_MAX; + }; + + case FIELD_GENERATOR -> switch (machineTier) { + case 0, 1 -> ItemList.Field_Generator_LV; + case 2 -> ItemList.Field_Generator_MV; + case 3 -> ItemList.Field_Generator_HV; + case 4 -> ItemList.Field_Generator_EV; + case 5 -> ItemList.Field_Generator_IV; + case 6 -> ItemList.Field_Generator_LuV; + case 7 -> ItemList.Field_Generator_ZPM; + case 8 -> ItemList.Field_Generator_UV; + case 9 -> ItemList.Field_Generator_UHV; + case 10 -> ItemList.Field_Generator_UEV; + case 11 -> ItemList.Field_Generator_UIV; + case 12 -> ItemList.Field_Generator_UMV; + case 13 -> ItemList.Field_Generator_UXV; + default -> ItemList.Field_Generator_MAX; + }; + + case ROTOR -> switch (machineTier) { + case 0, 1 -> OrePrefixes.rotor.get(Materials.Tin); + case 2 -> OrePrefixes.rotor.get(Materials.Bronze); + case 3 -> OrePrefixes.rotor.get(Materials.Steel); + case 4 -> OrePrefixes.rotor.get(Materials.StainlessSteel); + case 5 -> OrePrefixes.rotor.get(Materials.TungstenSteel); + case 6 -> OrePrefixes.rotor.get(ExternalMaterials.getRhodiumPlatedPalladium()); + case 7 -> OrePrefixes.rotor.get(Materials.Iridium); + default -> OrePrefixes.rotor.get(Materials.Osmium); + }; + + default -> throw new IllegalArgumentException("MISSING TIER MAPPING FOR: " + aRecipe[i] + " AT TIER " + machineTier); + }; + // spotless:on + } + + if (!GTModHandler.addCraftingRecipe( + aResult, + GTModHandler.RecipeBits.DISMANTLEABLE | GTModHandler.RecipeBits.BUFFERED + | GTModHandler.RecipeBits.NOT_REMOVABLE + | GTModHandler.RecipeBits.REVERSIBLE, + aRecipe)) { + throw new IllegalArgumentException("INVALID CRAFTING RECIPE FOR: " + aResult.getDisplayName()); + } + } + return true; + } + + /** + * Internal realisation of the Crafting Recipe adding Process. + */ + private static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, + int[] aEnchantmentLevelsAdded, boolean aMirrored, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable, + boolean aRemovable, boolean aReversible, boolean aRemoveAllOthersWithSameOutput, + boolean aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, boolean aRemoveAllOtherShapedsWithSameOutput, + boolean aRemoveAllOtherNativeRecipes, boolean aCheckForCollisions, + boolean aOnlyAddIfThereIsAnyRecipeOutputtingThis, boolean aOnlyAddIfResultIsNotNull, Object[] aRecipe) { + + aResult = GTOreDictUnificator.get(true, aResult); + if (aOnlyAddIfResultIsNotNull && aResult == null) return false; + if (aResult != null && Items.feather.getDamage(aResult) == W) Items.feather.setDamage(aResult, 0); + if (aRecipe == null || aRecipe.length == 0) return false; + + // The renamed variable clarifies what's happening + // noinspection UnnecessaryLocalVariable + boolean tDoWeCareIfThereWasARecipe = aOnlyAddIfThereIsAnyRecipeOutputtingThis; + boolean tThereWasARecipe = false; + + for (byte i = 0; i < aRecipe.length; i++) { + if (aRecipe[i] instanceof IItemContainer) aRecipe[i] = ((IItemContainer) aRecipe[i]).get(1); + else if (aRecipe[i] instanceof Enum) aRecipe[i] = ((Enum) aRecipe[i]).name(); + else if (!(aRecipe[i] == null || aRecipe[i] instanceof ItemStack + || aRecipe[i] instanceof ItemData + || aRecipe[i] instanceof String + || aRecipe[i] instanceof Character)) aRecipe[i] = aRecipe[i].toString(); + } + + try { + StringBuilder shape = new StringBuilder(E); + int idx = 0; + if (aRecipe[idx] instanceof Boolean) { + throw new IllegalArgumentException(); + } + + ArrayList tRecipeList = new ArrayList<>(Arrays.asList(aRecipe)); + + while (aRecipe[idx] instanceof String) { + StringBuilder s = new StringBuilder((String) aRecipe[idx++]); + shape.append(s); + while (s.length() < 3) s.append(" "); + if (s.length() > 3) throw new IllegalArgumentException(); + + for (char c : s.toString() + .toCharArray()) { + switch (c) { + case 'b' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolBlade.name()); + } + case 'c' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolCrowbar.name()); + } + case 'd' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolScrewdriver.name()); + } + case 'f' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolFile.name()); + } + case 'h' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolHardHammer.name()); + } + case 'i' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSolderingIron.name()); + } + case 'j' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSolderingMetal.name()); + } + case 'k' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolKnife.name()); + } + case 'm' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolMortar.name()); + } + case 'p' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolDrawplate.name()); + } + case 'r' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSoftHammer.name()); + } + case 's' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSaw.name()); + } + case 'w' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolWrench.name()); + } + case 'x' -> { + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolWireCutter.name()); + } + } + } + } + + aRecipe = tRecipeList.toArray(); + + if (aRecipe[idx] instanceof Boolean) { + idx++; + } + Map tItemStackMap = new HashMap<>(); + Map tItemDataMap = new HashMap<>(); + tItemStackMap.put(' ', null); + + boolean tRemoveRecipe = true; + + for (; idx < aRecipe.length; idx += 2) { + if (aRecipe[idx] == null || aRecipe[idx + 1] == null) { + if (D1) { + GTLog.err.println( + "WARNING: Missing Item for shaped Recipe: " + + (aResult == null ? "null" : aResult.getDisplayName())); + for (Object tContent : aRecipe) GTLog.err.println(tContent); + } + return false; + } + Character chr = (Character) aRecipe[idx]; + Object in = aRecipe[idx + 1]; + if (in instanceof ItemStack is) { + tItemStackMap.put(chr, GTUtility.copyOrNull(is)); + tItemDataMap.put(chr, GTOreDictUnificator.getItemData(is)); + } else if (in instanceof ItemData) { + String tString = in.toString(); + switch (tString) { + case "plankWood" -> tItemDataMap.put(chr, new ItemData(Materials.Wood, M)); + case "stoneNetherrack" -> tItemDataMap.put(chr, new ItemData(Materials.Netherrack, M)); + case "stoneObsidian" -> tItemDataMap.put(chr, new ItemData(Materials.Obsidian, M)); + case "stoneEndstone" -> tItemDataMap.put(chr, new ItemData(Materials.Endstone, M)); + default -> tItemDataMap.put(chr, (ItemData) in); + } + ItemStack tStack = GTOreDictUnificator.getFirstOre(in, 1); + if (tStack == null) tRemoveRecipe = false; + else tItemStackMap.put(chr, tStack); + in = aRecipe[idx + 1] = in.toString(); + } else if (in instanceof String) { + if (in.equals(OreDictNames.craftingChest.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Wood, M * 8)); + else if (in.equals(OreDictNames.craftingBook.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Paper, M * 3)); + else if (in.equals(OreDictNames.craftingPiston.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Stone, M * 4, Materials.Wood, M * 3)); + else if (in.equals(OreDictNames.craftingFurnace.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Stone, M * 8)); + else if (in.equals(OreDictNames.craftingIndustrialDiamond.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Diamond, M)); + else if (in.equals(OreDictNames.craftingAnvil.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Iron, M * 10)); + ItemStack tStack = GTOreDictUnificator.getFirstOre(in, 1); + if (tStack == null) tRemoveRecipe = false; + else tItemStackMap.put(chr, tStack); + } else { + throw new IllegalArgumentException(); + } + } + + if (aReversible && aResult != null) { + ItemData[] tData = new ItemData[9]; + int x = -1; + for (char chr : shape.toString() + .toCharArray()) tData[++x] = tItemDataMap.get(chr); + if (GTUtility.arrayContainsNonNull(tData)) + GTOreDictUnificator.addItemData(aResult, new ItemData(tData)); + } + + if (aCheckForCollisions && tRemoveRecipe) { + ItemStack[] tRecipe = new ItemStack[9]; + int x = -1; + for (char chr : shape.toString() + .toCharArray()) { + tRecipe[++x] = tItemStackMap.get(chr); + if (tRecipe[x] != null && Items.feather.getDamage(tRecipe[x]) == W) + Items.feather.setDamage(tRecipe[x], 0); + } + if (tDoWeCareIfThereWasARecipe || !aBuffered) tThereWasARecipe = removeRecipe(tRecipe) != null; + else removeRecipeDelayed(tRecipe); + } + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + + if (aResult == null || aResult.stackSize <= 0) return false; + + if (aRemoveAllOthersWithSameOutput || aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT + || aRemoveAllOtherShapedsWithSameOutput + || aRemoveAllOtherNativeRecipes) { + if (tDoWeCareIfThereWasARecipe || !aBuffered) tThereWasARecipe = removeRecipeByOutput( + aResult, + !aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, + aRemoveAllOtherShapedsWithSameOutput, + aRemoveAllOtherNativeRecipes) || tThereWasARecipe; + else removeRecipeByOutputDelayed(aResult); + } + + if (aOnlyAddIfThereIsAnyRecipeOutputtingThis && !tDoWeCareIfThereWasARecipe && !tThereWasARecipe) { + ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + int tList_sS = tList.size(); + for (int i = 0; i < tList_sS && !tThereWasARecipe; i++) { + IRecipe tRecipe = tList.get(i); + if (sSpecialRecipeClasses.contains( + tRecipe.getClass() + .getName())) + continue; + if (GTUtility.areStacksEqual(GTOreDictUnificator.get(tRecipe.getRecipeOutput()), aResult, true)) { + tList.remove(i--); + tList_sS = tList.size(); + tThereWasARecipe = true; + } + } + } + + if (Items.feather.getDamage(aResult) == W || Items.feather.getDamage(aResult) < 0) + Items.feather.setDamage(aResult, 0); + + GTUtility.updateItemStack(aResult); + + if (tThereWasARecipe || !aOnlyAddIfThereIsAnyRecipeOutputtingThis) { + if (sBufferCraftingRecipes && aBuffered) sBufferRecipeList.add( + new GTShapedRecipe( + GTUtility.copyOrNull(aResult), + aDismantleable, + aRemovable, + aKeepNBT, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + aRecipe).setMirrored(aMirrored)); + else GameRegistry.addRecipe( + new GTShapedRecipe( + GTUtility.copyOrNull(aResult), + aDismantleable, + aRemovable, + aKeepNBT, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + aRecipe).setMirrored(aMirrored)); + } + return true; + } + + /** + * Shapeless Crafting Recipes. Deletes conflicting Recipes too. + */ + public static boolean addShapelessEnchantingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, + int[] aEnchantmentLevelsAdded, Object[] aRecipe) { + return addShapelessCraftingRecipe( + aResult, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + true, + false, + false, + false, + aRecipe); + } + + /** + * Shapeless Crafting Recipes. Deletes conflicting Recipes too. + */ + public static boolean addShapelessCraftingRecipe(ItemStack aResult, Object[] aRecipe) { + return addShapelessCraftingRecipe( + aResult, + RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS | RecipeBits.BUFFERED, + aRecipe); + } + + /** + * Shapeless Crafting Recipes. Deletes conflicting Recipes too. + */ + public static boolean addShapelessCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) { + return addShapelessCraftingRecipe( + aResult, + new Enchantment[0], + new int[0], + (aBitMask & RecipeBits.BUFFERED) != 0, + (aBitMask & RecipeBits.KEEPNBT) != 0, + (aBitMask & RecipeBits.DISMANTLEABLE) != 0, + (aBitMask & RecipeBits.NOT_REMOVABLE) == 0, + aRecipe); + } + + /** + * Shapeless Crafting Recipes. Deletes conflicting Recipes too. + */ + private static boolean addShapelessCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, + int[] aEnchantmentLevelsAdded, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable, boolean aRemovable, + Object[] aRecipe) { + aResult = GTOreDictUnificator.get(true, aResult); + if (aRecipe == null || aRecipe.length == 0) return false; + for (byte i = 0; i < aRecipe.length; i++) { + if (aRecipe[i] instanceof IItemContainer) aRecipe[i] = ((IItemContainer) aRecipe[i]).get(1); + else if (aRecipe[i] instanceof Enum) aRecipe[i] = ((Enum) aRecipe[i]).name(); + else if (!(aRecipe[i] == null || aRecipe[i] instanceof ItemStack + || aRecipe[i] instanceof String + || aRecipe[i] instanceof Character)) aRecipe[i] = aRecipe[i].toString(); + } + try { + ItemStack[] tRecipe = new ItemStack[9]; + int i = 0; + for (Object tObject : aRecipe) { + if (tObject == null) { + if (D1) GTLog.err.println( + "WARNING: Missing Item for shapeless Recipe: " + + (aResult == null ? "null" : aResult.getDisplayName())); + for (Object tContent : aRecipe) GTLog.err.println(tContent); + return false; + } + if (tObject instanceof ItemStack) { + tRecipe[i] = (ItemStack) tObject; + } else if (tObject instanceof String) { + tRecipe[i] = GTOreDictUnificator.getFirstOre(tObject, 1); + if (tRecipe[i] == null) break; + } + i++; + } + if (sBufferCraftingRecipes && aBuffered) removeRecipeDelayed(tRecipe); + else removeRecipe(tRecipe); + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + + if (aResult == null || aResult.stackSize <= 0) return false; + + if (Items.feather.getDamage(aResult) == W || Items.feather.getDamage(aResult) < 0) + Items.feather.setDamage(aResult, 0); + + GTUtility.updateItemStack(aResult); + + if (sBufferCraftingRecipes && aBuffered) sBufferRecipeList.add( + new GTShapelessRecipe( + GTUtility.copyOrNull(aResult), + aDismantleable, + aRemovable, + aKeepNBT, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + aRecipe)); + else GameRegistry.addRecipe( + new GTShapelessRecipe( + GTUtility.copyOrNull(aResult), + aDismantleable, + aRemovable, + aKeepNBT, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + aRecipe)); + return true; + } + + /** + * Removes a Smelting Recipe + */ + public static boolean removeFurnaceSmelting(ItemStack aInput) { + if (aInput != null) { + for (ItemStack tInput : FurnaceRecipes.smelting() + .getSmeltingList() + .keySet()) { + if (GTUtility.isStackValid(tInput) && GTUtility.areStacksEqual(aInput, tInput, true)) { + FurnaceRecipes.smelting() + .getSmeltingList() + .remove(tInput); + return true; + } + } + } + return false; + } + + /** + * Removes all matching Smelting Recipes by output + */ + public static boolean removeFurnaceSmeltingByOutput(ItemStack aOutput) { + if (aOutput != null) { + return FurnaceRecipes.smelting() + .getSmeltingList() + .values() + .removeIf( + tOutput -> GTUtility.isStackValid(tOutput) && GTUtility.areStacksEqual(aOutput, tOutput, true)); + } + return false; + } + + /** + * Removes a Crafting Recipe and gives you the former output of it. + * + * @param aRecipe The content of the Crafting Grid as ItemStackArray with length 9 + * @return the output of the old Recipe or null if there was nothing. + */ + public static ItemStack removeRecipe(ItemStack... aRecipe) { + if (aRecipe == null) return null; + if (Arrays.stream(aRecipe) + .noneMatch(Objects::nonNull)) return null; + + ItemStack rReturn = null; + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { + + @Override + public boolean canInteractWith(EntityPlayer player) { + return false; + } + }, 3, 3); + for (int i = 0; i < aRecipe.length && i < 9; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); + ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + int tList_sS = tList.size(); + try { + for (int i = 0; i < tList_sS; i++) { + for (; i < tList_sS; i++) { + if ((!(tList.get(i) instanceof IGTCraftingRecipe) + || ((IGTCraftingRecipe) tList.get(i)).isRemovable()) && tList.get(i) + .matches(aCrafting, DW)) { + rReturn = tList.get(i) + .getCraftingResult(aCrafting); + if (rReturn != null) tList.remove(i--); + tList_sS = tList.size(); + } + } + } + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + return rReturn; + } + + public static void removeRecipeDelayed(ItemStack... aRecipe) { + if (!sBufferCraftingRecipes) { + removeRecipe(aRecipe); + return; + } + + if (aRecipe == null) return; + if (Arrays.stream(aRecipe) + .noneMatch(Objects::nonNull)) return; + + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { + + @Override + public boolean canInteractWith(EntityPlayer player) { + return false; + } + }, 3, 3); + for (int i = 0; i < aRecipe.length && i < 9; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); + delayedRemovalByRecipe.add(aCrafting); + } + + public static void bulkRemoveByRecipe(List toRemove) { + ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + GT_FML_LOGGER.info("BulkRemoveByRecipe: tList: " + tList.size() + " toRemove: " + toRemove.size()); + + Set tListToRemove = tList.parallelStream() + .filter(tRecipe -> { + if ((tRecipe instanceof IGTCraftingRecipe) && !((IGTCraftingRecipe) tRecipe).isRemovable()) + return false; + return toRemove.stream() + .anyMatch(aCrafting -> tRecipe.matches(aCrafting, DW)); + }) + .collect(Collectors.toSet()); + + tList.removeIf(tListToRemove::contains); + } + + public static boolean removeRecipeByOutputDelayed(ItemStack aOutput) { + if (sBufferCraftingRecipes) return delayedRemovalByOutput.add(aOutput); + else return removeRecipeByOutput(aOutput); + } + + public static boolean removeRecipeByOutputDelayed(ItemStack aOutput, boolean aIgnoreNBT, + boolean aNotRemoveShapelessRecipes, boolean aOnlyRemoveNativeHandlers) { + if (sBufferCraftingRecipes && (aIgnoreNBT && !aNotRemoveShapelessRecipes && !aOnlyRemoveNativeHandlers)) + // Too lazy to handle deferred versions of the parameters that aren't used very often + return delayedRemovalByOutput.add(aOutput); + else return removeRecipeByOutput(aOutput, aIgnoreNBT, aNotRemoveShapelessRecipes, aOnlyRemoveNativeHandlers); + } + + public static boolean removeRecipeByOutput(ItemStack aOutput) { + return removeRecipeByOutput(aOutput, true, false, false); + } + + /** + * Removes a Crafting Recipe. + * + * @param aOutput The output of the Recipe. + * @return if it has removed at least one Recipe. + */ + public static boolean removeRecipeByOutput(ItemStack aOutput, boolean aIgnoreNBT, + boolean aNotRemoveShapelessRecipes, boolean aOnlyRemoveNativeHandlers) { + if (aOutput == null) return false; + boolean rReturn = false; + final ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + aOutput = GTOreDictUnificator.get(aOutput); + int tList_sS = tList.size(); + for (int i = 0; i < tList_sS; i++) { + final IRecipe tRecipe = tList.get(i); + if (aNotRemoveShapelessRecipes + && (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe)) continue; + if (aOnlyRemoveNativeHandlers) { + if (!sNativeRecipeClasses.contains( + tRecipe.getClass() + .getName())) + continue; + } else { + if (sSpecialRecipeClasses.contains( + tRecipe.getClass() + .getName())) + continue; + } + ItemStack tStack = tRecipe.getRecipeOutput(); + if ((!(tRecipe instanceof IGTCraftingRecipe) || ((IGTCraftingRecipe) tRecipe).isRemovable()) + && GTUtility.areStacksEqual(GTOreDictUnificator.get(tStack), aOutput, aIgnoreNBT)) { + tList.remove(i--); + tList_sS = tList.size(); + rReturn = true; + } + } + return rReturn; + } + + public static boolean bulkRemoveRecipeByOutput(List toRemove) { + ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + + Set setToRemove = toRemove.parallelStream() + .map(GTOreDictUnificator::get_nocopy) + .collect(Collectors.toSet()); + + GT_FML_LOGGER.info("BulkRemoveRecipeByOutput: tList: " + tList.size() + " setToRemove: " + setToRemove.size()); + + Set tListToRemove = tList.parallelStream() + .filter(tRecipe -> { + if ((tRecipe instanceof IGTCraftingRecipe) && !((IGTCraftingRecipe) tRecipe).isRemovable()) + return false; + if (sSpecialRecipeClasses.contains( + tRecipe.getClass() + .getName())) + return false; + final ItemStack tStack = GTOreDictUnificator.get_nocopy(tRecipe.getRecipeOutput()); + return setToRemove.stream() + .anyMatch(aOutput -> GTUtility.areStacksEqual(tStack, aOutput, true)); + }) + .collect(Collectors.toSet()); + + tList.removeIf(tListToRemove::contains); + return true; + } + + /** + * Checks all Crafting Handlers for Recipe Output Used for the Autocrafting Table + */ + public static ItemStack getAllRecipeOutput(World aWorld, ItemStack... aRecipe) { + if (aRecipe == null || aRecipe.length == 0) return null; + + if (aWorld == null) aWorld = DW; + + boolean temp = false; + for (ItemStack itemStack : aRecipe) { + if (itemStack != null) { + temp = true; + break; + } + } + if (!temp) return null; + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { + + @Override + public boolean canInteractWith(EntityPlayer player) { + return false; + } + }, 3, 3); + for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); + List tList = CraftingManager.getInstance() + .getRecipeList(); + synchronized (sAllRecipeList) { + if (sAllRecipeList.size() != tList.size()) { + sAllRecipeList.clear(); + sAllRecipeList.addAll(tList); + } + for (int i = 0, j = sAllRecipeList.size(); i < j; i++) { + IRecipe tRecipe = sAllRecipeList.get(i); + if (tRecipe.matches(aCrafting, aWorld)) { + if (i > 10) { + sAllRecipeList.remove(i); + sAllRecipeList.add(i - 10, tRecipe); + } + return tRecipe.getCraftingResult(aCrafting); + } + } + } + + int tIndex = 0; + ItemStack tStack1 = null, tStack2 = null; + for (int i = 0, j = aCrafting.getSizeInventory(); i < j; i++) { + ItemStack tStack = aCrafting.getStackInSlot(i); + if (tStack != null) { + if (tIndex == 0) tStack1 = tStack; + if (tIndex == 1) tStack2 = tStack; + tIndex++; + } + } + + if (tIndex == 2 && tStack2 != null) { + if (tStack1.getItem() == tStack2.getItem() && tStack1.stackSize == 1 + && tStack2.stackSize == 1 + && tStack1.getItem() + .isRepairable()) { + int tNewDamage = tStack1.getMaxDamage() + tStack1.getItemDamage() + - tStack2.getItemDamage() + + tStack1.getMaxDamage() / 20; + return new ItemStack(tStack1.getItem(), 1, Math.max(tNewDamage, 0)); + } + } + + return null; + } + + /** + * Gives you a copy of the Output from a Crafting Recipe Used for Recipe Detection. + */ + public static ItemStack getRecipeOutput(ItemStack... aRecipe) { + return getRecipeOutput(false, true, aRecipe); + } + + public static ItemStack getRecipeOutputNoOreDict(ItemStack... aRecipe) { + return getRecipeOutput(false, false, aRecipe); + } + + public static ItemStack getRecipeOutput(boolean aUncopiedStack, ItemStack... aRecipe) { + return getRecipeOutput(aUncopiedStack, true, aRecipe); + } + + /** + * Gives you a copy of the Output from a Crafting Recipe Used for Recipe Detection. + */ + public static ItemStack getRecipeOutput(boolean aUncopiedStack, boolean allowOreDict, ItemStack... aRecipe) { + if (aRecipe == null || Arrays.stream(aRecipe) + .noneMatch(Objects::nonNull)) return null; + + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { + + @Override + public boolean canInteractWith(EntityPlayer player) { + return false; + } + }, 3, 3); + for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); + ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + boolean found = false; + + for (IRecipe iRecipe : tList) { + found = false; + if (!allowOreDict && iRecipe instanceof ShapedOreRecipe) continue; + + try { + found = iRecipe.matches(aCrafting, DW); + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + if (found) { + ItemStack tOutput = aUncopiedStack ? iRecipe.getRecipeOutput() : iRecipe.getCraftingResult(aCrafting); + if (tOutput == null || tOutput.stackSize <= 0) { + // Seriously, who would ever do that shit? + if (!GregTechAPI.sPostloadFinished) throw new GTItsNotMyFaultException( + "Seems another Mod added a Crafting Recipe with null Output. Tell the Developer of said Mod to fix that."); + } else { + if (aUncopiedStack) return tOutput; + return GTUtility.copyOrNull(tOutput); + } + } + } + return null; + } + + /** + * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for + * example This also removes old Recipes from the List. + */ + public static List getVanillyToolRecipeOutputs(ItemStack... aRecipe) { + if (!GregTechAPI.sPostloadStarted || GregTechAPI.sPostloadFinished) sSingleNonBlockDamagableRecipeList.clear(); + if (sSingleNonBlockDamagableRecipeList.isEmpty()) { + for (IRecipe tRecipe : CraftingManager.getInstance() + .getRecipeList()) { + ItemStack tStack = tRecipe.getRecipeOutput(); + if (GTUtility.isStackValid(tStack) && tStack.getMaxStackSize() == 1 + && tStack.getMaxDamage() > 0 + && !(tStack.getItem() instanceof ItemBlock) + && !(tStack.getItem() instanceof IReactorComponent) + && !isElectricItem(tStack) + && !GTUtility.isStackInList(tStack, sNonReplaceableItems)) { + if (!(tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe)) { + if (tRecipe instanceof ShapedOreRecipe) { + boolean temp = true; + for (Object tObject : ((ShapedOreRecipe) tRecipe).getInput()) if (tObject != null) { + if (tObject instanceof ItemStack && (((ItemStack) tObject).getItem() == null + || ((ItemStack) tObject).getMaxStackSize() < 2 + || ((ItemStack) tObject).getMaxDamage() > 0 + || ((ItemStack) tObject).getItem() instanceof ItemBlock)) { + temp = false; + break; + } + if (tObject instanceof List && ((List) tObject).isEmpty()) { + temp = false; + break; + } + } + if (temp) sSingleNonBlockDamagableRecipeList.add(tRecipe); + } else if (tRecipe instanceof ShapedRecipes) { + boolean temp = true; + for (ItemStack tObject : ((ShapedRecipes) tRecipe).recipeItems) { + if (tObject != null && (tObject.getItem() == null || tObject.getMaxStackSize() < 2 + || tObject.getMaxDamage() > 0 + || tObject.getItem() instanceof ItemBlock)) { + temp = false; + break; + } + } + if (temp) sSingleNonBlockDamagableRecipeList.add(tRecipe); + } else { + sSingleNonBlockDamagableRecipeList.add(tRecipe); + } + } + } + } + GTLog.out.println( + "GTMod: Created a List of Tool Recipes containing " + sSingleNonBlockDamagableRecipeList.size() + + " Recipes for recycling." + + (sSingleNonBlockDamagableRecipeList.size() > 1024 + ? " Scanning all these Recipes is the reason for the startup Lag you receive right now." + : E)); + } + List rList = getRecipeOutputs(sSingleNonBlockDamagableRecipeList, true, aRecipe); + if (!GregTechAPI.sPostloadStarted || GregTechAPI.sPostloadFinished) sSingleNonBlockDamagableRecipeList.clear(); + return rList; + } + + /** + * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for + * example + */ + public static List getRecipeOutputs(ItemStack... aRecipe) { + return getRecipeOutputs( + CraftingManager.getInstance() + .getRecipeList(), + false, + aRecipe); + } + + private static List bufferedRecipes = null; + + /** + * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for + * example Buffers a List which only has armor-alike crafting in it + */ + public static List getRecipeOutputsBuffered(ItemStack... aRecipe) { + + if (bufferedRecipes == null) bufferedRecipes = CraftingManager.getInstance() + .getRecipeList() + .stream() + .filter( + tRecipe -> !(tRecipe instanceof ShapelessRecipes) && !(tRecipe instanceof ShapelessOreRecipe) + && !(tRecipe instanceof IGTCraftingRecipe)) + .filter(tRecipe -> { + try { + ItemStack tOutput = tRecipe.getRecipeOutput(); + if (tOutput.stackSize == 1 && tOutput.getMaxDamage() > 0 && tOutput.getMaxStackSize() == 1) { + return true; + } + } catch (Exception ignored) {} + return false; + }) + .collect(Collectors.toList()); + return getRecipeOutputs(bufferedRecipes, false, aRecipe); + } + + /** + * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for + * example + */ + public static List getRecipeOutputs(List aList, boolean aDeleteFromList, ItemStack... aRecipe) { + List rList = new ArrayList<>(); + if (aRecipe == null || Arrays.stream(aRecipe) + .noneMatch(Objects::nonNull)) return rList; + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { + + @Override + public boolean canInteractWith(EntityPlayer player) { + return false; + } + }, 3, 3); + for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); + if (!aDeleteFromList) { + HashSet stacks = new HashSet<>(); + aList.stream() + .filter(tRecipe -> { + if (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe + || tRecipe instanceof IGTCraftingRecipe) return false; + try { + return tRecipe.matches(aCrafting, DW); + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + return false; + } + }) + .forEach(tRecipe -> stacks.add(tRecipe.getCraftingResult(aCrafting))); + rList = stacks.stream() + .filter( + tOutput -> tOutput.stackSize == 1 && tOutput.getMaxDamage() > 0 && tOutput.getMaxStackSize() == 1) + .collect(Collectors.toList()); + } else for (Iterator iterator = aList.iterator(); iterator.hasNext();) { + IRecipe tRecipe = iterator.next(); + boolean matched = false; + + try { + matched = tRecipe.matches(aCrafting, DW); + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + if (matched) { + ItemStack tOutput = tRecipe.getCraftingResult(aCrafting); + + if (tOutput == null || tOutput.stackSize <= 0) { + // Seriously, who would ever do that shit? + if (!GregTechAPI.sPostloadFinished) throw new GTItsNotMyFaultException( + "Seems another Mod added a Crafting Recipe with null Output. Tell the Developer of said Mod to fix that."); + continue; + } + if (tOutput.stackSize != 1) continue; + if (tOutput.getMaxDamage() <= 0) continue; + if (tOutput.getMaxStackSize() != 1) continue; + if (tRecipe instanceof ShapelessRecipes) continue; + if (tRecipe instanceof ShapelessOreRecipe) continue; + if (tRecipe instanceof IGTCraftingRecipe) continue; + rList.add(GTUtility.copyOrNull(tOutput)); + iterator.remove(); + } + } + return rList; + } + + /** + * Used in my own Furnace. + */ + public static ItemStack getSmeltingOutput(ItemStack aInput, boolean aRemoveInput, ItemStack aOutputSlot) { + if (aInput == null || aInput.stackSize < 1) return null; + ItemStack rStack = GTOreDictUnificator.get( + FurnaceRecipes.smelting() + .getSmeltingResult(aInput)); + + if (rStack != null && (aOutputSlot == null || (GTUtility.areStacksEqual(rStack, aOutputSlot) + && rStack.stackSize + aOutputSlot.stackSize <= aOutputSlot.getMaxStackSize()))) { + if (aRemoveInput) aInput.stackSize--; + return rStack; + } + return null; + } + + /** + * Used in my own Machines. Decreases StackSize of the Input if wanted. + *

+ * Checks also if there is enough Space in the Output Slots. + */ + public static ItemStack[] getMachineOutput(ItemStack aInput, Map aRecipeList, + boolean aRemoveInput, NBTTagCompound rRecipeMetaData, ItemStack... aOutputSlots) { + if (aOutputSlots == null || aOutputSlots.length == 0) return new ItemStack[0]; + if (aInput == null) return new ItemStack[aOutputSlots.length]; + try { + for (Entry tEntry : aRecipeList.entrySet()) { + if (tEntry.getKey() + .matches(aInput)) { + if (tEntry.getKey() + .getAmount() <= aInput.stackSize) { + ItemStack[] tList = tEntry.getValue().items.toArray(new ItemStack[0]); + if (tList.length == 0) break; + ItemStack[] rList = new ItemStack[aOutputSlots.length]; + rRecipeMetaData.setTag("return", tEntry.getValue().metadata); + for (byte i = 0; i < aOutputSlots.length && i < tList.length; i++) { + if (tList[i] != null) { + if (aOutputSlots[i] == null || (GTUtility.areStacksEqual(tList[i], aOutputSlots[i]) + && tList[i].stackSize + aOutputSlots[i].stackSize + <= aOutputSlots[i].getMaxStackSize())) { + rList[i] = GTUtility.copyOrNull(tList[i]); + } else { + return new ItemStack[aOutputSlots.length]; + } + } + } + + if (aRemoveInput) aInput.stackSize -= tEntry.getKey() + .getAmount(); + return rList; + } + break; + } + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return new ItemStack[aOutputSlots.length]; + } + + /** + * Used in my own Recycler. + *

+ * Only produces Scrap if aScrapChance == 0. aScrapChance is usually the random Number I give to the Function If you + * directly insert 0 as aScrapChance then you can check if its Recycler-Blacklisted or similar + */ + @Nullable + public static ItemStack getRecyclerOutput(ItemStack aInput, int aScrapChance) { + if (aInput == null || aScrapChance != 0) return null; + if (recyclerWhitelist == null) { + generateRecyclerCache(); + } + + if (recyclerWhitelist.isEmpty()) { + if (searchRecyclerCache(aInput, recyclerBlacklist)) { + return null; + } else { + return ItemList.IC2_Scrap.get(1); + } + } else { + if (searchRecyclerCache(aInput, recyclerWhitelist)) { + return ItemList.IC2_Scrap.get(1); + } else { + return null; + } + } + } + + private static void generateRecyclerCache() { + recyclerWhitelist = new HashSet<>(); + for (IRecipeInput input : ic2.api.recipe.Recipes.recyclerWhitelist) { + for (ItemStack stack : input.getInputs()) { + recyclerWhitelist.add(GTUtility.ItemId.create(stack.getItem(), stack.getItemDamage(), null)); + } + } + recyclerBlacklist = new HashSet<>(); + for (IRecipeInput input : ic2.api.recipe.Recipes.recyclerBlacklist) { + for (ItemStack stack : input.getInputs()) { + recyclerBlacklist.add(GTUtility.ItemId.create(stack.getItem(), stack.getItemDamage(), null)); + } + } + } + + private static boolean searchRecyclerCache(ItemStack stack, Set set) { + if (set.contains(GTUtility.ItemId.createWithoutNBT(stack))) { + return true; + } + // ic2.api.recipe.RecipeInputItemStack#matches expects item with wildcard meta to accept arbitrary meta + return set.contains(GTUtility.ItemId.createAsWildcard(stack)); + } + + /** + * For the Scrapboxinator + */ + public static ItemStack getRandomScrapboxDrop() { + return ic2.api.recipe.Recipes.scrapboxDrops.getDrop(ItemList.IC2_Scrapbox.get(1), false); + } + + /** + * Charges an Electric Item. Only if it's a valid Electric Item of course. This forces the Usage of proper Voltages + * (so not the transfer limits defined by the Items) unless you ignore the Transfer Limit. If aTier is + * Integer.MAX_VALUE it will ignore Tier based Limitations. + * + * @return the actually used Energy. + */ + public static int chargeElectricItem(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreLimit, + boolean aSimulate) { + try { + if (isElectricItem(aStack)) { + int tTier = ((ic2.api.item.IElectricItem) aStack.getItem()).getTier(aStack); + if (tTier < 0 || tTier == aTier || aTier == Integer.MAX_VALUE) { + if (!aIgnoreLimit && tTier >= 0) + aCharge = (int) Math.min(aCharge, V[Math.max(0, Math.min(V.length - 1, tTier))]); + if (aCharge > 0) { + int rCharge = (int) Math.max( + 0.0, + ic2.api.item.ElectricItem.manager.charge(aStack, aCharge, tTier, true, aSimulate)); + return rCharge + (rCharge * 4 > aTier ? aTier : 0); + } + } + } + } catch (Throwable e) { + /* Do nothing */ + } + return 0; + } + + /** + * Discharges an Electric Item. Only if it's a valid Electric Item for that of course. This forces the Usage of + * proper Voltages (so not the transfer limits defined by the Items) unless you ignore the Transfer Limit. If aTier + * is Integer.MAX_VALUE it will ignore Tier based Limitations. + * + * @return the Energy got from the Item. + */ + public static int dischargeElectricItem(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreLimit, + boolean aSimulate, boolean aIgnoreDischargability) { + try { + // if (isElectricItem(aStack) && (aIgnoreDischargability || + // ((ic2.api.item.IElectricItem)aStack.getItem()).canProvideEnergy(aStack))) { + if (isElectricItem(aStack)) { + int tTier = ((ic2.api.item.IElectricItem) aStack.getItem()).getTier(aStack); + if (tTier < 0 || tTier == aTier || aTier == Integer.MAX_VALUE) { + if (!aIgnoreLimit && tTier >= 0) aCharge = (int) Math.min( + aCharge, + V[Math.max(0, Math.min(V.length - 1, tTier))] + B[Math.max(0, Math.min(V.length - 1, tTier))]); + if (aCharge > 0) { + int rCharge = (int) Math.max( + 0, + ic2.api.item.ElectricItem.manager.discharge( + aStack, + aCharge + (aCharge * 4 > aTier ? aTier : 0), + tTier, + true, + !aIgnoreDischargability, + aSimulate)); + return rCharge - (rCharge * 4 > aTier ? aTier : 0); + } + } + } + } catch (Throwable e) { + /* Do nothing */ + } + return 0; + } + + /** + * Uses an Electric Item. Only if it's a valid Electric Item for that of course. + * + * @return if the action was successful + */ + public static boolean canUseElectricItem(ItemStack aStack, int aCharge) { + try { + if (isElectricItem(aStack)) { + return ic2.api.item.ElectricItem.manager.canUse(aStack, aCharge); + } + } catch (Throwable e) { + /* Do nothing */ + } + return false; + } + + /** + * Uses an Electric Item. Only if it's a valid Electric Item for that of course. + * + * @return if the action was successful + */ + public static boolean useElectricItem(ItemStack aStack, int aCharge, EntityPlayer aPlayer) { + try { + if (isElectricItem(aStack)) { + ic2.api.item.ElectricItem.manager.use(aStack, 0, aPlayer); + if (ic2.api.item.ElectricItem.manager.canUse(aStack, aCharge)) { + return ic2.api.item.ElectricItem.manager.use(aStack, aCharge, aPlayer); + } + } + } catch (Throwable e) { + /* Do nothing */ + } + return false; + } + + /** + * Uses an Item. Tries to discharge in case of Electric Items + */ + public static boolean damageOrDechargeItem(ItemStack aStack, int aDamage, int aDecharge, EntityLivingBase aPlayer) { + if (GTUtility.isStackInvalid(aStack) || (aStack.getMaxStackSize() <= 1 && aStack.stackSize > 1)) return false; + if (aPlayer instanceof EntityPlayer && ((EntityPlayer) aPlayer).capabilities.isCreativeMode) return true; + if (aStack.getItem() instanceof IDamagableItem) { + return ((IDamagableItem) aStack.getItem()).doDamageToItem(aStack, aDamage); + } else if (GTModHandler.isElectricItem(aStack)) { + if (canUseElectricItem(aStack, aDecharge)) { + if (aPlayer instanceof EntityPlayer) { + return GTModHandler.useElectricItem(aStack, aDecharge, (EntityPlayer) aPlayer); + } + return GTModHandler.dischargeElectricItem(aStack, aDecharge, Integer.MAX_VALUE, true, false, true) + >= aDecharge; + } + } else if (aStack.getItem() + .isDamageable()) { + if (aPlayer == null) { + aStack.setItemDamage(aStack.getItemDamage() + aDamage); + } else { + aStack.damageItem(aDamage, aPlayer); + } + if (aStack.getItemDamage() >= aStack.getMaxDamage()) { + aStack.setItemDamage(aStack.getMaxDamage() + 1); + ItemStack tStack = GTUtility.getContainerItem(aStack, true); + if (tStack != null) { + aStack.func_150996_a(tStack.getItem()); + aStack.setItemDamage(tStack.getItemDamage()); + aStack.stackSize = tStack.stackSize; + aStack.setTagCompound(tStack.getTagCompound()); + } else if (aStack.stackSize > 0) { + aStack.stackSize--; + } + } + return true; + } + return false; + } + + /** + * Uses a Soldering Iron from player or external inventory + */ + public static boolean useSolderingIron(ItemStack aStack, EntityLivingBase aPlayer, IInventory aExternalInventory) { + if (aPlayer == null || aStack == null) return false; + if (GTUtility.isStackInList(aStack, GregTechAPI.sSolderingToolList)) { + if (aPlayer instanceof EntityPlayer tPlayer) { + if (tPlayer.capabilities.isCreativeMode) return true; + if (isElectricItem(aStack) && ic2.api.item.ElectricItem.manager.getCharge(aStack) > 1000.0d) { + if (consumeSolderingMaterial(tPlayer) + || (aExternalInventory != null && consumeSolderingMaterial(aExternalInventory))) { + if (canUseElectricItem(aStack, 10000)) { + return GTModHandler.useElectricItem(aStack, 10000, (EntityPlayer) aPlayer); + } + GTModHandler.useElectricItem( + aStack, + (int) ic2.api.item.ElectricItem.manager.getCharge(aStack), + (EntityPlayer) aPlayer); + return false; + } else { + GTUtility.sendChatToPlayer( + (EntityPlayer) aPlayer, + GTUtility.trans("094.1", "Not enough soldering material!")); + } + } + } else { + damageOrDechargeItem(aStack, 1, 1000, aPlayer); + return true; + } + } + return false; + } + + public static boolean useSolderingIron(ItemStack aStack, EntityLivingBase aPlayer) { + return useSolderingIron(aStack, aPlayer, null); + } + + public static boolean consumeSolderingMaterial(EntityPlayer aPlayer) { + if (aPlayer.capabilities.isCreativeMode) return true; + IInventory tInventory = aPlayer.inventory; + if (consumeSolderingMaterial(tInventory)) { + if (aPlayer.inventoryContainer != null) { + aPlayer.inventoryContainer.detectAndSendChanges(); + } + return true; + } + for (int i = 0; i < tInventory.getSizeInventory(); i++) { + ItemStack tStack = tInventory.getStackInSlot(i); + if (tStack != null && tStack.getItem() instanceof ItemToolbox) { + IInventory tToolboxInventory = ((ItemToolbox) tStack.getItem()).getInventory(aPlayer, tStack); + if (consumeSolderingMaterial(tToolboxInventory)) { + tInventory.markDirty(); + if (aPlayer.inventoryContainer != null) { + aPlayer.inventoryContainer.detectAndSendChanges(); + } + return true; + } + } + } + return false; + } + + /** + * Consumes soldering material from given inventory + */ + public static boolean consumeSolderingMaterial(IInventory aInventory) { + for (int i = 0; i < aInventory.getSizeInventory(); i++) { + ItemStack tStack = aInventory.getStackInSlot(i); + if (GTUtility.isStackInList(tStack, GregTechAPI.sSolderingMetalList)) { + if (tStack.stackSize < 1) return false; + if (tStack.stackSize == 1) { + tStack = null; + } else { + tStack.stackSize--; + } + aInventory.setInventorySlotContents(i, tStack); + aInventory.markDirty(); + return true; + } + } + return false; + } + + /** + * Is this an electric Item, which can charge other Items? + */ + public static boolean isChargerItem(ItemStack aStack) { + try { + if (isElectricItem(aStack)) { + return ((ic2.api.item.IElectricItem) aStack.getItem()).canProvideEnergy(aStack); + } + } catch (Throwable e) { + /* Do nothing */ + } + return false; + } + + /** + * Is this an electric Item? + */ + public static boolean isElectricItem(ItemStack aStack) { + try { + return aStack != null && aStack.getItem() instanceof ic2.api.item.IElectricItem + && ((IElectricItem) aStack.getItem()).getTier(aStack) < Integer.MAX_VALUE; + } catch (Throwable e) { + /* Do nothing */ + } + return false; + } + + public static boolean isElectricItem(ItemStack aStack, byte aTier) { + try { + return aStack != null && aStack.getItem() instanceof ic2.api.item.IElectricItem + && ((IElectricItem) aStack.getItem()).getTier(aStack) == aTier; + } catch (Throwable e) { + /* Do nothing */ + } + return false; + } + + /** + * Returns the current charge and maximum charge of an ItemStack. + * + * @param aStack Any ItemStack. + * @return Optional.empty() if the stack is null or not an electric item, or an Optional containing a payload of an + * array containing [ current_charge, maximum_charge ] on success. + */ + public static Optional getElectricItemCharge(ItemStack aStack) { + if (aStack == null || !isElectricItem(aStack)) { + return Optional.empty(); + } + + final Item item = aStack.getItem(); + + if (item instanceof final MetaBaseItem metaBaseItem) { + final Long[] stats = metaBaseItem.getElectricStats(aStack); + if (stats != null && stats.length > 0) { + return Optional.of(new Long[] { metaBaseItem.getRealCharge(aStack), stats[0] }); + } + + } else if (item instanceof final IElectricItem ic2ElectricItem) { + return Optional.of( + new Long[] { (long) ic2.api.item.ElectricItem.manager.getCharge(aStack), + (long) ic2ElectricItem.getMaxCharge(aStack) }); + } + + return Optional.empty(); + } + + /** + * Allow item to be inserted into ic2 toolbox + */ + public static void registerBoxableItemToToolBox(ItemStack aStack) { + if (aStack != null) { + try { + ic2.api.item.ItemWrapper.registerBoxable(aStack.getItem(), (IBoxable) sBoxableWrapper); + } catch (Throwable ignored) { + /* Do nothing */ + } + sBoxableItems.add(new GTItemStack(aStack)); + } + } + + public static int getCapsuleCellContainerCountMultipliedWithStackSize(ItemStack... aStacks) { + int rAmount = 0; + for (ItemStack tStack : aStacks) + if (tStack != null) rAmount += getCapsuleCellContainerCount(tStack) * tStack.stackSize; + return rAmount; + } + + public static int getCapsuleCellContainerCount(ItemStack aStack) { + if (aStack == null) return 0; + + if (GTUtility.areStacksEqual(GTUtility.getContainerForFilledItem(aStack, true), ItemList.Cell_Empty.get(1))) { + return 1; + } + + if (GTUtility.areStacksEqual(aStack, getIC2Item("waterCell", 1, W))) { + return 1; + } + + for (OrePrefixes cellType : OrePrefixes.CELL_TYPES) { + if (cellType.contains(aStack)) { + return 1; + } + } + + return 0; + } + + public static class RecipeBits { + + /** + * Mirrors the Recipe + */ + public static long MIRRORED = B[0]; + /** + * Buffers the Recipe for later addition. This makes things more efficient. + */ + public static long BUFFERED = B[1]; + /** + * This is a special Tag I used for crafting Coins up and down. + */ + public static long KEEPNBT = B[2]; + /** + * Makes the Recipe Reverse Craftable in the Disassembler. + */ + public static long DISMANTLEABLE = B[3]; + /** + * Prevents the Recipe from accidentally getting removed by my own Handlers. + */ + public static long NOT_REMOVABLE = B[4]; + /** + * Reverses the Output of the Recipe for smelting and pulverising. + */ + public static long REVERSIBLE = B[5]; + /** + * Removes all Recipes with the same Output Item regardless of NBT, unless another Recipe Deletion Bit is added + * too. + */ + public static long DELETE_ALL_OTHER_RECIPES = B[6]; + /** + * Removes all Recipes with the same Output Item limited to the same NBT. + */ + public static long DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT = B[7]; + /** + * Removes all Recipes with the same Output Item limited to Shaped Recipes. + */ + public static long DELETE_ALL_OTHER_SHAPED_RECIPES = B[8]; + /** + * Removes all Recipes with the same Output Item limited to native Recipe Handlers. + */ + public static long DELETE_ALL_OTHER_NATIVE_RECIPES = B[9]; + /** + * Disables the check for colliding Recipes. + */ + public static long DO_NOT_CHECK_FOR_COLLISIONS = B[10]; + /** + * Only adds the Recipe if there is another Recipe having that Output + */ + public static long ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT = B[11]; + /** + * Only adds the Recipe if it has an Output + */ + public static long ONLY_ADD_IF_RESULT_IS_NOT_NULL = B[12]; + /** + * Don't remove shapeless recipes with this output + */ + public static long DONT_REMOVE_SHAPELESS = B[13]; + } +} diff --git a/src/main/java/gregtech/api/util/GTMusicSystem.java b/src/main/java/gregtech/api/util/GTMusicSystem.java new file mode 100644 index 0000000000..362c397e67 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTMusicSystem.java @@ -0,0 +1,667 @@ +package gregtech.api.util; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.SoundEventAccessorComposite; +import net.minecraft.client.audio.SoundRegistry; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemRecord; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.jetbrains.annotations.ApiStatus; +import org.joml.Vector4i; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.jcraft.jorbis.VorbisFile; + +import baubles.api.BaublesApi; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.network.ByteBufUtils; +import gregtech.GTMod; +import gregtech.api.enums.GTValues; +import gregtech.api.net.GTPacketMusicSystemData; +import gregtech.client.ElectricJukeboxSound; +import gregtech.common.items.ItemWirelessHeadphones; +import gregtech.common.tileentities.machines.basic.MTEBetterJukebox; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; + +/** + * A system that keeps track of jukebox music tracks playing in different locations. + * Compared to vanilla jukebox handling, this allows music to resume playing after reloading the chunk the jukeboxes are + * in. + * It also allows the headphone item to modify the hearing range of a given disc, including other dimensions. + *

+ * Vector4i coordinates point to X,Y,Z,Dimension of the source + * + * @author eigenraven + */ +public final class GTMusicSystem { + + private GTMusicSystem() {} + + public static final class MusicSource { + + /** Flag keeping track of when the data of this source needs to be sent to clients again */ + public boolean modified; + public final UUID sourceID; + /** Currently playing track */ + public ResourceLocation currentRecord; + /** Headphone range */ + public MTEBetterJukebox.HeadphoneLimit headphoneLimit; + /** + * {@link System#currentTimeMillis()} at the time this record started playing, in server time + */ + public long startedPlayingAtMs; + /** Time the record was playing for at the time it was serialized. */ + public long playingForMs; + /** The origin of this source used for wireless headphone range calculations */ + public final Vector4i originPosition = new Vector4i(); + /** Number of blocks from {@link MusicSource#originPosition} the headphones can work */ + public int headphoneBlockRange; + /** Densely packed parameters for each "emitter" associated with the source, for fast iteration */ + public int[] emitterParameters; // [{x,y,z,dim,volume}, {x, ...}, {x, ...}, ...] + /** Offsets into the parameters array */ + public static final int EMITTER_X = 0; + /** Offsets into the parameters array */ + public static final int EMITTER_Y = 1; + /** Offsets into the parameters array */ + public static final int EMITTER_Z = 2; + /** Offsets into the parameters array */ + public static final int EMITTER_DIMENSION = 3; + /** 100 times the floating point "volume" used by the sound system for range calculations */ + public static final int EMITTER_VOLUME_X_100 = 4; + /** Iteration stride for packed emitter parameters */ + public static final int EMITTER_STRIDE = EMITTER_VOLUME_X_100 + 1; + + public MusicSource(UUID sourceID) { + this.sourceID = sourceID; + } + + public void resizeEmitterArray(int count) { + int len = count * EMITTER_STRIDE; + if (emitterParameters == null || emitterParameters.length != len) { + if (emitterParameters == null) { + emitterParameters = new int[len]; + } else { + emitterParameters = Arrays.copyOf(emitterParameters, len); + } + modified = true; + } + } + + public void setEmitter(int index, Vector4i position, float volume) { + int arrIndex = index * EMITTER_STRIDE; + if (arrIndex < 0 || arrIndex >= emitterParameters.length) { + throw new IndexOutOfBoundsException( + "Trying to access emitter with index " + index + + " in an array of " + + emitterParameters.length / EMITTER_STRIDE); + } + + if (emitterParameters[arrIndex + EMITTER_X] != position.x) { + modified = true; + emitterParameters[arrIndex + EMITTER_X] = position.x; + } + if (emitterParameters[arrIndex + EMITTER_Y] != position.y) { + modified = true; + emitterParameters[arrIndex + EMITTER_Y] = position.y; + } + if (emitterParameters[arrIndex + EMITTER_Z] != position.z) { + modified = true; + emitterParameters[arrIndex + EMITTER_Z] = position.z; + } + if (emitterParameters[arrIndex + EMITTER_DIMENSION] != position.w) { + modified = true; + emitterParameters[arrIndex + EMITTER_DIMENSION] = position.w; + } + final int intVolume = (int) (volume * 100.0f); + if (emitterParameters[arrIndex + EMITTER_VOLUME_X_100] != intVolume) { + modified = true; + emitterParameters[arrIndex + EMITTER_VOLUME_X_100] = intVolume; + } + } + + /** x squared */ + private static int sq(int x) { + return x * x; + } + + /** @return Index of closest emitter in range, or -1 if none is nearby. */ + public int closestEmitter(int x, int y, int z, int dim) { + int closest = -1; + int closestDistanceSq = Integer.MAX_VALUE; + final int emittersCount = emitterParameters.length / EMITTER_STRIDE; + for (int i = 0; i < emittersCount; i++) { + final int offset = i * EMITTER_STRIDE; + final int eDim = emitterParameters[offset + EMITTER_DIMENSION]; + if (eDim != dim) { + continue; + } + final int eX = emitterParameters[offset + EMITTER_X]; + final int eY = emitterParameters[offset + EMITTER_Y]; + final int eZ = emitterParameters[offset + EMITTER_Z]; + final int distanceSq = sq(x - eX) + sq(y - eY) + sq(z - eZ); + if (distanceSq < closestDistanceSq) { + closestDistanceSq = distanceSq; + closest = i; + } + } + return closest; + } + + public boolean inHeadphoneRange(int x, int y, int z, int dim) { + return switch (headphoneLimit) { + case BETWEEN_DIMENSIONS -> true; + case INSIDE_DIMENSION -> dim == originPosition.w; + case BLOCK_RANGE -> dim == originPosition.w + && originPosition.distanceSquared(x, y, z, dim) <= sq(headphoneBlockRange); + }; + } + + public void encode(final ByteBuf target) { + target.writeLong(sourceID.getMostSignificantBits()); + target.writeLong(sourceID.getLeastSignificantBits()); + if (currentRecord != null) { + final int duration = getMusicRecordDurations().getOrDefault(currentRecord, Integer.MAX_VALUE); + if (playingForMs >= duration) { + // Record already finished playing, let's not send it to the client anymore. + target.writeBoolean(false); + } else { + target.writeBoolean(true); + ByteBufUtils.writeUTF8String(target, currentRecord.getResourceDomain()); + ByteBufUtils.writeUTF8String(target, currentRecord.getResourcePath()); + } + } else { + target.writeBoolean(false); + } + target.writeByte((byte) headphoneLimit.ordinal()); + ByteBufUtils.writeVarInt(target, headphoneBlockRange, 5); + target.writeLong(startedPlayingAtMs); + target.writeLong(playingForMs); + ByteBufUtils.writeVarInt(target, originPosition.x, 5); + ByteBufUtils.writeVarInt(target, originPosition.y, 5); + ByteBufUtils.writeVarInt(target, originPosition.z, 5); + ByteBufUtils.writeVarInt(target, originPosition.w, 5); + ByteBufUtils.writeVarInt(target, emitterParameters.length, 5); + for (int emitterParameter : emitterParameters) { + ByteBufUtils.writeVarInt(target, emitterParameter, 5); + } + } + + public static MusicSource decode(final ByteBuf bytes) { + final long uuidMsb = bytes.readLong(); + final long uuidLsb = bytes.readLong(); + final MusicSource source = new MusicSource(new UUID(uuidMsb, uuidLsb)); + final boolean hasRecord = bytes.readBoolean(); + if (hasRecord) { + final String domain = ByteBufUtils.readUTF8String(bytes); + final String path = ByteBufUtils.readUTF8String(bytes); + source.currentRecord = new ResourceLocation(domain, path); + } + source.headphoneLimit = MTEBetterJukebox.HeadphoneLimit.ENTRIES.get(bytes.readByte()); + source.headphoneBlockRange = ByteBufUtils.readVarInt(bytes, 5); + source.startedPlayingAtMs = bytes.readLong(); + source.playingForMs = bytes.readLong(); + final int originX = ByteBufUtils.readVarInt(bytes, 5); + final int originY = ByteBufUtils.readVarInt(bytes, 5); + final int originZ = ByteBufUtils.readVarInt(bytes, 5); + final int originW = ByteBufUtils.readVarInt(bytes, 5); + source.originPosition.set(originX, originY, originZ, originW); + final int emittersLength = ByteBufUtils.readVarInt(bytes, 5); + source.emitterParameters = new int[emittersLength]; + for (int i = 0; i < emittersLength; i++) { + source.emitterParameters[i] = ByteBufUtils.readVarInt(bytes, 5); + } + + return source; + } + + public void setRecord(final ResourceLocation record) { + setRecord(record, 0); + } + + public void setRecord(final ResourceLocation record, long seekOffset) { + modified = true; + currentRecord = record; + playingForMs = seekOffset; + startedPlayingAtMs = System.currentTimeMillis() - seekOffset; + } + } + + public static final class ServerSystem { + + static final Object2ObjectOpenHashMap musicSources = new Object2ObjectOpenHashMap<>(32); + static boolean musicSourcesDirty = false; + + // Everything is synchronized to allow calling into here from the client when singleplayer synchronization is + // needed. + + public static synchronized MusicSource registerOrGetMusicSource(UUID uuid) { + return musicSources.computeIfAbsent(uuid, (UUID id) -> { + musicSourcesDirty = true; + return new MusicSource(id); + }); + } + + public static synchronized void removeMusicSource(UUID uuid) { + musicSources.remove(uuid); + musicSourcesDirty = true; + } + + public static synchronized void reset() { + musicSources.clear(); + musicSourcesDirty = true; + } + + public static synchronized ByteBuf serialize() { + final ByteBuf out = Unpooled.buffer(); + ByteBufUtils.writeVarInt(out, musicSources.size(), 5); + musicSources.forEach((uuid, source) -> source.encode(out)); + return out; + } + + private static boolean tickAnyDirty; + + public static synchronized void tick() { + final long now = System.currentTimeMillis(); + tickAnyDirty = false; + musicSources.forEach((uuid, source) -> { + source.playingForMs = now - source.startedPlayingAtMs; + tickAnyDirty |= source.modified; + source.modified = false; + }); + if (tickAnyDirty || musicSourcesDirty) { + musicSourcesDirty = false; + GTValues.NW.sendToAll(new GTPacketMusicSystemData(serialize())); + } + } + + static synchronized void onPauseMs(long pauseDurationMs) { + musicSources.forEach((uuid, source) -> { source.startedPlayingAtMs += pauseDurationMs; }); + } + } + + public static final class ClientSystem { + + private static final class ClientSourceData { + + /** Currently playing sound data */ + public ElectricJukeboxSound currentSound = null; + /** Currently playing sound data */ + public ResourceLocation currentSoundResource = null; + /** + * Server's timer value of when the music started, mostly meaningless except for checking for replays of the + * same music file. + */ + public long originalStartTime = 0; + /** + * Computed client value of {@link System#currentTimeMillis()} of the time when the playback would have + * started if it was synchronized with the server. + */ + public long clientReferenceStartTime = 0; + /** Flag for mark and sweep removal of outdated sounds */ + public boolean markFlag = false; + + public void resetMark() { + markFlag = false; + } + + public void mark() { + markFlag = true; + } + + public void clearSound(final Minecraft mc) { + currentSoundResource = null; + if (currentSound != null) { + mc.getSoundHandler() + .stopSound(currentSound); + currentSound = null; + originalStartTime = 0; + } + } + + public boolean equalSound(final MusicSource source) { + if (source == null || source.currentRecord == null) { + return currentSoundResource == null; + } else { + return source.currentRecord.equals(currentSoundResource) + && originalStartTime == source.startedPlayingAtMs; + } + } + + public void resetSound(final Minecraft mc, final MusicSource source, final boolean onHeadphones) { + clearSound(mc); + if (source == null || source.emitterParameters.length == 0) { + return; + } + int closestEmitter = onHeadphones ? 0 + : source.closestEmitter( + (int) Math.floor(mc.thePlayer.posX), + (int) Math.floor(mc.thePlayer.posY), + (int) Math.floor(mc.thePlayer.posZ), + currentDimension); + if (closestEmitter < 0) { + return; + } + this.currentSoundResource = source.currentRecord; + this.originalStartTime = source.startedPlayingAtMs; + this.clientReferenceStartTime = System.currentTimeMillis() - source.playingForMs; + if (currentSoundResource != null) { + this.currentSound = makeRecord(source, closestEmitter); + if (onHeadphones) { + this.currentSound.volume = 1.0e20f; + } + mc.getSoundHandler() + .playSound(this.currentSound); + } + } + + public void updateSound(final Minecraft mc, final MusicSource source, final boolean onHeadphones) { + if (source == null || currentSound == null || source.emitterParameters.length == 0) { + return; + } + int closestEmitter = onHeadphones ? 0 + : source.closestEmitter( + (int) Math.floor(mc.thePlayer.posX), + (int) Math.floor(mc.thePlayer.posY), + (int) Math.floor(mc.thePlayer.posZ), + currentDimension); + if (closestEmitter < 0) { + currentSound.volume = 0.0f; + return; + } + final int offset = closestEmitter * MusicSource.EMITTER_STRIDE; + currentSound.xPosition = source.emitterParameters[offset + MusicSource.EMITTER_X]; + currentSound.yPosition = source.emitterParameters[offset + MusicSource.EMITTER_Y]; + currentSound.zPosition = source.emitterParameters[offset + MusicSource.EMITTER_Z]; + currentSound.volume = onHeadphones ? 1.0e20f + : source.emitterParameters[offset + MusicSource.EMITTER_VOLUME_X_100] / 100.0f; + } + } + + /** Latest music source list as synchronized from the server */ + public static final Object2ObjectOpenHashMap musicSources = new Object2ObjectOpenHashMap<>(); + + private static final Object2ObjectOpenHashMap activelyPlayingMusic = new Object2ObjectOpenHashMap<>( + 16); + + private static final ObjectOpenHashSet wornHeadphones = new ObjectOpenHashSet<>(); + + private static int currentDimension = Integer.MIN_VALUE; + + private static boolean soundsPaused = false; + private static long pauseTimeMs = 0; + private static int tickCounter = 0; + + public static void loadUpdatedSources(ByteBuf bytes) { + final int sourceCount = ByteBufUtils.readVarInt(bytes, 5); + musicSources.clear(); + for (int i = 0; i < sourceCount; i++) { + final MusicSource source = MusicSource.decode(bytes); + musicSources.put(source.sourceID, source); + } + } + + private static ElectricJukeboxSound makeRecord(MusicSource source, int emitter) { + final int x = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + MusicSource.EMITTER_X]; + final int y = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + MusicSource.EMITTER_Y]; + final int z = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + MusicSource.EMITTER_Z]; + final float volume = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + + MusicSource.EMITTER_VOLUME_X_100] / 100.0f; + return new ElectricJukeboxSound(source.currentRecord, volume, source.playingForMs, x, y, z); + } + + public static void dumpAllRecordDurations() { + try { + final Minecraft mc = Minecraft.getMinecraft(); + final SoundRegistry sm = mc.getSoundHandler().sndRegistry; + final SoundDurationsJson json = new SoundDurationsJson(); + @SuppressWarnings("unchecked") + final Map allRecords = ItemRecord.field_150928_b; + // Cursed hack because JOrbis does not support seeking in anything other than filesystem files. + // This is only a dev tool, so it can be a bit slow and use real files here. + final File tempFile = File.createTempFile("mcdecode", ".ogg"); + for (final ItemRecord record : allRecords.values()) { + try { + final ResourceLocation res = record.getRecordResource(record.recordName); + SoundEventAccessorComposite registryEntry = (SoundEventAccessorComposite) sm.getObject(res); + if (registryEntry == null) { + registryEntry = (SoundEventAccessorComposite) sm.getObject( + new ResourceLocation(res.getResourceDomain(), "records." + res.getResourcePath())); + } + final ResourceLocation realPath = registryEntry.func_148720_g() + .getSoundPoolEntryLocation(); + try (final InputStream is = mc.getResourceManager() + .getResource(realPath) + .getInputStream(); final OutputStream os = FileUtils.openOutputStream(tempFile)) { + IOUtils.copy(is, os); + os.close(); + final VorbisFile vf = new VorbisFile(tempFile.getAbsolutePath()); + final float totalSeconds = vf.time_total(-1); + json.soundDurationsMs.put(res.toString(), (int) Math.ceil(totalSeconds * 1000.0f)); + } + } catch (Exception e) { + GTMod.GT_FML_LOGGER.warn("Skipping {}", record.recordName, e); + } + } + GTMod.GT_FML_LOGGER.info( + "Sound durations json: \n{}", + new GsonBuilder().setPrettyPrinting() + .create() + .toJson(json)); + tempFile.delete(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void reset() { + musicSources.clear(); + tick(); + } + + public static void tick() { + final Minecraft mc = Minecraft.getMinecraft(); + if (mc == null || mc.renderGlobal == null + || mc.theWorld == null + || mc.thePlayer == null + || mc.theWorld.provider == null) { + return; + } + tickCounter++; + final long now = System.currentTimeMillis(); + currentDimension = mc.theWorld.provider.dimensionId; + + headphoneCheck: if ((tickCounter % 20) == 0) { + wornHeadphones.clear(); + final IInventory baubles = BaublesApi.getBaubles(mc.thePlayer); + if (baubles == null) { + break headphoneCheck; + } + final int baublesSize = baubles.getSizeInventory(); + for (int i = 0; i < baublesSize; i++) { + final ItemStack item = baubles.getStackInSlot(i); + if (item != null && item.getItem() instanceof ItemWirelessHeadphones headphones) { + final UUID id = headphones.getBoundJukeboxUUID(item); + if (id != null) { + wornHeadphones.add(id); + } + } + } + } + + activelyPlayingMusic.forEach((uuid, data) -> data.resetMark()); + + // Update and mark all present music streams + musicSources.forEach((uuid, musicSource) -> { + final ClientSourceData data = activelyPlayingMusic + .computeIfAbsent(uuid, ignored -> new ClientSourceData()); + data.mark(); + if (data.currentSound != null && !mc.getSoundHandler() + .isSoundPlaying(data.currentSound) + && (now - data.clientReferenceStartTime) + < getMusicRecordDurations().getOrDefault(data.currentSoundResource, Integer.MAX_VALUE)) { + data.currentSound = null; + data.currentSoundResource = null; + } + final boolean onHeadphones = wornHeadphones.contains(uuid); + if (!data.equalSound(musicSource)) { + data.resetSound(mc, musicSource, onHeadphones); + } else { + data.updateSound(mc, musicSource, onHeadphones); + } + }); + + // Sweep no longer present music streams + final var entries = activelyPlayingMusic.object2ObjectEntrySet() + .fastIterator(); + while (entries.hasNext()) { + final ClientSourceData entry = entries.next() + .getValue(); + if (!entry.markFlag) { + entry.clearSound(mc); + entries.remove(); + } + } + } + + @ApiStatus.Internal + public static void onSoundBatchStop() { + // All music was forcibly stopped, we can forget about the currently playing music + // and let the update loop re-start them on next tick + long now = System.currentTimeMillis(); + activelyPlayingMusic.forEach((uuid, data) -> { + data.currentSound = null; + data.currentSoundResource = null; + final MusicSource source = musicSources.get(uuid); + if (source == null) { + return; + } + source.playingForMs = now - data.clientReferenceStartTime; + }); + } + + @ApiStatus.Internal + public static void onSoundBatchPause() { + if (soundsPaused) { + return; + } + soundsPaused = true; + pauseTimeMs = System.currentTimeMillis(); + } + + @ApiStatus.Internal + public static void onSoundBatchResume() { + if (!soundsPaused) { + return; + } + final Minecraft mc = Minecraft.getMinecraft(); + if (mc == null || mc.renderGlobal == null + || mc.theWorld == null + || mc.thePlayer == null + || mc.theWorld.provider == null) { + return; + } + soundsPaused = false; + + if (!(mc.isSingleplayer() && !mc.getIntegratedServer() + .getPublic())) { + return; + } + final long now = System.currentTimeMillis(); + final long pauseDurationMs = now - pauseTimeMs; + + // We manipulate server state here, because we've checked this is singleplayer pausing. + GTMusicSystem.ServerSystem.onPauseMs(pauseDurationMs); + musicSources.forEach((uuid, source) -> { source.startedPlayingAtMs += pauseDurationMs; }); + activelyPlayingMusic.forEach((uuid, data) -> { + data.originalStartTime += pauseDurationMs; + data.clientReferenceStartTime += pauseDurationMs; + }); + + } + } + + private static final Object2IntOpenHashMap musicRecordDurations = new Object2IntOpenHashMap<>(); + private static volatile boolean musicRecordsInitialized; + + /** For GSON consumption */ + public static class SoundDurationsJson { + + public Map soundDurationsMs = new TreeMap<>(); + } + + public static Object2IntOpenHashMap getMusicRecordDurations() { + if (musicRecordsInitialized) { + return musicRecordDurations; + } + // double-checked locking for efficiency + synchronized (musicRecordDurations) { + if (musicRecordsInitialized) { + return musicRecordDurations; + } + + final Gson gson = new Gson(); + + try { + final ArrayList candidates = Collections.list( + GTMusicSystem.class.getClassLoader() + .getResources("soundmeta/durations.json")); + final Path configPath = Loader.instance() + .getConfigDir() + .toPath() + .resolve("soundmeta") + .resolve("durations.json"); + if (Files.exists(configPath)) { + candidates.add( + configPath.toUri() + .toURL()); + } + for (final URL url : candidates) { + try { + final String objectJson = IOUtils.toString(url); + final SoundDurationsJson object = gson.fromJson(objectJson, SoundDurationsJson.class); + if (object == null || object.soundDurationsMs == null || object.soundDurationsMs.isEmpty()) { + continue; + } + for (final var entry : object.soundDurationsMs.entrySet()) { + musicRecordDurations.put( + new ResourceLocation(entry.getKey()), + entry.getValue() + .intValue()); + } + } catch (Exception e) { + GTMod.GT_FML_LOGGER.error("Could not parse sound durations from {}", url, e); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + musicRecordsInitialized = true; + return musicRecordDurations; + } + } + +} diff --git a/src/main/java/gregtech/api/util/GTOreDictUnificator.java b/src/main/java/gregtech/api/util/GTOreDictUnificator.java new file mode 100644 index 0000000000..6168b03211 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTOreDictUnificator.java @@ -0,0 +1,578 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.E; +import static gregtech.api.enums.GTValues.M; +import static gregtech.api.enums.GTValues.W; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.annotation.Nullable; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +import gregtech.api.GregTechAPI; +import gregtech.api.enums.Dyes; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.SubTag; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.ItemData; +import gregtech.api.objects.MaterialStack; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * This is the Core of my OreDict Unification Code + *

+ * If you just want to use this to unificate your Items, then use the Function in the GregTechAPI File + *

+ * P.S. It is intended to be named "Unificator" and not "Unifier", because that sounds more awesome. + */ +public class GTOreDictUnificator { + + private static final Map sName2StackMap = new HashMap<>(); + private static final Map sItemStack2DataMap = new Object2ObjectOpenCustomHashMap<>( + GTItemStack.ITEMSTACK_HASH_STRATEGY2); + private static final Map> sUnificationTable = new Object2ObjectOpenCustomHashMap<>( + GTItemStack.ITEMSTACK_HASH_STRATEGY2); + private static final Set sNoUnificationList = new ObjectOpenCustomHashSet<>( + GTItemStack.ITEMSTACK_HASH_STRATEGY2); + private static int isRegisteringOre = 0, isAddingOre = 0; + private static boolean mRunThroughTheList = true; + + static { + GregTechAPI.sItemStackMappings.add(sItemStack2DataMap); + GregTechAPI.sItemStackMappings.add(sUnificationTable); + } + + /** + * The Blacklist just prevents the Item from being unificated into something else. Useful if you have things like + * the Industrial Diamond, which is better than regular Diamond, but also usable in absolutely all Diamond Recipes. + */ + public static void addToBlacklist(ItemStack aStack) { + if (GTUtility.isStackValid(aStack) && !GTUtility.isStackInStackSet(aStack, sNoUnificationList)) + sNoUnificationList.add(aStack); + } + + public static boolean isBlacklisted(ItemStack aStack) { + return GTUtility.isStackInStackSet(aStack, sNoUnificationList); + } + + public static void add(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack) { + set(aPrefix, aMaterial, aStack, false, false); + } + + public static void set(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack) { + set(aPrefix, aMaterial, aStack, true, false); + } + + public static void set(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack, boolean aOverwrite, + boolean aAlreadyRegistered) { + if (aMaterial == null || aPrefix == null + || GTUtility.isStackInvalid(aStack) + || Items.feather.getDamage(aStack) == W) return; + isAddingOre++; + aStack = GTUtility.copyAmount(1, aStack); + if (!aAlreadyRegistered) registerOre(aPrefix.get(aMaterial), aStack); + addAssociation(aPrefix, aMaterial, aStack, isBlacklisted(aStack)); + if (aOverwrite || GTUtility.isStackInvalid( + sName2StackMap.get( + aPrefix.get(aMaterial) + .toString()))) + sName2StackMap.put( + aPrefix.get(aMaterial) + .toString(), + aStack); + isAddingOre--; + } + + public static ItemStack getFirstOre(Object aName, long aAmount) { + if (GTUtility.isStringInvalid(aName)) return null; + ItemStack tStack = sName2StackMap.get(aName.toString()); + if (GTUtility.isStackValid(tStack)) return GTUtility.copyAmount(aAmount, tStack); + return GTUtility.copyAmount(aAmount, getOresImmutable(aName).toArray()); + } + + public static ItemStack get(Object aName, long aAmount) { + return get(aName, null, aAmount, true, true); + } + + public static ItemStack get(Object aName, ItemStack aReplacement, long aAmount) { + return get(aName, aReplacement, aAmount, true, true); + } + + public static ItemStack get(OrePrefixes aPrefix, Object aMaterial, long aAmount) { + return get(aPrefix, aMaterial, null, aAmount); + } + + public static ItemStack get(OrePrefixes aPrefix, Object aMaterial, ItemStack aReplacement, long aAmount) { + if (OrePrefixes.mPreventableComponents.contains(aPrefix) && aPrefix.mDisabledItems.contains(aMaterial)) + return aReplacement; + return get(aPrefix.get(aMaterial), aReplacement, aAmount, false, true); + } + + public static ItemStack get(OrePrefixes aPrefix, Object aMaterial, long aAmount, boolean aNoInvalidAmounts) { + if (OrePrefixes.mPreventableComponents.contains(aPrefix) && aPrefix.mDisabledItems.contains(aMaterial)) + return null; + return get(aPrefix.get(aMaterial), null, aAmount, false, aNoInvalidAmounts); + } + + public static ItemStack get(Object aName, ItemStack aReplacement, long aAmount, boolean aMentionPossibleTypos, + boolean aNoInvalidAmounts) { + if (aNoInvalidAmounts && aAmount < 1) return null; + final ItemStack stackFromName = sName2StackMap.get(aName.toString()); + if (stackFromName != null) return GTUtility.copyAmount(aAmount, stackFromName); + if (aMentionPossibleTypos) { + GTLog.err.println("Unknown Key for Unification, Typo? " + aName); + } + final ItemStack stackFirstOre = getFirstOre(aName, aAmount); + if (stackFirstOre != null) return GTUtility.copyAmount(aAmount, stackFirstOre); + return GTUtility.copyAmount(aAmount, aReplacement); + } + + public static ItemStack[] setStackArray(boolean aUseBlackList, ItemStack... aStacks) { + for (int i = 0; i < aStacks.length; i++) aStacks[i] = get(aUseBlackList, GTUtility.copyOrNull(aStacks[i])); + return aStacks; + } + + public static ItemStack[] getStackArray(boolean aUseBlackList, Object... aStacks) { + ItemStack[] rStacks = new ItemStack[aStacks.length]; + for (int i = 0; i < aStacks.length; i++) { + rStacks[i] = get(aUseBlackList, GTUtility.copy(aStacks[i]), true); + } + return rStacks; + } + + public static ItemStack setStack(ItemStack aStack) { + return setStack(true, aStack); + } + + public static ItemStack setStack(boolean aUseBlackList, ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return aStack; + ItemStack tStack = get(aUseBlackList, aStack); + if (GTUtility.areStacksEqual(aStack, tStack)) return aStack; + aStack.func_150996_a(tStack.getItem()); + Items.feather.setDamage(aStack, Items.feather.getDamage(tStack)); + return aStack; + } + + public static ItemStack get(ItemStack aStack) { + return get(true, aStack); + } + + public static ItemStack get(boolean aUseBlackList, ItemStack aStack) { + return get(aUseBlackList, aStack, false); + } + + /** + * @param unsafe If true, it does not limit stack size by 64. + */ + public static ItemStack get(boolean aUseBlackList, ItemStack aStack, boolean unsafe) { + if (GTUtility.isStackInvalid(aStack)) return null; + ItemData tPrefixMaterial = getAssociation(aStack); + if (tPrefixMaterial == null || !tPrefixMaterial.hasValidPrefixMaterialData() + || (aUseBlackList && tPrefixMaterial.mBlackListed)) return GTUtility.copyOrNull(aStack); + if (aUseBlackList && !GregTechAPI.sUnificationEntriesRegistered && isBlacklisted(aStack)) { + tPrefixMaterial.mBlackListed = true; + return GTUtility.copyOrNull(aStack); + } + if (tPrefixMaterial.mUnificationTarget == null) + tPrefixMaterial.mUnificationTarget = sName2StackMap.get(tPrefixMaterial.toString()); + ItemStack rStack = tPrefixMaterial.mUnificationTarget; + if (GTUtility.isStackInvalid(rStack)) return GTUtility.copyOrNull(aStack); + ItemStack newStack; + if (unsafe) { + newStack = GTUtility.copyAmountUnsafe(aStack.stackSize, rStack); + } else { + newStack = GTUtility.copyAmount(aStack.stackSize, rStack); + } + // NBT is assigned by reference here, so mutating it may have unexpected side effects. + newStack.setTagCompound(aStack.getTagCompound()); + return newStack; + } + + /** + * Doesn't copy the returned stack or set quantity. Be careful and do not mutate it; intended only to optimize + * comparisons + */ + public static ItemStack get_nocopy(ItemStack aStack) { + return get_nocopy(true, aStack); + } + + /** + * Doesn't copy the returned stack or set quantity. Be careful and do not mutate it; intended only to optimize + * comparisons + */ + static ItemStack get_nocopy(boolean aUseBlackList, ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return null; + ItemData tPrefixMaterial = getAssociation(aStack); + if (tPrefixMaterial == null || !tPrefixMaterial.hasValidPrefixMaterialData() + || (aUseBlackList && tPrefixMaterial.mBlackListed)) return aStack; + if (aUseBlackList && !GregTechAPI.sUnificationEntriesRegistered && isBlacklisted(aStack)) { + tPrefixMaterial.mBlackListed = true; + return aStack; + } + if (tPrefixMaterial.mUnificationTarget == null) + tPrefixMaterial.mUnificationTarget = sName2StackMap.get(tPrefixMaterial.toString()); + ItemStack rStack = tPrefixMaterial.mUnificationTarget; + if (GTUtility.isStackInvalid(rStack)) return aStack; + + // Yes, == and not .equals(). + // This check is primarily intended to optimize for the case where both rStack and aStack + // do not have NBT, and so we would be comparing null == null. + // + // Even if aStack and rStack may have equal NBT, we prefer to do an inexpensive + // new ItemStack() over the potentially expensive NBTTagCompound.equals(). + if (aStack.getTagCompound() == rStack.getTagCompound()) { + // Warning: rStack's stack size may not be equal to aStack's stack size. + return rStack; + } + + // Okay, okay, I lied, we actually do need to make a copy. + // This is to fix a long-standing bug where we were mutating NBT directly on rStack, + // which had unexpected and unpredictable ripple effects. + // + // We will do some custom copying here, to avoid ItemStack.copy(), + // which calls the potentially expensive NBTTagCompound.copy() + // NBT is assigned by reference here, so mutating it may have unexpected side effects. + ItemStack newStack = new ItemStack(rStack.getItem(), aStack.stackSize, Items.feather.getDamage(rStack)); + newStack.setTagCompound(aStack.getTagCompound()); + return newStack; + } + + /** + * Compares the first argument against an already-unificated second argument as if aUseBlackList was both true and + * false. + */ + public static boolean isInputStackEqual(ItemStack aStack, ItemStack unified_tStack) { + if (GTUtility.isStackInvalid(aStack)) return false; + return isInputStackEqual(aStack, getAssociation(aStack), unified_tStack); + } + + /** + * Compares the first argument against an already-unificated second argument as if aUseBlackList was both true and + * false. + */ + public static boolean isInputStackEqual(ItemStack aStack, ItemData aStackPrefixData, ItemStack unified_tStack) { + boolean alreadyCompared = false; + if (GTUtility.isStackInvalid(aStack)) return false; + ItemStack rStack = null; + if (aStackPrefixData == null || !aStackPrefixData.hasValidPrefixMaterialData()) + return GTUtility.areStacksEqual(aStack, unified_tStack, true); + else if (aStackPrefixData.mBlackListed) { + if (GTUtility.areStacksEqual(aStack, unified_tStack, true)) return true; + else alreadyCompared = true; + } + if (!alreadyCompared && !GregTechAPI.sUnificationEntriesRegistered && isBlacklisted(aStack)) { + aStackPrefixData.mBlackListed = true; + if (GTUtility.areStacksEqual(aStack, unified_tStack, true)) return true; + else alreadyCompared = true; + } + if (aStackPrefixData.mUnificationTarget == null) + aStackPrefixData.mUnificationTarget = sName2StackMap.get(aStackPrefixData.toString()); + rStack = aStackPrefixData.mUnificationTarget; + if (GTUtility.isStackInvalid(rStack)) + return !alreadyCompared && GTUtility.areStacksEqual(aStack, unified_tStack, true); + return GTUtility.areStacksEqual(rStack, unified_tStack, true); + } + + public static List getNonUnifiedStacks(Object obj) { + if (sUnificationTable.isEmpty() && !sItemStack2DataMap.isEmpty()) { + // use something akin to double check lock. this synchronization overhead is causing lag whenever my + // 5900x tries to do NEI lookup + synchronized (sUnificationTable) { + if (sUnificationTable.isEmpty() && !sItemStack2DataMap.isEmpty()) { + for (ItemStack tGTStack0 : sItemStack2DataMap.keySet()) { + ItemStack tStack0 = GTItemStack.internalCopyStack(tGTStack0); + ItemStack tStack1 = get_nocopy(false, tStack0); + if (!GTUtility.areStacksEqual(tStack0, tStack1)) { + List list = sUnificationTable.computeIfAbsent(tStack1, k -> new ArrayList<>()); + // greg's original code tries to dedupe the list using List#contains, which won't work + // on vanilla ItemStack. I removed it since it never worked and can be slow. + list.add(tStack0); + } + } + } + } + } + ItemStack[] aStacks = {}; + if (obj instanceof ItemStack) aStacks = new ItemStack[] { (ItemStack) obj }; + else if (obj instanceof ItemStack[]) aStacks = (ItemStack[]) obj; + else if (obj instanceof List) aStacks = (ItemStack[]) ((List) obj).toArray(new ItemStack[0]); + List rList = new ArrayList<>(); + for (ItemStack aStack : aStacks) { + if (aStack == null) continue; + rList.add(aStack); + List tList = sUnificationTable.get(aStack); + if (tList != null) { + for (ItemStack tStack : tList) { + ItemStack tStack1 = GTUtility.copyAmount(aStack.stackSize, tStack); + rList.add(tStack1); + } + } + } + return rList; + } + + public static void addItemData(ItemStack aStack, ItemData aData) { + if (GTUtility.isStackValid(aStack) && getItemData(aStack) == null && aData != null) setItemData(aStack, aData); + } + + public static void addItemDataFromInputs(ItemStack output, Object... inputs) { + int length = inputs.length; + ItemData[] tData = new ItemData[length]; + for (int i = 0; i < length; i++) { + if (inputs[i] instanceof ItemStack) { + tData[i] = GTOreDictUnificator.getItemData((ItemStack) inputs[i]); + } else if (inputs[i] instanceof ItemData) { + tData[i] = (ItemData) inputs[i]; + } else { + throw new IllegalArgumentException(); + } + } + if (GTUtility.arrayContainsNonNull(tData)) { + GTOreDictUnificator.addItemData(output, new ItemData(tData)); + } + } + + public static void setItemData(ItemStack aStack, ItemData aData) { + if (GTUtility.isStackInvalid(aStack) || aData == null) return; + ItemData tData = getItemData(aStack); + if (tData == null || !tData.hasValidPrefixMaterialData()) { + if (tData != null) for (Object tObject : tData.mExtraData) + if (!aData.mExtraData.contains(tObject)) aData.mExtraData.add(tObject); + if (aStack.stackSize > 1) { + if (aData.mMaterial != null) aData.mMaterial.mAmount /= aStack.stackSize; + for (MaterialStack tMaterial : aData.mByProducts) tMaterial.mAmount /= aStack.stackSize; + aStack = GTUtility.copyAmount(1, aStack); + } + sItemStack2DataMap.put(aStack, aData); + if (aData.hasValidMaterialData()) { + long tValidMaterialAmount = aData.mMaterial.mMaterial.contains(SubTag.NO_RECYCLING) ? 0 + : aData.mMaterial.mAmount >= 0 ? aData.mMaterial.mAmount : M; + for (MaterialStack tMaterial : aData.mByProducts) + tValidMaterialAmount += tMaterial.mMaterial.contains(SubTag.NO_RECYCLING) ? 0 + : tMaterial.mAmount >= 0 ? tMaterial.mAmount : M; + if (tValidMaterialAmount < M) GTModHandler.addToRecyclerBlackList(aStack); + } + if (mRunThroughTheList) { + if (GregTechAPI.sLoadStarted) { + mRunThroughTheList = false; + for (Entry tEntry : sItemStack2DataMap.entrySet()) if (!tEntry.getValue() + .hasValidPrefixData() || tEntry.getValue().mPrefix.mAllowNormalRecycling) + GTRecipeRegistrator.registerMaterialRecycling( + GTItemStack.internalCopyStack(tEntry.getKey()), + tEntry.getValue()); + } + } else { + if (!aData.hasValidPrefixData() || aData.mPrefix.mAllowNormalRecycling) + GTRecipeRegistrator.registerMaterialRecycling(aStack, aData); + } + } else { + for (Object tObject : aData.mExtraData) + if (!tData.mExtraData.contains(tObject)) tData.mExtraData.add(tObject); + } + } + + public static void removeItemData(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) { + return; + } + sItemStack2DataMap.remove(aStack); + } + + public static void addAssociation(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack, + boolean aBlackListed) { + if (aPrefix == null || aMaterial == null || GTUtility.isStackInvalid(aStack)) return; + if (Items.feather.getDamage(aStack) == W) for (byte i = 0; i < 16; i++) + setItemData(GTUtility.copyAmountAndMetaData(1, i, aStack), new ItemData(aPrefix, aMaterial, aBlackListed)); + setItemData(aStack, new ItemData(aPrefix, aMaterial, aBlackListed)); + } + + @Nullable + public static ItemData getItemData(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return null; + ItemData rData = sItemStack2DataMap.get(aStack); + if (rData == null) { // Try the lookup again but with wildcard damage value + rData = sItemStack2DataMap.get(GTItemStack.internalCopyStack(aStack, true)); + } + return rData; + } + + @Nullable + public static ItemData getAssociation(ItemStack aStack) { + ItemData rData = getItemData(aStack); + return rData != null && rData.hasValidPrefixMaterialData() ? rData : null; + } + + public static boolean isItemStackInstanceOf(ItemStack aStack, Object aName) { + if (GTUtility.isStringInvalid(aName) || GTUtility.isStackInvalid(aStack)) return false; + for (ItemStack tOreStack : getOresImmutable(aName.toString())) + if (GTUtility.areStacksEqual(tOreStack, aStack, true)) return true; + return false; + } + + public static boolean isItemStackDye(ItemStack aStack) { + if (GTUtility.isStackInvalid(aStack)) return false; + + for (Dyes tDye : Dyes.VALUES) if (isItemStackInstanceOf(aStack, tDye.toString())) return true; + + return false; + } + + public static boolean registerOre(OrePrefixes aPrefix, Object aMaterial, ItemStack aStack) { + return registerOre(aPrefix.get(aMaterial), aStack); + } + + public static boolean registerOre(Object aName, ItemStack aStack) { + if (aName == null || GTUtility.isStackInvalid(aStack)) return false; + + String tName = aName.toString(); + + if (GTUtility.isStringInvalid(tName)) return false; + + for (ItemStack itemStack : getOresImmutable(tName)) + if (GTUtility.areStacksEqual(itemStack, aStack, true)) return false; + + isRegisteringOre++; + OreDictionary.registerOre(tName, GTUtility.copyAmount(1, aStack)); + isRegisteringOre--; + return true; + } + + public static boolean isRegisteringOres() { + return isRegisteringOre > 0; + } + + public static boolean isAddingOres() { + return isAddingOre > 0; + } + + public static void resetUnificationEntries() { + for (ItemData tPrefixMaterial : sItemStack2DataMap.values()) tPrefixMaterial.mUnificationTarget = null; + } + + public static ItemStack getGem(MaterialStack aMaterial) { + return aMaterial == null ? null : getGem(aMaterial.mMaterial, aMaterial.mAmount); + } + + public static ItemStack getGem(Materials aMaterial, OrePrefixes aPrefix) { + return aMaterial == null ? null : getGem(aMaterial, aPrefix.mMaterialAmount); + } + + public static ItemStack getGem(Materials aMaterial, long aMaterialAmount) { + ItemStack rStack = null; + if (((aMaterialAmount >= M))) rStack = get(OrePrefixes.gem, aMaterial, aMaterialAmount / M); + if (rStack == null) { + if ((((aMaterialAmount * 2) % M == 0) || aMaterialAmount >= M * 16)) + rStack = get(OrePrefixes.gemFlawed, aMaterial, (aMaterialAmount * 2) / M); + if ((((aMaterialAmount * 4) >= M))) + rStack = get(OrePrefixes.gemChipped, aMaterial, (aMaterialAmount * 4) / M); + } + return rStack; + } + + public static ItemStack getDust(MaterialStack aMaterial) { + return aMaterial == null ? null : getDust(aMaterial.mMaterial, aMaterial.mAmount); + } + + public static ItemStack getDust(Materials aMaterial, OrePrefixes aPrefix) { + return aMaterial == null ? null : getDust(aMaterial, aPrefix.mMaterialAmount); + } + + public static ItemStack getDust(Materials aMaterial, long aMaterialAmount) { + if (aMaterialAmount <= 0) return null; + ItemStack rStack = null; + if (((aMaterialAmount % M == 0) || aMaterialAmount >= M * 16)) + rStack = get(OrePrefixes.dust, aMaterial, aMaterialAmount / M); + if (rStack == null && (((aMaterialAmount * 4) % M == 0) || aMaterialAmount >= M * 8)) + rStack = get(OrePrefixes.dustSmall, aMaterial, (aMaterialAmount * 4) / M); + if (rStack == null && (((aMaterialAmount * 9) >= M))) + rStack = get(OrePrefixes.dustTiny, aMaterial, (aMaterialAmount * 9) / M); + return rStack; + } + + public static ItemStack getIngot(MaterialStack aMaterial) { + return aMaterial == null ? null : getIngot(aMaterial.mMaterial, aMaterial.mAmount); + } + + public static ItemStack getIngot(Materials aMaterial, OrePrefixes aPrefix) { + return aMaterial == null ? null : getIngot(aMaterial, aPrefix.mMaterialAmount); + } + + public static ItemStack getIngot(Materials aMaterial, long aMaterialAmount) { + if (aMaterialAmount <= 0) return null; + ItemStack rStack = null; + if (((aMaterialAmount % (M * 9) == 0 && aMaterialAmount / (M * 9) > 1) || aMaterialAmount >= M * 72)) + rStack = get(OrePrefixes.block, aMaterial, aMaterialAmount / (M * 9)); + if (rStack == null && ((aMaterialAmount % M == 0) || aMaterialAmount >= M * 8)) + rStack = get(OrePrefixes.ingot, aMaterial, aMaterialAmount / M); + if (rStack == null && (((aMaterialAmount * 9) >= M))) + rStack = get(OrePrefixes.nugget, aMaterial, (aMaterialAmount * 9) / M); + return rStack; + } + + public static ItemStack getIngotOrDust(Materials aMaterial, long aMaterialAmount) { + if (aMaterialAmount <= 0) return null; + ItemStack rStack = getIngot(aMaterial, aMaterialAmount); + if (rStack == null) rStack = getDust(aMaterial, aMaterialAmount); + return rStack; + } + + public static ItemStack getIngotOrDust(MaterialStack aMaterial) { + ItemStack rStack = getIngot(aMaterial); + if (rStack == null) rStack = getDust(aMaterial); + return rStack; + } + + public static ItemStack getDustOrIngot(Materials aMaterial, long aMaterialAmount) { + if (aMaterialAmount <= 0) return null; + ItemStack rStack = getDust(aMaterial, aMaterialAmount); + if (rStack == null) rStack = getIngot(aMaterial, aMaterialAmount); + return rStack; + } + + public static ItemStack getDustOrIngot(MaterialStack aMaterial) { + ItemStack rStack = getDust(aMaterial); + if (rStack == null) rStack = getIngot(aMaterial); + return rStack; + } + + /** + * @return a Copy of the OreDictionary.getOres() List + */ + public static ArrayList getOres(OrePrefixes aPrefix, Object aMaterial) { + return getOres(aPrefix.get(aMaterial)); + } + + /** + * @return a Copy of the OreDictionary.getOres() List + */ + public static ArrayList getOres(Object aOreName) { + String aName = aOreName == null ? E : aOreName.toString(); + ArrayList rList = new ArrayList<>(); + if (GTUtility.isStringValid(aName)) rList.addAll(OreDictionary.getOres(aName)); + return rList; + } + + /** + * Fast version of {@link #getOres(Object)}, which doesn't call + * {@link System#arraycopy(Object, int, Object, int, int)} in {@link ArrayList#addAll} + */ + public static List getOresImmutable(@Nullable Object aOreName) { + String aName = aOreName == null ? E : aOreName.toString(); + + return GTUtility.isStringValid(aName) ? Collections.unmodifiableList(OreDictionary.getOres(aName)) + : Collections.emptyList(); + } +} diff --git a/src/main/java/gregtech/api/util/GTPlayedSound.java b/src/main/java/gregtech/api/util/GTPlayedSound.java new file mode 100644 index 0000000000..0b527136b3 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTPlayedSound.java @@ -0,0 +1,31 @@ +package gregtech.api.util; + +import net.minecraft.util.ResourceLocation; + +public class GTPlayedSound { + + public final String mSoundName; + public final int mX, mY, mZ; + + public GTPlayedSound(ResourceLocation aSoundResourceLocation, double aX, double aY, double aZ) { + mSoundName = aSoundResourceLocation.toString(); + mX = (int) aX; + mY = (int) aY; + mZ = (int) aZ; + } + + @Override + public boolean equals(Object aObject) { + if (aObject instanceof GTPlayedSound) { + return ((GTPlayedSound) aObject).mX == mX && ((GTPlayedSound) aObject).mY == mY + && ((GTPlayedSound) aObject).mZ == mZ + && ((GTPlayedSound) aObject).mSoundName.equals(mSoundName); + } + return false; + } + + @Override + public int hashCode() { + return mX + mY + mZ + mSoundName.hashCode(); + } +} diff --git a/src/main/java/gregtech/api/util/GTRecipe.java b/src/main/java/gregtech/api/util/GTRecipe.java new file mode 100644 index 0000000000..7aa3dfbdfb --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRecipe.java @@ -0,0 +1,1366 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.D2; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; +import gregtech.GTMod; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.logic.FluidInventoryLogic; +import gregtech.api.logic.ItemInventoryLogic; +import gregtech.api.metatileentity.implementations.MTEHatchInput; +import gregtech.api.metatileentity.implementations.MTEHatchInputBus; +import gregtech.api.metatileentity.implementations.MTEHatchMultiInput; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeCategory; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.EmptyRecipeMetadataStorage; +import gregtech.api.recipe.metadata.IRecipeMetadataStorage; +import gregtech.api.util.extensions.ArrayExt; +import gregtech.api.util.item.ItemHolder; +import gregtech.common.tileentities.machines.MTEHatchInputBusME; +import gregtech.common.tileentities.machines.MTEHatchInputME; +import gregtech.nei.GTNEIDefaultHandler; +import ic2.core.Ic2Items; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.Reference2LongArrayMap; +import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; + +public class GTRecipe implements Comparable { + + private static ItemStack dataStick; + private static ItemStack dataOrb; + private static ItemStack ic2FluidCell; + + public static void setItemStacks() { + ic2FluidCell = Ic2Items.FluidCell.copy(); + dataStick = ItemList.Tool_DataStick.get(1L); + dataOrb = ItemList.Tool_DataOrb.get(1L); + } + + /** + * If you want to change the Output, feel free to modify or even replace the whole ItemStack Array, for Inputs, + * please add a new Recipe, because of the HashMaps. + */ + public ItemStack[] mInputs, mOutputs; + /** + * If you want to change the Output, feel free to modify or even replace the whole ItemStack Array, for Inputs, + * please add a new Recipe, because of the HashMaps. + */ + public FluidStack[] mFluidInputs, mFluidOutputs; + /** + * If you changed the amount of Array-Items inside the Output Array then the length of this Array must be larger or + * equal to the Output Array. A chance of 10000 equals 100% + */ + public int[] mChances; + /** + * An Item that needs to be inside the Special Slot, like for example the Copy Slot inside the Printer. This is only + * useful for Fake Recipes in NEI, since findRecipe() and containsInput() don't give a shit about this Field. Lists + * are also possible. + */ + public Object mSpecialItems; + + public int mDuration, mEUt, mSpecialValue; + /** + * Use this to just disable a specific Recipe, but the Configuration enables that already for every single Recipe. + */ + public boolean mEnabled = true; + /** + * If this Recipe is hidden from NEI + */ + public boolean mHidden = false; + /** + * If this Recipe is Fake and therefore doesn't get found by the findRecipe Function (It is still in the HashMaps, + * so that containsInput does return T on those fake Inputs) + */ + public boolean mFakeRecipe = false; + /** + * If this Recipe can be stored inside a Machine in order to make Recipe searching more Efficient by trying the + * previously used Recipe first. In case you have a Recipe Map overriding things and returning one time use Recipes, + * you have to set this to F. + */ + public boolean mCanBeBuffered = true; + /** + * If this Recipe needs the Output Slots to be completely empty. Needed in case you have randomised Outputs + */ + public boolean mNeedsEmptyOutput = false; + /** + * If this is set to true, NBT equality is required for recipe check. + */ + public boolean isNBTSensitive = false; + /** + * Used for describing recipes that do not fit the default recipe pattern (for example Large Boiler Fuels) + */ + private String[] neiDesc = null; + /** + * Holds a set of metadata for this recipe. + */ + @Nonnull + private final IRecipeMetadataStorage metadataStorage; + /** + * Category this recipe belongs to. Recipes belonging to recipemap are forced to have non-null category when added, + * otherwise it can be null. + */ + private RecipeCategory recipeCategory; + /** + * Stores which mod added this recipe + */ + public List owners = new ArrayList<>(); + /** + * Stores stack traces where this recipe was added + */ + // BW wants to overwrite it, so no final + public List> stackTraces = new ArrayList<>(); + + /** Used for simple cache validation */ + private ItemStack[] inputsAtCacheTime = null; + /** Unified and type-merged stacks of mInputs, each item is guaranteed to be unique */ + private RecipeItemInput[] mergedInputCache = null; + private static final RecipeItemInput[] EMPTY_INPUT_CACHE = new RecipeItemInput[0]; + + /** A single recipe input, used for an internal cache to speed up recipe matching */ + public static final class RecipeItemInput { + + /** Item count is ignored on this stack, do not mutate it either */ + public final ItemStack unifiedStack; + /** Number of input items required */ + public long inputAmount; + /** True if the input is NBT-sensitive */ + public final boolean usesNbtMatching; + + public RecipeItemInput(ItemStack stack, boolean recipeIsNBTSensitive) { + Objects.requireNonNull(stack); + this.inputAmount = stack.stackSize; + final boolean stackNeedsNBT = GTRecipe.shouldCheckNBT(stack); + this.usesNbtMatching = recipeIsNBTSensitive | stackNeedsNBT; + if (stackNeedsNBT) { + this.unifiedStack = stack; + } else { + this.unifiedStack = GTOreDictUnificator.get_nocopy(true, stack); + if (!this.usesNbtMatching) { + this.unifiedStack.setTagCompound(null); + } + } + } + + /** + * @return True if the passed in stack is of the same item type as this input (respecting + * {@link RecipeItemInput#usesNbtMatching}). + */ + public boolean matchesType(final ItemStack other) { + return GTUtility.areStacksEqual(this.unifiedStack, other, !usesNbtMatching); + } + + /** + * @return True if the given input+oredict data for that input can be used as a valid recipe ingredient. + */ + public boolean matchesRecipe(final ItemData oredictOther, final ItemStack other) { + if (usesNbtMatching) { + return GTUtility.areStacksEqual(this.unifiedStack, other, false); + } else { + return GTOreDictUnificator.isInputStackEqual(other, oredictOther, unifiedStack); + } + } + } + + private GTRecipe(GTRecipe aRecipe, boolean shallow) { + mInputs = shallow ? aRecipe.mInputs : GTUtility.copyItemArray(aRecipe.mInputs); + mOutputs = shallow ? aRecipe.mOutputs : GTUtility.copyItemArray(aRecipe.mOutputs); + mSpecialItems = aRecipe.mSpecialItems; + mChances = aRecipe.mChances; + mFluidInputs = shallow ? aRecipe.mFluidInputs : GTUtility.copyFluidArray(aRecipe.mFluidInputs); + mFluidOutputs = shallow ? aRecipe.mFluidOutputs : GTUtility.copyFluidArray(aRecipe.mFluidOutputs); + mDuration = aRecipe.mDuration; + mSpecialValue = aRecipe.mSpecialValue; + mEUt = aRecipe.mEUt; + mNeedsEmptyOutput = aRecipe.mNeedsEmptyOutput; + isNBTSensitive = aRecipe.isNBTSensitive; + mCanBeBuffered = aRecipe.mCanBeBuffered; + mFakeRecipe = aRecipe.mFakeRecipe; + mEnabled = aRecipe.mEnabled; + mHidden = aRecipe.mHidden; + metadataStorage = EmptyRecipeMetadataStorage.INSTANCE; + owners = new ArrayList<>(aRecipe.owners); + reloadOwner(); + } + + /** + * Only for {@link GTRecipeBuilder}. + */ + GTRecipe(ItemStack[] mInputs, ItemStack[] mOutputs, FluidStack[] mFluidInputs, FluidStack[] mFluidOutputs, + int[] mChances, Object mSpecialItems, int mDuration, int mEUt, int mSpecialValue, boolean mEnabled, + boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, boolean mNeedsEmptyOutput, boolean nbtSensitive, + String[] neiDesc, @Nullable IRecipeMetadataStorage metadataStorage, RecipeCategory recipeCategory) { + this.mInputs = mInputs; + this.mOutputs = mOutputs; + this.mFluidInputs = mFluidInputs; + this.mFluidOutputs = mFluidOutputs; + this.mChances = mChances; + this.mSpecialItems = mSpecialItems; + this.mDuration = mDuration; + this.mEUt = mEUt; + this.mSpecialValue = mSpecialValue; + this.mEnabled = mEnabled; + this.mHidden = mHidden; + this.mFakeRecipe = mFakeRecipe; + this.mCanBeBuffered = mCanBeBuffered; + this.mNeedsEmptyOutput = mNeedsEmptyOutput; + this.isNBTSensitive = nbtSensitive; + this.neiDesc = neiDesc; + this.metadataStorage = metadataStorage == null ? EmptyRecipeMetadataStorage.INSTANCE : metadataStorage.copy(); + this.recipeCategory = recipeCategory; + + reloadOwner(); + } + + public GTRecipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, + FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { + if (aInputs == null) aInputs = new ItemStack[0]; + if (aOutputs == null) aOutputs = new ItemStack[0]; + if (aFluidInputs == null) aFluidInputs = new FluidStack[0]; + if (aFluidOutputs == null) aFluidOutputs = new FluidStack[0]; + if (aChances == null) aChances = new int[aOutputs.length]; + if (aChances.length < aOutputs.length) aChances = Arrays.copyOf(aChances, aOutputs.length); + + aInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new); + aOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new); + aFluidInputs = ArrayExt.withoutNulls(aFluidInputs, FluidStack[]::new); + aFluidOutputs = ArrayExt.withoutNulls(aFluidOutputs, FluidStack[]::new); + + GTOreDictUnificator.setStackArray(true, aInputs); + GTOreDictUnificator.setStackArray(true, aOutputs); + + for (ItemStack tStack : aOutputs) GTUtility.updateItemStack(tStack); + + for (int i = 0; i < aChances.length; i++) if (aChances[i] <= 0) aChances[i] = 10000; + for (int i = 0; i < aFluidInputs.length; i++) aFluidInputs[i] = aFluidInputs[i].copy(); + for (int i = 0; i < aFluidOutputs.length; i++) aFluidOutputs[i] = aFluidOutputs[i].copy(); + + if (aOptimize && aDuration >= 32) { + ArrayList tList = new ArrayList<>(); + tList.addAll(Arrays.asList(aInputs)); + tList.addAll(Arrays.asList(aOutputs)); + for (int i = 0; i < tList.size(); i++) if (tList.get(i) == null) tList.remove(i--); + + for (byte i = (byte) Math.min(64, aDuration / 16); i > 1; i--) if (aDuration / i >= 16) { + boolean temp = true; + for (ItemStack stack : tList) if (stack.stackSize % i != 0) { + temp = false; + break; + } + if (temp) for (FluidStack aFluidInput : aFluidInputs) if (aFluidInput.amount % i != 0) { + temp = false; + break; + } + if (temp) for (FluidStack aFluidOutput : aFluidOutputs) if (aFluidOutput.amount % i != 0) { + temp = false; + break; + } + if (temp) { + for (ItemStack itemStack : tList) itemStack.stackSize /= i; + for (FluidStack aFluidInput : aFluidInputs) aFluidInput.amount /= i; + for (FluidStack aFluidOutput : aFluidOutputs) aFluidOutput.amount /= i; + aDuration /= i; + } + } + } + + mInputs = aInputs; + mOutputs = aOutputs; + mSpecialItems = aSpecialItems; + mChances = aChances; + mFluidInputs = aFluidInputs; + mFluidOutputs = aFluidOutputs; + mDuration = aDuration; + mSpecialValue = aSpecialValue; + mEUt = aEUt; + metadataStorage = EmptyRecipeMetadataStorage.INSTANCE; + // checkCellBalance(); + reloadOwner(); + } + + // aSpecialValue = EU per Liter! If there is no Liquid for this Object, then it gets multiplied with 1000! + public GTRecipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, + int aSpecialValue, int aType) { + this( + true, + new ItemStack[] { aInput1 }, + new ItemStack[] { aOutput1, aOutput2, aOutput3, aOutput4 }, + null, + null, + null, + null, + 0, + 0, + Math.max(1, aSpecialValue)); + + if (mInputs.length > 0 && aSpecialValue > 0) { + switch (aType) { + // Diesel Generator + case 0 -> { + RecipeMaps.dieselFuels.addRecipe(this); + RecipeMaps.largeBoilerFakeFuels.getBackend() + .addDieselRecipe(this); + } + // Gas Turbine + case 1 -> RecipeMaps.gasTurbineFuels.addRecipe(this); + + // Thermal Generator + case 2 -> RecipeMaps.hotFuels.addRecipe(this); + + // Plasma Generator + case 4 -> RecipeMaps.plasmaFuels.addRecipe(this); + + // Magic Generator + case 5 -> RecipeMaps.magicFuels.addRecipe(this); + + // Fluid Generator. Usually 3. Every wrong Type ends up in the Semifluid Generator + default -> { + RecipeMaps.denseLiquidFuels.addRecipe(this); + RecipeMaps.largeBoilerFakeFuels.getBackend() + .addDenseLiquidRecipe(this); + } + } + } + } + + // Dummy GTRecipe maker... + public GTRecipe(ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, + FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { + this( + true, + aInputs, + aOutputs, + aSpecialItems, + aChances, + aFluidInputs, + aFluidOutputs, + aDuration, + aEUt, + aSpecialValue); + } + + /** + * Re-unificates all the items present in recipes. + */ + public static void reInit() { + GTLog.out.println("GTMod: Re-Unificating Recipes."); + for (RecipeMap map : RecipeMap.ALL_RECIPE_MAPS.values()) { + map.getBackend() + .reInit(); + } + } + + public ItemStack getRepresentativeInput(int aIndex) { + if (aIndex < 0 || aIndex >= mInputs.length) return null; + return GTUtility.copyOrNull(mInputs[aIndex]); + } + + public ItemStack getOutput(int aIndex) { + if (aIndex < 0 || aIndex >= mOutputs.length) return null; + return GTUtility.copyOrNull(mOutputs[aIndex]); + } + + /** + * Dictates the ItemStacks displayed in the output slots of any NEI page handled by the default GT NEI handler. + * Override to make shown items differ from a GTRecipe's item output array + * + * @see GTNEIDefaultHandler + * @param i Slot index + * @return ItemStack to be displayed in the slot + */ + public ItemStack getRepresentativeOutput(int i) { + return getOutput(i); + } + + public int getOutputChance(int aIndex) { + if (mChances == null) return 10000; + if (aIndex < 0 || aIndex >= mChances.length) return 10000; + return mChances[aIndex]; + } + + public FluidStack getRepresentativeFluidInput(int aIndex) { + if (aIndex < 0 || aIndex >= mFluidInputs.length || mFluidInputs[aIndex] == null) return null; + return mFluidInputs[aIndex].copy(); + } + + public FluidStack getFluidOutput(int aIndex) { + if (aIndex < 0 || aIndex >= mFluidOutputs.length || mFluidOutputs[aIndex] == null) return null; + return mFluidOutputs[aIndex].copy(); + } + + public void checkCellBalance() { + if (!D2 || mInputs.length < 1) return; + + int tInputAmount = GTModHandler.getCapsuleCellContainerCountMultipliedWithStackSize(mInputs); + int tOutputAmount = GTModHandler.getCapsuleCellContainerCountMultipliedWithStackSize(mOutputs); + + if (tInputAmount < tOutputAmount) { + if (!Materials.Tin.contains(mInputs)) { + GTLog.err.println("You get more Cells, than you put in? There must be something wrong."); + new Exception().printStackTrace(GTLog.err); + } + } else if (tInputAmount > tOutputAmount) { + if (!Materials.Tin.contains(mOutputs)) { + GTLog.err.println("You get less Cells, than you put in? GT Machines usually don't destroy Cells."); + new Exception().printStackTrace(GTLog.err); + } + } + } + + public GTRecipe copy() { + return new GTRecipe(this, false); + } + + public GTRecipe copyShallow() { + return new GTRecipe(this, true); + } + + public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, FluidStack[] aFluidInputs, + ItemStack... aInputs) { + return isRecipeInputEqual(aDecreaseStacksizeBySuccess, false, 1, aFluidInputs, aInputs); + } + + // For non-multiplied recipe amount values + public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes, + FluidStack[] aFluidInputs, ItemStack... aInputs) { + return isRecipeInputEqual(aDecreaseStacksizeBySuccess, aDontCheckStackSizes, 1, aFluidInputs, aInputs); + } + + /** + * Okay, did some code archeology to figure out what's going on here. + * + *

+ * This variable was added in this + * commit, in order to fix the issues mentioned in the PR. + * + *

+ * It looks like it controls checking NBT. At this point, since we are still using universal fluid cells which store + * their fluids in NBT, it probably will not be safe to disable the NBT checks in the near future. Data sticks may + * be another case. Anyway, we probably can't get rid of this without some significant changes to clean up recipe + * inputs. + */ + public static boolean GTppRecipeHelper; + + /** + * @return Computes a (cached) array of all input items, combined by type into stacks. Do not mutate. + */ + private @NotNull RecipeItemInput @NotNull [] getCachedCombinedItemInputs() { + if (mergedInputCache != null) { + if (mInputs != inputsAtCacheTime) { + throw new IllegalStateException( + "Inputs to this recipe have been modified since first recipe match: " + this); + } + return mergedInputCache; + } + + synchronized (this) { + // In case another thread initialized it while this synchronized block was locked: + if (mergedInputCache != null) { + if (mInputs != inputsAtCacheTime) { + throw new IllegalStateException( + "Inputs to this recipe have been modified since first recipe match: " + this); + } + return mergedInputCache; + } + + final ItemStack[] inputs = mInputs; + inputsAtCacheTime = inputs; + if (inputs == null || inputs.length == 0) { + mergedInputCache = EMPTY_INPUT_CACHE; + return mergedInputCache; + } + final ObjectArrayList<@NotNull RecipeItemInput> newCache = ObjectArrayList + .wrap(new RecipeItemInput[inputs.length], 0); + for (final ItemStack itemStack : inputs) { + if (itemStack == null) continue; + final RecipeItemInput existingInput = newCache.stream() + .filter(existing -> existing.matchesType(itemStack)) + .findAny() + .orElse(null); + if (existingInput == null) { + newCache.add(new RecipeItemInput(itemStack, isNBTSensitive)); + } else { + existingInput.inputAmount = Math.addExact(existingInput.inputAmount, itemStack.stackSize); + } + } + final RecipeItemInput[] frozenCache = newCache.toArray(new RecipeItemInput[0]); + if (GregTechAPI.sFullLoadFinished) { + mergedInputCache = frozenCache; + } + return frozenCache; + } + } + + /** + * WARNING: Do not call this method with both {@code aDecreaseStacksizeBySuccess} and {@code aDontCheckStackSizes} + * set to {@code true}! You'll get weird behavior. + */ + public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes, + int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) { + double maxParallel = maxParallelCalculatedByInputs(amountMultiplier, aFluidInputs, aInputs); + if (aDontCheckStackSizes) { + return maxParallel > 0; + } else if (maxParallel >= amountMultiplier) { + if (aDecreaseStacksizeBySuccess) { + consumeInput(amountMultiplier, aFluidInputs, aInputs); + } + return true; + } + return false; + } + + /** + * WARNING: Ensure that item inputs and fluid inputs are enough to be consumed with + * {@link #maxParallelCalculatedByInputs} before calling this method! + */ + public void consumeInput(int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) { + if (amountMultiplier <= 0) return; + + if (aFluidInputs != null) { + for (FluidStack recipeFluidCost : mFluidInputs) { + if (recipeFluidCost != null) { + long remainingCost = (long) recipeFluidCost.amount * amountMultiplier; + + for (FluidStack providedFluid : aFluidInputs) { + if (providedFluid != null && providedFluid.isFluidEqual(recipeFluidCost)) { + if (providedFluid.amount >= remainingCost) { + providedFluid.amount -= remainingCost; + break; + } else { + remainingCost -= providedFluid.amount; + providedFluid.amount = 0; + } + } + } + } + } + } + + if (aInputs == null || aInputs.length == 0) { + return; + } + + final ItemData[] unifiedProvidedInputs = new ItemData[aInputs.length]; + for (int i = 0; i < aInputs.length; i++) { + unifiedProvidedInputs[i] = GTOreDictUnificator.getAssociation(aInputs[i]); + } + final @NotNull RecipeItemInput @NotNull [] combinedInputs = getCachedCombinedItemInputs(); + + for (final RecipeItemInput recipeItemCost : combinedInputs) { + long remainingCost = recipeItemCost.inputAmount * amountMultiplier; + + for (int iProvided = 0; iProvided < aInputs.length && remainingCost > 0; iProvided++) { + final ItemStack providedItem = aInputs[iProvided]; + if (providedItem == null || providedItem.stackSize == 0) { + continue; + } + + final ItemData providedUnifiedItem = unifiedProvidedInputs[iProvided]; + if (!recipeItemCost.matchesRecipe(providedUnifiedItem, providedItem)) { + continue; + } + + if (providedItem.stackSize >= remainingCost) { + providedItem.stackSize -= (int) remainingCost; + break; + } else { + remainingCost -= providedItem.stackSize; + providedItem.stackSize = 0; + } + } + } + } + + /** + * Returns the number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that inputs + * are found but not enough. + */ + public double maxParallelCalculatedByInputs(int maxParallel, FluidStack[] aFluidInputs, ItemStack... aInputs) { + if (mInputs.length > 0 && aInputs == null) return 0; + if (mFluidInputs.length > 0 && aFluidInputs == null) return 0; + + double currentParallel = maxParallel; + + // We need to have any fluids inputs, otherwise the code below does nothing. The second check is always true + // because of early exit condition above. + if (mFluidInputs.length > 0 /* && aFluidInputs != null */) { + // Create map for fluid -> stored amount + Reference2LongMap fluidMap = new Reference2LongArrayMap<>(2); + Reference2LongMap fluidCost = new Reference2LongArrayMap<>(2); + for (FluidStack fluidStack : aFluidInputs) { + if (fluidStack == null) continue; + fluidMap.mergeLong(fluidStack.getFluid(), fluidStack.amount, Long::sum); + } + for (FluidStack fluidStack : mFluidInputs) { + if (fluidStack == null) continue; + fluidCost.mergeLong(fluidStack.getFluid(), fluidStack.amount, Long::sum); + } + + // Check how many parallels can it perform for each fluid + for (Reference2LongMap.Entry costEntry : fluidCost.reference2LongEntrySet()) { + if (costEntry.getLongValue() > 0) { + currentParallel = Math.min( + currentParallel, + (double) fluidMap.getOrDefault(costEntry.getKey(), 0L) / costEntry.getLongValue()); + } + if (currentParallel <= 0) { + return 0; + } + } + } + + if (mInputs.length > 0) { + final @NotNull RecipeItemInput @NotNull [] combinedInputs = getCachedCombinedItemInputs(); + + if (aInputs.length < combinedInputs.length) { + // Fewer item types provided than required by the recipe, making it impossible to satisfy. + return 0; + } + final ItemData[] unifiedProvidedInputs = new ItemData[aInputs.length]; + for (int i = 0; i < aInputs.length; i++) { + unifiedProvidedInputs[i] = GTOreDictUnificator.getAssociation(aInputs[i]); + } + + recipeItemLoop: for (final RecipeItemInput combinedInput : combinedInputs) { + double remainingCost = combinedInput.inputAmount * currentParallel; + long providedAmount = 0; + + for (int i = 0; i < unifiedProvidedInputs.length; i++) { + final ItemData providedUnifiedItem = unifiedProvidedInputs[i]; + final ItemStack providedItem = aInputs[i]; + if (!combinedInput.matchesRecipe(providedUnifiedItem, providedItem)) { + continue; + } + + providedAmount += providedItem.stackSize; + + if (providedAmount >= remainingCost) { + continue recipeItemLoop; + } + } + if (providedAmount == 0) { + return 0; + } + currentParallel = Math.min(currentParallel, (double) providedAmount / combinedInput.inputAmount); + } + } + return currentParallel; + } + + /** + * Please see JavaDoc on {@link #GTppRecipeHelper} for why this is here. + */ + private static boolean shouldCheckNBT(ItemStack item) { + if (GTppRecipeHelper) { + return GTUtility.areStacksEqual(item, ic2FluidCell, true) || GTUtility.areStacksEqual(item, dataStick, true) + || GTUtility.areStacksEqual(item, dataOrb, true); + } + return false; + } + + public boolean isRecipePossible(@Nullable ItemInventoryLogic itemInput, @Nullable FluidInventoryLogic fluidInput) { + return getAmountOfRecipesDone(itemInput, fluidInput, 1, true) > 0; + } + + public long getAmountOfRecipesDone(@Nullable ItemInventoryLogic itemInput, @Nullable FluidInventoryLogic fluidInput, + long maxParallel, boolean simulate) { + if (itemInput == null) { + itemInput = new ItemInventoryLogic(0); + } + + if (fluidInput == null) { + fluidInput = new FluidInventoryLogic(0, 0); + } + + itemInput.startRecipeCheck(); + Map recipeItems = getItemInputsAsItemMap(); + for (Entry entry : recipeItems.entrySet()) { + maxParallel = Math + .min(maxParallel, itemInput.calculateAmountOfTimesItemCanBeTaken(entry.getKey(), entry.getValue())); + } + + for (FluidStack fluid : mFluidInputs) { + if (fluid == null) continue; + maxParallel = Math + .min(maxParallel, fluidInput.calculateAmountOfTimesFluidCanBeTaken(fluid.getFluid(), fluid.amount)); + } + + if (simulate) { + itemInput.stopRecipeCheck(); + return maxParallel; + } + + for (Entry entry : recipeItems.entrySet()) { + itemInput.subtractItemAmount(entry.getKey(), entry.getValue() * maxParallel, false); + } + + for (FluidStack fluid : mFluidInputs) { + if (fluid == null) continue; + fluidInput.drain(fluid.getFluid(), fluid.amount * maxParallel, false); + } + itemInput.stopRecipeCheck(); + return maxParallel; + } + + private Map getItemInputsAsItemMap() { + Map items = new HashMap<>(); + for (ItemStack item : mInputs) { + if (item == null) continue; + ItemHolder itemHolder = new ItemHolder(item); + items.put(itemHolder, items.getOrDefault(itemHolder, 0L) + item.stackSize); + } + return items; + } + + @Override + public int compareTo(GTRecipe recipe) { + // first lowest tier recipes + // then fastest + // then with lowest special value + // then dry recipes + // then with fewer inputs + if (this.mEUt != recipe.mEUt) { + return Integer.compare(this.mEUt, recipe.mEUt); + } else if (this.mDuration != recipe.mDuration) { + return Integer.compare(this.mDuration, recipe.mDuration); + } else if (this.mSpecialValue != recipe.mSpecialValue) { + return Integer.compare(this.mSpecialValue, recipe.mSpecialValue); + } else if (this.mFluidInputs.length != recipe.mFluidInputs.length) { + return Integer.compare(this.mFluidInputs.length, recipe.mFluidInputs.length); + } else if (this.mInputs.length != recipe.mInputs.length) { + return Integer.compare(this.mInputs.length, recipe.mInputs.length); + } + return 0; + } + + public String[] getNeiDesc() { + return neiDesc; + } + + /** + * Sets description shown on NEI.
+ * If you have a large number of recipes for the recipemap, this is not efficient memory wise, so use + * {@link gregtech.api.recipe.RecipeMapBuilder#neiSpecialInfoFormatter} instead. + */ + public void setNeiDesc(String... neiDesc) { + this.neiDesc = neiDesc; + } + + // region metadata + + // Don't try implementing setMetadata, as metadataStorage can be EmptyRecipeMetadataStorage + + /** + * Gets metadata associated with this recipe. Can return null. Use + * {@link #getMetadataOrDefault(RecipeMetadataKey, Object)} + * if you want to specify default value. + */ + @Nullable + public T getMetadata(RecipeMetadataKey key) { + return key.cast(metadataStorage.getMetadata(key)); + } + + /** + * Gets metadata associated with this recipe with default value. Does not return null unless default value is null. + */ + @Contract("_, !null -> !null") + @Nullable + public T getMetadataOrDefault(RecipeMetadataKey key, @Nullable T defaultValue) { + return key.cast(metadataStorage.getMetadataOrDefault(key, defaultValue)); + } + + @Nonnull + public IRecipeMetadataStorage getMetadataStorage() { + return metadataStorage; + } + + // endregion + + public RecipeCategory getRecipeCategory() { + return recipeCategory; + } + + /** + * Exists only for recipe copying from external. For ordinal use case, use {@link GTRecipeBuilder#recipeCategory}. + */ + public void setRecipeCategory(RecipeCategory recipeCategory) { + this.recipeCategory = recipeCategory; + } + + private static final List excludedStacktraces = Arrays.asList( + "java.lang.Thread", + "gregtech.api.interfaces.IRecipeMap", + "gregtech.api.interfaces.IRecipeMap$1", + "gregtech.api.recipe.RecipeMap", + "gregtech.api.recipe.RecipeMapBackend", + "gregtech.api.recipe.RecipeMapBackendPropertiesBuilder", + "gregtech.api.util.GTRecipe", + "gregtech.api.util.GTRecipeBuilder", + "gregtech.api.util.GTRecipeConstants", + "gregtech.api.util.GTRecipeMapUtil", + "gregtech.common.GTRecipeAdder"); + + public void reloadOwner() { + setOwner( + Loader.instance() + .activeModContainer()); + + if (GTMod.gregtechproxy.mNEIRecipeOwnerStackTrace) { + List toAdd = new ArrayList<>(); + for (StackTraceElement stackTrace : Thread.currentThread() + .getStackTrace()) { + if (excludedStacktraces.stream() + .noneMatch( + c -> stackTrace.getClassName() + .equals(c))) { + toAdd.add(formatStackTrace(stackTrace)); + } + } + stackTraces.add(toAdd); + } + } + + private static String formatStackTrace(StackTraceElement stackTraceElement) { + String raw = stackTraceElement.toString(); + int startParen = raw.lastIndexOf('('); + int colon = raw.lastIndexOf(':'); + if (colon == -1) { + // native or unknown source + return raw; + } + // strip class name and leave line number, as class name is already shown + return raw.substring(0, startParen + 1) + raw.substring(colon); + } + + public void setOwner(ModContainer newOwner) { + ModContainer oldOwner = !owners.isEmpty() ? this.owners.get(owners.size() - 1) : null; + if (newOwner != null && newOwner != oldOwner) { + owners.add(newOwner); + } + } + + /** + * Use in case {@link Loader#activeModContainer()} isn't helpful + */ + public void setOwner(String modId) { + for (ModContainer mod : Loader.instance() + .getModList()) { + if (mod.getModId() + .equals(modId)) { + setOwner(mod); + return; + } + } + } + + public GTRecipe setInputs(ItemStack... aInputs) { + // TODO determine if we need this without trailing nulls call + this.mInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new); + return this; + } + + public GTRecipe setOutputs(ItemStack... aOutputs) { + this.mOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new); + return this; + } + + public GTRecipe setFluidInputs(FluidStack... aInputs) { + this.mFluidInputs = ArrayExt.withoutTrailingNulls(aInputs, FluidStack[]::new); + return this; + } + + public GTRecipe setFluidOutputs(FluidStack... aOutputs) { + this.mFluidOutputs = ArrayExt.withoutTrailingNulls(aOutputs, FluidStack[]::new); + return this; + } + + public GTRecipe setDuration(int aDuration) { + this.mDuration = aDuration; + return this; + } + + public GTRecipe setEUt(int aEUt) { + this.mEUt = aEUt; + return this; + } + + public static class RecipeAssemblyLine { + + public static final ArrayList sAssemblylineRecipes = new ArrayList<>(); + + static { + if (!Boolean.getBoolean("com.gtnh.gt5u.ignore-invalid-assline-recipe")) + GregTechAPI.sFirstWorldTick.add(RecipeAssemblyLine::checkInvalidRecipes); + else GTLog.out.println("NOT CHECKING INVALID ASSLINE RECIPE."); + } + + private static void checkInvalidRecipes() { + int invalidCount = 0; + GTLog.out.println("Started assline validation"); + for (RecipeAssemblyLine recipe : sAssemblylineRecipes) { + if (recipe.getPersistentHash() == 0) { + invalidCount++; + GTLog.err.printf("Invalid recipe: %s%n", recipe); + } + } + if (invalidCount > 0) throw new RuntimeException( + "There are " + invalidCount + " invalid assembly line recipe(s)! Check GregTech.log for details!"); + } + + public ItemStack mResearchItem; + public int mResearchTime; + public ItemStack[] mInputs; + public FluidStack[] mFluidInputs; + public ItemStack mOutput; + public int mDuration; + public int mEUt; + public ItemStack[][] mOreDictAlt; + private int mPersistentHash; + + /** + * THIS CONSTRUCTOR DOES SET THE PERSISTENT HASH. + *

+ * if you set one yourself, it will give you one of the RunetimeExceptions! + */ + public RecipeAssemblyLine(ItemStack aResearchItem, int aResearchTime, ItemStack[] aInputs, + FluidStack[] aFluidInputs, ItemStack aOutput, int aDuration, int aEUt) { + this( + aResearchItem, + aResearchTime, + aInputs, + aFluidInputs, + aOutput, + aDuration, + aEUt, + new ItemStack[aInputs.length][]); + int tPersistentHash = 1; + for (ItemStack tInput : aInputs) + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(tInput, true, false); + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(aResearchItem, true, false); + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(aOutput, true, false); + for (FluidStack tFluidInput : aFluidInputs) + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(tFluidInput, true, false); + tPersistentHash = tPersistentHash * 31 + aResearchTime; + tPersistentHash = tPersistentHash * 31 + aDuration; + tPersistentHash = tPersistentHash * 31 + aEUt; + setPersistentHash(tPersistentHash); + } + + /** + * THIS CONSTRUCTOR DOES NOT SET THE PERSISTENT HASH. + *

+ * if you don't set one yourself, it will break a lot of stuff! + */ + public RecipeAssemblyLine(ItemStack aResearchItem, int aResearchTime, ItemStack[] aInputs, + FluidStack[] aFluidInputs, ItemStack aOutput, int aDuration, int aEUt, ItemStack[][] aAlt) { + mResearchItem = aResearchItem; + mResearchTime = aResearchTime; + mInputs = aInputs; + mFluidInputs = aFluidInputs; + mOutput = aOutput; + mDuration = aDuration; + mEUt = aEUt; + mOreDictAlt = aAlt; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + GTItemStack[] thisInputs = new GTItemStack[this.mInputs.length]; + int totalInputStackSize = 0; + for (int i = 0; i < this.mInputs.length; i++) { + thisInputs[i] = new GTItemStack(this.mInputs[i]); + totalInputStackSize += thisInputs[i].mStackSize; + } + int inputHash = Arrays.deepHashCode(thisInputs); + int inputFluidHash = Arrays.deepHashCode(this.mFluidInputs); + GTItemStack thisOutput = new GTItemStack(mOutput); + GTItemStack thisResearch = new GTItemStack(mResearchItem); + int miscRecipeDataHash = Arrays.deepHashCode( + new Object[] { totalInputStackSize, mDuration, mEUt, thisOutput, thisResearch, mResearchTime }); + result = prime * result + inputFluidHash; + result = prime * result + inputHash; + result = prime * result + miscRecipeDataHash; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof RecipeAssemblyLine other)) { + return false; + } + if (this.mInputs.length != other.mInputs.length) { + return false; + } + if (this.mFluidInputs.length != other.mFluidInputs.length) { + return false; + } + // Check Outputs Match + GTItemStack output1 = new GTItemStack(this.mOutput); + GTItemStack output2 = new GTItemStack(other.mOutput); + if (!output1.equals(output2)) { + return false; + } + // Check Scanned Item Match + GTItemStack scan1 = new GTItemStack(this.mResearchItem); + GTItemStack scan2 = new GTItemStack(other.mResearchItem); + if (!scan1.equals(scan2)) { + return false; + } + // Check Items Match + GTItemStack[] thisInputs = new GTItemStack[this.mInputs.length]; + GTItemStack[] otherInputs = new GTItemStack[other.mInputs.length]; + for (int i = 0; i < thisInputs.length; i++) { + thisInputs[i] = new GTItemStack(this.mInputs[i]); + otherInputs[i] = new GTItemStack(other.mInputs[i]); + } + for (int i = 0; i < thisInputs.length; i++) { + if (!thisInputs[i].equals(otherInputs[i]) || thisInputs[i].mStackSize != otherInputs[i].mStackSize) { + return false; + } + } + // Check Fluids Match + for (int i = 0; i < this.mFluidInputs.length; i++) { + if (!this.mFluidInputs[i].isFluidStackIdentical(other.mFluidInputs[i])) { + return false; + } + } + + return this.mDuration == other.mDuration && this.mEUt == other.mEUt + && this.mResearchTime == other.mResearchTime; + } + + public int getPersistentHash() { + if (mPersistentHash == 0) + GTLog.err.println("Assline recipe persistent hash has not been set! Recipe: " + mOutput); + return mPersistentHash; + } + + @Override + public String toString() { + return "GTRecipe_AssemblyLine{" + "mResearchItem=" + + mResearchItem + + ", mResearchTime=" + + mResearchTime + + ", mInputs=" + + Arrays.toString(mInputs) + + ", mFluidInputs=" + + Arrays.toString(mFluidInputs) + + ", mOutput=" + + mOutput + + ", mDuration=" + + mDuration + + ", mEUt=" + + mEUt + + ", mOreDictAlt=" + + Arrays.toString(mOreDictAlt) + + '}'; + } + + /** + * @param aPersistentHash the persistent hash. it should reflect the exact input used to generate this recipe If + * 0 is passed in, the actual persistent hash will be automatically remapped to 1 + * instead. + * @throws IllegalStateException if the persistent hash has been set already + */ + public void setPersistentHash(int aPersistentHash) { + if (this.mPersistentHash != 0) throw new IllegalStateException("Cannot set persistent hash twice!"); + if (aPersistentHash == 0) this.mPersistentHash = 1; + else this.mPersistentHash = aPersistentHash; + } + + /** + * @param inputBusses List of input busses to check. + * @return An array containing the amount of item to consume from the first slot of every input bus. + * {@code null} if at least one item fails to match the recipe ingredient. + */ + public static int[] getItemConsumptionAmountArray(ArrayList inputBusses, + RecipeAssemblyLine recipe) { + int itemCount = recipe.mInputs.length; + if (itemCount == 0) return null; + int[] tStacks = new int[itemCount]; + for (int i = 0; i < itemCount; i++) { + MTEHatchInputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) return null; + ItemStack slotStack; + if (inputBus instanceof MTEHatchInputBusME meBus) { + slotStack = meBus.getShadowItemStack(0); + } else { + slotStack = inputBus.getStackInSlot(0); + } + if (slotStack == null) return null; + + int amount = getMatchedIngredientAmount(slotStack, recipe.mInputs[i], recipe.mOreDictAlt[i]); + if (amount < 0) return null; + + tStacks[i] = amount; + } + return tStacks; + } + + public static int getMatchedIngredientAmount(ItemStack aSlotStack, ItemStack aIngredient, ItemStack[] alts) { + if (alts == null || alts.length == 0) { + if (GTUtility.areStacksEqual(aSlotStack, aIngredient, true)) { + return aIngredient.stackSize; + } + return -1; + } + for (ItemStack tAltStack : alts) { + if (GTUtility.areStacksEqual(aSlotStack, tAltStack, true)) { + return tAltStack.stackSize; + } + } + return -1; + } + + /** + * @param inputBusses Input bus list to check. Usually the input bus list of multi. + * @param itemConsumptions Should be generated by {@link RecipeAssemblyLine#getItemConsumptionAmountArray}. + * @Return The number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that + * inputs are found but not enough. + */ + public static double maxParallelCalculatedByInputItems(ArrayList inputBusses, int maxParallel, + int[] itemConsumptions, Map inputsFromME) { + // Recipe item matching is done in the generation of itemConsumptions. + + Map itemConsumptionsFromME = new Object2LongOpenHashMap<>(); + double currentParallel = maxParallel; + + // Calculate the amount of each item to consume from ME + for (int i = 0; i < itemConsumptions.length; i++) { + MTEHatchInputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) return 0; + if (inputBus instanceof MTEHatchInputBusME meBus) { + ItemStack item = meBus.getShadowItemStack(0); + if (item == null) return 0; + GTUtility.ItemId id = GTUtility.ItemId.createNoCopy(item); + itemConsumptionsFromME.merge(id, (long) itemConsumptions[i], Long::sum); + } + } + // Calculate parallel from ME input busses + for (Entry entry : itemConsumptionsFromME.entrySet()) { + if (!inputsFromME.containsKey(entry.getKey())) return 0; + long consume = entry.getValue(); + // For non-consumed inputs + if (consume == 0) continue; + currentParallel = Math + .min(currentParallel, (double) inputsFromME.get(entry.getKey()).stackSize / consume); + if (currentParallel <= 0) return 0; + } + + // Calculate parallel from regular input busses + for (int i = 0; i < itemConsumptions.length; i++) { + MTEHatchInputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) return 0; + if (inputBus instanceof MTEHatchInputBusME) continue; + + ItemStack item = inputBus.getStackInSlot(0); + if (item == null) return 0; + // For non-consumed inputs + if (itemConsumptions[i] == 0) continue; + currentParallel = Math.min(currentParallel, (double) item.stackSize / itemConsumptions[i]); + if (currentParallel <= 0) return 0; + } + return currentParallel; + } + + /** + * @param inputHatches Input hatch list to check. Usually the input hatch list of multi. + * @param fluidConsumptions Fluid inputs of the recipe. + * @return The number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that + * fluids are found but not enough. + */ + public static double maxParallelCalculatedByInputFluids(ArrayList inputHatches, int maxParallel, + FluidStack[] fluidConsumptions, Map fluidsFromME) { + Map fluidConsumptionsFromME = new Reference2LongOpenHashMap<>(); + double currentParallel = maxParallel; + + // Calculate the amount of each fluid to consume from ME + for (int i = 0; i < fluidConsumptions.length; i++) { + MTEHatchInput inputHatch = inputHatches.get(i); + if (!inputHatch.isValid()) return 0; + if (inputHatch instanceof MTEHatchInputME meHatch) { + FluidStack fluid = meHatch.getShadowFluidStack(0); + if (fluid == null) return 0; + if (!GTUtility.areFluidsEqual(fluid, fluidConsumptions[i])) return 0; + fluidConsumptionsFromME.merge(fluid.getFluid(), (long) fluidConsumptions[i].amount, Long::sum); + } + } + // Calculate parallel from ME input hatches + for (Entry entry : fluidConsumptionsFromME.entrySet()) { + Fluid fluid = entry.getKey(); + if (!fluidsFromME.containsKey(fluid)) return 0; + long consume = entry.getValue(); + currentParallel = Math.min(currentParallel, (double) fluidsFromME.get(fluid).amount / consume); + if (currentParallel <= 0) return 0; + } + + // Calculate parallel from regular input hatches + for (int i = 0; i < fluidConsumptions.length; i++) { + MTEHatchInput inputHatch = inputHatches.get(i); + if (!inputHatch.isValid()) return 0; + if (inputHatch instanceof MTEHatchInputME) continue; + + FluidStack fluid; + if (inputHatch instanceof MTEHatchMultiInput multiInput) { + fluid = multiInput.getFluid(0); + } else { + fluid = inputHatch.getFillableStack(); + } + if (fluid == null) return 0; + if (!GTUtility.areFluidsEqual(fluid, fluidConsumptions[i])) return 0; + currentParallel = Math.min(currentParallel, (double) fluid.amount / fluidConsumptions[i].amount); + if (currentParallel <= 0) return 0; + } + return currentParallel; + } + + /** + * WARNING: Ensure that item inputs are enough to be consumed with + * {@link RecipeAssemblyLine#maxParallelCalculatedByInputItems} before calling this method! + * + * @param inputBusses Input bus list to check. Usually the input bus list of multi. + * @param itemConsumptions Should be generated by {@link RecipeAssemblyLine#getItemConsumptionAmountArray}. + */ + public static void consumeInputItems(ArrayList inputBusses, int amountMultiplier, + int[] itemConsumptions, Map inputsFromME) { + for (int i = 0; i < itemConsumptions.length; i++) { + MTEHatchInputBus inputBus = inputBusses.get(i); + if (!inputBus.isValid()) continue; + ItemStack item; + if (inputBus instanceof MTEHatchInputBusME meBus) { + item = inputsFromME.get(GTUtility.ItemId.createNoCopy(meBus.getShadowItemStack(0))); + } else { + item = inputBus.getStackInSlot(0); + } + item.stackSize -= itemConsumptions[i] * amountMultiplier; + } + } + + /** + * WARNING: Ensure that fluid inputs are enough to be consumed with + * {@link RecipeAssemblyLine#maxParallelCalculatedByInputFluids} before calling this method! + * + * @param inputHatches Input hatch list to check. Usually the input hatch list of multi. + * @param fluidConsumptions Fluid inputs of the recipe. + */ + public static void consumeInputFluids(ArrayList inputHatches, int amountMultiplier, + FluidStack[] fluidConsumptions, Map fluidsFromME) { + for (int i = 0; i < fluidConsumptions.length; i++) { + MTEHatchInput inputHatch = inputHatches.get(i); + if (!inputHatch.isValid()) continue; + FluidStack fluid; + if (inputHatch instanceof MTEHatchInputME meHatch) { + fluid = fluidsFromME.get( + meHatch.getShadowFluidStack(0) + .getFluid()); + } else if (inputHatch instanceof MTEHatchMultiInput multiInput) { + fluid = multiInput.getFluid(0); + } else { + fluid = inputHatch.getFillableStack(); + } + fluid.amount -= fluidConsumptions[i].amount * amountMultiplier; + } + } + } + + public static class GTRecipe_WithAlt extends GTRecipe { + + public ItemStack[][] mOreDictAlt; + + /** + * Only for {@link GTRecipeBuilder}. + */ + GTRecipe_WithAlt(ItemStack[] mInputs, ItemStack[] mOutputs, FluidStack[] mFluidInputs, + FluidStack[] mFluidOutputs, int[] mChances, Object mSpecialItems, int mDuration, int mEUt, + int mSpecialValue, boolean mEnabled, boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, + boolean mNeedsEmptyOutput, boolean nbtSensitive, String[] neiDesc, + @Nullable IRecipeMetadataStorage metadataStorage, RecipeCategory recipeCategory, + ItemStack[][] mOreDictAlt) { + super( + mInputs, + mOutputs, + mFluidInputs, + mFluidOutputs, + mChances, + mSpecialItems, + mDuration, + mEUt, + mSpecialValue, + mEnabled, + mHidden, + mFakeRecipe, + mCanBeBuffered, + mNeedsEmptyOutput, + nbtSensitive, + neiDesc, + metadataStorage, + recipeCategory); + this.mOreDictAlt = mOreDictAlt; + } + + public GTRecipe_WithAlt(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, + int[] aChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, + int aSpecialValue, ItemStack[][] aAlt) { + super( + aOptimize, + aInputs, + aOutputs, + aSpecialItems, + aChances, + aFluidInputs, + aFluidOutputs, + aDuration, + aEUt, + aSpecialValue); + mOreDictAlt = aAlt; + } + + public Object getAltRepresentativeInput(int aIndex) { + if (aIndex < 0) return null; + if (aIndex < mOreDictAlt.length) { + if (mOreDictAlt[aIndex] != null && mOreDictAlt[aIndex].length > 0) { + ItemStack[] rStacks = new ItemStack[mOreDictAlt[aIndex].length]; + for (int i = 0; i < mOreDictAlt[aIndex].length; i++) { + rStacks[i] = GTUtility.copyOrNull(mOreDictAlt[aIndex][i]); + } + return rStacks; + } + } + if (aIndex >= mInputs.length) return null; + return GTUtility.copyOrNull(mInputs[aIndex]); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTRecipeBuilder.java b/src/main/java/gregtech/api/util/GTRecipeBuilder.java new file mode 100644 index 0000000000..6f8acfb2dc --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRecipeBuilder.java @@ -0,0 +1,946 @@ +package gregtech.api.util; + +import static gregtech.api.util.GTRecipeMapUtil.SPECIAL_VALUE_ALIASES; +import static gregtech.api.util.GTUtility.copyFluidArray; +import static gregtech.api.util.GTUtility.copyItemArray; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Stream; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.item.ItemStack; +import net.minecraft.launchwrapper.Launch; +import net.minecraftforge.fluids.FluidStack; + +import org.jetbrains.annotations.Contract; + +import gregtech.GTMod; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Mods; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.recipe.RecipeCategory; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.IRecipeMetadataStorage; +import gregtech.api.recipe.metadata.RecipeMetadataStorage; +import gregtech.api.util.extensions.ArrayExt; + +@SuppressWarnings({ "unused", "UnusedReturnValue" }) +public class GTRecipeBuilder { + + // debug mode expose problems. panic mode help you check nothing is wrong-ish without you actively monitoring + private static final boolean DEBUG_MODE_NULL; + // Any stable release should be tested at least once with this: -Dgt.recipebuilder.panic.null=true + private static boolean PANIC_MODE_NULL; + private static final boolean DEBUG_MODE_INVALID; + private static final boolean DEBUG_MODE_FULL_ENERGY; + // Any stable release should be tested at least once with this: -Dgt.recipebuilder.panic.invalid=true + private static final boolean PANIC_MODE_INVALID; + private static final boolean DEBUG_MODE_COLLISION; + + // Any stable release should be tested at least once with this: -Dgt.recipebuilder.panic.collision=true + private static final boolean PANIC_MODE_COLLISION; + + // This should only be enabled in non stable instances only with -Dgt.recipebuilder.recipe_collision_check=true + public static final boolean ENABLE_COLLISION_CHECK; + + public static final int WILDCARD = 32767; + + // time units + public static final int HOURS = 20 * 60 * 60; + public static final int MINUTES = 20 * 60; + public static final int SECONDS = 20; + public static final int TICKS = 1; + + // fluid units + public static final int INGOTS = 144; + public static final int HALF_INGOT = 72; + public static final int QUARTER_INGOT = 36; + public static final int EIGHTH_INGOT = 18; + public static final int NUGGETS = 16; + public static final int BUCKETS = 1000; + + static { + final boolean debugAll; + if (System.getProperties() + .containsKey("gt.recipebuilder.debug")) { + debugAll = Boolean.getBoolean("gt.recipebuilder.debug"); + } else { + // turn on debug by default in dev mode + debugAll = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); + } + DEBUG_MODE_NULL = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.null"); + DEBUG_MODE_INVALID = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.invalid"); + DEBUG_MODE_COLLISION = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.collision"); + DEBUG_MODE_FULL_ENERGY = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.fullenergy"); + + final boolean panicAll = Boolean.getBoolean("gt.recipebuilder.panic"); + PANIC_MODE_NULL = panicAll || Boolean.getBoolean("gt.recipebuilder.panic.null"); + PANIC_MODE_INVALID = panicAll || Boolean.getBoolean("gt.recipebuilder.panic.invalid"); + PANIC_MODE_COLLISION = panicAll || Boolean.getBoolean("gt.recipebuilder.panic.collision"); + ENABLE_COLLISION_CHECK = Boolean.getBoolean("gt.recipebuilder.recipe_collision_check"); + } + + protected ItemStack[] inputsBasic = new ItemStack[0]; + protected Object[] inputsOreDict; + protected ItemStack[] outputs = new ItemStack[0]; + protected ItemStack[][] alts; + protected FluidStack[] fluidInputs = new FluidStack[0]; + protected FluidStack[] fluidOutputs = new FluidStack[0]; + protected int[] chances; + protected Object special; + protected int duration = -1; + protected int eut = -1; + protected int specialValue; + protected boolean enabled = true; + protected boolean hidden = false; + protected boolean fakeRecipe = false; + protected boolean mCanBeBuffered = true; + protected boolean mNeedsEmptyOutput = false; + protected boolean nbtSensitive = false; + protected String[] neiDesc; + protected RecipeCategory recipeCategory; + protected boolean optimize = true; + @Nullable + protected IRecipeMetadataStorage metadataStorage; + protected boolean checkForCollision = true; + /** + * If recipe addition should be skipped. + */ + protected boolean skip = false; + protected boolean valid = true; + + GTRecipeBuilder() {} + + private GTRecipeBuilder(ItemStack[] inputsBasic, Object[] inputsOreDict, ItemStack[] outputs, ItemStack[][] alts, + FluidStack[] fluidInputs, FluidStack[] fluidOutputs, int[] chances, Object special, int duration, int eut, + int specialValue, boolean enabled, boolean hidden, boolean fakeRecipe, boolean mCanBeBuffered, + boolean mNeedsEmptyOutput, boolean nbtSensitive, String[] neiDesc, RecipeCategory recipeCategory, + boolean optimize, @Nullable IRecipeMetadataStorage metadataStorage, boolean checkForCollision, boolean skip, + boolean valid) { + this.inputsBasic = inputsBasic; + this.inputsOreDict = inputsOreDict; + this.outputs = outputs; + this.alts = alts; + this.fluidInputs = fluidInputs; + this.fluidOutputs = fluidOutputs; + this.chances = chances; + this.special = special; + this.duration = duration; + this.eut = eut; + this.specialValue = specialValue; + this.enabled = enabled; + this.hidden = hidden; + this.fakeRecipe = fakeRecipe; + this.mCanBeBuffered = mCanBeBuffered; + this.mNeedsEmptyOutput = mNeedsEmptyOutput; + this.nbtSensitive = nbtSensitive; + this.neiDesc = neiDesc; + this.recipeCategory = recipeCategory; + this.optimize = optimize; + this.metadataStorage = metadataStorage; + if (this.metadataStorage != null) { + this.metadataStorage = this.metadataStorage.copy(); + } + this.checkForCollision = checkForCollision; + this.skip = skip; + this.valid = valid; + } + + // region helper methods + + private static FluidStack[] fix(FluidStack[] fluidInputs) { + return Arrays.stream(fluidInputs) + .filter(Objects::nonNull) + .map(FluidStack::copy) + .toArray(FluidStack[]::new); + } + + private static ItemStack[] fix(ItemStack[] inputs) { + return GTOreDictUnificator.setStackArray(true, ArrayExt.withoutTrailingNulls(inputs, ItemStack[]::new)); + } + + public static GTRecipeBuilder builder() { + return new GTRecipeBuilder(); + } + + /** + * Creates empty builder where only duration and EU/t are set to 0. + */ + public static GTRecipeBuilder empty() { + return new GTRecipeBuilder().duration(0) + .eut(0); + } + + private static boolean containsNull(Object[] arr) { + return arr == null || Arrays.stream(arr) + .anyMatch(Objects::isNull); + } + + private static void handleNullRecipeComponents(String componentType) { + // place a breakpoint here to catch all these issues + GTLog.err.print("null detected in "); + GTLog.err.println(componentType); + new NullPointerException().printStackTrace(GTLog.err); + if (PANIC_MODE_NULL) { + throw new IllegalArgumentException("null in argument"); + } + } + + private static boolean debugNull() { + return DEBUG_MODE_NULL || PANIC_MODE_NULL; + } + + public static void handleInvalidRecipe() { + if (!DEBUG_MODE_INVALID && !PANIC_MODE_INVALID) { + return; + } + // place a breakpoint here to catch all these issues + GTLog.err.print("invalid recipe"); + new IllegalArgumentException().printStackTrace(GTLog.err); + if (PANIC_MODE_INVALID) { + throw new IllegalArgumentException("invalid recipe"); + } + } + + public static void handleRecipeCollision(String details) { + if (!DEBUG_MODE_COLLISION && !PANIC_MODE_COLLISION) { + return; + } + GTLog.err.print("Recipe collision resulting in recipe loss detected with "); + GTLog.err.println(details); + if (PANIC_MODE_COLLISION) { + throw new IllegalArgumentException("Recipe Collision"); + } else { + // place a breakpoint here to catch all these issues + new IllegalArgumentException().printStackTrace(GTLog.err); + } + } + + public static void onConfigLoad() { + PANIC_MODE_NULL |= GTMod.gregtechproxy.crashOnNullRecipeInput; + } + + // endregion + + // region setter + + /** + * Non-OreDicted item inputs. Assumes input is unified. + */ + public GTRecipeBuilder itemInputsUnified(ItemStack... inputs) { + if (skip) return this; + if (debugNull() && containsNull(inputs)) handleNullRecipeComponents("itemInputUnified"); + inputsBasic = ArrayExt.withoutTrailingNulls(inputs, ItemStack[]::new); + inputsOreDict = null; + alts = null; + return this; + } + + /** + * Non-OreDicted item inputs. Assumes input is not unified. + */ + public GTRecipeBuilder itemInputs(ItemStack... inputs) { + if (skip) return this; + if (debugNull() && containsNull(inputs)) handleNullRecipeComponents("itemInputs"); + inputsBasic = fix(inputs); + inputsOreDict = null; + alts = null; + return this; + } + + /** + * OreDicted item inputs. Currently only used for assline recipes adder. + */ + public GTRecipeBuilder itemInputs(Object... inputs) { + if (skip) return this; + inputsOreDict = inputs; + alts = new ItemStack[inputs.length][]; + for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) { + Object input = inputs[i]; + if (input instanceof ItemStack) { + alts[i] = new ItemStack[] { (ItemStack) input }; + } else if (input instanceof ItemStack[]) { + alts[i] = ((ItemStack[]) input).clone(); + } else if (input instanceof Object[]arr) { + if (arr.length != 2) continue; + List ores = GTOreDictUnificator.getOres(arr[0]); + if (ores.isEmpty()) continue; + int size = ((Number) arr[1]).intValue(); + alts[i] = ores.stream() + .map(s -> GTUtility.copyAmount(size, s)) + .filter(GTUtility::isStackValid) + .toArray(ItemStack[]::new); + } else if (input == null) { + handleNullRecipeComponents("recipe oredict input"); + alts[i] = new ItemStack[0]; + } else { + throw new IllegalArgumentException("index " + i + ", unexpected type: " + input.getClass()); + } + } + inputsBasic = Arrays.stream(alts) + .map(ss -> ss.length > 0 ? ss[0] : null) + .toArray(ItemStack[]::new); + // optimize cannot handle recipes with alts + return noOptimize(); + } + + public GTRecipeBuilder itemOutputs(ItemStack... outputs) { + if (skip) return this; + if (debugNull() && containsNull(outputs)) handleNullRecipeComponents("itemOutputs"); + this.outputs = outputs; + if (chances != null && chances.length != outputs.length) { + throw new IllegalArgumentException("Output chances array and items array length differs"); + } + return this; + } + + /** + * Not intended to be used by recipe authors. + * Intended for recipe rewrite middlewares. + */ + public GTRecipeBuilder itemOutputs(ItemStack[] outputs, int[] chances) { + if (skip) return this; + if (debugNull() && containsNull(outputs)) handleNullRecipeComponents("itemOutputs"); + this.outputs = outputs; + this.chances = chances; + if (chances != null && chances.length != outputs.length) { + throw new IllegalArgumentException("Output chances array and items array length differs"); + } + return this; + } + + public GTRecipeBuilder fluidInputs(FluidStack... fluidInputs) { + if (skip) return this; + if (debugNull() && containsNull(fluidInputs)) handleNullRecipeComponents("fluidInputs"); + this.fluidInputs = fix(fluidInputs); + return this; + } + + public GTRecipeBuilder fluidOutputs(FluidStack... fluidOutputs) { + if (skip) return this; + if (debugNull() && containsNull(fluidOutputs)) handleNullRecipeComponents("fluidOutputs"); + this.fluidOutputs = fix(fluidOutputs); + return this; + } + + public GTRecipeBuilder outputChances(int... chances) { + if (skip) return this; + if (outputs != null && chances.length != outputs.length) { + throw new IllegalArgumentException("Output chances array and items array length differs"); + } + this.chances = chances; + return this; + } + + public GTRecipeBuilder special(Object special) { + this.special = special; + return this; + } + + public GTRecipeBuilder duration(int duration) { + this.duration = duration; + return this; + } + + public GTRecipeBuilder duration(long duration) { + this.duration = (int) duration; + return this; + } + + public GTRecipeBuilder eut(int eut) { + if (DEBUG_MODE_FULL_ENERGY) { + // Ignores ULV voltage + for (int i = 1; i < GTValues.VP.length; i++) { + if (eut <= GTValues.V[i] && eut > GTValues.VP[i]) { + GTLog.err.println( + "EUt > Practical Voltage detected. EUt: " + eut + ", Practical Voltage: " + GTValues.VP[i]); + new IllegalArgumentException().printStackTrace(GTLog.err); + break; + } + } + } + this.eut = eut; + return this; + } + + public GTRecipeBuilder eut(long eut) { + return eut((int) eut); + } + + /** + * prefer to use metadata over this. should only use when the target recipe map does not yet support metadata + * system, or it's to bridge legacy code and modern code. + */ + public GTRecipeBuilder specialValue(int specialValue) { + this.specialValue = specialValue; + return this; + } + + // I don't expect anyone to actually call this... + public GTRecipeBuilder disabled() { + this.enabled = false; + return this; + } + + public GTRecipeBuilder hidden() { + this.hidden = true; + return this; + } + + public GTRecipeBuilder fake() { + this.fakeRecipe = true; + return this; + } + + public GTRecipeBuilder noBuffer() { + this.mCanBeBuffered = false; + return this; + } + + public GTRecipeBuilder needsEmptyOutput() { + this.mNeedsEmptyOutput = true; + return this; + } + + public GTRecipeBuilder nbtSensitive() { + this.nbtSensitive = true; + return this; + } + + public GTRecipeBuilder setNEIDesc(String... neiDesc) { + this.neiDesc = neiDesc; + return this; + } + + public GTRecipeBuilder recipeCategory(RecipeCategory recipeCategory) { + this.recipeCategory = recipeCategory; + return this; + } + + /** + * Prevent the resulting recipe from optimizing recipe, which is a process that reduce recipe batch size. + */ + public GTRecipeBuilder noOptimize() { + this.optimize = false; + return this; + } + + /** + * Prevents checking collision with existing recipes when adding the built recipe. + */ + public GTRecipeBuilder ignoreCollision() { + this.checkForCollision = false; + return this; + } + + /** + * Sets metadata of the recipe. It can be used for recipe emitter to do special things, or for being stored in the + * built recipe and used for actual recipe processing. + *

+ * {@link GTRecipeConstants} has a series of metadata keys. Or you can create one by yourself. + */ + public GTRecipeBuilder metadata(RecipeMetadataKey key, T value) { + if (skip) return this; + if (metadataStorage == null) { + metadataStorage = new RecipeMetadataStorage(); + } + metadataStorage.store(key, value); + return this; + } + + /** + * Gets metadata already set for this builder. Can return null. Use + * {@link #getMetadataOrDefault(RecipeMetadataKey, Object)} + * if you want to specify default value. + */ + @Nullable + public T getMetadata(RecipeMetadataKey key) { + if (metadataStorage == null) { + return null; + } + return key.cast(metadataStorage.getMetadata(key)); + } + + /** + * Gets metadata already set for this builder with default value. Does not return null unless default value is null. + */ + @Contract("_, !null -> !null") + @Nullable + public T getMetadataOrDefault(RecipeMetadataKey key, T defaultValue) { + if (metadataStorage == null) { + return defaultValue; + } + return key.cast(metadataStorage.getMetadataOrDefault(key, defaultValue)); + } + + /** + * Specifies mods required to add the recipe. If any of the mods is not loaded, all the operations for this builder + * will be ignored. + * + * @param mods Mod(s) required for the recipe. + */ + public GTRecipeBuilder requireMods(Mods... mods) { + skip = Stream.of(mods) + .anyMatch(mod -> !mod.isModLoaded()); + return this; + } + + public GTRecipeBuilder requiresCleanRoom() { + return metadata(GTRecipeConstants.CLEANROOM, true); + } + + public GTRecipeBuilder requiresLowGravity() { + return metadata(GTRecipeConstants.LOW_GRAVITY, true); + } + + // endregion + + private static T[] copy(T[] arr) { + return arr == null ? null : arr.clone(); + } + + private static int[] copy(int[] arr) { + return arr == null ? null : arr.clone(); + } + + /** + * produce a deep copy of current values. anything unset will remain unset. IMPORTANT: If metadata contains mutable + * value, they will not be cloned! + *

+ * checkout docs/RecipeBuilder.md for more info on whether to copy or not. + */ + public GTRecipeBuilder copy() { + return new GTRecipeBuilder( + copyItemArray(inputsBasic), + copy(inputsOreDict), + copyItemArray(outputs), + copy(alts), + copyFluidArray(fluidInputs), + copyFluidArray(fluidOutputs), + copy(chances), + special, + duration, + eut, + specialValue, + enabled, + hidden, + fakeRecipe, + mCanBeBuffered, + mNeedsEmptyOutput, + nbtSensitive, + copy(neiDesc), + recipeCategory, + optimize, + metadataStorage, + checkForCollision, + skip, + valid); + } + + /** + * produce a deep copy of current values. anything unset will remain unset. discard all existing metadata + */ + public GTRecipeBuilder copyNoMetadata() { + return new GTRecipeBuilder( + copyItemArray(inputsBasic), + copy(inputsOreDict), + copyItemArray(outputs), + copy(alts), + copyFluidArray(fluidInputs), + copyFluidArray(fluidOutputs), + copy(chances), + special, + duration, + eut, + specialValue, + enabled, + hidden, + fakeRecipe, + mCanBeBuffered, + mNeedsEmptyOutput, + nbtSensitive, + copy(neiDesc), + recipeCategory, + optimize, + null, + checkForCollision, + skip, + valid); + } + + // region getter + + public ItemStack getItemInputBasic(int index) { + return index < inputsBasic.length ? inputsBasic[index] : null; + } + + public Object getItemInputOreDict(int index) { + return index < inputsOreDict.length ? inputsOreDict[index] : null; + } + + public ItemStack getItemOutput(int index) { + return index < outputs.length ? outputs[index] : null; + } + + public FluidStack getFluidInput(int index) { + return index < fluidInputs.length ? fluidInputs[index] : null; + } + + public FluidStack getFluidOutput(int index) { + return index < fluidOutputs.length ? fluidOutputs[index] : null; + } + + public ItemStack[] getItemInputsBasic() { + return inputsBasic; + } + + public Object[] getItemInputsOreDict() { + return inputsOreDict; + } + + public ItemStack[] getItemOutputs() { + return outputs; + } + + public FluidStack[] getFluidInputs() { + return fluidInputs; + } + + public FluidStack[] getFluidOutputs() { + return fluidOutputs; + } + + public int getDuration() { + return duration; + } + + public int[] getChances() { + return chances; + } + + public int getEUt() { + return eut; + } + + public RecipeCategory getRecipeCategory() { + return recipeCategory; + } + + public boolean isOptimize() { + return optimize; + } + + public boolean isCheckForCollision() { + return checkForCollision; + } + + // endregion + + // region validator + + public GTRecipeBuilder clearInvalid() { + valid = true; + return this; + } + + public GTRecipeBuilder invalidate() { + valid = false; + return this; + } + + public boolean isValid() { + return valid; + } + + private static boolean isArrayValid(@Nonnull Object[] arr, int min, int max) { + int count = 0; + for (Object o : arr) { + if (o != null) count += 1; + } + return min <= count && max >= count; + } + + /** + * Validate if input item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateNoInput() { + if (skip) return this; + return GTUtility.isArrayEmptyOrNull(inputsBasic) ? this : invalidate(); + } + + /** + * Validate if input fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateNoInputFluid() { + if (skip) return this; + return GTUtility.isArrayEmptyOrNull(fluidInputs) ? this : invalidate(); + } + + /** + * Validate if output item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateNoOutput() { + if (skip) return this; + return GTUtility.isArrayEmptyOrNull(outputs) ? this : invalidate(); + } + + /** + * Validate if output fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateNoOutputFluid() { + if (skip) return this; + return GTUtility.isArrayEmptyOrNull(fluidOutputs) ? this : invalidate(); + } + + /** + * Validate if input item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateInputCount(int min, int max) { + if (skip) return this; + if (inputsBasic == null) return min < 0 ? this : invalidate(); + return isArrayValid(inputsBasic, min, max) ? this : invalidate(); + } + + /** + * Validate if input fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateInputFluidCount(int min, int max) { + if (skip) return this; + if (fluidInputs == null) return min < 0 ? this : invalidate(); + return isArrayValid(fluidInputs, min, max) ? this : invalidate(); + } + + /** + * Validate if output item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateOutputCount(int min, int max) { + if (skip) return this; + if (outputs == null) return min < 0 ? this : invalidate(); + return isArrayValid(outputs, min, max) ? this : invalidate(); + } + + /** + * Validate if output fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow + * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. + */ + public GTRecipeBuilder validateOutputFluidCount(int min, int max) { + if (skip) return this; + if (fluidOutputs == null) return min < 0 ? this : invalidate(); + return isArrayValid(fluidOutputs, min, max) ? this : invalidate(); + } + + public GTRecipeBuilder validateAnyInput() { + if (skip) return this; + if (fluidInputs != null && isArrayValid(fluidInputs, 1, Integer.MAX_VALUE)) { + return this; + } + if (inputsBasic != null && isArrayValid(inputsBasic, 1, Integer.MAX_VALUE)) { + return this; + } + return invalidate(); + } + + public GTRecipeBuilder validateAnyOutput() { + if (skip) return this; + if (fluidOutputs != null && isArrayValid(fluidOutputs, 1, Integer.MAX_VALUE)) { + return this; + } + if (outputs != null && isArrayValid(outputs, 1, Integer.MAX_VALUE)) { + return this; + } + return invalidate(); + } + + // endregion + + /** + * Builds new recipe, without custom behavior of recipemaps. For adding recipe to recipemap, + * use {@link #addTo} instead. + * + * @return Built recipe. Returns empty if failed to build. + */ + public Optional build() { + if (skip) { + return Optional.empty(); + } + if (!valid) { + handleInvalidRecipe(); + return Optional.empty(); + } + preBuildChecks(); + optimize(); + return Optional.of( + decorate( + new GTRecipe( + inputsBasic, + outputs, + fluidInputs, + fluidOutputs, + chances, + special, + duration, + eut, + specialValue, + enabled, + hidden, + fakeRecipe, + mCanBeBuffered, + mNeedsEmptyOutput, + nbtSensitive, + neiDesc, + metadataStorage, + recipeCategory))); + } + + public GTRecipeBuilder forceOreDictInput() { + if (inputsOreDict != null || inputsBasic == null) return this; + return itemInputs((Object[]) inputsBasic); + } + + public Optional buildWithAlt() { + if (skip) { + return Optional.empty(); + } + if (inputsOreDict == null) { + throw new UnsupportedOperationException(); + } + if (!valid) { + handleInvalidRecipe(); + return Optional.empty(); + } + preBuildChecks(); + // no optimize. + return Optional.of( + decorate( + new GTRecipe.GTRecipe_WithAlt( + inputsBasic, + outputs, + fluidInputs, + fluidOutputs, + chances, + special, + duration, + eut, + specialValue, + enabled, + hidden, + fakeRecipe, + mCanBeBuffered, + mNeedsEmptyOutput, + nbtSensitive, + neiDesc, + metadataStorage, + recipeCategory, + alts))); + } + + private void preBuildChecks() { + if (duration == -1) throw new IllegalStateException("no duration"); + if (eut == -1) throw new IllegalStateException("no eut"); + } + + private void optimize() { + if (optimize) { + ArrayList l = new ArrayList<>(); + l.addAll(Arrays.asList(inputsBasic)); + l.addAll(Arrays.asList(outputs)); + for (int i = 0; i < l.size(); i++) if (l.get(i) == null) l.remove(i--); + + outer: for (byte i = (byte) Math.min(64, duration / 16); i > 1; i--) { + if (duration / i >= 16) { + for (ItemStack stack : l) { + if (stack.stackSize % i != 0) continue outer; + } + for (FluidStack fluidInput : fluidInputs) { + if (fluidInput.amount % i != 0) continue outer; + } + for (FluidStack fluidOutput : fluidOutputs) { + if (fluidOutput.amount % i != 0) continue outer; + } + for (ItemStack itemStack : l) itemStack.stackSize /= i; + for (FluidStack fluidInput : fluidInputs) fluidInput.amount /= i; + for (FluidStack fluidOutput : fluidOutputs) fluidOutput.amount /= i; + duration /= i; + } + } + optimize = false; + } + } + + private T decorate(T r) { + r.mHidden = hidden; + r.mCanBeBuffered = mCanBeBuffered; + r.mNeedsEmptyOutput = mNeedsEmptyOutput; + r.isNBTSensitive = nbtSensitive; + r.mFakeRecipe = fakeRecipe; + r.mEnabled = enabled; + if (neiDesc != null) r.setNeiDesc(neiDesc); + applyDefaultSpecialValues(r); + return r; + } + + private void applyDefaultSpecialValues(GTRecipe recipe) { + if (recipe.mSpecialValue != 0) return; + + int specialValue = 0; + if (getMetadataOrDefault(GTRecipeConstants.LOW_GRAVITY, false)) specialValue -= 100; + if (getMetadataOrDefault(GTRecipeConstants.CLEANROOM, false)) specialValue -= 200; + for (RecipeMetadataKey ident : SPECIAL_VALUE_ALIASES) { + Integer metadata = getMetadataOrDefault(ident, null); + if (metadata != null) { + specialValue = metadata; + break; + } + } + recipe.mSpecialValue = specialValue; + } + + public Collection addTo(IRecipeMap recipeMap) { + if (skip) { + return Collections.emptyList(); + } + return recipeMap.doAdd(this); + } + + public GTRecipeBuilder reset() { + metadataStorage = null; + alts = null; + chances = null; + duration = -1; + enabled = true; + eut = -1; + fakeRecipe = false; + fluidInputs = null; + fluidOutputs = null; + hidden = false; + inputsBasic = null; + inputsOreDict = null; + mCanBeBuffered = true; + mNeedsEmptyOutput = false; + nbtSensitive = false; + neiDesc = null; + recipeCategory = null; + optimize = true; + outputs = null; + special = null; + specialValue = 0; + skip = false; + valid = true; + return this; + } +} diff --git a/src/main/java/gregtech/api/util/GTRecipeConstants.java b/src/main/java/gregtech/api/util/GTRecipeConstants.java new file mode 100644 index 0000000000..82a477756a --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRecipeConstants.java @@ -0,0 +1,691 @@ +package gregtech.api.util; + +import static gregtech.api.recipe.RecipeMaps.scannerFakeRecipes; +import static gregtech.api.util.GTRecipeMapUtil.convertCellToFluid; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Optional; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeCategories; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.SimpleRecipeMetadataKey; +import gregtech.common.items.IDMetaItem03; +import gregtech.common.items.MetaGeneratedItem03; +import gtnhlanth.common.item.ItemPhotolithographicMask; +import gtnhlanth.common.item.MaskList; +import gtnhlanth.common.register.LanthItemList; + +// this class is intended to be import-static-ed on every recipe script +// so take care to not put unrelated stuff here! +public class GTRecipeConstants { + + /** + * Set to true to signal the recipe require low gravity. do nothing if recipe set specialValue explicitly. Can + * coexist with CLEANROOM just fine + */ + public static final RecipeMetadataKey LOW_GRAVITY = SimpleRecipeMetadataKey + .create(Boolean.class, "low_gravity"); + /** + * Set to true to signal the recipe require cleanroom. do nothing if recipe set specialValue explicitly. Can coexist + * with LOW_GRAVITY just fine + */ + public static final RecipeMetadataKey CLEANROOM = SimpleRecipeMetadataKey + .create(Boolean.class, "cleanroom"); + /** + * Common additive to use in recipe, e.g. for PBF, this is coal amount. + */ + public static final RecipeMetadataKey ADDITIVE_AMOUNT = SimpleRecipeMetadataKey + .create(Integer.class, "additives"); + /** + * Used for fusion reactor. Denotes ignition threshold. + */ + public static final RecipeMetadataKey FUSION_THRESHOLD = SimpleRecipeMetadataKey + .create(Integer.class, "fusion_threshold"); + /** + * Research time in a scanner used in ticks. + */ + public static final RecipeMetadataKey RESEARCH_TIME = SimpleRecipeMetadataKey + .create(Integer.class, "research_time"); + /** + * Fuel type. TODO should we use enum directly? + */ + public static final RecipeMetadataKey FUEL_TYPE = SimpleRecipeMetadataKey + .create(Integer.class, "fuel_type"); + /** + * Fuel value. + */ + public static final RecipeMetadataKey FUEL_VALUE = SimpleRecipeMetadataKey + .create(Integer.class, "fuel_value"); + /** + * Required heat for heating coil (Kelvin). + */ + public static final RecipeMetadataKey COIL_HEAT = SimpleRecipeMetadataKey + .create(Integer.class, "coil_heat"); + /** + * Research item used by assline recipes. + */ + public static final RecipeMetadataKey RESEARCH_ITEM = SimpleRecipeMetadataKey + .create(ItemStack.class, "research_item"); + /** + * For assembler. It accepts a single item as oredict. It looks like no one uses this anyway... + */ + public static final RecipeMetadataKey OREDICT_INPUT = SimpleRecipeMetadataKey + .create(Object.class, "oredict_input"); + /** + * Replicator output material. + */ + public static final RecipeMetadataKey MATERIAL = SimpleRecipeMetadataKey + .create(Materials.class, "material"); + /** + * Marker for {@link #UniversalArcFurnace} to tell that the recipe belongs to recycling category. + */ + public static final RecipeMetadataKey RECYCLE = SimpleRecipeMetadataKey.create(Boolean.class, "recycle"); + /** + * For Microwave. + */ + public static final RecipeMetadataKey EXPLODE = SimpleRecipeMetadataKey.create(Boolean.class, "explode"); + /** + * For Microwave. + */ + public static final RecipeMetadataKey ON_FIRE = SimpleRecipeMetadataKey.create(Boolean.class, "on_fire"); + + /** + * Nano Forge Tier. + */ + public static final RecipeMetadataKey NANO_FORGE_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "nano_forge_tier"); + + /** + * FOG Exotic recipe tier. + */ + public static final RecipeMetadataKey FOG_EXOTIC_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "fog_exotic_tier"); + + /** + * FOG Plasma recipe tier. + */ + public static final RecipeMetadataKey FOG_PLASMA_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "fog_plasma_tier"); + + /** + * DEFC Casing tier. + */ + public static final RecipeMetadataKey DEFC_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "defc_casing_tier"); + + /** + * Chemplant Casing tier. Beware, codewise index starts at 0, but it is tier 1. + */ + public static final RecipeMetadataKey CHEMPLANT_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "chemplant_casing_tier"); + + /** + * QFT Focus tier. + */ + public static final RecipeMetadataKey QFT_FOCUS_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "qft_focus_tier"); + + /** + * Tier of advanced compression (HIP/black hole) + */ + public static final RecipeMetadataKey COMPRESSION_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "compression"); + + /** + * Dissolution Tank Ratio. + */ + public static final RecipeMetadataKey DISSOLUTION_TANK_RATIO = SimpleRecipeMetadataKey + .create(Integer.class, "dissolution_tank_ratio"); + + /** + * Duration in days for the RTG. + */ + public static final RecipeMetadataKey RTG_DURATION_IN_DAYS = SimpleRecipeMetadataKey + .create(Integer.class, "rtg_duration_in_days"); + + /** + * Basic output for the Large Naquadah Generator. + */ + public static final RecipeMetadataKey LNG_BASIC_OUTPUT = SimpleRecipeMetadataKey + .create(Integer.class, "lng_basic_output"); + + /** + * Coil tier for the Naquadah Fuel Refinery. + */ + public static final RecipeMetadataKey NFR_COIL_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "nfr_coil_tier"); + + /** + * NKE range for the neutron activator. + */ + public static final RecipeMetadataKey NKE_RANGE = SimpleRecipeMetadataKey + .create(Integer.class, "nke_range"); + /** + * Precise Assembler casing tier. + */ + public static final RecipeMetadataKey PRECISE_ASSEMBLER_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "precise_assembler_casing_tier"); + /** + * CoAL casing tier. + */ + public static final RecipeMetadataKey COAL_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "coal_casing_tier"); + + /** + * LFTR output power. + */ + public static final RecipeMetadataKey LFTR_OUTPUT_POWER = SimpleRecipeMetadataKey + .create(Integer.class, "lftr_output_power"); + + /** + * Research Station data. + */ + public static final RecipeMetadataKey RESEARCH_STATION_DATA = SimpleRecipeMetadataKey + .create(Integer.class, "research_station_data"); + + /** + * glass tier required for the biovat recipes. + */ + public static final RecipeMetadataKey SIEVERTS = SimpleRecipeMetadataKey.create(Integer.class, "sieverts"); + + public static final RecipeMetadataKey DECAY_TICKS = SimpleRecipeMetadataKey + .create(Integer.class, "decay_ticks"); + + public static final RecipeMetadataKey NOBLE_GASES = SimpleRecipeMetadataKey + .create(Boolean.class, "noble_gases"); + + public static final RecipeMetadataKey ANAEROBE_GASES = SimpleRecipeMetadataKey + .create(Boolean.class, "anaerobe_gases"); + + public static final RecipeMetadataKey NO_GAS = SimpleRecipeMetadataKey.create(Boolean.class, "no_gas"); + + /** + * Add a arc furnace recipe. Adds to both normal arc furnace and plasma arc furnace. + * Will override the fluid input with oxygen/plasma for the respective recipe maps, so there is no point setting it. + */ + public static final IRecipeMap UniversalArcFurnace = IRecipeMap.newRecipeMap(builder -> { + if (!GTUtility.isArrayOfLength(builder.getItemInputsBasic(), 1) + || GTUtility.isArrayEmptyOrNull(builder.getItemOutputs())) return Collections.emptyList(); + int aDuration = builder.getDuration(); + if (aDuration <= 0) { + return Collections.emptyList(); + } + builder.duration(aDuration); + boolean recycle = builder.getMetadataOrDefault(RECYCLE, false); + Collection ret = new ArrayList<>(); + for (Materials mat : new Materials[] { Materials.Argon, Materials.Nitrogen }) { + int tPlasmaAmount = (int) Math.max(1L, aDuration / (mat.getMass() * 16L)); + GTRecipeBuilder plasmaBuilder = builder.copy() + .fluidInputs(mat.getPlasma(tPlasmaAmount)) + .fluidOutputs(mat.getGas(tPlasmaAmount)); + if (recycle) { + plasmaBuilder.recipeCategory(RecipeCategories.plasmaArcFurnaceRecycling); + } + ret.addAll(RecipeMaps.plasmaArcFurnaceRecipes.doAdd(plasmaBuilder)); + } + GTRecipeBuilder arcBuilder = builder.copy() + .fluidInputs(Materials.Oxygen.getGas(aDuration)); + if (recycle) { + arcBuilder.recipeCategory(RecipeCategories.arcFurnaceRecycling); + } + ret.addAll(RecipeMaps.arcFurnaceRecipes.doAdd(arcBuilder)); + return ret; + }); + + /** + * Add a chemical reactor recipe to both LCR and singleblocks. + */ + public static final IRecipeMap UniversalChemical = IRecipeMap.newRecipeMap(builder -> { + for (ItemStack input : builder.getItemInputsBasic()) { + // config >= 10 -> this is a special chemical recipe that output fluid/canned fluid variant. + // it doesn't belong to multiblocks + if (GTUtility.isAnyIntegratedCircuit(input) && input.getItemDamage() >= 10) { + return builder.addTo(RecipeMaps.chemicalReactorRecipes); + } + } + return GTUtility.concat( + builder.copy() + .addTo(RecipeMaps.chemicalReactorRecipes), + convertCellToFluid(builder, false) + // LCR does not need cleanroom. + .metadata(CLEANROOM, false) + .addTo(RecipeMaps.multiblockChemicalReactorRecipes)); + }); + + /** + * Adds an engraver recipe that might use purified water. Still added to the regular recipemap if it ends up not + * needing it. + */ + public static final IRecipeMap WaferEngravingRecipes = IRecipeMap.newRecipeMap(builder -> { + // spotless:off + enum Wafer{ + Naquadah, + Europium, + Americium, + // Beamline masks + MaskT1, + MaskT2, + MaskT3, + } + // spotless:on + // Find the wafer used + Wafer wafer = null; + ItemPhotolithographicMask t1Item = (ItemPhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK1); + ItemPhotolithographicMask t2Item = (ItemPhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK2); + ItemPhotolithographicMask t3Item = (ItemPhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK3); + for (ItemStack input : builder.getItemInputsBasic()) { + if (input.getItem() instanceof MetaGeneratedItem03) { + int meta = input.getItemDamage() - 32000; + // Check if this input item is indicating a wafer recipe we want to modify + if (meta == IDMetaItem03.Circuit_Silicon_Wafer3.ID) wafer = Wafer.Naquadah; + else if (meta == IDMetaItem03.Circuit_Silicon_Wafer4.ID) wafer = Wafer.Europium; + else if (meta == IDMetaItem03.Circuit_Silicon_Wafer5.ID) wafer = Wafer.Americium; + } + + // Now look for beamline masks + if (input.getItem() instanceof ItemPhotolithographicMask mask) { + String spectrum = mask.getDescSpectrum(); + if (spectrum.equals(t1Item.getDescSpectrum())) wafer = Wafer.MaskT1; + else if (spectrum.equals(t2Item.getDescSpectrum())) wafer = Wafer.MaskT2; + else if (spectrum.equals(t3Item.getDescSpectrum())) wafer = Wafer.MaskT3; + } + + // Found a wafer, stop checking inputs + if (wafer != null) break; + } + + int recipeTime = builder.duration; + // Bonus for using purified water of a higher tier than necessary + int halfBoostedRecipeTime = (int) (recipeTime * 0.75); + int boostedRecipeTime = (int) (recipeTime * 0.5); + + // If this recipe does not use a wafer, exit without modifying it. + if (wafer == null) return builder.addTo(RecipeMaps.laserEngraverRecipes); + switch (wafer) { + case Naquadah -> { + ArrayList items = new ArrayList<>(Arrays.asList(builder.getItemInputsBasic())); + ItemStack[] itemInputs = items.toArray(new ItemStack[] {}); + // Naquadah wafers can use grade 1-2 purified water for a bonus, otherwise use distilled so we don't + // have to + // deal with circuits + return GTUtility.concat( + builder.copy() + .itemInputs(itemInputs) + .fluidInputs(GTModHandler.getDistilledWater(100L)) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .itemInputs(itemInputs) + .fluidInputs(Materials.Grade1PurifiedWater.getFluid(100L)) + .duration(halfBoostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .itemInputs(itemInputs) + .fluidInputs(Materials.Grade2PurifiedWater.getFluid(100L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case Europium -> { + // Require purified water for europium wafers, at least grade 3 + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade3PurifiedWater.getFluid(100L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade4PurifiedWater.getFluid(100L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case Americium -> { + // Require purified water for americium wafers, at least grade 5 + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade5PurifiedWater.getFluid(100L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade6PurifiedWater.getFluid(100L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + // Masks require much more purified water because they can make many wafers at once + case MaskT1 -> { + // T1 masks require grade 1, 2 or 3 purified water + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade1PurifiedWater.getFluid(32000L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade2PurifiedWater.getFluid(32000L)) + .duration(halfBoostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade3PurifiedWater.getFluid(32000L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case MaskT2 -> { + // T2 masks require grade 4 or 5 purified water + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade4PurifiedWater.getFluid(32000L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade5PurifiedWater.getFluid(32000L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case MaskT3 -> { + // T3 masks require grade 6, 7 or 8 purified water + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade6PurifiedWater.getFluid(32000L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade7PurifiedWater.getFluid(32000L)) + .duration(halfBoostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade8PurifiedWater.getFluid(32000L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + } + + throw new RuntimeException("Unreachable code reached in Laser Engraver Recipe Transformer"); + }); + + /** + * The one and only :tm: assline recipe adder. + * Uses {@link #RESEARCH_ITEM} metadata as research item, and {@link #RESEARCH_TIME} metadata as research time, unit + * in ticks. + */ + public static final IRecipeMap AssemblyLine = IRecipeMap.newRecipeMap(builder -> { + Optional rr = builder.forceOreDictInput() + .validateInputCount(4, 16) + .validateOutputCount(1, 1) + .validateOutputFluidCount(-1, 0) + .validateInputFluidCount(1, 4) + .buildWithAlt(); + // noinspection SimplifyOptionalCallChains + if (!rr.isPresent()) return Collections.emptyList(); + GTRecipe.GTRecipe_WithAlt r = rr.get(); + ItemStack[][] mOreDictAlt = r.mOreDictAlt; + Object[] inputs = builder.getItemInputsOreDict(); + ItemStack aResearchItem = builder.getMetadata(RESEARCH_ITEM); + if (aResearchItem == null) { + return Collections.emptyList(); + } + ItemStack aOutput = r.mOutputs[0]; + int tPersistentHash = 1; + for (int i = 0, mOreDictAltLength = mOreDictAlt.length; i < mOreDictAltLength; i++) { + ItemStack[] alts = mOreDictAlt[i]; + Object input = inputs[i]; + if (input == null) { + GTLog.err.println( + "addAssemblingLineRecipe " + aResearchItem.getDisplayName() + + " --> " + + aOutput.getUnlocalizedName() + + " there is some null item in that recipe"); + } + if (input instanceof ItemStack) { + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash((ItemStack) input, true, false); + } else if (input instanceof ItemStack[]) { + for (ItemStack alt : ((ItemStack[]) input)) { + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(alt, true, false); + if (alt == null) { + GTLog.err.println( + "addAssemblingLineRecipe " + aResearchItem.getDisplayName() + + " --> " + + aOutput.getUnlocalizedName() + + " there is some null alt item in that recipe"); + } + } + tPersistentHash *= 31; + } else if (input instanceof Object[]objs) { + Arrays.sort( + alts, + Comparator + .comparing(s -> GameRegistry.findUniqueIdentifierFor(s.getItem()).modId) + .thenComparing(s -> GameRegistry.findUniqueIdentifierFor(s.getItem()).name) + .thenComparingInt(Items.feather::getDamage) + .thenComparingInt(s -> s.stackSize)); + + tPersistentHash = tPersistentHash * 31 + (objs[0] == null ? "" : objs[0].toString()).hashCode(); + tPersistentHash = tPersistentHash * 31 + ((Number) objs[1]).intValue(); + } + } + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(aResearchItem, true, false); + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(aOutput, true, false); + for (FluidStack fluidInput : r.mFluidInputs) { + if (fluidInput == null) continue; + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(fluidInput, true, false); + } + int aResearchTime = builder.getMetadataOrDefault(RESEARCH_TIME, 0); + tPersistentHash = tPersistentHash * 31 + aResearchTime; + tPersistentHash = tPersistentHash * 31 + r.mDuration; + tPersistentHash = tPersistentHash * 31 + r.mEUt; + + GTRecipe.RecipeAssemblyLine tRecipe = new GTRecipe.RecipeAssemblyLine( + aResearchItem, + aResearchTime, + r.mInputs, + r.mFluidInputs, + aOutput, + r.mDuration, + r.mEUt, + r.mOreDictAlt); + tRecipe.setPersistentHash(tPersistentHash); + GTRecipe.RecipeAssemblyLine.sAssemblylineRecipes.add(tRecipe); + AssemblyLineUtils.addRecipeToCache(tRecipe); + + ItemStack writesDataStick = ItemList.Tool_DataStick.getWithName(1L, "Writes Research result"); + AssemblyLineUtils.setAssemblyLineRecipeOnDataStick(writesDataStick, tRecipe, false); + Collection ret = new ArrayList<>(3); + ret.addAll( + GTValues.RA.stdBuilder() + .itemInputs(aResearchItem) + .itemOutputs(aOutput) + .special(writesDataStick) + .duration(aResearchTime) + .eut(TierEU.RECIPE_LV) + .specialValue(-201) // means it's scanned + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes)); + + ItemStack readsDataStick = ItemList.Tool_DataStick.getWithName(1L, "Reads Research result"); + AssemblyLineUtils.setAssemblyLineRecipeOnDataStick(readsDataStick, tRecipe, false); + ret.add( + RecipeMaps.assemblylineVisualRecipes.addFakeRecipe( + false, + r.mInputs, + new ItemStack[] { aOutput }, + new ItemStack[] { readsDataStick }, + r.mFluidInputs, + null, + r.mDuration, + r.mEUt, + 0, + r.mOreDictAlt, + false)); + + return ret; + }); + + /** + * Adds an Electric Blast Furnace recipe that might use gas. + */ + public static final IRecipeMap BlastFurnaceWithGas = IRecipeMap.newRecipeMap(builder -> { + Collection ret = new ArrayList<>(); + int basicGasAmount = builder.getMetadataOrDefault(ADDITIVE_AMOUNT, 1000); + double durationBase = builder.getDuration(); + ArrayList items = new ArrayList<>(Arrays.asList(builder.getItemInputsBasic())); + int circuitConfig = 1; + if (items.size() == 1) {// Set circuit config if it is a dust -> ingot recipe. + ItemData data = GTOreDictUnificator.getAssociation(items.get(0)); + if (data != null) { + OrePrefixes prefix = data.mPrefix; + if (OrePrefixes.dust.equals(prefix)) { + circuitConfig = 1; + } else if (OrePrefixes.dustSmall.equals(prefix)) { + circuitConfig = 4; + } else if (OrePrefixes.dustTiny.equals(prefix)) { + circuitConfig = 9; + } + } + } else { // Set circuit config if there is an integrated circuit + for (int i = 0; i < items.size(); i++) { + if (GTUtility.isAnyIntegratedCircuit(items.get(i))) { + circuitConfig = items.get(i) + .getItemDamage(); + items.remove(i--); + } + } + } + + if (builder.getMetadataOrDefault(NO_GAS, false)) { + items.add(GTUtility.getIntegratedCircuit(circuitConfig)); + ret.addAll( + builder.copy() + .itemInputs(items.toArray(new ItemStack[0])) + .fluidInputs() + .duration((int) Math.max(durationBase * 1.1, 1)) + .addTo(RecipeMaps.blastFurnaceRecipes)); + items.remove(items.size() - 1); + circuitConfig += 10; + } + + items.add(GTUtility.getIntegratedCircuit(circuitConfig)); + boolean nobleGases = builder.getMetadataOrDefault(NOBLE_GASES, false); + boolean anaerobeGases = builder.getMetadataOrDefault(ANAEROBE_GASES, false); + Collection gases = new ArrayList<>(); + + if (nobleGases && anaerobeGases) { + gases = BlastFurnaceGasStat.getNobleAndAnaerobeGases(); + } else if (nobleGases) { + gases = BlastFurnaceGasStat.getNobleGases(); + } else if (anaerobeGases) { + gases = BlastFurnaceGasStat.getAnaerobeGases(); + } + for (BlastFurnaceGasStat gas : gases) { + int gasAmount = (int) (gas.recipeConsumedAmountMultiplier * basicGasAmount); + int duration = (int) Math.max(gas.recipeTimeMultiplier * durationBase, 1); + ret.addAll( + builder.copy() + .itemInputs(items.toArray(new ItemStack[0])) + .fluidInputs(GTUtility.copyAmount(gasAmount, gas.gas)) + .duration(duration) + .addTo(RecipeMaps.blastFurnaceRecipes)); + } + return ret; + }); + + /** + * Just like any normal assembler recipe, however it accepts one input item to be oredicted. Pass in the item to + * oredict via {@link #OREDICT_INPUT}. It will be used along all other item inputs as input of this recipe. + */ + public static IRecipeMap AssemblerOD = IRecipeMap.newRecipeMap(builder -> { + Collection ret = new ArrayList<>(); + for (ItemStack input : GTOreDictUnificator.getOresImmutable(builder.getMetadata(OREDICT_INPUT))) { + ret.addAll( + builder.copy() + .itemInputs(GTRecipeMapUtil.appendArray(builder.getItemInputsBasic(), input)) + .addTo(RecipeMaps.assemblerRecipes)); + } + return ret; + }); + + /** + * A universal fuel adder. It's actually just a dispatcher towards all actual fuel recipe maps. + * Dispatch based on {@link #FUEL_TYPE}. Uses {@link #FUEL_VALUE} as fuel value. + * Can use {@link FuelType#ordinal()} as a human-readable form of what FUEL_TYPE should be. + * You can bypass this and add to relevant fuel maps directly if you wish. + */ + public static IRecipeMap Fuel = IRecipeMap.newRecipeMap(builder -> { + builder.validateInputCount(1, 1) + .validateNoInputFluid() + .validateOutputCount(-1, 1) + .validateNoOutputFluid(); + if (!builder.isValid()) return Collections.emptyList(); + Integer fuelType = builder.getMetadata(FUEL_TYPE); + if (fuelType == null) return Collections.emptyList(); + builder.metadata(FUEL_VALUE, builder.getMetadataOrDefault(FUEL_VALUE, 0)); + return FuelType.get(fuelType) + .getTarget() + .doAdd(builder); + }); + + public enum FuelType { + + // ORDER MATTERS. DO NOT INSERT ELEMENT BETWEEN EXISTING ONES + DieselFuel(RecipeMaps.dieselFuels), + GasTurbine(RecipeMaps.gasTurbineFuels), + // appears unused + HotFuel(RecipeMaps.hotFuels), + SemiFluid(RecipeMaps.denseLiquidFuels), + PlasmaTurbine(RecipeMaps.plasmaFuels), + Magic(RecipeMaps.magicFuels),; + + private static final FuelType[] VALUES = values(); + private final IRecipeMap target; + + FuelType(IRecipeMap target) { + this.target = target; + } + + public static FuelType get(int fuelType) { + if (fuelType < 0 || fuelType >= VALUES.length) return SemiFluid; + return VALUES[fuelType]; + } + + public IRecipeMap getTarget() { + return target; + } + } + + static { + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COIL_HEAT); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FUSION_THRESHOLD); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FUEL_VALUE); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NANO_FORGE_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FOG_EXOTIC_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FOG_PLASMA_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DEFC_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(CHEMPLANT_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(QFT_FOCUS_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DISSOLUTION_TANK_RATIO); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(RTG_DURATION_IN_DAYS); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(LNG_BASIC_OUTPUT); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NFR_COIL_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NKE_RANGE); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(PRECISE_ASSEMBLER_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COAL_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COMPRESSION_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(RESEARCH_STATION_DATA); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(SIEVERTS); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DECAY_TICKS); + + } +} diff --git a/src/main/java/gregtech/api/util/GTRecipeMapUtil.java b/src/main/java/gregtech/api/util/GTRecipeMapUtil.java new file mode 100644 index 0000000000..86ef5b4031 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRecipeMapUtil.java @@ -0,0 +1,198 @@ +package gregtech.api.util; + +import static gregtech.api.enums.Mods.GregTech; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import cpw.mods.fml.common.Loader; +import gnu.trove.list.TIntList; +import gnu.trove.list.array.TIntArrayList; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.recipe.RecipeMetadataKey; + +/** + * Define helpers useful in the creation of recipe maps. + */ +public class GTRecipeMapUtil { + + public static final Function ALL_FAKE_RECIPE = r -> { + r.mFakeRecipe = true; + return r; + }; + + private static final Map addonRecipeMaps = new HashMap<>(); + private static final Multimap> delayedActions = ArrayListMultimap.create(); + + /** + * Set of metadata that work as alias for special values. + */ + public static final Set> SPECIAL_VALUE_ALIASES = new HashSet<>(); + + public static T[] appendArray(T[] arr, T val) { + T[] newArr = Arrays.copyOf(arr, arr.length + 1); + newArr[arr.length] = val; + return newArr; + } + + public static GTRecipeTemplate asTemplate(GTRecipe r) { + return asTemplate(r, false); + } + + public static GTRecipeTemplate asTemplate(GTRecipe r, boolean includeTemplate) { + return new GTRecipeTemplate(r, includeTemplate); + } + + public static List buildRecipeForMultiblock(GTRecipeBuilder b) { + return buildOrEmpty(convertCellToFluid(b, true)); + + } + + public static List buildRecipeForMultiblockNoCircuit(GTRecipeBuilder b) { + return buildOrEmpty(convertCellToFluid(b, false)); + } + + public static GTRecipeBuilder convertCellToFluid(GTRecipeBuilder b, boolean removeIntegratedCircuit) { + List itemInputs = new ArrayList<>(Arrays.asList(b.getItemInputsBasic())); + List itemOutputs = new ArrayList<>(Arrays.asList(b.getItemOutputs())); + List fluidInputs = new ArrayList<>(Arrays.asList(b.getFluidInputs())); + List fluidOutputs = new ArrayList<>(Arrays.asList(b.getFluidOutputs())); + TIntList chances = b.getChances() != null ? new TIntArrayList(b.getChances()) : null; + cellToFluid(itemInputs, fluidInputs, removeIntegratedCircuit, null); + cellToFluid(itemOutputs, fluidOutputs, removeIntegratedCircuit, chances); + itemInputs.removeIf(Objects::isNull); + if (chances == null) { + itemOutputs.removeIf(Objects::isNull); + } + fluidInputs.removeIf(Objects::isNull); + fluidOutputs.removeIf(Objects::isNull); + b.itemInputs(itemInputs.toArray(new ItemStack[0])); + b.itemOutputs(itemOutputs.toArray(new ItemStack[0]), chances != null ? chances.toArray() : null); + b.fluidInputs(fluidInputs.toArray(new FluidStack[0])); + b.fluidOutputs(fluidOutputs.toArray(new FluidStack[0])); + return b; + } + + private static void cellToFluid(List items, List fluids, boolean removeIntegratedCircuit, + TIntList chances) { + for (int i = items.size() - 1; i >= 0; i--) { + ItemStack item = items.get(i); + if (GTUtility.getFluidForFilledItem(item, true) != null || GTUtility.isCellEmpty(item) + || (removeIntegratedCircuit && GTUtility.isAnyIntegratedCircuit(item))) { + fluids.add(GTUtility.convertCellToFluid(item)); + items.remove(i); + if (chances != null) chances.removeAt(i); + } + } + } + + public static List buildOrEmpty(GTRecipeBuilder builder) { + return builder.build() + .map(Collections::singletonList) + .orElse(Collections.emptyList()); + } + + /** + * Register a recipe map as part of your mod's public API under your modID and your given identifier. + * + * @param identifier map name + * @param recipeMap the map to register + * @param dependencies fully qualified identifier of dependent recipe maps. scheduler will only add recipes to one + * of the dependent recipe maps and this recipe map concurrently, guaranteeing thread safety. + * Currently unused, but you are advised to fill them, so that when The Day (tm) comes we don't + * end up with a bunch of weird concurrency bugs. + */ + public static void registerRecipeMap(String identifier, IRecipeMap recipeMap, RecipeMapDependency... dependencies) { + String modId = Loader.instance() + .activeModContainer() + .getModId(); + if (GregTech.ID.equals(modId)) throw new IllegalStateException( + "do not register recipe map under the name of gregtech! do it in your own preinit!"); + String id = modId + "@" + identifier; + addonRecipeMaps.put(id, recipeMap); + for (Consumer action : delayedActions.get(id)) { + action.accept(recipeMap); + } + } + + /** + * Use this to register recipes for a recipe map in addon not present at compile time. + *

+ * Do not use this for recipes maps already in {@link GTRecipeConstants}. None of them will be available via this + * interface! + * + * @param identifier recipe map id + * @param registerAction DO NOT ADD RECIPES TO MAPS OTHER THAN THE ONE PASSED TO YOU. DO NOT DO ANYTHING OTHER THAN + * ADDING RECIPES TO THIS R + */ + public static void registerRecipesFor(String modid, String identifier, Consumer registerAction) { + String id = modid + "@" + identifier; + IRecipeMap map = addonRecipeMaps.get(id); + if (map == null) delayedActions.put(id, registerAction); + else registerAction.accept(map); + } + + public static final class GTRecipeTemplate { + + private final GTRecipe template; + private final List derivatives = new ArrayList<>(); + + private GTRecipeTemplate(GTRecipe template, boolean includeTemplate) { + this.template = template; + if (includeTemplate) derivatives.add(template); + } + + public GTRecipe derive() { + GTRecipe derived = template.copyShallow(); + derivatives.add(derived); + return derived; + } + + public List getAll() { + // fix shallow references + Set references = Collections.newSetFromMap(new IdentityHashMap<>()); + for (GTRecipe r : derivatives) { + if (!references.add(r.mInputs)) r.mInputs = r.mInputs.clone(); + if (!references.add(r.mOutputs)) r.mOutputs = r.mOutputs.clone(); + if (!references.add(r.mFluidInputs)) r.mFluidInputs = r.mFluidInputs.clone(); + if (!references.add(r.mFluidOutputs)) r.mFluidOutputs = r.mFluidOutputs.clone(); + } + return derivatives; + } + } + + public static final class RecipeMapDependency { + + private final IRecipeMap obj; + private final String id; + + public RecipeMapDependency(IRecipeMap obj, String id) { + this.obj = obj; + this.id = id; + } + + public static RecipeMapDependency create(String id) { + return new RecipeMapDependency(null, id); + } + + public static RecipeMapDependency create(IRecipeMap obj) { + return new RecipeMapDependency(obj, null); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTRecipeRegistrator.java b/src/main/java/gregtech/api/util/GTRecipeRegistrator.java new file mode 100644 index 0000000000..919b37e7d9 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRecipeRegistrator.java @@ -0,0 +1,872 @@ +package gregtech.api.util; + +import static gregtech.api.enums.GTValues.L; +import static gregtech.api.enums.GTValues.M; +import static gregtech.api.enums.GTValues.RA; +import static gregtech.api.enums.GTValues.VP; +import static gregtech.api.enums.Materials.Bronze; +import static gregtech.api.enums.Materials.Cobalt; +import static gregtech.api.enums.Materials.DarkSteel; +import static gregtech.api.enums.Materials.Diamond; +import static gregtech.api.enums.Materials.FierySteel; +import static gregtech.api.enums.Materials.Gold; +import static gregtech.api.enums.Materials.Iron; +import static gregtech.api.enums.Materials.IronWood; +import static gregtech.api.enums.Materials.Knightmetal; +import static gregtech.api.enums.Materials.Lead; +import static gregtech.api.enums.Materials.Ruby; +import static gregtech.api.enums.Materials.Sapphire; +import static gregtech.api.enums.Materials.Steel; +import static gregtech.api.enums.Materials.Steeleaf; +import static gregtech.api.enums.Materials.Thaumium; +import static gregtech.api.enums.Materials.Void; +import static gregtech.api.recipe.RecipeMaps.fluidExtractionRecipes; +import static gregtech.api.recipe.RecipeMaps.hammerRecipes; +import static gregtech.api.recipe.RecipeMaps.maceratorRecipes; +import static gregtech.api.recipe.RecipeMaps.wiremillRecipes; +import static gregtech.api.util.GTRecipeBuilder.SECONDS; +import static gregtech.api.util.GTRecipeBuilder.TICKS; +import static gregtech.api.util.GTRecipeConstants.RECYCLE; +import static gregtech.api.util.GTRecipeConstants.UniversalArcFurnace; +import static gregtech.api.util.GTUtility.calculateRecipeEU; +import static gregtech.api.util.GTUtility.getTier; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.item.crafting.ShapelessRecipes; +import net.minecraftforge.oredict.ShapedOreRecipe; +import net.minecraftforge.oredict.ShapelessOreRecipe; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.SetMultimap; + +import cpw.mods.fml.relauncher.ReflectionHelper; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.SubTag; +import gregtech.api.enums.TierEU; +import gregtech.api.objects.ItemData; +import gregtech.api.objects.MaterialStack; +import gregtech.api.recipe.RecipeCategories; +import ic2.api.reactor.IReactorComponent; + +/** + * Class for Automatic Recipe registering. + */ +public class GTRecipeRegistrator { + + /** + * List of Materials, which are used in the Creation of Sticks. All Rod Materials are automatically added to this + * List. + */ + public static final List sRodMaterialList = new ArrayList<>(); + + private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0); + private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R"; + private static final RecipeShape[] sShapes = new RecipeShape[] { + new RecipeShape(sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null), + new RecipeShape(sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1), + new RecipeShape(null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1), + new RecipeShape(sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null), + new RecipeShape(sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1), + new RecipeShape(sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1), + new RecipeShape(null, null, null, sMt1, null, sMt1, sMt1, null, sMt1), + new RecipeShape(null, sMt1, null, null, sMt1, null, null, sMt2, null), + new RecipeShape(sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null), + new RecipeShape(null, sMt1, null, null, sMt2, null, null, sMt2, null), + new RecipeShape(sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null), + new RecipeShape(null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null), + new RecipeShape(sMt1, sMt1, null, null, sMt2, null, null, sMt2, null), + new RecipeShape(null, sMt1, sMt1, null, sMt2, null, null, sMt2, null), + new RecipeShape(null, sMt1, null, sMt1, null, null, null, sMt1, sMt2), + new RecipeShape(null, sMt1, null, null, null, sMt1, sMt2, sMt1, null), + new RecipeShape(null, sMt1, null, sMt1, null, sMt1, null, null, sMt2), + new RecipeShape(null, sMt1, null, sMt1, null, sMt1, sMt2, null, null), + new RecipeShape(null, sMt2, null, null, sMt1, null, null, sMt1, null), + new RecipeShape(null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1), + new RecipeShape(null, sMt2, null, null, sMt2, null, null, sMt1, null), + new RecipeShape(null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null), + new RecipeShape(null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1), + new RecipeShape(null, sMt2, null, null, sMt2, null, sMt1, sMt1, null), + new RecipeShape(sMt1, null, null, null, sMt2, null, null, null, sMt2), + new RecipeShape(null, null, sMt1, null, sMt2, null, sMt2, null, null), + new RecipeShape(sMt1, null, null, null, sMt2, null, null, null, null), + new RecipeShape(null, null, sMt1, null, sMt2, null, null, null, null), + new RecipeShape(sMt1, sMt2, null, null, null, null, null, null, null), + new RecipeShape(sMt2, sMt1, null, null, null, null, null, null, null), + new RecipeShape(sMt1, null, null, sMt2, null, null, null, null, null), + new RecipeShape(sMt2, null, null, sMt1, null, null, null, null, null), + new RecipeShape(sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null), + new RecipeShape(sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null), + new RecipeShape(null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1), + new RecipeShape(null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1), + new RecipeShape(sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null), + new RecipeShape(sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null), + new RecipeShape(null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1), + new RecipeShape(null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1), + new RecipeShape(sMt1, null, null, null, sMt1, null, null, null, null), + new RecipeShape(null, sMt1, null, sMt1, null, null, null, null, null), + new RecipeShape(sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null), + new RecipeShape(null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2) }; + public static final Field SHAPED_ORE_RECIPE_WIDTH = ReflectionHelper.findField(ShapedOreRecipe.class, "width"); + public static final Field SHAPED_ORE_RECIPE_HEIGHT = ReflectionHelper.findField(ShapedOreRecipe.class, "height"); + private static volatile Map> indexedRecipeListCache; + private static final String[][] sShapesA = new String[][] { null, null, null, + { "Helmet", s_P + s_P + s_P, s_P + s_H + s_P }, + { "ChestPlate", s_P + s_H + s_P, s_P + s_P + s_P, s_P + s_P + s_P }, + { "Pants", s_P + s_P + s_P, s_P + s_H + s_P, s_P + " " + s_P }, { "Boots", s_P + " " + s_P, s_P + s_H + s_P }, + { "Sword", " " + s_P + " ", s_F + s_P + s_H, " " + s_R + " " }, + { "Pickaxe", s_P + s_I + s_I, s_F + s_R + s_H, " " + s_R + " " }, + { "Shovel", s_F + s_P + s_H, " " + s_R + " ", " " + s_R + " " }, + { "Axe", s_P + s_I + s_H, s_P + s_R + " ", s_F + s_R + " " }, + { "Axe", s_P + s_I + s_H, s_P + s_R + " ", s_F + s_R + " " }, + { "Hoe", s_P + s_I + s_H, s_F + s_R + " ", " " + s_R + " " }, + { "Hoe", s_P + s_I + s_H, s_F + s_R + " ", " " + s_R + " " }, + { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, + { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, + { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, + { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, + { "Sword", " " + s_R + " ", s_F + s_P + s_H, " " + s_P + " " }, + { "Pickaxe", " " + s_R + " ", s_F + s_R + s_H, s_P + s_I + s_I }, + { "Shovel", " " + s_R + " ", " " + s_R + " ", s_F + s_P + s_H }, + { "Axe", s_F + s_R + " ", s_P + s_R + " ", s_P + s_I + s_H }, + { "Axe", s_F + s_R + " ", s_P + s_R + " ", s_P + s_I + s_H }, + { "Hoe", " " + s_R + " ", s_F + s_R + " ", s_P + s_I + s_H }, + { "Hoe", " " + s_R + " ", s_F + s_R + " ", s_P + s_I + s_H }, + { "Spear", s_P + s_H + " ", s_F + s_R + " ", " " + " " + s_R }, + { "Spear", s_P + s_H + " ", s_F + s_R + " ", " " + " " + s_R }, { "Knive", s_H + s_P, s_R + s_F }, + { "Knive", s_F + s_H, s_P + s_R }, { "Knive", s_F + s_H, s_P + s_R }, { "Knive", s_P + s_F, s_R + s_H }, + { "Knive", s_P + s_F, s_R + s_H }, null, null, null, null, + { "WarAxe", s_P + s_P + s_P, s_P + s_R + s_P, s_F + s_R + s_H }, null, null, null, + { "Shears", s_H + s_P, s_P + s_F }, { "Shears", s_H + s_P, s_P + s_F }, + { "Scythe", s_I + s_P + s_H, s_R + s_F + s_P, s_R + " " + " " }, + { "Scythe", s_H + s_P + s_I, s_P + s_F + s_R, " " + " " + s_R } }; + + static { + // flush the cache on post load finish + GregTechAPI.sAfterGTPostload.add(() -> indexedRecipeListCache = null); + } + + public static void registerMaterialRecycling(ItemStack aStack, Materials aMaterial, long aMaterialAmount, + MaterialStack aByproduct) { + if (GTUtility.isStackInvalid(aStack)) return; + if (aByproduct != null) { + aByproduct = aByproduct.clone(); + aByproduct.mAmount /= aStack.stackSize; + } + GTOreDictUnificator.addItemData( + GTUtility.copyAmount(1, aStack), + new ItemData(aMaterial, aMaterialAmount / aStack.stackSize, aByproduct)); + } + + public static void registerMaterialRecycling(ItemStack aStack, ItemData aData) { + if (GTUtility.isStackInvalid(aStack) || GTUtility.areStacksEqual(new ItemStack(Items.blaze_rod), aStack) + || aData == null + || !aData.hasValidMaterialData() + || !aData.mMaterial.mMaterial.mAutoGenerateRecycleRecipes + || aData.mMaterial.mAmount <= 0 + || GTUtility.getFluidForFilledItem(aStack, false) != null + || aData.mMaterial.mMaterial.mSubTags.contains(SubTag.NO_RECIPES)) return; + registerReverseMacerating(GTUtility.copyAmount(1, aStack), aData, aData.mPrefix == null); + if (!GTUtility.areStacksEqual(GTModHandler.getIC2Item("iridiumOre", 1L), aStack)) { + registerReverseSmelting( + GTUtility.copyAmount(1, aStack), + aData.mMaterial.mMaterial, + aData.mMaterial.mAmount, + true); + registerReverseFluidSmelting( + GTUtility.copyAmount(1, aStack), + aData.mMaterial.mMaterial, + aData.mMaterial.mAmount, + aData.getByProduct(0)); + registerReverseArcSmelting(GTUtility.copyAmount(1, aStack), aData); + } + } + + /** + * @param aStack the stack to be recycled. + * @param aMaterial the Material. + * @param aMaterialAmount the amount of it in Material Units. + */ + public static void registerReverseFluidSmelting(ItemStack aStack, Materials aMaterial, long aMaterialAmount, + MaterialStack aByproduct) { + if (aStack == null || aMaterial == null + || aMaterial.mSmeltInto.mStandardMoltenFluid == null + || !aMaterial.contains(SubTag.SMELTING_TO_FLUID) + || (L * aMaterialAmount) / (M * aStack.stackSize) <= 0) return; + + ItemStack recipeOutput = aByproduct == null ? null + : aByproduct.mMaterial.contains(SubTag.NO_SMELTING) || !aByproduct.mMaterial.contains(SubTag.METAL) + ? aByproduct.mMaterial.contains(SubTag.FLAMMABLE) + ? GTOreDictUnificator.getDust(Materials.Ash, aByproduct.mAmount / 2) + : aByproduct.mMaterial.contains(SubTag.UNBURNABLE) + ? GTOreDictUnificator.getDustOrIngot(aByproduct.mMaterial.mSmeltInto, aByproduct.mAmount) + : null + : GTOreDictUnificator.getIngotOrDust(aByproduct.mMaterial.mSmeltInto, aByproduct.mAmount); + + GTRecipeBuilder builder = RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, aStack)); + if (recipeOutput != null) { + builder.itemOutputs(recipeOutput); + } + long powerUsage = Math.max(8, (long) Math.sqrt(2 * aMaterial.mSmeltInto.mStandardMoltenFluid.getTemperature())); + // avoid full amp recipes + int powerTier = getTier(powerUsage); + if (powerTier > 0 && powerTier < VP.length && powerUsage > VP[powerTier]) { + powerUsage = VP[powerTier]; + } + builder.fluidOutputs(aMaterial.mSmeltInto.getMolten((L * aMaterialAmount) / (M * aStack.stackSize))) + .duration((int) Math.max(1, (24 * aMaterialAmount) / M)) + .eut(powerUsage) + .recipeCategory(RecipeCategories.fluidExtractorRecycling) + .addTo(fluidExtractionRecipes); + } + + /** + * @param aStack the stack to be recycled. + * @param aMaterial the Material. + * @param aMaterialAmount the amount of it in Material Units. + * @param aAllowAlloySmelter if it is allowed to be recycled inside the Alloy Smelter. + */ + public static void registerReverseSmelting(ItemStack aStack, Materials aMaterial, long aMaterialAmount, + boolean aAllowAlloySmelter) { + if (aStack == null || aMaterial == null + || aMaterialAmount <= 0 + || aMaterial.contains(SubTag.NO_SMELTING) + || (aMaterialAmount > M && aMaterial.contains(SubTag.METAL)) + || (aMaterial.getProcessingMaterialTierEU() > TierEU.IV)) return; + if (aMaterial == Materials.Naquadah || aMaterial == Materials.NaquadahEnriched) return; + + aMaterialAmount /= aStack.stackSize; + + if (aAllowAlloySmelter) GTModHandler.addSmeltingAndAlloySmeltingRecipe( + GTUtility.copyAmount(1, aStack), + GTOreDictUnificator.getIngot(aMaterial.mSmeltInto, aMaterialAmount), + false); + else GTModHandler.addSmeltingRecipe( + GTUtility.copyAmount(1, aStack), + GTOreDictUnificator.getIngot(aMaterial.mSmeltInto, aMaterialAmount)); + } + + public static void registerReverseArcSmelting(ItemStack aStack, Materials aMaterial, long aMaterialAmount, + MaterialStack aByProduct01, MaterialStack aByProduct02, MaterialStack aByProduct03) { + registerReverseArcSmelting( + aStack, + new ItemData( + aMaterial == null ? null : new MaterialStack(aMaterial, aMaterialAmount), + aByProduct01, + aByProduct02, + aByProduct03)); + } + + public static void registerReverseArcSmelting(ItemStack aStack, ItemData aData) { + if (aStack == null || aData == null) return; + aData = new ItemData(aData); + + if (!aData.hasValidMaterialData()) return; + boolean isRecycle = true; + + for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { + if (tMaterial.mMaterial == Materials.Iron || tMaterial.mMaterial == Materials.Copper + || tMaterial.mMaterial == Materials.WroughtIron + || tMaterial.mMaterial == Materials.AnnealedCopper) { + ItemData stackData = GTOreDictUnificator.getItemData(aStack); + if (stackData != null + && (stackData.mPrefix == OrePrefixes.ingot || stackData.mPrefix == OrePrefixes.dust)) { + // iron ingot/dust -> wrought iron, copper ingot/dust -> annealed copper + isRecycle = false; + } + } + + if (tMaterial.mMaterial.contains(SubTag.UNBURNABLE)) { + tMaterial.mMaterial = tMaterial.mMaterial.mSmeltInto.mArcSmeltInto; + continue; + } + if (tMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) { + tMaterial.mMaterial = Materials.Ash; + tMaterial.mAmount /= 16; + continue; + } + if (tMaterial.mMaterial.contains(SubTag.FLAMMABLE)) { + tMaterial.mMaterial = Materials.Ash; + tMaterial.mAmount /= 8; + continue; + } + if (tMaterial.mMaterial.contains(SubTag.NO_SMELTING)) { + tMaterial.mAmount = 0; + continue; + } + if (tMaterial.mMaterial.contains(SubTag.METAL)) { + + tMaterial.mMaterial = tMaterial.mMaterial.mSmeltInto.mArcSmeltInto; + continue; + } + tMaterial.mAmount = 0; + } + + aData = new ItemData(aData); + if (aData.mByProducts.length > 3) for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { + if (tMaterial.mMaterial == Materials.Ash) tMaterial.mAmount = 0; + } + + aData = new ItemData(aData); + + if (!aData.hasValidMaterialData()) return; + + long tAmount = 0; + for (MaterialStack tMaterial : aData.getAllMaterialStacks()) + tAmount += tMaterial.mAmount * tMaterial.mMaterial.getMass(); + + ArrayList outputs = new ArrayList<>(); + if (GTOreDictUnificator.getIngotOrDust(aData.mMaterial) != null) { + outputs.add(GTOreDictUnificator.getIngotOrDust(aData.mMaterial)); + } + for (int i = 0; i < 8; i++) { + if (GTOreDictUnificator.getIngotOrDust(aData.getByProduct(i)) != null) { + outputs.add(GTOreDictUnificator.getIngotOrDust(aData.getByProduct(i))); + } + } + if (!outputs.isEmpty()) { + GTRecipeBuilder recipeBuilder = GTValues.RA.stdBuilder(); + recipeBuilder.itemInputs(aStack) + .itemOutputs(outputs.toArray(new ItemStack[0])) + .fluidInputs(Materials.Oxygen.getGas((int) Math.max(16, tAmount / M))) + .duration(((int) Math.max(16, tAmount / M)) * TICKS) + .eut(90) + .metadata(RECYCLE, isRecycle) + .addTo(UniversalArcFurnace); + } + + } + + public static void registerReverseMacerating(ItemStack aStack, Materials aMaterial, long aMaterialAmount, + MaterialStack aByProduct01, MaterialStack aByProduct02, MaterialStack aByProduct03, boolean aAllowHammer) { + registerReverseMacerating( + aStack, + new ItemData( + aMaterial == null ? null : new MaterialStack(aMaterial, aMaterialAmount), + aByProduct01, + aByProduct02, + aByProduct03), + aAllowHammer); + } + + public static void registerReverseMacerating(ItemStack aStack, ItemData aData, boolean aAllowHammer) { + if (aStack == null || aData == null) return; + aData = new ItemData(aData); + + if (!aData.hasValidMaterialData()) return; + + for (MaterialStack tMaterial : aData.getAllMaterialStacks()) + tMaterial.mMaterial = tMaterial.mMaterial.mMacerateInto; + + aData = new ItemData(aData); + + if (!aData.hasValidMaterialData()) return; + + long tAmount = 0; + for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { + tAmount += tMaterial.mAmount * tMaterial.mMaterial.getMass(); + } + + { + ArrayList outputs = new ArrayList<>(); + if (GTOreDictUnificator.getDust(aData.mMaterial) != null) { + outputs.add(GTOreDictUnificator.getDust(aData.mMaterial)); + } + for (int i = 0; i < 3; i++) { + if (GTOreDictUnificator.getDust(aData.getByProduct(i)) != null) { + outputs.add(GTOreDictUnificator.getDust(aData.getByProduct(i))); + } + } + if (!outputs.isEmpty()) { + ItemStack[] outputsArray = outputs.toArray(new ItemStack[0]); + GTRecipeBuilder recipeBuilder = GTValues.RA.stdBuilder(); + recipeBuilder.itemInputs(aStack) + .itemOutputs(outputsArray) + .duration( + (aData.mMaterial.mMaterial == Materials.Marble ? 1 : (int) Math.max(16, tAmount / M)) * TICKS) + .eut(4) + .recipeCategory(RecipeCategories.maceratorRecycling) + .addTo(maceratorRecipes); + } + } + + if (!aAllowHammer) { + return; + } + + for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { + if (tMaterial.mMaterial.contains(SubTag.CRYSTAL) && !tMaterial.mMaterial.contains(SubTag.METAL) + && tMaterial.mMaterial != Materials.Glass + && GTOreDictUnificator.getDust(aData.mMaterial) != null) { + GTValues.RA.stdBuilder() + .itemInputs(GTUtility.copyAmount(1, aStack)) + .itemOutputs(GTOreDictUnificator.getDust(aData.mMaterial)) + .duration(10 * SECONDS) + .eut(TierEU.RECIPE_LV) + .recipeCategory(RecipeCategories.forgeHammerRecycling) + .addTo(hammerRecipes); + break; + } + } + + } + + /** + * Place Materials which you want to replace in Non-GT-Recipes here (warning HUGHE impact on loading times!) + */ + private static final Materials[] VANILLA_MATS = { Cobalt, Gold, Iron, Lead, FierySteel, Void, Bronze, Diamond, Ruby, + Sapphire, Steel, IronWood, Steeleaf, Knightmetal, Thaumium, DarkSteel, }; + + /** + * You give this Function a Material and it will scan almost everything for adding recycling Recipes and replacing + * Ingots, Gems etc. + * + * @param aMats Materials, for example an Ingot or a Gem. + * @param aPlate the Plate referenced to aMat + * @param aRecipeReplacing allows to replace the Recipe with a Plate variant + */ + public static synchronized void registerUsagesForMaterials(String aPlate, boolean aRecipeReplacing, + ItemStack... aMats) { + for (ItemStack aMat : aMats) { + aMat = GTUtility.copyOrNull(aMat); + + if (aMat == null) continue; + + ItemData aItemData = GTOreDictUnificator.getItemData(aMat); + if (aItemData == null || aItemData.mPrefix != OrePrefixes.ingot) aPlate = null; + if (aPlate != null && GTOreDictUnificator.getFirstOre(aPlate, 1) == null) aPlate = null; + + sMt1.func_150996_a(aMat.getItem()); + sMt1.stackSize = 1; + Items.feather.setDamage(sMt1, Items.feather.getDamage(aMat)); + + sMt2.func_150996_a(new ItemStack(Blocks.dirt).getItem()); + sMt2.stackSize = 1; + Items.feather.setDamage(sMt2, 0); + + if (aItemData != null && aItemData.hasValidPrefixMaterialData()) { + for (RecipeShape tRecipe : sShapes) { + for (ItemStack tCrafted : GTModHandler.getRecipeOutputsBuffered(tRecipe.shape)) { + GTOreDictUnificator.addItemData( + tCrafted, + new ItemData(aItemData.mMaterial.mMaterial, aItemData.mMaterial.mAmount * tRecipe.amount1)); + // + // GTLog.out.println("###################################################################################"); + // GTLog.out.println("registerUsagesForMaterials used aPlate: "+aPlate); + // GTLog.out.println("registerUsagesForMaterials used aPlate: + // "+aMat.getUnlocalizedName()); + // GTLog.out.println("registerUsagesForMaterials used aPlate: + // "+aMat.getDisplayName()); + // + // GTLog.out.println("###################################################################################"); + } + } + } + registerStickStuff(aPlate, aItemData, aRecipeReplacing); + } + } + + private static List getRecipeList(RecipeShape shape) { + boolean force = !GregTechAPI.sPostloadStarted || GregTechAPI.sPostloadFinished; + if (force || indexedRecipeListCache == null) { + synchronized (GTRecipeRegistrator.class) { + if (indexedRecipeListCache == null || force) { + indexedRecipeListCache = createIndexedRecipeListCache(); + } + } + } + return indexedRecipeListCache.get(shape); + } + + private static Map> createIndexedRecipeListCache() { + Map> result = new IdentityHashMap<>(); + ArrayList allRecipeList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + // filter using the empty slots in the shape. + // if the empty slots doesn't match, the recipe will definitely fail + SetMultimap, RecipeShape> filter = HashMultimap.create(); + for (RecipeShape shape : sShapes) { + for (List list : shape.getEmptySlotsAllVariants()) { + filter.put(list, shape); + } + } + List buffer = new ArrayList<>(9); + for (IRecipe tRecipe : allRecipeList) { + if (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe) { + // we don't target shapeless recipes + continue; + } + buffer.clear(); + ItemStack tStack = tRecipe.getRecipeOutput(); + if (GTUtility.isStackValid(tStack) && tStack.getMaxStackSize() == 1 + && tStack.getMaxDamage() > 0 + && !(tStack.getItem() instanceof ItemBlock) + && !(tStack.getItem() instanceof IReactorComponent) + && !GTModHandler.isElectricItem(tStack) + && !GTUtility.isStackInList(tStack, GTModHandler.sNonReplaceableItems)) { + if (tRecipe instanceof ShapedOreRecipe tShapedRecipe) { + if (checkRecipeShape( + buffer, + tShapedRecipe.getInput(), + getRecipeWidth(tShapedRecipe), + getRecipeHeight(tShapedRecipe))) { + for (RecipeShape s : filter.get(buffer)) { + result.computeIfAbsent(s, k -> new ArrayList<>()) + .add(tRecipe); + } + } + } else if (tRecipe instanceof ShapedRecipes tShapedRecipe) { + if (checkRecipeShape( + buffer, + tShapedRecipe.recipeItems, + getRecipeWidth(tShapedRecipe), + getRecipeHeight(tShapedRecipe))) { + for (RecipeShape s : filter.get(buffer)) { + result.computeIfAbsent(s, k -> new ArrayList<>()) + .add(tRecipe); + } + } + } else { + for (RecipeShape s : sShapes) { + // unknown recipe type. cannot determine empty slots. we choose to add to the recipe list for + // all shapes + result.computeIfAbsent(s, k -> new ArrayList<>()) + .add(tRecipe); + } + } + } + } + return result; + } + + private static boolean checkRecipeShape(List emptySlotIndexesBuffer, Object[] input, int tRecipeWidth, + int tRecipeHeight) { + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 3; x++) { + if (x >= tRecipeWidth || y >= tRecipeHeight) { + emptySlotIndexesBuffer.add(x + y * 3); + continue; + } + Object tObject = input[x + y * tRecipeWidth]; + if (tObject == null) { + emptySlotIndexesBuffer.add(x + y * 3); + continue; + } + if (tObject instanceof ItemStack + && (((ItemStack) tObject).getItem() == null || ((ItemStack) tObject).getMaxStackSize() < 2 + || ((ItemStack) tObject).getMaxDamage() > 0 + || ((ItemStack) tObject).getItem() instanceof ItemBlock)) { + return false; + } + if (tObject instanceof List && ((List) tObject).isEmpty()) { + return false; + } + } + } + return true; + } + + private static synchronized void registerStickStuff(String aPlate, ItemData aItemData, boolean aRecipeReplacing) { + ItemStack tStack; + for (Materials tMaterial : sRodMaterialList) { + ItemStack tMt2 = GTOreDictUnificator.get(OrePrefixes.stick, tMaterial, 1); + if (tMt2 != null) { + sMt2.func_150996_a(tMt2.getItem()); + sMt2.stackSize = 1; + Items.feather.setDamage(sMt2, Items.feather.getDamage(tMt2)); + + for (int i = 0; i < sShapes.length; i++) { + RecipeShape tRecipe = sShapes[i]; + + for (ItemStack tCrafted : GTModHandler + .getRecipeOutputs(getRecipeList(tRecipe), true, tRecipe.shape)) { + if (aItemData != null && aItemData.hasValidPrefixMaterialData()) + GTOreDictUnificator.addItemData( + tCrafted, + new ItemData( + aItemData.mMaterial.mMaterial, + aItemData.mMaterial.mAmount * tRecipe.amount1, + new MaterialStack(tMaterial, OrePrefixes.stick.mMaterialAmount * tRecipe.amount2))); + + if (aRecipeReplacing && aPlate != null && sShapesA[i] != null && sShapesA[i].length > 1) { + assert aItemData != null; + + if (null != (tStack = GTModHandler.removeRecipe(tRecipe.shape))) { + switch (sShapesA[i].length) { + case 2 -> GTModHandler.addCraftingRecipe( + tStack, + GTModHandler.RecipeBits.BUFFERED, + new Object[] { sShapesA[i][1], s_P.charAt(0), aPlate, s_R.charAt(0), + OrePrefixes.stick.get(tMaterial), s_I.charAt(0), aItemData }); + case 3 -> GTModHandler.addCraftingRecipe( + tStack, + GTModHandler.RecipeBits.BUFFERED, + new Object[] { sShapesA[i][1], sShapesA[i][2], s_P.charAt(0), aPlate, + s_R.charAt(0), OrePrefixes.stick.get(tMaterial), s_I.charAt(0), + aItemData }); + default -> GTModHandler.addCraftingRecipe( + tStack, + GTModHandler.RecipeBits.BUFFERED, + new Object[] { sShapesA[i][1], sShapesA[i][2], sShapesA[i][3], s_P.charAt(0), + aPlate, s_R.charAt(0), OrePrefixes.stick.get(tMaterial), s_I.charAt(0), + aItemData }); + } + } + } + } + } + } + } + } + + /** + * Registers wiremill recipes for given material using integrated circuits. + * + * @param aMaterial material to register + * @param baseDuration base duration ticks for ingot -> 1x wire recipe + * @param aEUt EU/t for recipe If you provide a proper EU tier for recipe processing then aEUt will be + * overriden with it. + */ + public static void registerWiremillRecipes(Materials aMaterial, int baseDuration, int aEUt) { + registerWiremillRecipes( + aMaterial, + baseDuration, + calculateRecipeEU(aMaterial, aEUt), + OrePrefixes.ingot, + OrePrefixes.stick, + 2); + } + + /** + * Registers wiremill recipes for given material using integrated circuits. + * + * @param aMaterial material to register + * @param baseDuration base duration ticks for ingot -> 1x wire recipe + * @param aEUt EU/t for recipe + * @param prefix1 prefix corresponds to ingot + * @param prefix2 prefix corresponds to stick + * @param multiplier amount of wires created from 1 ingot + */ + public static void registerWiremillRecipes(Materials aMaterial, int baseDuration, int aEUt, OrePrefixes prefix1, + OrePrefixes prefix2, int multiplier) { + if (GTOreDictUnificator.get(prefix1, aMaterial, 1L) != null + && GTOreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(GTOreDictUnificator.get(prefix1, aMaterial, 1L), GTUtility.getIntegratedCircuit(1)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, multiplier)) + .duration(baseDuration * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix1, aMaterial, 2L / multiplier), + GTUtility.getIntegratedCircuit(2)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt02, aMaterial, 1L)) + .duration(((int) (baseDuration * 1.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix1, aMaterial, 4L / multiplier), + GTUtility.getIntegratedCircuit(4)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt04, aMaterial, 1L)) + .duration(baseDuration * 2 * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix1, aMaterial, 8L / multiplier), + GTUtility.getIntegratedCircuit(8)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt08, aMaterial, 1L)) + .duration(((int) (baseDuration * 2.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix1, aMaterial, 12L / multiplier), + GTUtility.getIntegratedCircuit(12)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt12, aMaterial, 1L)) + .duration(baseDuration * 3 * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix1, aMaterial, 16L / multiplier), + GTUtility.getIntegratedCircuit(16)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt16, aMaterial, 1L)) + .duration(((int) (baseDuration * 3.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + } + + if (GTOreDictUnificator.get(prefix2, aMaterial, 1L) != null + && GTOreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(GTOreDictUnificator.get(prefix2, aMaterial, 1L), GTUtility.getIntegratedCircuit(1)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 2L / multiplier)) + .duration(((int) (baseDuration * 0.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix2, aMaterial, 4L / multiplier), + GTUtility.getIntegratedCircuit(2)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt02, aMaterial, 1L)) + .duration(baseDuration * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix2, aMaterial, 8L / multiplier), + GTUtility.getIntegratedCircuit(4)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt04, aMaterial, 1L)) + .duration(((int) (baseDuration * 1.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix2, aMaterial, 16L / multiplier), + GTUtility.getIntegratedCircuit(8)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt08, aMaterial, 1L)) + .duration(baseDuration * 2 * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix2, aMaterial, 24L / multiplier), + GTUtility.getIntegratedCircuit(12)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt12, aMaterial, 1L)) + .duration(((int) (baseDuration * 2.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + GTValues.RA.stdBuilder() + .itemInputs( + GTOreDictUnificator.get(prefix2, aMaterial, 32L / multiplier), + GTUtility.getIntegratedCircuit(16)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireGt16, aMaterial, 1L)) + .duration(baseDuration * 3 * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + } + if (GTOreDictUnificator.get(prefix1, aMaterial, 1L) != null + && GTOreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(GTOreDictUnificator.get(prefix1, aMaterial, 1L), GTUtility.getIntegratedCircuit(3)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 4L * multiplier)) + .duration(baseDuration * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + } + if (GTOreDictUnificator.get(prefix2, aMaterial, 1L) != null + && GTOreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 1L) != null) { + GTValues.RA.stdBuilder() + .itemInputs(GTOreDictUnificator.get(prefix2, aMaterial, 1L), GTUtility.getIntegratedCircuit(3)) + .itemOutputs(GTOreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 2L * multiplier)) + .duration(((int) (baseDuration * 0.5f)) * TICKS) + .eut(aEUt) + .addTo(wiremillRecipes); + } + } + + public static boolean hasVanillaRecipes(Materials materials) { + return Arrays.stream(VANILLA_MATS) + .anyMatch(mat -> mat == materials); + } + + private static int getRecipeWidth(ShapedOreRecipe r) { + try { + return (int) SHAPED_ORE_RECIPE_WIDTH.get(r); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + private static int getRecipeHeight(ShapedOreRecipe r) { + try { + return (int) SHAPED_ORE_RECIPE_HEIGHT.get(r); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + private static int getRecipeHeight(ShapedRecipes r) { + return r.recipeHeight; + } + + private static int getRecipeWidth(ShapedRecipes r) { + return r.recipeWidth; + } + + private static class RecipeShape { + + private final ItemStack[] shape; + private int amount1; + private int amount2; + + public RecipeShape(ItemStack... shape) { + this.shape = shape; + + for (ItemStack stack : shape) { + if (stack == sMt1) this.amount1++; + if (stack == sMt2) this.amount2++; + } + } + + public List> getEmptySlotsAllVariants() { + // "shake" the grid in 8 direction and see if the recipe shape is still valid + // also include the "no movement" case + ImmutableList.Builder> b = ImmutableList.builder(); + for (int i = -1; i < 2; i++) { + if (i != 0 && !isColClear(i + 1)) continue; + for (int j = -1; j < 2; j++) { + if (j != 0 && !isRowClear(j + 1)) continue; + b.add(getEmptySlots(i, j)); + } + } + return b.build(); + } + + private boolean isRowClear(int row) { + for (int i = 0; i < 3; i++) { + if (shape[i + row * 3] != null) return false; + } + return true; + } + + private boolean isColClear(int col) { + for (int i = 0; i < 3; i++) { + if (shape[col + i * 3] != null) return false; + } + return true; + } + + private List getEmptySlots(int offsetX, int offsetY) { + ImmutableList.Builder b = ImmutableList.builder(); + for (int i = 0; i < shape.length; i++) { + int mappedIndex = i - offsetX - offsetY * 3; + // empty slot if it either + // 1) map to a slot outside the original shape + // 2) map to an empty slot in original shape + if (mappedIndex < 0 || mappedIndex > 8 || shape[mappedIndex] == null) b.add(i); + } + return b.build(); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTRenderingWorld.java b/src/main/java/gregtech/api/util/GTRenderingWorld.java new file mode 100644 index 0000000000..ace0e9cd8d --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRenderingWorld.java @@ -0,0 +1,195 @@ +package gregtech.api.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.event.world.ChunkEvent; +import net.minecraftforge.event.world.WorldEvent; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; + +/** + * Provide a fake IBlockAccess to support CTM. Facade are supposed to set these when they are placed/received by client. + */ +public class GTRenderingWorld implements IBlockAccess { + + private static final GTRenderingWorld INSTANCE = new GTRenderingWorld(); + /* + * I do not think this map would ever grow too huge, so I won't go too overcomplicated on this one + */ + private final Map infos = new HashMap<>(); + private final Map> index = new HashMap<>(); + private IBlockAccess mWorld = Minecraft.getMinecraft().theWorld; + + private GTRenderingWorld() { + new FMLEventHandler(); + new ForgeEventHandler(); + } + + public static GTRenderingWorld getInstance() { + return INSTANCE; + } + + public static GTRenderingWorld getInstance(IBlockAccess aWorld) { + if (aWorld == INSTANCE) return INSTANCE; + if (aWorld == null) INSTANCE.mWorld = Minecraft.getMinecraft().theWorld; + else INSTANCE.mWorld = aWorld; + return INSTANCE; + } + + private void setWorld(IBlockAccess aWorld) { + if (aWorld == null) mWorld = Minecraft.getMinecraft().theWorld; + else mWorld = aWorld; + } + + public void register(int x, int y, int z, Block block, int meta) { + ChunkPosition key = new ChunkPosition(x, y, z); + infos.put(key, new BlockInfo(block, meta)); + index.computeIfAbsent(new ChunkCoordIntPair(x >> 4, z >> 4), p -> new HashSet<>()) + .add(key); + } + + public void unregister(int x, int y, int z, Block block, int meta) { + ChunkPosition key = new ChunkPosition(x, y, z); + if (infos.remove(key, new BlockInfo(block, meta))) { + ChunkCoordIntPair chunkKey = new ChunkCoordIntPair(x >> 4, z >> 4); + Set set = index.get(chunkKey); + set.remove(key); + if (set.isEmpty()) index.remove(chunkKey); + } + } + + @Override + public Block getBlock(int p_147439_1_, int p_147439_2_, int p_147439_3_) { + BlockInfo blockInfo = infos.get(new ChunkPosition(p_147439_1_, p_147439_2_, p_147439_3_)); + return blockInfo != null ? blockInfo.block : mWorld.getBlock(p_147439_1_, p_147439_2_, p_147439_3_); + } + + @Override + public TileEntity getTileEntity(int p_147438_1_, int p_147438_2_, int p_147438_3_) { + return mWorld.getTileEntity(p_147438_1_, p_147438_2_, p_147438_3_); + } + + @Override + public int getLightBrightnessForSkyBlocks(int p_72802_1_, int p_72802_2_, int p_72802_3_, int p_72802_4_) { + return mWorld.getLightBrightnessForSkyBlocks(p_72802_1_, p_72802_2_, p_72802_3_, p_72802_4_); + } + + @Override + public int getBlockMetadata(int p_72805_1_, int p_72805_2_, int p_72805_3_) { + BlockInfo blockInfo = infos.get(new ChunkPosition(p_72805_1_, p_72805_2_, p_72805_3_)); + return blockInfo != null ? blockInfo.meta : mWorld.getBlockMetadata(p_72805_1_, p_72805_2_, p_72805_3_); + } + + @Override + public int isBlockProvidingPowerTo(int p_72879_1_, int p_72879_2_, int p_72879_3_, int p_72879_4_) { + return mWorld.isBlockProvidingPowerTo(p_72879_1_, p_72879_2_, p_72879_3_, p_72879_4_); + } + + @Override + public boolean isAirBlock(int p_147437_1_, int p_147437_2_, int p_147437_3_) { + return getBlock(p_147437_1_, p_147437_2_, p_147437_3_).isAir(mWorld, p_147437_1_, p_147437_2_, p_147437_3_); + } + + @Override + public BiomeGenBase getBiomeGenForCoords(int p_72807_1_, int p_72807_2_) { + return mWorld.getBiomeGenForCoords(p_72807_1_, p_72807_2_); + } + + @Override + public int getHeight() { + return mWorld.getHeight(); + } + + @Override + public boolean extendedLevelsInChunkCache() { + return mWorld.extendedLevelsInChunkCache(); + } + + @Override + public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) { + return getBlock(x, y, z).isSideSolid(this, x, y, z, side); + } + + public class FMLEventHandler { + + public FMLEventHandler() { + FMLCommonHandler.instance() + .bus() + .register(this); + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onRenderTickStart(TickEvent.RenderTickEvent e) { + if (e.phase == TickEvent.Phase.START) mWorld = Minecraft.getMinecraft().theWorld; + } + } + + public class ForgeEventHandler { + + private ForgeEventHandler() { + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onChunkUnloaded(ChunkEvent.Unload e) { + if (!e.world.isRemote) return; + Set set = index.remove( + e.getChunk() + .getChunkCoordIntPair()); + if (set != null) infos.keySet() + .removeAll(set); + } + + @SubscribeEvent + public void onWorldUnloaded(WorldEvent.Unload e) { + if (!e.world.isRemote) return; + infos.clear(); + index.clear(); + } + } + + private static class BlockInfo { + + private final Block block; + private final int meta; + + public BlockInfo(Block block, int meta) { + this.block = block; + this.meta = meta; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + BlockInfo blockInfo = (BlockInfo) o; + + if (meta != blockInfo.meta) return false; + return Objects.equals(block, blockInfo.block); + } + + @Override + public int hashCode() { + int result = block != null ? block.hashCode() : 0; + result = 31 * result + meta; + return result; + } + } +} diff --git a/src/main/java/gregtech/api/util/GTShapedRecipe.java b/src/main/java/gregtech/api/util/GTShapedRecipe.java new file mode 100644 index 0000000000..587f3fa852 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTShapedRecipe.java @@ -0,0 +1,100 @@ +package gregtech.api.util; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraftforge.oredict.ShapedOreRecipe; + +import gregtech.api.interfaces.internal.IGTCraftingRecipe; + +public class GTShapedRecipe extends ShapedOreRecipe implements IGTCraftingRecipe { + + public final boolean mRemovableByGT, mKeepingNBT; + private final Enchantment[] mEnchantmentsAdded; + private final int[] mEnchantmentLevelsAdded; + + public GTShapedRecipe(ItemStack aResult, boolean aDismantleAble, boolean aRemovableByGT, boolean aKeepingNBT, + Enchantment[] aEnchantmentsAdded, int[] aEnchantmentLevelsAdded, Object... aRecipe) { + super(aResult, aRecipe); + mEnchantmentsAdded = aEnchantmentsAdded; + mEnchantmentLevelsAdded = aEnchantmentLevelsAdded; + mRemovableByGT = aRemovableByGT; + mKeepingNBT = aKeepingNBT; + } + + @Override + public boolean matches(InventoryCrafting aGrid, World aWorld) { + if (mKeepingNBT) { + ItemStack tStack = null; + for (int i = 0; i < aGrid.getSizeInventory(); i++) { + if (aGrid.getStackInSlot(i) != null) { + if (tStack != null) { + if ((tStack.hasTagCompound() != aGrid.getStackInSlot(i) + .hasTagCompound()) || (tStack.hasTagCompound() + && !tStack.getTagCompound() + .equals( + aGrid.getStackInSlot(i) + .getTagCompound()))) + return false; + } + tStack = aGrid.getStackInSlot(i); + } + } + } + return super.matches(aGrid, aWorld); + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting aGrid) { + ItemStack rStack = super.getCraftingResult(aGrid); + if (rStack != null) { + // Update the Stack + GTUtility.updateItemStack(rStack); + + // Keeping NBT + if (mKeepingNBT) for (int i = 0; i < aGrid.getSizeInventory(); i++) { + if (aGrid.getStackInSlot(i) != null && aGrid.getStackInSlot(i) + .hasTagCompound()) { + rStack.setTagCompound( + (NBTTagCompound) aGrid.getStackInSlot(i) + .getTagCompound() + .copy()); + break; + } + } + + // Charge Values + if (GTModHandler.isElectricItem(rStack)) { + GTModHandler.dischargeElectricItem(rStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); + int tCharge = 0; + for (int i = 0; i < aGrid.getSizeInventory(); i++) tCharge += GTModHandler.dischargeElectricItem( + aGrid.getStackInSlot(i), + Integer.MAX_VALUE, + Integer.MAX_VALUE, + true, + true, + true); + if (tCharge > 0) GTModHandler.chargeElectricItem(rStack, tCharge, Integer.MAX_VALUE, true, false); + } + + // Add Enchantments + for (int i = 0; i < mEnchantmentsAdded.length; i++) GTUtility.ItemNBT.addEnchantment( + rStack, + mEnchantmentsAdded[i], + EnchantmentHelper.getEnchantmentLevel(mEnchantmentsAdded[i].effectId, rStack) + + mEnchantmentLevelsAdded[i]); + + // Update the Stack again + GTUtility.updateItemStack(rStack); + } + return rStack; + } + + @Override + public boolean isRemovable() { + return mRemovableByGT; + } +} diff --git a/src/main/java/gregtech/api/util/GTShapelessRecipe.java b/src/main/java/gregtech/api/util/GTShapelessRecipe.java new file mode 100644 index 0000000000..20c1d361be --- /dev/null +++ b/src/main/java/gregtech/api/util/GTShapelessRecipe.java @@ -0,0 +1,100 @@ +package gregtech.api.util; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraftforge.oredict.ShapelessOreRecipe; + +import gregtech.api.interfaces.internal.IGTCraftingRecipe; + +public class GTShapelessRecipe extends ShapelessOreRecipe implements IGTCraftingRecipe { + + public final boolean mRemovableByGT, mKeepingNBT; + private final Enchantment[] mEnchantmentsAdded; + private final int[] mEnchantmentLevelsAdded; + + public GTShapelessRecipe(ItemStack aResult, boolean aDismantleAble, boolean aRemovableByGT, boolean aKeepingNBT, + Enchantment[] aEnchantmentsAdded, int[] aEnchantmentLevelsAdded, Object... aRecipe) { + super(aResult, aRecipe); + mEnchantmentsAdded = aEnchantmentsAdded; + mEnchantmentLevelsAdded = aEnchantmentLevelsAdded; + mRemovableByGT = aRemovableByGT; + mKeepingNBT = aKeepingNBT; + } + + @Override + public boolean matches(InventoryCrafting aGrid, World aWorld) { + if (mKeepingNBT) { + ItemStack tStack = null; + for (int i = 0; i < aGrid.getSizeInventory(); i++) { + if (aGrid.getStackInSlot(i) != null) { + if (tStack != null) { + if ((tStack.hasTagCompound() != aGrid.getStackInSlot(i) + .hasTagCompound()) || (tStack.hasTagCompound() + && !tStack.getTagCompound() + .equals( + aGrid.getStackInSlot(i) + .getTagCompound()))) + return false; + } + tStack = aGrid.getStackInSlot(i); + } + } + } + return super.matches(aGrid, aWorld); + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting aGrid) { + ItemStack rStack = super.getCraftingResult(aGrid); + if (rStack != null) { + // Update the Stack + GTUtility.updateItemStack(rStack); + + // Keeping NBT + if (mKeepingNBT) for (int i = 0; i < aGrid.getSizeInventory(); i++) { + if (aGrid.getStackInSlot(i) != null && aGrid.getStackInSlot(i) + .hasTagCompound()) { + rStack.setTagCompound( + (NBTTagCompound) aGrid.getStackInSlot(i) + .getTagCompound() + .copy()); + break; + } + } + + // Charge Values + if (GTModHandler.isElectricItem(rStack)) { + GTModHandler.dischargeElectricItem(rStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); + int tCharge = 0; + for (int i = 0; i < aGrid.getSizeInventory(); i++) tCharge += GTModHandler.dischargeElectricItem( + aGrid.getStackInSlot(i), + Integer.MAX_VALUE, + Integer.MAX_VALUE, + true, + true, + true); + if (tCharge > 0) GTModHandler.chargeElectricItem(rStack, tCharge, Integer.MAX_VALUE, true, false); + } + + // Add Enchantments + for (int i = 0; i < mEnchantmentsAdded.length; i++) GTUtility.ItemNBT.addEnchantment( + rStack, + mEnchantmentsAdded[i], + EnchantmentHelper.getEnchantmentLevel(mEnchantmentsAdded[i].effectId, rStack) + + mEnchantmentLevelsAdded[i]); + + // Update the Stack again + GTUtility.updateItemStack(rStack); + } + return rStack; + } + + @Override + public boolean isRemovable() { + return mRemovableByGT; + } +} diff --git a/src/main/java/gregtech/api/util/GTSpawnEventHandler.java b/src/main/java/gregtech/api/util/GTSpawnEventHandler.java new file mode 100644 index 0000000000..2e86fef136 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTSpawnEventHandler.java @@ -0,0 +1,81 @@ +package gregtech.api.util; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.entity.monster.EntitySlime; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingSpawnEvent.CheckSpawn; + +import cpw.mods.fml.common.eventhandler.Event; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gregtech.api.enums.GTValues; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.common.tileentities.machines.basic.MTEMonsterRepellent; + +public class GTSpawnEventHandler { + + public static volatile List mobReps = new CopyOnWriteArrayList<>(); + // Future Optimiztation ideas, if this isn't sufficient + // 1: Keep a weakref list of mob repellents so we already have the tile + // 2: Have the tick method update a HashMap of (int[], range) so we don't have to load the tile at all + + public GTSpawnEventHandler() { + MinecraftForge.EVENT_BUS.register(this); + } + + // Range of a powered repellent + public static int getPoweredRepellentRange(int aTier) { + return 16 + (48 * aTier); + } + + // Range of an unpowered repellent + public static int getUnpoweredRepellentRange(int aTier) { + return 4 + (12 * aTier); + } + + @SubscribeEvent + public void denyMobSpawn(CheckSpawn event) { + if (event.getResult() == Event.Result.DENY) return; + + if (event.entityLiving instanceof EntitySlime slime && !slime.hasCustomNameTag() + && event.getResult() == Event.Result.ALLOW) { + event.setResult(Event.Result.DEFAULT); + } + + if (event.getResult() == Event.Result.ALLOW) { + return; + } + + if (event.entityLiving.isCreatureType(EnumCreatureType.monster, false)) { + final double maxRangeCheck = Math.pow(getPoweredRepellentRange(GTValues.V.length - 1), 2); + for (int[] rep : mobReps) { + if (rep[3] == event.entity.worldObj.provider.dimensionId) { + // If the chunk isn't loaded, we ignore this Repellent + if (!event.entity.worldObj.blockExists(rep[0], rep[1], rep[2])) continue; + final double dx = rep[0] + 0.5F - event.entity.posX; + final double dy = rep[1] + 0.5F - event.entity.posY; + final double dz = rep[2] + 0.5F - event.entity.posZ; + + final double check = (dx * dx + dz * dz + dy * dy); + // Fail early if outside of max range + if (check > maxRangeCheck) continue; + + final TileEntity tTile = event.entity.worldObj.getTileEntity(rep[0], rep[1], rep[2]); + if (tTile instanceof BaseMetaTileEntity metaTile + && metaTile.getMetaTileEntity() instanceof MTEMonsterRepellent repellent + && check <= Math.pow(repellent.mRange, 2)) { + if (event.entityLiving instanceof EntitySlime slime) { + slime.setCustomNameTag("DoNotSpawnSlimes"); + } + event.setResult(Event.Result.DENY); + // We're already DENYing it. No reason to keep checking + return; + } + } + } + } + } +} diff --git a/src/main/java/gregtech/api/util/GTStreamUtil.java b/src/main/java/gregtech/api/util/GTStreamUtil.java new file mode 100644 index 0000000000..4b71fe5ee8 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTStreamUtil.java @@ -0,0 +1,44 @@ +package gregtech.api.util; + +import java.util.Arrays; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public final class GTStreamUtil { + + /** + * Backport of {@link Stream#ofNullable}. + */ + public static Stream ofNullable(@Nullable T value) { + return value == null ? Stream.empty() : Stream.of(value); + } + + /** + * Returns a sequential ordered {@code Stream} whose elements are the specified values, + * if {@code condition} is true, otherwise returns an empty {@code Stream}. + * + * @param the type of stream elements + * @param values the elements of the new stream + * @return the new stream + */ + public static Stream ofConditional(boolean condition, T[] values) { + return condition ? Arrays.stream(values) : Stream.empty(); + } + + /** + * Returns a sequential {@code Stream} containing a single element, which will be lazily evaluated from supplier. + * + * @param the type of stream elements + * @param supplier the supplier for single stream element + * @return the new stream + */ + public static Stream ofSupplier(Supplier supplier) { + return Stream.generate(supplier) + .limit(1); + } +} diff --git a/src/main/java/gregtech/api/util/GTStructureUtility.java b/src/main/java/gregtech/api/util/GTStructureUtility.java new file mode 100644 index 0000000000..2109a7e75b --- /dev/null +++ b/src/main/java/gregtech/api/util/GTStructureUtility.java @@ -0,0 +1,616 @@ +package gregtech.api.util; + +import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.ACCEPT; +import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.ACCEPT_STOP; +import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.REJECT; +import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.SKIP; +import static com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode.EXACT; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.ToIntFunction; + +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; + +import gregtech.api.GregTechAPI; +import gregtech.api.enums.HeatingCoilLevel; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.interfaces.IHeatingCoil; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.MTETieredMachineBlock; +import gregtech.common.blocks.BlockCasings5; +import gregtech.common.blocks.BlockCyclotronCoils; +import gregtech.common.blocks.BlockFrameBox; +import gregtech.common.blocks.ItemMachines; + +public class GTStructureUtility { + + // private static final Map, String> customNames = new HashMap<>(); + private GTStructureUtility() { + throw new AssertionError("Not instantiable"); + } + + public static boolean hasMTE(IGregTechTileEntity aTile, Class clazz) { + return aTile != null && clazz.isInstance(aTile.getMetaTileEntity()); + } + + public static IStructureElementNoPlacement ofHatchAdder(IGTHatchAdder aHatchAdder, int aTextureIndex, + int aDots) { + return ofHatchAdder(aHatchAdder, aTextureIndex, StructureLibAPI.getBlockHint(), aDots - 1); + } + + public static IStructureElement ofFrame(Materials aFrameMaterial) { + if (aFrameMaterial == null) throw new IllegalArgumentException(); + return new IStructureElement<>() { + + private IIcon[] mIcons; + + @Override + public boolean check(T t, World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (block instanceof BlockFrameBox frameBox) { + int meta = world.getBlockMetadata(x, y, z); + Materials material = frameBox.getMaterial(meta); + return aFrameMaterial == material; + } + return false; + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + if (mIcons == null) { + mIcons = new IIcon[6]; + Arrays.fill(mIcons, aFrameMaterial.mIconSet.mTextures[OrePrefixes.frameGt.mTextureIndex].getIcon()); + } + StructureLibAPI.hintParticleTinted(world, x, y, z, mIcons, aFrameMaterial.mRGBa); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + ItemStack tFrameStack = getFrameStack(); + if (!GTUtility.isStackValid(tFrameStack) + || !(tFrameStack.getItem() instanceof ItemBlock tFrameStackItem)) return false; + return tFrameStackItem + .placeBlockAt(tFrameStack, null, world, x, y, z, 6, 0, 0, 0, Items.feather.getDamage(tFrameStack)); + } + + private ItemStack getFrameStack() { + return GTOreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1); + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + ItemStack tFrameStack = getFrameStack(); + if (!GTUtility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock)) + return BlocksToPlace.errored; + return BlocksToPlace.create(tFrameStack); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + return survivalPlaceBlock( + t, + world, + x, + y, + z, + trigger, + AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + if (check(t, world, x, y, z)) return SKIP; + ItemStack tFrameStack = getFrameStack(); + if (!GTUtility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock)) + return REJECT; // honestly, this is more like a programming error or pack issue + return com.gtnewhorizon.structurelib.structure.StructureUtility.survivalPlaceBlock( + tFrameStack, + ItemStackPredicate.NBTMode.IGNORE_KNOWN_INSIGNIFICANT_TAGS, + null, + false, + world, + x, + y, + z, + env.getSource(), + env.getActor(), + env.getChatter()); + } + }; + } + + public static HatchElementBuilder buildHatchAdder() { + return HatchElementBuilder.builder(); + } + + /** + * Completely equivalent to {@link #buildHatchAdder()}, except it plays nicer with type inference when statically + * imported + */ + public static HatchElementBuilder buildHatchAdder(Class typeToken) { + return HatchElementBuilder.builder(); + } + + public static IStructureElementNoPlacement ofHatchAdder(IGTHatchAdder aHatchAdder, int aTextureIndex, + Block aHintBlock, int aHintMeta) { + if (aHatchAdder == null || aHintBlock == null) { + throw new IllegalArgumentException(); + } + return new IStructureElementNoPlacement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IGregTechTileEntity + && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); + return true; + } + }; + } + + public static IStructureElement ofHatchAdder(IGTHatchAdder aHatchAdder, int aTextureIndex, + Block aHintBlock, int aHintMeta, BiPredicate shouldSkip, + Function> aMetaId, final IStructureElement.PlaceResult acceptType) { + if (aHatchAdder == null) { + throw new IllegalArgumentException(); + } + return new IStructureElement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IGregTechTileEntity + && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int i, int i1, int i2, ItemStack itemStack) { + // TODO + return false; + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + Class clazz = aMetaId.apply(t); + if (clazz == null) return BlocksToPlace.createEmpty(); + return BlocksToPlace.create(is -> clazz.isInstance(ItemMachines.getMetaTileEntity(is))); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + return survivalPlaceBlock( + t, + world, + x, + y, + z, + trigger, + AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + if (shouldSkip != null) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IGregTechTileEntity + && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return SKIP; + } + if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return REJECT; + Class clazz = aMetaId.apply(t); + if (clazz == null) return REJECT; + ItemStack taken = env.getSource() + .takeOne(is -> clazz.isInstance(ItemMachines.getMetaTileEntity(is)), true); + if (GTUtility.isStackInvalid(taken)) { + env.getChatter() + .accept( + new ChatComponentTranslation( + "GT5U.autoplace.error.no_mte.class_name", + clazz.getSimpleName())); + return REJECT; + } + if (com.gtnewhorizon.structurelib.structure.StructureUtility + .survivalPlaceBlock(taken, EXACT, null, true, world, x, y, z, env.getSource(), env.getActor()) + == ACCEPT) return acceptType; + return REJECT; + } + }; + } + + public static IStructureElement ofHatchAdder(IGTHatchAdder aHatchAdder, int aTextureIndex, + Block aHintBlock, int aHintMeta, BiPredicate shouldSkip, ToIntFunction aMetaId) { + if (aHatchAdder == null) { + throw new IllegalArgumentException(); + } + return new IStructureElement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IGregTechTileEntity + && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int i, int i1, int i2, ItemStack itemStack) { + // TODO + return false; + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + ItemMachines item = (ItemMachines) Item.getItemFromBlock(GregTechAPI.sBlockMachines); + int meta = aMetaId.applyAsInt(t); + if (meta < 0) return BlocksToPlace.createEmpty(); + return BlocksToPlace.create( + ItemStackPredicate.from(item) + .setMeta(meta)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + return survivalPlaceBlock( + t, + world, + x, + y, + z, + trigger, + AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + if (shouldSkip != null) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IGregTechTileEntity + && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return SKIP; + } + if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return REJECT; + ItemMachines item = (ItemMachines) Item.getItemFromBlock(GregTechAPI.sBlockMachines); + int meta = aMetaId.applyAsInt(t); + if (meta < 0) return REJECT; + ItemStack taken = env.getSource() + .takeOne( + ItemStackPredicate.from(item) + .setMeta(meta), + true); + if (GTUtility.isStackInvalid(taken)) { + env.getChatter() + .accept(new ChatComponentTranslation("GT5U.autoplace.error.no_mte.id", meta)); + return REJECT; + } + return com.gtnewhorizon.structurelib.structure.StructureUtility + .survivalPlaceBlock(taken, EXACT, null, true, world, x, y, z, env.getSource(), env.getActor()) + == ACCEPT ? ACCEPT_STOP : REJECT; + } + }; + } + + public static IStructureElement ofHatchAdderOptional(IGTHatchAdder aHatchAdder, int textureIndex, + int dots, Block placeCasing, int placeCasingMeta) { + return ofHatchAdderOptional( + aHatchAdder, + textureIndex, + StructureLibAPI.getBlockHint(), + dots - 1, + placeCasing, + placeCasingMeta); + } + + public static IStructureElement ofHatchAdderOptional(IGTHatchAdder aHatchAdder, int aTextureIndex, + Block aHintBlock, int hintMeta, Block placeCasing, int placeCasingMeta) { + if (aHatchAdder == null || aHintBlock == null) { + throw new IllegalArgumentException(); + } + return new IStructureElement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + Block worldBlock = world.getBlock(x, y, z); + return (tileEntity instanceof IGregTechTileEntity + && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex)) + || (worldBlock == placeCasing && worldBlock.getDamageValue(world, x, y, z) == placeCasingMeta); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, hintMeta); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + world.setBlock(x, y, z, placeCasing, placeCasingMeta, 2); + return true; + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + if (check(t, world, x, y, z)) return SKIP; + return com.gtnewhorizon.structurelib.structure.StructureUtility + .survivalPlaceBlock(placeCasing, placeCasingMeta, world, x, y, z, s, actor, chatter); + } + }; + } + + /** + * Assume all coils accepted. + * + * @see #ofCoil(BiPredicate, Function) + */ + public static IStructureElement ofCoil(BiConsumer aHeatingCoilSetter, + Function aHeatingCoilGetter) { + return ofCoil((t, l) -> { + aHeatingCoilSetter.accept(t, l); + return true; + }, aHeatingCoilGetter); + } + + /** + * Heating coil structure element. + * + * @param aHeatingCoilSetter Notify the controller of this new coil. Got called exactly once per coil. Might be + * called less times if structure test fails. If the setter returns false then it assumes + * the coil is rejected. + * @param aHeatingCoilGetter Get the current heating level. Null means no coil recorded yet. + */ + public static IStructureElement ofCoil(BiPredicate aHeatingCoilSetter, + Function aHeatingCoilGetter) { + if (aHeatingCoilSetter == null || aHeatingCoilGetter == null) { + throw new IllegalArgumentException(); + } + return new IStructureElement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (!(block instanceof IHeatingCoil)) return false; + HeatingCoilLevel existingLevel = aHeatingCoilGetter.apply(t), + newLevel = ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z)); + if (existingLevel == null || existingLevel == HeatingCoilLevel.None) { + return aHeatingCoilSetter.test(t, newLevel); + } else { + return newLevel == existingLevel; + } + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, GregTechAPI.sBlockCasings5, getMetaFromHint(trigger)); + return true; + } + + private int getMetaFromHint(ItemStack trigger) { + return BlockCasings5.getMetaFromCoilHeat(getHeatFromHint(trigger)); + } + + private HeatingCoilLevel getHeatFromHint(ItemStack trigger) { + return HeatingCoilLevel + .getFromTier((byte) Math.min(HeatingCoilLevel.getMaxTier(), Math.max(0, trigger.stackSize - 1))); + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + return world.setBlock(x, y, z, GregTechAPI.sBlockCasings5, getMetaFromHint(trigger), 3); + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + return BlocksToPlace.create(GregTechAPI.sBlockCasings5, getMetaFromHint(trigger)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + return survivalPlaceBlock( + t, + world, + x, + y, + z, + trigger, + AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + Block block = world.getBlock(x, y, z); + boolean isCoil = block instanceof IHeatingCoil + && ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z)) == getHeatFromHint(trigger); + if (isCoil) return SKIP; + return com.gtnewhorizon.structurelib.structure.StructureUtility.survivalPlaceBlock( + GregTechAPI.sBlockCasings5, + getMetaFromHint(trigger), + world, + x, + y, + z, + env.getSource(), + env.getActor(), + env.getChatter()); + } + }; + } + + /** + * Assumes all solenoids are accepted. + * + * @see #ofSolenoidCoil(BiPredicate, Function) + */ + public static IStructureElement ofSolenoidCoil(BiConsumer aSolenoidTierSetter, + Function aSolenoidTierGetter) { + return ofSolenoidCoil((t, l) -> { + aSolenoidTierSetter.accept(t, l); + return true; + }, aSolenoidTierGetter); + } + + /** + * Solenoid coil structure element. + * + * @param aSolenoidTierSetter Notify the controller of this new solenoid. Got called exactly once per solenoid. + * Might be + * called less times if structure test fails. If the setter returns false then it assumes + * the solenoid is rejected. + * @param aSolenoidTierGetter Get the solenoid voltage tier. Null means no tier recorded yet. + */ + public static IStructureElement ofSolenoidCoil(BiPredicate aSolenoidTierSetter, + Function aSolenoidTierGetter) { + if (aSolenoidTierSetter == null || aSolenoidTierGetter == null) { + throw new IllegalArgumentException(); + } + return new IStructureElement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + if (block != GregTechAPI.sSolenoidCoilCasings) return false; + + var coils = ((BlockCyclotronCoils) GregTechAPI.sSolenoidCoilCasings); + + Byte existingLevel = aSolenoidTierGetter.apply(t); + byte newLevel = (byte) (coils.getVoltageTier(world.getBlockMetadata(x, y, z))); + + if (existingLevel == null) { + return aSolenoidTierSetter.test(t, newLevel); + } else { + return newLevel == existingLevel; + } + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI + .hintParticle(world, x, y, z, GregTechAPI.sSolenoidCoilCasings, getMetaFromHint(trigger)); + return true; + } + + private int getMetaFromHint(ItemStack trigger) { + return Math.min(Math.max(trigger.stackSize - 1, 0), 10); + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + return world.setBlock(x, y, z, GregTechAPI.sSolenoidCoilCasings, getMetaFromHint(trigger), 3); + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + return BlocksToPlace.create(GregTechAPI.sSolenoidCoilCasings, getMetaFromHint(trigger)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + return survivalPlaceBlock( + t, + world, + x, + y, + z, + trigger, + AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + Block block = world.getBlock(x, y, z); + + boolean isCoil = block == GregTechAPI.sSolenoidCoilCasings + && world.getBlockMetadata(x, y, z) == getMetaFromHint(trigger); + + if (isCoil) return SKIP; + + return com.gtnewhorizon.structurelib.structure.StructureUtility.survivalPlaceBlock( + GregTechAPI.sSolenoidCoilCasings, + getMetaFromHint(trigger), + world, + x, + y, + z, + env.getSource(), + env.getActor(), + env.getChatter()); + } + }; + } + + @Nonnull + public static Predicate filterByMTEClass(List> list) { + return is -> { + IMetaTileEntity tile = ItemMachines.getMetaTileEntity(is); + return tile != null && list.stream() + .anyMatch(c -> c.isInstance(tile)); + }; + } + + @Nonnull + public static Predicate filterByMTETier(int aMinTier, int aMaxTier) { + return is -> { + IMetaTileEntity tile = ItemMachines.getMetaTileEntity(is); + return tile instanceof MTETieredMachineBlock && ((MTETieredMachineBlock) tile).mTier <= aMaxTier + && ((MTETieredMachineBlock) tile).mTier >= aMinTier; + }; + } +} diff --git a/src/main/java/gregtech/api/util/GTToolHarvestHelper.java b/src/main/java/gregtech/api/util/GTToolHarvestHelper.java new file mode 100644 index 0000000000..8dd5d6b93c --- /dev/null +++ b/src/main/java/gregtech/api/util/GTToolHarvestHelper.java @@ -0,0 +1,71 @@ +package gregtech.api.util; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; + +import ic2.core.block.BlockMultiID; +import ic2.core.block.BlockScaffold; +import ic2.core.block.machine.BlockMiningPipe; +import ic2.core.block.machine.BlockMiningTip; +import ic2.core.block.wiring.BlockCable; +import ic2.core.crop.BlockCrop; + +public class GTToolHarvestHelper { + + public static boolean isAppropriateTool(Block aBlock, byte aMetaData, String... tTools) { + + if (aBlock == null || tTools == null) { + return false; + } + String targetTool = aBlock.getHarvestTool(aMetaData); + return !isStringEmpty(targetTool) && isArrayContains(targetTool, tTools); + } + + public static boolean isAppropriateMaterial(Block aBlock, Material... tMats) { + if (aBlock == null || tMats == null) { + return false; + } + return isArrayContains(aBlock.getMaterial(), tMats); + } + + public static boolean isSpecialBlock(Block aBlock, Block... tBlocks) { + if (aBlock == null || tBlocks == null) { + return false; + } + return isArrayContains(aBlock, tBlocks); + } + + public static boolean isArrayContains(T obj, T[] list) { + + if (obj == null || list == null) { + return false; + } + + for (T iObj : list) { + if (obj == iObj || obj.equals(iObj)) { + return true; + } + } + return false; + } + + public static boolean isStringEmpty(String s) { + return s == null || s.isEmpty(); + } + + public static boolean isIC2Wrenchable(Block block) { + return (block instanceof BlockMultiID && !(block instanceof BlockCable) && !(block instanceof BlockCrop)) + || block instanceof BlockScaffold + || block instanceof BlockMiningPipe + || block instanceof BlockMiningTip; + } + + public static boolean hasNull(Object... obj) { + for (Object iObj : obj) { + if (iObj == null) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/gregtech/api/util/GTTooltipDataCache.java b/src/main/java/gregtech/api/util/GTTooltipDataCache.java new file mode 100644 index 0000000000..a26f7a84d8 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTTooltipDataCache.java @@ -0,0 +1,104 @@ +package gregtech.api.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.util.StatCollector; + +import gregtech.GTMod; + +public class GTTooltipDataCache { + + public static class TooltipData { + + public List text; + public List shiftText; + + public TooltipData(List text, List shiftText) { + this.text = text; + this.shiftText = shiftText; + } + } + + private final Map fetchedTooltipData = new HashMap<>(); + + /** + * Returns tooltip data respecting the user's configured verbosity levels, applying any formatting arguments. + * + * @param key the key to lookup + * @param args arguments for string formatting (prefer using positional arguments) + * @return The tooltip data the user asked for + */ + public TooltipData getData(String key, Object... args) { + TooltipData tooltipData = fetchedTooltipData.get(key); + if (tooltipData == null) { + tooltipData = getUncachedTooltipData(key, args); + fetchedTooltipData.put(key, tooltipData); + } + return tooltipData; + } + + /** + * Builds tooltip data respecting the user's configured verbosity levels, applying any formatting arguments. + * + * @param key the key to lookup + * @param args arguments for string formatting (prefer using positional arguments) + * @return The tooltip data the user asked for + */ + public TooltipData getUncachedTooltipData(String key, Object... args) { + List lines = getAllLines(key, args); + int normalLines = lines.size(); + if (Math.max(GTMod.gregtechproxy.mTooltipVerbosity, GTMod.gregtechproxy.mTooltipShiftVerbosity) >= 3) { + lines.addAll(getAllLines(key + ".extended", args)); // Are extended lines enabled? If so add them to the + // lines + } + if (lines.size() == 0) { + lines.add(key); // Fallback in case no lines could be found at all + } + return new TooltipData( + lines.subList(0, getVerbosityIndex(GTMod.gregtechproxy.mTooltipVerbosity, normalLines, lines.size())), + lines.subList(0, getVerbosityIndex(GTMod.gregtechproxy.mTooltipShiftVerbosity, normalLines, lines.size()))); + } + + /** + * Gets all the lines for the given key and every other subsequent consecutive key with a .n suffix, n in {1,2,3...} + * + * @param key the key to lookup + * @param args arguments for string formatting (prefer using positional arguments) + * @return The lines for the key and all of it's subkeys + */ + private List getAllLines(String key, Object... args) { + List lines = new ArrayList<>(); + String keyToLookup = key; + int i = 1; // First loop has no .number postfix + while (StatCollector.canTranslate(keyToLookup)) { + lines.add(StatCollector.translateToLocalFormatted(keyToLookup, args)); + keyToLookup = key + "." + i++; + } + return lines; + } + + /** + * Determines how many lines from a tooltip to include from the full line list to respect a given verbosity level. + * + * @param tooltipVerbosity the verbosity level we're applying + * @param defaultIndex return if tooltipVerbosity is 2 + * @param maxIndex return if tooltipVerbosity is greater than 2 + * @return verbosity appropriate index + */ + private static int getVerbosityIndex(int tooltipVerbosity, int defaultIndex, int maxIndex) { + int index; + if (tooltipVerbosity < 1) { + index = 0; + } else if (tooltipVerbosity == 1) { + index = 1; + } else if (tooltipVerbosity == 2) { + index = defaultIndex; + } else { + index = maxIndex; + } + return index; + } +} diff --git a/src/main/java/gregtech/api/util/GTUtil.java b/src/main/java/gregtech/api/util/GTUtil.java new file mode 100644 index 0000000000..db2a628bbe --- /dev/null +++ b/src/main/java/gregtech/api/util/GTUtil.java @@ -0,0 +1,344 @@ +package gregtech.api.util; + +import static gregtech.api.util.GTUtility.filterValidMTEs; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.Tuple; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.util.Constants; + +import gregtech.api.enums.ItemList; +import gregtech.api.interfaces.IDataCopyable; +import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.metatileentity.implementations.MTEMultiBlockBase; +import gregtech.api.multitileentity.interfaces.IMultiTileEntity; +import gregtech.common.items.behaviors.BehaviourDataOrb; + +public class GTUtil { + + // Last broken tile entity + public static final ThreadLocal LAST_BROKEN_TILEENTITY = new ThreadLocal<>(); + + public static Tuple tuple(String key, Object value) { + return new Tuple(key, value); + } + + public static NBTTagCompound fuseNBT(NBTTagCompound nbt1, NBTTagCompound nbt2) { + if (nbt1 == null) return nbt2 == null ? new NBTTagCompound() : (NBTTagCompound) nbt2.copy(); + final NBTTagCompound rNBT = (NBTTagCompound) nbt1.copy(); + if (nbt2 == null) return rNBT; + for (Object tKey : nbt2.func_150296_c /* getKeySet */()) + if (!rNBT.hasKey(tKey.toString())) rNBT.setTag(tKey.toString(), nbt2.getTag(tKey.toString())); + return rNBT; + } + + /** + * Construct a NBTTagCompound from a series of key, value pairs. Inspired from GT6. + */ + public static NBTTagCompound makeNBT(Tuple... tags) { + final NBTTagCompound nbt = new NBTTagCompound(); + for (Tuple t : tags) { + if (t.getSecond() == null) continue; + + if (t.getSecond() instanceof Boolean) nbt.setBoolean( + t.getFirst() + .toString(), + (Boolean) t.getSecond()); + else if (t.getSecond() instanceof Byte) nbt.setByte( + t.getFirst() + .toString(), + (Byte) t.getSecond()); + else if (t.getSecond() instanceof Short) nbt.setShort( + t.getFirst() + .toString(), + (Short) t.getSecond()); + else if (t.getSecond() instanceof Integer) nbt.setInteger( + t.getFirst() + .toString(), + (Integer) t.getSecond()); + else if (t.getSecond() instanceof Long) nbt.setLong( + t.getFirst() + .toString(), + (Long) t.getSecond()); + else if (t.getSecond() instanceof Float) nbt.setFloat( + t.getFirst() + .toString(), + (Float) t.getSecond()); + else if (t.getSecond() instanceof Double) nbt.setDouble( + t.getFirst() + .toString(), + (Double) t.getSecond()); + else if (t.getSecond() instanceof String) nbt.setString( + t.getFirst() + .toString(), + (String) t.getSecond()); + else if (t.getSecond() instanceof NBTBase) nbt.setTag( + t.getFirst() + .toString(), + (NBTBase) t.getSecond()); + else nbt.setString( + t.getFirst() + .toString(), + t.getSecond() + .toString()); + } + + return nbt; + } + + /** + * Get a TileEntity + */ + public static TileEntity getTileEntity(World world, int x, int y, int z, boolean aLoadUnloadedChunks) { + if (aLoadUnloadedChunks || world.blockExists(x, y, z)) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IMultiTileEntity && ((IMultiTileEntity) tileEntity).isDead()) return null; + if (tileEntity != null) return tileEntity; + tileEntity = LAST_BROKEN_TILEENTITY.get(); + if (tileEntity != null && tileEntity.xCoord == x && tileEntity.yCoord == y && tileEntity.zCoord == z) + return tileEntity; + } + return null; + } + + /** + * Sets the TileEntity at the passed position, with the option of turning adjacent TileEntity updates off. + */ + public static TileEntity setTileEntity(World world, int x, int y, int z, TileEntity aTileEntity, + boolean aCauseTileEntityUpdates) { + if (aCauseTileEntityUpdates) world.setTileEntity(x, y, z, aTileEntity); + else { + final Chunk tChunk = world.getChunkFromChunkCoords(x >> 4, z >> 4); + if (tChunk != null) { + world.addTileEntity(aTileEntity); + tChunk.func_150812_a /* setBlockTileEntityInChunk */(x & 15, y, z & 15, aTileEntity); + tChunk.setChunkModified(); + } + } + return aTileEntity; + } + + public static boolean setBlock(World world, int x, int y, int z, Block block, short aMeta, long aFlags, + boolean aRemoveGrassBelow) { + if (aRemoveGrassBelow) { + final Block blockBelow = world.getBlock(x, y - 1, z); + if (blockBelow == Blocks.grass || blockBelow == Blocks.mycelium) + world.setBlock(x, y - 1, z, Blocks.dirt, 0, (byte) aFlags); + } + return world.setBlock(x, y, z, block, aMeta, (byte) aFlags); + } + + public static TileEntity getTileEntity(World world, ChunkCoordinates coords, boolean loadUnloadedChunks) { + return getTileEntity(world, coords.posX, coords.posY, coords.posZ, loadUnloadedChunks); + } + + /** + * Marks a Chunk dirty so it is saved + */ + public static boolean markChunkDirty(World world, int x, int z) { + if (world == null || world.isRemote) return false; + Chunk aChunk = world.getChunkFromBlockCoords(x, z); + if (aChunk == null) { + world.getBlockMetadata(x, 0, z); + aChunk = world.getChunkFromBlockCoords(x, z); + if (aChunk == null) { + GTLog.err.println( + "Some important Chunk does not exist for some reason at Coordinates X: " + x + " and Z: " + z); + return false; + } + } + aChunk.setChunkModified(); + return true; + } + + /** + * Marks a Chunk dirty so it is saved + */ + public static boolean markChunkDirty(Object maybeTile) { + return maybeTile instanceof TileEntity tileEntity + && markChunkDirty(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.zCoord); + } + + public static int mixRGBInt(int aRGB1, int aRGB2) { + return getRGBInt( + new short[] { (short) ((getR(aRGB1) + getR(aRGB2)) >> 1), (short) ((getG(aRGB1) + getG(aRGB2)) >> 1), + (short) ((getB(aRGB1) + getB(aRGB2)) >> 1) }); + } + + public static int getRGBInt(short[] aColors) { + return aColors == null ? 16777215 : (aColors[0] << 16) | (aColors[1] << 8) | aColors[2]; + } + + public static int getRGBaInt(short[] aColors) { + return aColors == null ? 16777215 : (aColors[0]) << 16 | (aColors[1] << 8) | aColors[2] | (aColors[3] << 24); + } + + public static String toHexString(short[] aColors) { + return aColors == null ? "FFFFFF" : Integer.toHexString((aColors[0] << 16) | (aColors[1] << 8) | aColors[2]); + } + + public static int getRGBInt(short aR, short aG, short aB) { + return (aR << 16) | (aG << 8) | aB; + } + + public static int getRGBaInt(short aR, short aG, short aB, short aA) { + return (aR << 16) | (aG << 8) | aB | (aA << 24); + } + + public static short[] getRGBaArray(int aColors) { + return new short[] { (short) ((aColors >>> 16) & 255), (short) ((aColors >>> 8) & 255), (short) (aColors & 255), + (short) ((aColors >>> 24) & 255) }; + } + + public static short getR(int aColors) { + return (short) ((aColors >>> 16) & 255); + } + + public static short getG(int aColors) { + return (short) ((aColors >>> 8) & 255); + } + + public static short getB(int aColors) { + return (short) (aColors & 255); + } + + public static short getA(int aColors) { + return (short) ((aColors >>> 24) & 255); + } + + public static boolean saveMultiblockInputConfiguration(MTEMultiBlockBase controller, EntityPlayer player) { + NBTTagCompound newTag = new NBTTagCompound(); + ItemStack dataOrb = player.getHeldItem(); + if (GTUtility.isStackInvalid(dataOrb) || !ItemList.Tool_DataOrb.isStackEqual(dataOrb, false, true)) { + return false; + } + if (!controller.saveOtherHatchConfiguration(player)) { + return false; + } + newTag.setString("type", "MultiblockConfiguration"); + int count = 0; + NBTTagList list = saveConfigurationToDataStick(player, controller.mInputBusses); + if (list == null) return false; + newTag.setTag("mInputBusses", list); + count += list.tagCount(); + list = saveConfigurationToDataStick(player, controller.mInputHatches); + if (list == null) return false; + newTag.setTag("mInputHatches", list); + count += list.tagCount(); + list = saveConfigurationToDataStick(player, controller.mOutputBusses); + if (list == null) return false; + newTag.setTag("mOutputBusses", list); + count += list.tagCount(); + // Output hatch config currently cannot be copied, so we omit this part for now + // TODO this doesn't work for now + // newTag.setTag("mDualInputHatches", saveToDataStick(player, controller.mDualInputHatches)); + dataOrb.setTagCompound(newTag); + BehaviourDataOrb.setDataTitle(dataOrb, "Multiblock Hatch Configuration"); + BehaviourDataOrb.setDataName(dataOrb, String.format("%s configuration saved", count)); + return true; + } + + public static boolean hasMultiblockInputConfiguration(ItemStack dataOrb) { + return !GTUtility.isStackInvalid(dataOrb) && ItemList.Tool_DataOrb.isStackEqual(dataOrb, false, true) + && dataOrb.getTagCompound() != null + && "MultiblockConfiguration".equals( + dataOrb.getTagCompound() + .getString("type")); + } + + public static boolean loadMultiblockInputConfiguration(MTEMultiBlockBase controller, EntityPlayer player) { + ItemStack dataOrb = player.getHeldItem(); + if (!hasMultiblockInputConfiguration(dataOrb)) { + return false; + } + if (!controller.loadOtherHatchConfiguration(player)) { + return false; + } + NBTTagCompound tag = dataOrb.getTagCompound(); + if (!checkCanLoadConfigurationFromDataStick( + tag.getTagList("mInputBusses", Constants.NBT.TAG_COMPOUND), + player, + controller.mInputBusses) + || !checkCanLoadConfigurationFromDataStick( + tag.getTagList("mInputHatches", Constants.NBT.TAG_COMPOUND), + player, + controller.mInputHatches) + || !checkCanLoadConfigurationFromDataStick( + tag.getTagList("mOutputBusses", Constants.NBT.TAG_COMPOUND), + player, + controller.mOutputBusses)) + return false; + + if (!loadConfigurationFromDataStick( + tag.getTagList("mInputBusses", Constants.NBT.TAG_COMPOUND), + player, + controller.mInputBusses)) return false; + if (!loadConfigurationFromDataStick( + tag.getTagList("mInputHatches", Constants.NBT.TAG_COMPOUND), + player, + controller.mInputHatches)) return false; + if (!loadConfigurationFromDataStick( + tag.getTagList("mOutputBusses", Constants.NBT.TAG_COMPOUND), + player, + controller.mOutputBusses)) return false; + return true; + } + + private static NBTTagList saveConfigurationToDataStick(EntityPlayer player, List hatches) { + NBTTagList list = new NBTTagList(); + for (MTEHatch tHatch : filterValidMTEs(hatches)) { + if (!(tHatch instanceof IDataCopyable copyable)) { + list.appendTag(new NBTTagCompound()); + continue; + } + NBTTagCompound tag = copyable.getCopiedData(player); + if (tag == null) return null; + list.appendTag(tag); + } + return list; + } + + private static boolean loadConfigurationFromDataStick(NBTTagList list, EntityPlayer player, + List hatches) { + if (list == null || list.tagList.isEmpty()) return false; + List validMTEs = filterValidMTEs(hatches); + int end = Math.min(validMTEs.size(), list.tagCount()); + for (int i = 0; i < end; i++) { + MTEHatch tHatch = validMTEs.get(i); + NBTTagCompound tag = list.getCompoundTagAt(i); + if (!(tHatch instanceof IDataCopyable copyable)) { + if (tag.hasNoTags()) continue; + return false; + } + if (tag.hasNoTags()) return false; + if (!copyable.pasteCopiedData(player, tag)) return false; + } + return true; + } + + private static boolean checkCanLoadConfigurationFromDataStick(NBTTagList list, EntityPlayer player, + List hatches) { + if (list == null || list.tagList.isEmpty()) return false; + List validMTEs = filterValidMTEs(hatches); + int end = Math.min(validMTEs.size(), list.tagCount()); + for (int i = 0; i < end; i++) { + MTEHatch tHatch = validMTEs.get(i); + NBTTagCompound tag = list.getCompoundTagAt(i); + if (tag.hasNoTags()) continue; + if (!(tHatch instanceof IDataCopyable copyable) || !copyable.getCopiedDataIdentifier(player) + .equals(tag.getString("type"))) return false; + } + return true; + } +} diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java new file mode 100644 index 0000000000..08a1711b97 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -0,0 +1,4852 @@ +package gregtech.api.util; + +import static gregtech.GTMod.GT_FML_LOGGER; +import static gregtech.api.enums.GTValues.COMPASS_DIRECTIONS; +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.GTValues.E; +import static gregtech.api.enums.GTValues.GT; +import static gregtech.api.enums.GTValues.L; +import static gregtech.api.enums.GTValues.M; +import static gregtech.api.enums.GTValues.NW; +import static gregtech.api.enums.GTValues.V; +import static gregtech.api.enums.GTValues.W; +import static gregtech.api.enums.Materials.FLUID_MAP; +import static gregtech.api.enums.Mods.Translocator; +import static gregtech.common.UndergroundOil.undergroundOilReadInformation; +import static net.minecraftforge.common.util.ForgeDirection.DOWN; +import static net.minecraftforge.common.util.ForgeDirection.EAST; +import static net.minecraftforge.common.util.ForgeDirection.NORTH; +import static net.minecraftforge.common.util.ForgeDirection.SOUTH; +import static net.minecraftforge.common.util.ForgeDirection.UNKNOWN; +import static net.minecraftforge.common.util.ForgeDirection.UP; +import static net.minecraftforge.common.util.ForgeDirection.WEST; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.AbstractCollection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTBase.NBTPrimitive; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.network.play.server.S07PacketRespawn; +import net.minecraft.network.play.server.S1DPacketEntityEffect; +import net.minecraft.network.play.server.S1FPacketSetExperience; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Vec3; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.common.util.FakePlayerFactory; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidContainerItem; +import net.minecraftforge.fluids.IFluidHandler; +import net.minecraftforge.oredict.OreDictionary; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.SetMultimap; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; +import com.mojang.authlib.GameProfile; + +import buildcraft.api.transport.IPipeTile; +import cofh.api.energy.IEnergyReceiver; +import cofh.api.transport.IItemDuct; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.GregTechAPI; +import gregtech.api.damagesources.GTDamageSources; +import gregtech.api.damagesources.GTDamageSources.DamageSourceHotItem; +import gregtech.api.enchants.EnchantmentHazmat; +import gregtech.api.enchants.EnchantmentRadioactivity; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.Mods; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.SoundResource; +import gregtech.api.enums.SubTag; +import gregtech.api.enums.Textures; +import gregtech.api.enums.ToolDictNames; +import gregtech.api.events.BlockScanningEvent; +import gregtech.api.interfaces.IBlockContainer; +import gregtech.api.interfaces.IDebugableBlock; +import gregtech.api.interfaces.IHasIndexedTexture; +import gregtech.api.interfaces.IProjectileItem; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IBasicEnergyContainer; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IGregTechDeviceInformation; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.IMachineProgress; +import gregtech.api.interfaces.tileentity.IUpgradableMachine; +import gregtech.api.items.GTGenericItem; +import gregtech.api.items.ItemEnergyArmor; +import gregtech.api.items.MetaGeneratedTool; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.net.GTPacketSound; +import gregtech.api.objects.CollectorUtils; +import gregtech.api.objects.GTItemStack; +import gregtech.api.objects.GTItemStack2; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.threads.RunnableSound; +import gregtech.api.util.extensions.ArrayExt; +import gregtech.common.Pollution; +import gregtech.common.blocks.BlockOresAbstract; +import ic2.api.recipe.IRecipeInput; +import ic2.api.recipe.RecipeInputItemStack; +import ic2.api.recipe.RecipeInputOreDict; +import ic2.api.recipe.RecipeOutput; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; + +/** + * NEVER INCLUDE THIS FILE IN YOUR MOD!!! + *

+ * Just a few Utility Functions I use. + */ +public class GTUtility { + + /** + * Formats a number with group separator and at most 2 fraction digits. + */ + private static final Map decimalFormatters = new HashMap<>(); + + /** + * Forge screwed the Fluid Registry up again, so I make my own, which is also much more efficient than the stupid + * Stuff over there. + */ + private static final List sFluidContainerList = new ArrayList<>(); + + private static final Map sFilledContainerToData = new /* Concurrent */ HashMap<>(); + private static final Map> sEmptyContainerToFluidToData = new HashMap<>(); + private static final Map> sFluidToContainers = new HashMap<>(); + /** + * Must use {@code Supplier} here because the ore prefixes have not yet been registered at class load time. + */ + private static final Map> sOreToCobble = new HashMap<>(); + + private static final Map sOreTable = new HashMap<>(); + public static boolean TE_CHECK = false, BC_CHECK = false, CHECK_ALL = true, RF_CHECK = false; + public static Map sPlayedSoundMap = new /* Concurrent */ HashMap<>(); + private static int sBookCount = 0; + public static UUID defaultUuid = null; // maybe default non-null? + // UUID.fromString("00000000-0000-0000-0000-000000000000"); + + static { + GregTechAPI.sItemStackMappings.add(sFilledContainerToData); + GregTechAPI.sItemStackMappings.add(sEmptyContainerToFluidToData); + + // 1 is the magic index to get the cobblestone block. + // See: GT_Block_Stones.java, GT_Block_Granites.java + Function> materialToCobble = m -> Suppliers.memoize( + () -> GTOreDictUnificator.getOres(OrePrefixes.stone, m) + .get(1))::get; + sOreToCobble.put(OrePrefixes.oreBlackgranite, materialToCobble.apply(Materials.GraniteBlack)); + sOreToCobble.put(OrePrefixes.oreRedgranite, materialToCobble.apply(Materials.GraniteRed)); + sOreToCobble.put(OrePrefixes.oreMarble, materialToCobble.apply(Materials.Marble)); + sOreToCobble.put(OrePrefixes.oreBasalt, materialToCobble.apply(Materials.Basalt)); + sOreToCobble.put(OrePrefixes.oreNetherrack, () -> new ItemStack(Blocks.netherrack)); + sOreToCobble.put(OrePrefixes.oreEndstone, () -> new ItemStack(Blocks.end_stone)); + } + + public static int safeInt(long number, int margin) { + return number > Integer.MAX_VALUE - margin ? Integer.MAX_VALUE - margin : (int) number; + } + + public static int safeInt(long number) { + return number > V[V.length - 1] ? safeInt(V[V.length - 1], 1) + : number < Integer.MIN_VALUE ? Integer.MIN_VALUE : (int) number; + } + + public static Field getPublicField(Object aObject, String aField) { + Field rField = null; + try { + rField = aObject.getClass() + .getDeclaredField(aField); + } catch (Throwable e) { + /* Do nothing */ + } + return rField; + } + + public static Field getField(Object aObject, String aField) { + Field rField = null; + try { + rField = aObject.getClass() + .getDeclaredField(aField); + rField.setAccessible(true); + } catch (Throwable e) { + /* Do nothing */ + } + return rField; + } + + public static Field getField(Class aObject, String aField) { + Field rField = null; + try { + rField = aObject.getDeclaredField(aField); + rField.setAccessible(true); + } catch (Throwable e) { + /* Do nothing */ + } + return rField; + } + + public static Method getMethod(Class aObject, String aMethod, Class... aParameterTypes) { + Method rMethod = null; + try { + rMethod = aObject.getMethod(aMethod, aParameterTypes); + rMethod.setAccessible(true); + } catch (Throwable e) { + /* Do nothing */ + } + return rMethod; + } + + public static Method getMethod(Object aObject, String aMethod, Class... aParameterTypes) { + Method rMethod = null; + try { + rMethod = aObject.getClass() + .getMethod(aMethod, aParameterTypes); + rMethod.setAccessible(true); + } catch (Throwable e) { + /* Do nothing */ + } + return rMethod; + } + + public static Field getField(Object aObject, String aField, boolean aPrivate, boolean aLogErrors) { + try { + Field tField = (aObject instanceof Class) ? ((Class) aObject).getDeclaredField(aField) + : (aObject instanceof String) ? Class.forName((String) aObject) + .getDeclaredField(aField) + : aObject.getClass() + .getDeclaredField(aField); + if (aPrivate) tField.setAccessible(true); + return tField; + } catch (Throwable e) { + if (aLogErrors) e.printStackTrace(GTLog.err); + } + return null; + } + + public static Object getFieldContent(Object aObject, String aField, boolean aPrivate, boolean aLogErrors) { + try { + Field tField = (aObject instanceof Class) ? ((Class) aObject).getDeclaredField(aField) + : (aObject instanceof String) ? Class.forName((String) aObject) + .getDeclaredField(aField) + : aObject.getClass() + .getDeclaredField(aField); + if (aPrivate) tField.setAccessible(true); + return tField.get(aObject instanceof Class || aObject instanceof String ? null : aObject); + } catch (Throwable e) { + if (aLogErrors) e.printStackTrace(GTLog.err); + } + return null; + } + + public static Object callPublicMethod(Object aObject, String aMethod, Object... aParameters) { + return callMethod(aObject, aMethod, false, false, true, aParameters); + } + + public static Object callPrivateMethod(Object aObject, String aMethod, Object... aParameters) { + return callMethod(aObject, aMethod, true, false, true, aParameters); + } + + public static Object callMethod(Object aObject, String aMethod, boolean aPrivate, boolean aUseUpperCasedDataTypes, + boolean aLogErrors, Object... aParameters) { + try { + Class[] tParameterTypes = new Class[aParameters.length]; + for (byte i = 0; i < aParameters.length; i++) { + if (aParameters[i] instanceof Class) { + tParameterTypes[i] = (Class) aParameters[i]; + aParameters[i] = null; + } else { + tParameterTypes[i] = aParameters[i].getClass(); + } + if (!aUseUpperCasedDataTypes) { + if (tParameterTypes[i] == Boolean.class) tParameterTypes[i] = boolean.class; + else if (tParameterTypes[i] == Byte.class) tParameterTypes[i] = byte.class; + else if (tParameterTypes[i] == Short.class) tParameterTypes[i] = short.class; + else if (tParameterTypes[i] == Integer.class) tParameterTypes[i] = int.class; + else if (tParameterTypes[i] == Long.class) tParameterTypes[i] = long.class; + else if (tParameterTypes[i] == Float.class) tParameterTypes[i] = float.class; + else if (tParameterTypes[i] == Double.class) tParameterTypes[i] = double.class; + } + } + + Method tMethod = (aObject instanceof Class) ? ((Class) aObject).getMethod(aMethod, tParameterTypes) + : aObject.getClass() + .getMethod(aMethod, tParameterTypes); + if (aPrivate) tMethod.setAccessible(true); + return tMethod.invoke(aObject, aParameters); + } catch (Throwable e) { + if (aLogErrors) e.printStackTrace(GTLog.err); + } + return null; + } + + public static Object callConstructor(String aClass, int aConstructorIndex, Object aReplacementObject, + boolean aLogErrors, Object... aParameters) { + try { + return callConstructor( + Class.forName(aClass), + aConstructorIndex, + aReplacementObject, + aLogErrors, + aParameters); + } catch (Throwable e) { + if (aLogErrors) e.printStackTrace(GTLog.err); + } + return aReplacementObject; + } + + public static Object callConstructor(Class aClass, int aConstructorIndex, Object aReplacementObject, + boolean aLogErrors, Object... aParameters) { + if (aConstructorIndex < 0) { + try { + for (Constructor tConstructor : aClass.getConstructors()) { + try { + return tConstructor.newInstance(aParameters); + } catch (Throwable ignored) {} + } + } catch (Throwable e) { + if (aLogErrors) e.printStackTrace(GTLog.err); + } + } else { + try { + return aClass.getConstructors()[aConstructorIndex].newInstance(aParameters); + } catch (Throwable e) { + if (aLogErrors) e.printStackTrace(GTLog.err); + } + } + return aReplacementObject; + } + + public static String capitalizeString(String aString) { + if (aString != null && aString.length() > 0) return aString.substring(0, 1) + .toUpperCase() + aString.substring(1); + return E; + } + + public static boolean getPotion(EntityLivingBase aPlayer, int aPotionIndex) { + try { + Field tPotionHashmap = null; + + Field[] fields = EntityLiving.class.getDeclaredFields(); + + for (Field field : fields) { + if (field.getType() == HashMap.class) { + tPotionHashmap = field; + tPotionHashmap.setAccessible(true); + break; + } + } + + if (tPotionHashmap != null) return ((HashMap) tPotionHashmap.get(aPlayer)).get(aPotionIndex) != null; + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return false; + } + + public static String getClassName(Object aObject) { + if (aObject == null) return "null"; + return aObject.getClass() + .getName() + .substring( + aObject.getClass() + .getName() + .lastIndexOf(".") + 1); + } + + public static void removePotion(EntityLivingBase aPlayer, int aPotionIndex) { + try { + Field tPotionHashmap = null; + + Field[] fields = EntityLiving.class.getDeclaredFields(); + + for (Field field : fields) { + if (field.getType() == HashMap.class) { + tPotionHashmap = field; + tPotionHashmap.setAccessible(true); + break; + } + } + + if (tPotionHashmap != null) ((HashMap) tPotionHashmap.get(aPlayer)).remove(aPotionIndex); + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + } + + public static boolean getFullInvisibility(EntityPlayer aPlayer) { + try { + if (aPlayer.isInvisible()) { + for (int i = 0; i < 4; i++) { + if (aPlayer.inventory.armorInventory[i] != null) { + if (aPlayer.inventory.armorInventory[i].getItem() instanceof ItemEnergyArmor) { + if ((((ItemEnergyArmor) aPlayer.inventory.armorInventory[i].getItem()).mSpecials & 512) + != 0) { + if (GTModHandler.canUseElectricItem(aPlayer.inventory.armorInventory[i], 10000)) { + return true; + } + } + } + } + } + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + return false; + } + + public static ItemStack suckOneItemStackAt(World aWorld, double aX, double aY, double aZ, double aL, double aH, + double aW) { + for (EntityItem tItem : aWorld.getEntitiesWithinAABB( + EntityItem.class, + AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + aL, aY + aH, aZ + aW))) { + if (!tItem.isDead) { + aWorld.removeEntity(tItem); + tItem.setDead(); + return tItem.getEntityItem(); + } + } + return null; + } + + public static byte getOppositeSide(ForgeDirection side) { + return (byte) side.getOpposite() + .ordinal(); + } + + public static byte getTier(long l) { + byte i = -1; + while (++i < V.length) if (l <= V[i]) return i; + return (byte) (V.length - 1); + } + + public static long getAmperageForTier(long voltage, byte tier) { + return ceilDiv(voltage, GTValues.V[tier]); + } + + /** + * Rounds up partial voltage that exceeds tiered voltage, e.g. 4,096 -> 8,192(IV) + */ + public static long roundUpVoltage(long voltage) { + if (voltage > V[V.length - 1]) { + return voltage; + } + return V[GTUtility.getTier(voltage)]; + } + + public static String getColoredTierNameFromVoltage(long voltage) { + return getColoredTierNameFromTier(getTier(voltage)); + } + + public static String getColoredTierNameFromTier(byte tier) { + return GTValues.TIER_COLORS[tier] + GTValues.VN[tier] + EnumChatFormatting.RESET; + } + + /** + * @return e.g. {@code " (LV)"} + */ + @Nonnull + public static String getTierNameWithParentheses(long voltage) { + byte tier = getTier(voltage); + if (tier < 0) { + return ""; + } else if (tier == 0) { + return " (" + GTValues.VN[1] + ")"; + } else if (tier >= GTValues.VN.length - 1) { + return " (MAX+)"; + } + return " (" + GTValues.VN[tier] + ")"; + } + + public static void sendChatToPlayer(EntityPlayer aPlayer, String aChatMessage) { + if (aPlayer instanceof EntityPlayerMP && aChatMessage != null) { + aPlayer.addChatComponentMessage(new ChatComponentText(aChatMessage)); + } + } + + public static void checkAvailabilities() { + if (CHECK_ALL) { + try { + Class tClass = IItemDuct.class; + tClass.getCanonicalName(); + TE_CHECK = true; + } catch (Throwable e) { + /**/ + } + try { + Class tClass = buildcraft.api.transport.IPipeTile.class; + tClass.getCanonicalName(); + BC_CHECK = true; + } catch (Throwable e) { + /**/ + } + try { + Class tClass = cofh.api.energy.IEnergyReceiver.class; + tClass.getCanonicalName(); + RF_CHECK = true; + } catch (Throwable e) { + /**/ + } + CHECK_ALL = false; + } + } + + public static boolean isConnectableNonInventoryPipe(TileEntity tileEntity, ForgeDirection side) { + if (tileEntity == null) return false; + checkAvailabilities(); + if (TE_CHECK && tileEntity instanceof IItemDuct) return true; + if (BC_CHECK && tileEntity instanceof buildcraft.api.transport.IPipeTile pipeTile) + return pipeTile.isPipeConnected(side); + return Translocator.isModLoaded() && tileEntity instanceof codechicken.translocator.TileItemTranslocator; + } + + /** + * Moves Stack from Inv-Slot to Inv-Slot, without checking if its even allowed. + * + * @return the Amount of moved Items + */ + public static byte moveStackIntoPipe(IInventory aTileEntity1, Object aTileEntity2, int[] aGrabSlots, + ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, + byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { + return moveStackIntoPipe( + aTileEntity1, + aTileEntity2, + aGrabSlots, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + true); + } + + /** + * Moves Stack from Inv-Slot to Inv-Slot, without checking if it is even allowed. + * + * @return the Amount of moved Items + */ + public static byte moveStackIntoPipe(IInventory fromInventory, Object toObject, int[] fromSlots, + ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, + byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, + boolean dropItem) { + if (fromInventory == null || aMaxTargetStackSize <= 0 + || aMinTargetStackSize <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMaxMoveAtOnce <= 0 + || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; + if (toObject != null) { + checkAvailabilities(); + if (TE_CHECK && toObject instanceof IItemDuct itemDuct) { + for (final int aGrabSlot : fromSlots) { + if (listContainsItem(aFilter, fromInventory.getStackInSlot(aGrabSlot), true, aInvertFilter)) { + if (isAllowedToTakeFromSlot( + fromInventory, + aGrabSlot, + fromSide, + fromInventory.getStackInSlot(aGrabSlot))) { + if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) + <= fromInventory.getStackInSlot(aGrabSlot).stackSize) { + ItemStack tStack = copyAmount( + Math.min( + fromInventory.getStackInSlot(aGrabSlot).stackSize, + Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), + fromInventory.getStackInSlot(aGrabSlot)); + ItemStack rStack = itemDuct.insertItem(putSide, copyOrNull(tStack)); + byte tMovedItemCount = (byte) (tStack.stackSize + - (rStack == null ? 0 : rStack.stackSize)); + if (tMovedItemCount >= 1 /* Math.max(aMinMoveAtOnce, aMinTargetStackSize) */) { + fromInventory.decrStackSize(aGrabSlot, tMovedItemCount); + fromInventory.markDirty(); + return tMovedItemCount; + } + } + } + } + } + return 0; + } + if (BC_CHECK && toObject instanceof buildcraft.api.transport.IPipeTile bcPipe) { + for (int fromSlot : fromSlots) { + if (listContainsItem(aFilter, fromInventory.getStackInSlot(fromSlot), true, aInvertFilter)) { + if (isAllowedToTakeFromSlot( + fromInventory, + fromSlot, + fromSide, + fromInventory.getStackInSlot(fromSlot))) { + if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) + <= fromInventory.getStackInSlot(fromSlot).stackSize) { + ItemStack tStack = copyAmount( + Math.min( + fromInventory.getStackInSlot(fromSlot).stackSize, + Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), + fromInventory.getStackInSlot(fromSlot)); + byte tMovedItemCount = (byte) bcPipe.injectItem(copyOrNull(tStack), false, putSide); + if (tMovedItemCount >= Math.max(aMinMoveAtOnce, aMinTargetStackSize)) { + tMovedItemCount = (byte) (bcPipe + .injectItem(copyAmount(tMovedItemCount, tStack), true, putSide)); + fromInventory.decrStackSize(fromSlot, tMovedItemCount); + fromInventory.markDirty(); + return tMovedItemCount; + } + } + } + } + } + return 0; + } + } + + if (fromInventory instanceof TileEntity fromTileEntity && fromSide != ForgeDirection.UNKNOWN + && fromSide.getOpposite() == ForgeDirection.getOrientation(putSide.ordinal())) { + int tX = fromTileEntity.xCoord + fromSide.offsetX, tY = fromTileEntity.yCoord + fromSide.offsetY, + tZ = fromTileEntity.zCoord + fromSide.offsetZ; + if (!hasBlockHitBox(((TileEntity) fromInventory).getWorldObj(), tX, tY, tZ) && dropItem) { + for (final int fromSlot : fromSlots) { + if (listContainsItem(aFilter, fromInventory.getStackInSlot(fromSlot), true, aInvertFilter)) { + if (isAllowedToTakeFromSlot( + fromInventory, + fromSlot, + fromSide, + fromInventory.getStackInSlot(fromSlot))) { + if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) + <= fromInventory.getStackInSlot(fromSlot).stackSize) { + final ItemStack tStack = copyAmount( + Math.min( + fromInventory.getStackInSlot(fromSlot).stackSize, + Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), + fromInventory.getStackInSlot(fromSlot)); + final EntityItem tEntity = new EntityItem( + ((TileEntity) fromInventory).getWorldObj(), + tX + 0.5, + tY + 0.5, + tZ + 0.5, + tStack); + tEntity.motionX = tEntity.motionY = tEntity.motionZ = 0; + ((TileEntity) fromInventory).getWorldObj() + .spawnEntityInWorld(tEntity); + assert tStack != null; + fromInventory.decrStackSize(fromSlot, tStack.stackSize); + fromInventory.markDirty(); + return (byte) tStack.stackSize; + } + } + } + } + } + } + return 0; + } + + /** + * Moves Stack from Inv-Slot to Inv-Slot, without checking if its even allowed. (useful for internal Inventory + * Operations) + * + * @return the Amount of moved Items + */ + public static byte moveStackFromSlotAToSlotB(IInventory aTileEntity1, IInventory aTileEntity2, int aGrabFrom, + int aPutTo, byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { + if (aTileEntity1 == null || aTileEntity2 == null + || aMinTargetStackSize <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMaxMoveAtOnce <= 0 + || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; + + ItemStack tStack1 = aTileEntity1.getStackInSlot(aGrabFrom), tStack2 = aTileEntity2.getStackInSlot(aPutTo), + tStack3; + if (tStack1 != null) { + if (tStack2 != null && !areStacksEqual(tStack1, tStack2)) return 0; + tStack3 = copyOrNull(tStack1); + aMaxTargetStackSize = (byte) Math.min( + aMaxTargetStackSize, + Math.min( + tStack3.getMaxStackSize(), + Math.min( + tStack2 == null ? Integer.MAX_VALUE : tStack2.getMaxStackSize(), + aTileEntity2.getInventoryStackLimit()))); + tStack3.stackSize = Math + .min(tStack3.stackSize, aMaxTargetStackSize - (tStack2 == null ? 0 : tStack2.stackSize)); + if (tStack3.stackSize > aMaxMoveAtOnce) tStack3.stackSize = aMaxMoveAtOnce; + if (tStack3.stackSize + (tStack2 == null ? 0 : tStack2.stackSize) + >= Math.min(tStack3.getMaxStackSize(), aMinTargetStackSize) && tStack3.stackSize >= aMinMoveAtOnce) { + tStack3 = aTileEntity1.decrStackSize(aGrabFrom, tStack3.stackSize); + aTileEntity1.markDirty(); + if (tStack3 != null) { + if (tStack2 == null) { + aTileEntity2.setInventorySlotContents(aPutTo, copyOrNull(tStack3)); + } else { + tStack2.stackSize += tStack3.stackSize; + } + aTileEntity2.markDirty(); + return (byte) tStack3.stackSize; + } + } + } + return 0; + } + + public static boolean isAllowedToTakeFromSlot(IInventory aTileEntity, int aSlot, ForgeDirection side, + ItemStack aStack) { + if (side == ForgeDirection.UNKNOWN) { + return Arrays.stream(ForgeDirection.VALID_DIRECTIONS) + .anyMatch(d -> isAllowedToTakeFromSlot(aTileEntity, aSlot, d, aStack)); + } + if (aTileEntity instanceof ISidedInventory sided) return sided.canExtractItem(aSlot, aStack, side.ordinal()); + return true; + } + + public static boolean isAllowedToPutIntoSlot(IInventory aTileEntity, int aSlot, ForgeDirection side, + ItemStack aStack, byte aMaxStackSize) { + ItemStack tStack = aTileEntity.getStackInSlot(aSlot); + if (tStack != null && (!areStacksEqual(tStack, aStack) || tStack.stackSize >= tStack.getMaxStackSize())) + return false; + if (side == ForgeDirection.UNKNOWN) { + return Arrays.stream(ForgeDirection.VALID_DIRECTIONS) + .anyMatch(d -> isAllowedToPutIntoSlot(aTileEntity, aSlot, d, aStack, aMaxStackSize)); + } + if (aTileEntity instanceof ISidedInventory + && !((ISidedInventory) aTileEntity).canInsertItem(aSlot, aStack, side.ordinal())) return false; + return aSlot < aTileEntity.getSizeInventory() && aTileEntity.isItemValidForSlot(aSlot, aStack); + } + + /** + * moves multiple stacks from Inv-Side to Inv-Side + * + * @return the Amount of moved Items + */ + public static int moveMultipleItemStacks(Object aTileEntity1, Object aTileEntity2, ForgeDirection fromSide, + ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, + byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, int aStackAmount) { + if (aTileEntity1 instanceof IInventory) return moveMultipleItemStacks( + (IInventory) aTileEntity1, + aTileEntity2, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aStackAmount, + true); + return 0; + } + + public static int moveMultipleItemStacks(IInventory fromInventory, Object toObject, ForgeDirection fromSide, + ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, + byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, int aMaxStackTransfer, + boolean aDoCheckChests) { + if (fromInventory == null || aMaxTargetStackSize <= 0 + || aMinTargetStackSize <= 0 + || aMaxMoveAtOnce <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMinMoveAtOnce > aMaxMoveAtOnce + || aMaxStackTransfer == 0) return 0; + + // find where to take from + final int[] tGrabSlots = new int[fromInventory.getSizeInventory()]; + int tGrabSlotsSize = 0; + if (fromInventory instanceof ISidedInventory) { + for (int i : ((ISidedInventory) fromInventory).getAccessibleSlotsFromSide(fromSide.ordinal())) { + final ItemStack s = fromInventory.getStackInSlot(i); + if (s == null || !isAllowedToTakeFromSlot(fromInventory, i, fromSide, s) + || s.stackSize < aMinMoveAtOnce + || !listContainsItem(aFilter, s, true, aInvertFilter)) continue; + tGrabSlots[tGrabSlotsSize++] = i; + } + } else { + for (int i = 0; i < tGrabSlots.length; i++) { + ItemStack s = fromInventory.getStackInSlot(i); + if (s == null || s.stackSize < aMinMoveAtOnce || !listContainsItem(aFilter, s, true, aInvertFilter)) + continue; + tGrabSlots[tGrabSlotsSize++] = i; + } + } + + // no source, bail out + if (tGrabSlotsSize == 0) { + // maybe source is a double chest. check it + if (aDoCheckChests && fromInventory instanceof TileEntityChest chest) return moveFromAdjacentChests( + chest, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer); + return 0; + } + + // if target is an inventory, e.g. chest, machine, drawers... + if (toObject instanceof IInventory toInventory) { + + // partially filled slot spare space mapping. + // value is the sum of all spare space left not counting completely empty slot + final HashMap tPutItems = new HashMap<>(toInventory.getSizeInventory()); + // partially filled slot contents + final HashMap> tPutItemStacks = new HashMap<>(toInventory.getSizeInventory()); + // completely empty slots + final List tPutFreeSlots = new ArrayList<>(toInventory.getSizeInventory()); + + // find possible target slots + int[] accessibleSlots = null; + if (toObject instanceof ISidedInventory sided) + accessibleSlots = sided.getAccessibleSlotsFromSide(putSide.ordinal()); + for (int i = 0; i < toInventory.getSizeInventory(); i++) { + int slot = i; + if (accessibleSlots != null) { + if (accessibleSlots.length <= i) break; + slot = accessibleSlots[slot]; + } + ItemStack s = toInventory.getStackInSlot(slot); + if (s == null) { + tPutFreeSlots.add(slot); + } else if ((s.stackSize < s.getMaxStackSize() && s.stackSize < toInventory.getInventoryStackLimit()) + && aMinMoveAtOnce <= s.getMaxStackSize() - s.stackSize + && isAllowedToPutIntoSlot(toInventory, slot, putSide, s, (byte) 64)) { + ItemId sID = ItemId.createNoCopy(s); + tPutItems.merge( + sID, + (Math.min(s.getMaxStackSize(), toInventory.getInventoryStackLimit()) - s.stackSize), + Integer::sum); + tPutItemStacks.computeIfAbsent(sID, k -> new ArrayList<>()) + .add(s); + } + } + + // target completely filled, bail out + if (tPutItems.isEmpty() && tPutFreeSlots.isEmpty()) { + // maybe target is a double chest. check it. + if (aDoCheckChests && toObject instanceof TileEntityChest chest) return moveToAdjacentChests( + fromInventory, + chest, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer); + return 0; + } + + // go over source stacks one by one + int tStacksMoved = 0, tTotalItemsMoved = 0; + for (int j = 0; j < tGrabSlotsSize; j++) { + final int grabSlot = tGrabSlots[j]; + int tMovedItems; + int tStackSize; + do { + tMovedItems = 0; + final ItemStack tGrabStack = fromInventory.getStackInSlot(grabSlot); + if (tGrabStack == null) break; + tStackSize = tGrabStack.stackSize; + final ItemId sID = ItemId.createNoCopy(tGrabStack); + + if (tPutItems.containsKey(sID)) { + // there is a partially filled slot, try merging + final int canPut = Math.min(tPutItems.get(sID), aMaxMoveAtOnce); + if (canPut >= aMinMoveAtOnce) { + final List putStack = tPutItemStacks.get(sID); + if (!putStack.isEmpty()) { + // can move, do merge + int toPut = Math.min(canPut, tStackSize); + tMovedItems = toPut; + for (int i = 0; i < putStack.size(); i++) { + final ItemStack s = putStack.get(i); + final int sToPut = Math.min( + Math.min( + Math.min(toPut, s.getMaxStackSize() - s.stackSize), + toInventory.getInventoryStackLimit() - s.stackSize), + aMaxTargetStackSize - s.stackSize); + if (sToPut <= 0) continue; + if (sToPut < aMinMoveAtOnce) continue; + if (s.stackSize + sToPut < aMinTargetStackSize) continue; + toPut -= sToPut; + s.stackSize += sToPut; + if (s.stackSize == s.getMaxStackSize() + || s.stackSize == toInventory.getInventoryStackLimit()) { + // this slot is full. remove this stack from candidate list + putStack.remove(i); + i--; + } + if (toPut == 0) break; + } + tMovedItems -= toPut; + if (tMovedItems > 0) { + tStackSize -= tMovedItems; + tTotalItemsMoved += tMovedItems; + // deduct spare space + tPutItems.merge(sID, tMovedItems, (a, b) -> a.equals(b) ? null : a - b); + + if (tStackSize == 0) fromInventory.setInventorySlotContents(grabSlot, null); + else tGrabStack.stackSize = tStackSize; + + fromInventory.markDirty(); + toInventory.markDirty(); + } + } + } + } + // still stuff to move & have completely empty slots + if (tStackSize > 0 && !tPutFreeSlots.isEmpty()) { + for (int i = 0; i < tPutFreeSlots.size(); i++) { + final int tPutSlot = tPutFreeSlots.get(i); + if (isAllowedToPutIntoSlot(toInventory, tPutSlot, putSide, tGrabStack, (byte) 64)) { + // allowed, now do moving + final int tMoved = moveStackFromSlotAToSlotB( + fromInventory, + toInventory, + grabSlot, + tPutSlot, + aMaxTargetStackSize, + aMinTargetStackSize, + (byte) (aMaxMoveAtOnce - tMovedItems), + aMinMoveAtOnce); + if (tMoved > 0) { + final ItemStack s = toInventory.getStackInSlot(tPutSlot); + if (s != null) { + // s might be null if tPutInventory is very special, e.g. infinity chest + // if s is null, we will not mark this slot as target candidate for anything + final int spare = Math + .min(s.getMaxStackSize(), toInventory.getInventoryStackLimit()) + - s.stackSize; + if (spare > 0) { + final ItemId ssID = ItemId.createNoCopy(s); + // add back to spare space count + tPutItems.merge(ssID, spare, Integer::sum); + // add to partially filled slot list + tPutItemStacks.computeIfAbsent(ssID, k -> new ArrayList<>()) + .add(s); + } + // this is no longer free + tPutFreeSlots.remove(i); + i--; + } + // else -> noop + // this is still a free slot. no need to do anything. + tTotalItemsMoved += tMoved; + tMovedItems += tMoved; + tStackSize -= tMoved; + if (tStackSize == 0) break; + } + } + } + } + + if (tMovedItems > 0) { + // check if we have moved enough stacks + if (++tStacksMoved >= aMaxStackTransfer) return tTotalItemsMoved; + } + } while (tMovedItems > 0 && tStackSize > 0); // support inventories that store more than a stack in a + // slot + } + + // check if source is a double chest, if yes, try move from the adjacent as well + if (aDoCheckChests && fromInventory instanceof TileEntityChest chest) { + final int tAmount = moveFromAdjacentChests( + chest, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer - tStacksMoved); + if (tAmount != 0) return tAmount + tTotalItemsMoved; + } + + // check if target is a double chest, if yes, try move to the adjacent as well + if (aDoCheckChests && toObject instanceof TileEntityChest chest) { + final int tAmount = moveToAdjacentChests( + fromInventory, + chest, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer - tStacksMoved); + if (tAmount != 0) return tAmount + tTotalItemsMoved; + } + + return tTotalItemsMoved; + } + // there should be a function to transfer more than 1 stack in a pipe + // however I do not see any ways to improve it. too much work for what it is worth + int tTotalItemsMoved = 0; + final int tGrabInventorySize = tGrabSlots.length; + for (int i = 0; i < tGrabInventorySize; i++) { + final int tMoved = moveStackIntoPipe( + fromInventory, + toObject, + tGrabSlots, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aDoCheckChests); + if (tMoved == 0) return tTotalItemsMoved; + else tTotalItemsMoved += tMoved; + } + return 0; + } + + private static int moveToAdjacentChests(IInventory aTileEntity1, TileEntityChest aTargetChest, + ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, + byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, + int aMaxStackTransfer) { + if (aTargetChest.adjacentChestChecked) { + if (aTargetChest.adjacentChestXNeg != null) { + return moveMultipleItemStacks( + aTileEntity1, + aTargetChest.adjacentChestXNeg, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } else if (aTargetChest.adjacentChestZNeg != null) { + return moveMultipleItemStacks( + aTileEntity1, + aTargetChest.adjacentChestZNeg, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } else if (aTargetChest.adjacentChestXPos != null) { + return moveMultipleItemStacks( + aTileEntity1, + aTargetChest.adjacentChestXPos, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } else if (aTargetChest.adjacentChestZPos != null) { + return moveMultipleItemStacks( + aTileEntity1, + aTargetChest.adjacentChestZPos, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } + } + return 0; + } + + private static int moveFromAdjacentChests(TileEntityChest fromTileEntityChest, Object toObject, + ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, + byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, + int aMaxStackTransfer) { + if (fromTileEntityChest.adjacentChestXNeg != null) { + return moveMultipleItemStacks( + fromTileEntityChest.adjacentChestXNeg, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } else if (fromTileEntityChest.adjacentChestZNeg != null) { + return moveMultipleItemStacks( + fromTileEntityChest.adjacentChestZNeg, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } else if (fromTileEntityChest.adjacentChestXPos != null) { + return moveMultipleItemStacks( + fromTileEntityChest.adjacentChestXPos, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } else if (fromTileEntityChest.adjacentChestZPos != null) { + return moveMultipleItemStacks( + fromTileEntityChest.adjacentChestZPos, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aMaxStackTransfer, + false); + } + return 0; + } + + /** + * Moves Stack from Inv-Side to Inv-Side. + * + * @return the Amount of moved Items + */ + public static byte moveOneItemStack(Object fromObject, Object toObject, ForgeDirection fromSide, + ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, + byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { + if (fromObject instanceof IInventory inv) return moveOneItemStack( + inv, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + true); + return 0; + } + + /** + * This is only because I needed an additional Parameter for the Double Chest Check. + */ + private static byte moveOneItemStack(IInventory fromInventory, Object toObject, ForgeDirection fromSide, + ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, + byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, boolean aDoCheckChests) { + if (fromInventory == null || aMaxTargetStackSize <= 0 + || aMinTargetStackSize <= 0 + || aMaxMoveAtOnce <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; + + int[] tGrabSlots = null; + if (fromInventory instanceof ISidedInventory) + tGrabSlots = ((ISidedInventory) fromInventory).getAccessibleSlotsFromSide(fromSide.ordinal()); + if (tGrabSlots == null) { + tGrabSlots = new int[fromInventory.getSizeInventory()]; + for (int i = 0; i < tGrabSlots.length; i++) tGrabSlots[i] = i; + } + + if (toObject instanceof IInventory inv) { + int[] tPutSlots = null; + if (toObject instanceof ISidedInventory sided) + tPutSlots = sided.getAccessibleSlotsFromSide(putSide.ordinal()); + + if (tPutSlots == null) { + tPutSlots = new int[inv.getSizeInventory()]; + for (int i = 0; i < tPutSlots.length; i++) tPutSlots[i] = i; + } + + for (final int tGrabSlot : tGrabSlots) { + byte tMovedItemCount = 0; + final ItemStack tGrabStack = fromInventory.getStackInSlot(tGrabSlot); + if (listContainsItem(aFilter, tGrabStack, true, aInvertFilter) + && (tGrabStack.stackSize >= aMinMoveAtOnce + && isAllowedToTakeFromSlot(fromInventory, tGrabSlot, fromSide, tGrabStack))) { + for (final int tPutSlot : tPutSlots) { + if (isAllowedToPutIntoSlot(inv, tPutSlot, putSide, tGrabStack, aMaxTargetStackSize)) { + tMovedItemCount += moveStackFromSlotAToSlotB( + fromInventory, + inv, + tGrabSlot, + tPutSlot, + aMaxTargetStackSize, + aMinTargetStackSize, + (byte) (aMaxMoveAtOnce - tMovedItemCount), + aMinMoveAtOnce); + if (tMovedItemCount >= aMaxMoveAtOnce || (tMovedItemCount > 0 && aMaxTargetStackSize < 64)) + return tMovedItemCount; + } + } + + } + if (tMovedItemCount > 0) return tMovedItemCount; + } + + if (aDoCheckChests && fromInventory instanceof TileEntityChest fromChest + && (fromChest.adjacentChestChecked)) { + byte tAmount = 0; + if (fromChest.adjacentChestXNeg != null) { + tAmount = moveOneItemStack( + fromChest.adjacentChestXNeg, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (fromChest.adjacentChestZNeg != null) { + tAmount = moveOneItemStack( + fromChest.adjacentChestZNeg, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (fromChest.adjacentChestXPos != null) { + tAmount = moveOneItemStack( + fromChest.adjacentChestXPos, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (fromChest.adjacentChestZPos != null) { + tAmount = moveOneItemStack( + fromChest.adjacentChestZPos, + toObject, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } + if (tAmount != 0) return tAmount; + + } + if (aDoCheckChests && toObject instanceof TileEntityChest toChest && (toChest.adjacentChestChecked)) { + byte tAmount = 0; + if (toChest.adjacentChestXNeg != null) { + tAmount = moveOneItemStack( + fromInventory, + toChest.adjacentChestXNeg, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (toChest.adjacentChestZNeg != null) { + tAmount = moveOneItemStack( + fromInventory, + toChest.adjacentChestZNeg, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (toChest.adjacentChestXPos != null) { + tAmount = moveOneItemStack( + fromInventory, + toChest.adjacentChestXPos, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (toChest.adjacentChestZPos != null) { + tAmount = moveOneItemStack( + fromInventory, + toChest.adjacentChestZPos, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } + if (tAmount != 0) return tAmount; + + } + } + + return moveStackIntoPipe( + fromInventory, + toObject, + tGrabSlots, + fromSide, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aDoCheckChests); + } + + /** + * Moves Stack from Inv-Side to Inv-Slot. + * + * @return the Amount of moved Items + */ + public static byte moveOneItemStackIntoSlot(Object fromTileEntity, Object toTileEntity, ForgeDirection fromSide, + int putSlot, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, + byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { + if (!(fromTileEntity instanceof IInventory fromInv) || aMaxTargetStackSize <= 0 + || aMinTargetStackSize <= 0 + || aMaxMoveAtOnce <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; + + int[] tGrabSlots = null; + if (fromTileEntity instanceof ISidedInventory sided) + tGrabSlots = sided.getAccessibleSlotsFromSide(fromSide.ordinal()); + if (tGrabSlots == null) { + tGrabSlots = new int[fromInv.getSizeInventory()]; + for (int i = 0; i < tGrabSlots.length; i++) tGrabSlots[i] = i; + } + + if (toTileEntity instanceof IInventory toInv) { + for (final int tGrabSlot : tGrabSlots) { + if (listContainsItem(aFilter, fromInv.getStackInSlot(tGrabSlot), true, aInvertFilter)) { + if (isAllowedToTakeFromSlot(fromInv, tGrabSlot, fromSide, fromInv.getStackInSlot(tGrabSlot))) { + if (isAllowedToPutIntoSlot( + toInv, + putSlot, + ForgeDirection.UNKNOWN, + fromInv.getStackInSlot(tGrabSlot), + aMaxTargetStackSize)) { + byte tMovedItemCount = moveStackFromSlotAToSlotB( + fromInv, + toInv, + tGrabSlot, + putSlot, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce); + if (tMovedItemCount > 0) return tMovedItemCount; + } + } + } + } + } + + final ForgeDirection toSide = fromSide.getOpposite(); + moveStackIntoPipe( + fromInv, + toTileEntity, + tGrabSlots, + fromSide, + ForgeDirection.UNKNOWN, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce); + return 0; + } + + /** + * Moves Stack from Inv-Slot to Inv-Slot. + * + * @return the Amount of moved Items + */ + public static byte moveFromSlotToSlot(IInventory fromInv, IInventory toInv, int aGrabFrom, int aPutTo, + List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, + byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { + if (fromInv == null || toInv == null + || aGrabFrom < 0 + || aPutTo < 0 + || aMinTargetStackSize <= 0 + || aMaxMoveAtOnce <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; + if (listContainsItem(aFilter, fromInv.getStackInSlot(aGrabFrom), true, aInvertFilter)) { + if (isAllowedToTakeFromSlot( + fromInv, + aGrabFrom, + ForgeDirection.UNKNOWN, + fromInv.getStackInSlot(aGrabFrom))) { + if (isAllowedToPutIntoSlot( + toInv, + aPutTo, + ForgeDirection.UNKNOWN, + fromInv.getStackInSlot(aGrabFrom), + aMaxTargetStackSize)) { + byte tMovedItemCount = moveStackFromSlotAToSlotB( + fromInv, + toInv, + aGrabFrom, + aPutTo, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce); + if (tMovedItemCount > 0) return tMovedItemCount; + } + } + } + return 0; + } + + /** + * Moves Stack from Inv-Side to Inv-Slot. + * + * @return the Amount of moved Items + */ + public static byte moveFromSlotToSide(IInventory fromTile, Object toTile, int fromSlot, ForgeDirection putSide, + List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, + byte aMaxMoveAtOnce, byte aMinMoveAtOnce, boolean aDoCheckChests) { + if (fromTile == null || fromSlot < 0 + || aMinTargetStackSize <= 0 + || aMaxMoveAtOnce <= 0 + || aMinTargetStackSize > aMaxTargetStackSize + || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; + + if (!listContainsItem(aFilter, fromTile.getStackInSlot(fromSlot), true, aInvertFilter) + || !isAllowedToTakeFromSlot(fromTile, fromSlot, ForgeDirection.UNKNOWN, fromTile.getStackInSlot(fromSlot))) + return 0; + + if (toTile instanceof IInventory) { + int[] tPutSlots = null; + if (toTile instanceof ISidedInventory sided) + tPutSlots = sided.getAccessibleSlotsFromSide(putSide.ordinal()); + + if (tPutSlots == null) { + tPutSlots = new int[((IInventory) toTile).getSizeInventory()]; + for (int i = 0; i < tPutSlots.length; i++) tPutSlots[i] = i; + } + + byte tMovedItemCount = 0; + for (final int tPutSlot : tPutSlots) { + if (isAllowedToPutIntoSlot( + (IInventory) toTile, + tPutSlot, + putSide, + fromTile.getStackInSlot(fromSlot), + aMaxTargetStackSize)) { + tMovedItemCount += moveStackFromSlotAToSlotB( + fromTile, + (IInventory) toTile, + fromSlot, + tPutSlot, + aMaxTargetStackSize, + aMinTargetStackSize, + (byte) (aMaxMoveAtOnce - tMovedItemCount), + aMinMoveAtOnce); + if (tMovedItemCount >= aMaxMoveAtOnce) { + return tMovedItemCount; + } + } + } + if (tMovedItemCount > 0) return tMovedItemCount; + + if (aDoCheckChests && toTile instanceof TileEntityChest tTileEntity2) { + if (tTileEntity2.adjacentChestChecked) { + if (tTileEntity2.adjacentChestXNeg != null) { + tMovedItemCount = moveFromSlotToSide( + fromTile, + tTileEntity2.adjacentChestXNeg, + fromSlot, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (tTileEntity2.adjacentChestZNeg != null) { + tMovedItemCount = moveFromSlotToSide( + fromTile, + tTileEntity2.adjacentChestZNeg, + fromSlot, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (tTileEntity2.adjacentChestXPos != null) { + tMovedItemCount = moveFromSlotToSide( + fromTile, + tTileEntity2.adjacentChestXPos, + fromSlot, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } else if (tTileEntity2.adjacentChestZPos != null) { + tMovedItemCount = moveFromSlotToSide( + fromTile, + tTileEntity2.adjacentChestZPos, + fromSlot, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + false); + } + if (tMovedItemCount > 0) return tMovedItemCount; + } + } + } + return moveStackIntoPipe( + fromTile, + toTile, + new int[] { fromSlot }, + ForgeDirection.UNKNOWN, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + aDoCheckChests); + } + + public static byte moveFromSlotToSide(IInventory fromTile, Object toTile, int fromSlot, ForgeDirection putSide, + List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, + byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { + return moveFromSlotToSide( + fromTile, + toTile, + fromSlot, + putSide, + aFilter, + aInvertFilter, + aMaxTargetStackSize, + aMinTargetStackSize, + aMaxMoveAtOnce, + aMinMoveAtOnce, + true); + } + + /** + * Move up to maxAmount amount of fluid from source to dest, with optional filtering via allowMove. note that this + * filter cannot bypass filtering done by IFluidHandlers themselves. + * + * this overload will assume the fill side is the opposite of drainSide + * + * @param source tank to drain from. method become noop if this is null + * @param dest tank to fill to. method become noop if this is null + * @param drainSide side used during draining operation + * @param maxAmount max amount of fluid to transfer. method become noop if this is not a positive integer + * @param allowMove filter. can be null to signal all fluids are accepted + */ + public static void moveFluid(IFluidHandler source, IFluidHandler dest, ForgeDirection drainSide, int maxAmount, + @Nullable Predicate allowMove) { + moveFluid(source, dest, drainSide, drainSide.getOpposite(), maxAmount, allowMove); + } + + /** + * Move up to maxAmount amount of fluid from source to dest, with optional filtering via allowMove. note that this + * filter cannot bypass filtering done by IFluidHandlers themselves. + * + * @param source tank to drain from. method become noop if this is null + * @param dest tank to fill to. method become noop if this is null + * @param drainSide side used during draining operation + * @param fillSide side used during filling operation + * @param maxAmount max amount of fluid to transfer. method become noop if this is not a positive integer + * @param allowMove filter. can be null to signal all fluids are accepted + */ + public static void moveFluid(IFluidHandler source, IFluidHandler dest, ForgeDirection drainSide, + ForgeDirection fillSide, int maxAmount, @Nullable Predicate allowMove) { + if (source == null || dest == null || maxAmount <= 0) return; + FluidStack liquid = source.drain(drainSide, maxAmount, false); + if (liquid == null) return; + liquid = liquid.copy(); + liquid.amount = dest.fill(fillSide, liquid, false); + if (liquid.amount > 0 && (allowMove == null || allowMove.test(liquid))) { + dest.fill(fillSide, source.drain(drainSide, liquid.amount, true), true); + } + } + + public static boolean listContainsItem(Collection aList, ItemStack aStack, boolean aTIfListEmpty, + boolean aInvertFilter) { + if (aStack == null || aStack.stackSize < 1) return false; + if (aList == null) return aTIfListEmpty; + boolean tEmpty = true; + for (ItemStack tStack : aList) { + if (tStack != null) { + tEmpty = false; + if (areStacksEqual(aStack, tStack)) { + return !aInvertFilter; + } + } + } + return tEmpty ? aTIfListEmpty : aInvertFilter; + } + + public static boolean areStacksOrToolsEqual(ItemStack aStack1, ItemStack aStack2) { + if (aStack1 != null && aStack2 != null && aStack1.getItem() == aStack2.getItem()) { + if (aStack1.getItem() + .isDamageable()) return true; + return ((aStack1.getTagCompound() == null) == (aStack2.getTagCompound() == null)) + && (aStack1.getTagCompound() == null || aStack1.getTagCompound() + .equals(aStack2.getTagCompound())) + && (Items.feather.getDamage(aStack1) == Items.feather.getDamage(aStack2) + || Items.feather.getDamage(aStack1) == W + || Items.feather.getDamage(aStack2) == W); + } + return false; + } + + public static boolean areFluidsEqual(FluidStack aFluid1, FluidStack aFluid2) { + return areFluidsEqual(aFluid1, aFluid2, false); + } + + public static boolean areFluidsEqual(FluidStack aFluid1, FluidStack aFluid2, boolean aIgnoreNBT) { + return aFluid1 != null && aFluid2 != null + && aFluid1.getFluid() == aFluid2.getFluid() + && (aIgnoreNBT || ((aFluid1.tag == null) == (aFluid2.tag == null)) + && (aFluid1.tag == null || aFluid1.tag.equals(aFluid2.tag))); + } + + public static boolean areStacksEqual(ItemStack aStack1, ItemStack aStack2) { + return areStacksEqual(aStack1, aStack2, false); + } + + public static boolean areStacksEqual(ItemStack aStack1, ItemStack aStack2, boolean aIgnoreNBT) { + return aStack1 != null && aStack2 != null + && aStack1.getItem() == aStack2.getItem() + && (Items.feather.getDamage(aStack1) == Items.feather.getDamage(aStack2) + || Items.feather.getDamage(aStack1) == W + || Items.feather.getDamage(aStack2) == W) + && (aIgnoreNBT || (((aStack1.getTagCompound() == null) == (aStack2.getTagCompound() == null)) + && (aStack1.getTagCompound() == null || aStack1.getTagCompound() + .equals(aStack2.getTagCompound())))); + } + + public static boolean areStacksEqualOrNull(ItemStack stack1, ItemStack stack2) { + return (stack1 == null && stack2 == null) || GTUtility.areStacksEqual(stack1, stack2); + } + + /** + * Treat both null list, or both null item stack at same list position as equal. + *

+ * Since ItemStack doesn't override equals and hashCode, you cannot just use Objects.equals + */ + public static boolean areStackListsEqual(List lhs, List rhs, boolean ignoreStackSize, + boolean ignoreNBT) { + if (lhs == null) return rhs == null; + if (rhs == null) return false; + if (lhs.size() != rhs.size()) return false; + for (Iterator it1 = lhs.iterator(), it2 = rhs.iterator(); it1.hasNext() && it2.hasNext();) { + if (!areStacksEqualExtended(it1.next(), it2.next(), ignoreStackSize, ignoreNBT)) return false; + } + return true; + } + + private static boolean areStacksEqualExtended(ItemStack lhs, ItemStack rhs, boolean ignoreStackSize, + boolean ignoreNBT) { + if (lhs == null) return rhs == null; + if (rhs == null) return false; + return lhs.getItem() == rhs.getItem() + && (ignoreNBT || Objects.equals(lhs.stackTagCompound, rhs.stackTagCompound)) + && (ignoreStackSize || lhs.stackSize == rhs.stackSize); + } + + public static boolean areUnificationsEqual(ItemStack aStack1, ItemStack aStack2) { + return areUnificationsEqual(aStack1, aStack2, false); + } + + public static boolean areUnificationsEqual(ItemStack aStack1, ItemStack aStack2, boolean aIgnoreNBT) { + return areStacksEqual( + GTOreDictUnificator.get_nocopy(aStack1), + GTOreDictUnificator.get_nocopy(aStack2), + aIgnoreNBT); + } + + public static String getFluidName(Fluid aFluid, boolean aLocalized) { + if (aFluid == null) return E; + String rName = aLocalized ? aFluid.getLocalizedName(new FluidStack(aFluid, 0)) : aFluid.getUnlocalizedName(); + if (rName.contains("fluid.") || rName.contains("tile.")) return capitalizeString( + rName.replaceAll("fluid.", E) + .replaceAll("tile.", E)); + return rName; + } + + public static String getFluidName(FluidStack aFluid, boolean aLocalized) { + if (aFluid == null) return E; + return getFluidName(aFluid.getFluid(), aLocalized); + } + + public static void reInit() { + sFilledContainerToData.clear(); + sEmptyContainerToFluidToData.clear(); + sFluidToContainers.clear(); + for (FluidContainerData tData : sFluidContainerList) { + String fluidName = tData.fluid.getFluid() + .getName(); + sFilledContainerToData.put(new GTItemStack(tData.filledContainer), tData); + Map tFluidToContainer = sEmptyContainerToFluidToData + .get(new GTItemStack(tData.emptyContainer)); + List tContainers = sFluidToContainers.get(fluidName); + if (tFluidToContainer == null) { + sEmptyContainerToFluidToData + .put(new GTItemStack(tData.emptyContainer), tFluidToContainer = new /* Concurrent */ HashMap<>()); + } + tFluidToContainer.put(fluidName, tData); + if (tContainers == null) { + tContainers = new ArrayList<>(); + tContainers.add(tData.filledContainer); + sFluidToContainers.put(fluidName, tContainers); + } else tContainers.add(tData.filledContainer); + } + } + + public static void addFluidContainerData(FluidContainerData aData) { + String fluidName = aData.fluid.getFluid() + .getName(); + sFluidContainerList.add(aData); + sFilledContainerToData.put(new GTItemStack(aData.filledContainer), aData); + Map tFluidToContainer = sEmptyContainerToFluidToData + .get(new GTItemStack(aData.emptyContainer)); + List tContainers = sFluidToContainers.get(fluidName); + if (tFluidToContainer == null) { + sEmptyContainerToFluidToData + .put(new GTItemStack(aData.emptyContainer), tFluidToContainer = new /* Concurrent */ HashMap<>()); + } + tFluidToContainer.put(fluidName, aData); + if (tContainers == null) { + tContainers = new ArrayList<>(); + tContainers.add(aData.filledContainer); + sFluidToContainers.put(fluidName, tContainers); + } else tContainers.add(aData.filledContainer); + } + + public static List getContainersFromFluid(FluidStack tFluidStack) { + if (tFluidStack != null) { + List tContainers = sFluidToContainers.get( + tFluidStack.getFluid() + .getName()); + if (tContainers == null) return new ArrayList<>(); + return tContainers; + } + return new ArrayList<>(); + } + + public static ItemStack fillFluidContainer(FluidStack aFluid, ItemStack aStack, boolean aRemoveFluidDirectly, + boolean aCheckIFluidContainerItems) { + if (isStackInvalid(aStack) || aFluid == null) return null; + if (GTModHandler.isWater(aFluid) && ItemList.Bottle_Empty.isStackEqual(aStack)) { + if (aFluid.amount >= 1000) { + return new ItemStack(Items.potionitem, 1, 0); + } + return null; + } + if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem + && ((IFluidContainerItem) aStack.getItem()).getFluid(aStack) == null + && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) <= aFluid.amount) { + if (aRemoveFluidDirectly) aFluid.amount -= ((IFluidContainerItem) aStack.getItem()) + .fill(aStack = copyAmount(1, aStack), aFluid, true); + else((IFluidContainerItem) aStack.getItem()).fill(aStack = copyAmount(1, aStack), aFluid, true); + return aStack; + } + Map tFluidToContainer = sEmptyContainerToFluidToData.get(new GTItemStack(aStack)); + if (tFluidToContainer == null) return null; + FluidContainerData tData = tFluidToContainer.get( + aFluid.getFluid() + .getName()); + if (tData == null || tData.fluid.amount > aFluid.amount) return null; + if (aRemoveFluidDirectly) aFluid.amount -= tData.fluid.amount; + return copyAmount(1, tData.filledContainer); + } + + public static int calculateRecipeEU(Materials aMaterial, int defaultRecipeEUPerTick) { + return aMaterial.getProcessingMaterialTierEU() == 0 ? defaultRecipeEUPerTick + : aMaterial.getProcessingMaterialTierEU(); + } + + public static ItemStack getFluidDisplayStack(Fluid aFluid) { + return aFluid == null ? null : getFluidDisplayStack(new FluidStack(aFluid, 0), false); + } + + public static ItemStack getFluidDisplayStack(FluidStack aFluid, boolean aUseStackSize) { + return getFluidDisplayStack(aFluid, aUseStackSize, false); + } + + public static ItemStack getFluidDisplayStack(FluidStack aFluid, boolean aUseStackSize, boolean aHideStackSize) { + if (aFluid == null || aFluid.getFluid() == null) return null; + int tmp = 0; + try { + tmp = aFluid.getFluid() + .getID(); + } catch (Exception e) { + System.err.println(e); + } + ItemStack rStack = ItemList.Display_Fluid.getWithDamage(1, tmp); + NBTTagCompound tNBT = new NBTTagCompound(); + tNBT.setLong("mFluidDisplayAmount", aUseStackSize ? aFluid.amount : 0); + tNBT.setLong( + "mFluidDisplayHeat", + aFluid.getFluid() + .getTemperature(aFluid)); + tNBT.setBoolean( + "mFluidState", + aFluid.getFluid() + .isGaseous(aFluid)); + tNBT.setBoolean("mHideStackSize", aHideStackSize); + try { + tNBT.setString("mFluidMaterialName", FLUID_MAP.get(aFluid.getFluid()).mName); + } catch (Exception ignored) {} + rStack.setTagCompound(tNBT); + return rStack; + } + + public static FluidStack getFluidFromDisplayStack(ItemStack aDisplayStack) { + if (!isStackValid(aDisplayStack) || aDisplayStack.getItem() != ItemList.Display_Fluid.getItem() + || !aDisplayStack.hasTagCompound()) return null; + Fluid tFluid = FluidRegistry.getFluid( + ItemList.Display_Fluid.getItem() + .getDamage(aDisplayStack)); + return new FluidStack( + tFluid, + (int) aDisplayStack.getTagCompound() + .getLong("mFluidDisplayAmount")); + } + + public static boolean containsFluid(ItemStack aStack, FluidStack aFluid, boolean aCheckIFluidContainerItems) { + if (isStackInvalid(aStack) || aFluid == null) return false; + if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem + && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) + return aFluid + .isFluidEqual(((IFluidContainerItem) aStack.getItem()).getFluid(aStack = copyAmount(1, aStack))); + FluidContainerData tData = sFilledContainerToData.get(new GTItemStack(aStack)); + return tData != null && tData.fluid.isFluidEqual(aFluid); + } + + public static FluidStack getFluidForFilledItem(ItemStack aStack, boolean aCheckIFluidContainerItems) { + if (isStackInvalid(aStack)) return null; + if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem + && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) + return ((IFluidContainerItem) aStack.getItem()).drain(copyAmount(1, aStack), Integer.MAX_VALUE, true); + FluidContainerData tData = sFilledContainerToData.get(new GTItemStack(aStack)); + return tData == null ? null : tData.fluid.copy(); + } + + /** + * Get empty fluid container from filled one. + */ + public static ItemStack getContainerForFilledItem(ItemStack aStack, boolean aCheckIFluidContainerItems) { + if (isStackInvalid(aStack)) return null; + FluidContainerData tData = sFilledContainerToData.get(new GTItemStack(aStack)); + if (tData != null) return copyAmount(1, tData.emptyContainer); + if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem + && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) { + ((IFluidContainerItem) aStack.getItem()).drain(aStack = copyAmount(1, aStack), Integer.MAX_VALUE, true); + return aStack; + } + return null; + } + + /** + * This is NOT meant for fluid manipulation! It's for getting item container, which is generally used for + * crafting recipes. While it also works for many of the fluid containers, some don't. + *

+ * Use {@link #getContainerForFilledItem} for getting empty fluid container. + */ + public static ItemStack getContainerItem(ItemStack aStack, boolean aCheckIFluidContainerItems) { + if (isStackInvalid(aStack)) return null; + if (aStack.getItem() + .hasContainerItem(aStack)) + return aStack.getItem() + .getContainerItem(aStack); + /* + * These are all special Cases, in which it is intended to have only GT Blocks outputting those Container Items + */ + if (ItemList.Cell_Empty.isStackEqual(aStack, false, true)) return null; + if (aStack.getItem() == Items.potionitem || aStack.getItem() == Items.experience_bottle + || ItemList.TF_Vial_FieryBlood.isStackEqual(aStack) + || ItemList.TF_Vial_FieryTears.isStackEqual(aStack)) return ItemList.Bottle_Empty.get(1); + + if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem + && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) { + ItemStack tStack = copyAmount(1, aStack); + ((IFluidContainerItem) aStack.getItem()).drain(tStack, Integer.MAX_VALUE, true); + if (!areStacksEqual(aStack, tStack)) return tStack; + return null; + } + + int tCapsuleCount = GTModHandler.getCapsuleCellContainerCount(aStack); + if (tCapsuleCount > 0) return ItemList.Cell_Empty.get(tCapsuleCount); + + if (ItemList.IC2_ForgeHammer.isStackEqual(aStack) || ItemList.IC2_WireCutter.isStackEqual(aStack)) + return copyMetaData(Items.feather.getDamage(aStack) + 1, aStack); + return null; + } + + public static FluidStack getFluidFromContainerOrFluidDisplay(ItemStack stack) { + FluidStack fluidStack = GTUtility.getFluidForFilledItem(stack, true); + if (fluidStack == null) { + fluidStack = GTUtility.getFluidFromDisplayStack(stack); + } + return fluidStack; + } + + public static synchronized boolean removeIC2BottleRecipe(ItemStack aContainer, ItemStack aInput, + Map aRecipeList, ItemStack aOutput) { + if ((isStackInvalid(aInput) && isStackInvalid(aOutput) && isStackInvalid(aContainer)) || aRecipeList == null) + return false; + boolean rReturn = false; + Iterator> tIterator = aRecipeList + .entrySet() + .iterator(); + aOutput = GTOreDictUnificator.get(aOutput); + while (tIterator.hasNext()) { + Map.Entry tEntry = tIterator.next(); + if (aInput == null || tEntry.getKey() + .matches(aContainer, aInput)) { + List tList = tEntry.getValue().items; + if (tList != null) for (ItemStack tOutput : tList) + if (aOutput == null || areStacksEqual(GTOreDictUnificator.get(tOutput), aOutput)) { + tIterator.remove(); + rReturn = true; + break; + } + } + } + return rReturn; + } + + public static synchronized boolean removeSimpleIC2MachineRecipe(ItemStack aInput, + Map aRecipeList, ItemStack aOutput) { + if ((isStackInvalid(aInput) && isStackInvalid(aOutput)) || aRecipeList == null) return false; + boolean rReturn = false; + Iterator> tIterator = aRecipeList.entrySet() + .iterator(); + aOutput = GTOreDictUnificator.get(aOutput); + while (tIterator.hasNext()) { + Map.Entry tEntry = tIterator.next(); + if (aInput == null || tEntry.getKey() + .matches(aInput)) { + List tList = tEntry.getValue().items; + if (tList != null) for (ItemStack tOutput : tList) + if (aOutput == null || areStacksEqual(GTOreDictUnificator.get(tOutput), aOutput)) { + tIterator.remove(); + rReturn = true; + break; + } + } + } + return rReturn; + } + + public static synchronized void bulkRemoveSimpleIC2MachineRecipe(Map toRemove, + Map aRecipeList) { + if (aRecipeList == null || aRecipeList.isEmpty()) return; + toRemove.entrySet() + .removeIf(aEntry -> (isStackInvalid(aEntry.getKey()) && isStackInvalid(aEntry.getValue()))); + final Map finalToRemove = Maps.transformValues(toRemove, GTOreDictUnificator::get_nocopy); + + aRecipeList.entrySet() + .removeIf( + tEntry -> finalToRemove.entrySet() + .stream() + .anyMatch(aEntry -> { + final ItemStack aInput = aEntry.getKey(), aOutput = aEntry.getValue(); + final List tList = tEntry.getValue().items; + + if (tList == null) return false; + if (aInput != null && !tEntry.getKey() + .matches(aInput)) return false; + + return tList.stream() + .anyMatch( + tOutput -> (aOutput == null + || areStacksEqual(GTOreDictUnificator.get(tOutput), aOutput))); + })); + } + + public static boolean addSimpleIC2MachineRecipe(ItemStack aInput, Map aRecipeList, + NBTTagCompound aNBT, Object... aOutput) { + if (isStackInvalid(aInput) || aOutput.length == 0 || aRecipeList == null) return false; + ItemData tOreName = GTOreDictUnificator.getAssociation(aInput); + for (Object o : aOutput) { + if (o == null) { + GT_FML_LOGGER.info("EmptyIC2Output!" + aInput.getUnlocalizedName()); + return false; + } + } + ItemStack[] tStack = GTOreDictUnificator.getStackArray(true, aOutput); + if (tStack.length > 0 && areStacksEqual(aInput, tStack[0])) return false; + if (tOreName != null) { + if (tOreName.toString() + .equals("dustAsh") + && tStack[0].getUnlocalizedName() + .equals("tile.volcanicAsh")) + return false; + aRecipeList + .put(new RecipeInputOreDict(tOreName.toString(), aInput.stackSize), new RecipeOutput(aNBT, tStack)); + } else { + aRecipeList + .put(new RecipeInputItemStack(copyOrNull(aInput), aInput.stackSize), new RecipeOutput(aNBT, tStack)); + } + return true; + } + + public static ItemStack getWrittenBook(String aMapping, ItemStack aStackToPutNBT) { + if (isStringInvalid(aMapping)) return null; + ItemStack rStack = GregTechAPI.sBookList.get(aMapping); + if (rStack == null) return aStackToPutNBT; + if (aStackToPutNBT != null) { + aStackToPutNBT.setTagCompound(rStack.getTagCompound()); + return aStackToPutNBT; + } + return copyAmount(1, rStack); + } + + public static ItemStack getWrittenBook(String aMapping, String aTitle, String aAuthor, String... aPages) { + if (isStringInvalid(aMapping)) return null; + ItemStack rStack = GregTechAPI.sBookList.get(aMapping); + if (rStack != null) return copyAmount(1, rStack); + if (isStringInvalid(aTitle) || isStringInvalid(aAuthor) || aPages.length == 0) return null; + sBookCount++; + rStack = new ItemStack(Items.written_book, 1); + NBTTagCompound tNBT = new NBTTagCompound(); + tNBT.setString("title", GTLanguageManager.addStringLocalization("Book." + aTitle + ".Name", aTitle)); + tNBT.setString("author", aAuthor); + NBTTagList tNBTList = new NBTTagList(); + for (byte i = 0; i < aPages.length; i++) { + aPages[i] = GTLanguageManager + .addStringLocalization("Book." + aTitle + ".Page" + ((i < 10) ? "0" + i : i), aPages[i]); + if (i < 48) { + if (aPages[i].length() < 256) tNBTList.appendTag(new NBTTagString(aPages[i])); + else GTLog.err.println("WARNING: String for written Book too long! -> " + aPages[i]); + } else { + GTLog.err.println("WARNING: Too much Pages for written Book! -> " + aTitle); + break; + } + } + tNBTList.appendTag( + new NBTTagString( + "Credits to " + aAuthor + + " for writing this Book. This was Book Nr. " + + sBookCount + + " at its creation. Gotta get 'em all!")); + tNBT.setTag("pages", tNBTList); + rStack.setTagCompound(tNBT); + GTLog.out.println( + "GTMod: Added Book to Book List - Mapping: '" + aMapping + + "' - Name: '" + + aTitle + + "' - Author: '" + + aAuthor + + "'"); + GregTechAPI.sBookList.put(aMapping, rStack); + return copyOrNull(rStack); + } + + public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength) { + if (aSoundName == null) return false; + return doSoundAtClient(aSoundName, aTimeUntilNextSound, aSoundStrength, GT.getThePlayer()); + } + + public static boolean doSoundAtClient(SoundResource sound, int aTimeUntilNextSound, float aSoundStrength) { + return doSoundAtClient(sound.resourceLocation, aTimeUntilNextSound, aSoundStrength, GT.getThePlayer()); + } + + public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, + float aSoundStrength) { + return doSoundAtClient(aSoundResourceLocation, aTimeUntilNextSound, aSoundStrength, GT.getThePlayer()); + } + + public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength, + Entity aEntity) { + if (aEntity == null || aSoundName == null) return false; + return doSoundAtClient( + aSoundName, + aTimeUntilNextSound, + aSoundStrength, + aEntity.posX, + aEntity.posY, + aEntity.posZ); + } + + public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, + float aSoundStrength, Entity aEntity) { + if (aEntity == null) return false; + return doSoundAtClient( + aSoundResourceLocation.toString(), + aTimeUntilNextSound, + aSoundStrength, + aEntity.posX, + aEntity.posY, + aEntity.posZ); + } + + public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, + float aSoundStrength, double aX, double aY, double aZ) { + return doSoundAtClient(aSoundResourceLocation, aTimeUntilNextSound, aSoundStrength, 1.01818028F, aX, aY, aZ); + } + + /** + * @inheritDoc + * @deprecated Use {@link #doSoundAtClient(ResourceLocation, int, float, double, double, double)} + */ + @Deprecated + public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength, double aX, + double aY, double aZ) { + if (aSoundName == null) return false; + return doSoundAtClient( + new ResourceLocation(aSoundName), + aTimeUntilNextSound, + aSoundStrength, + 1.01818028F, + aX, + aY, + aZ); + } + + public static boolean doSoundAtClient(SoundResource aSound, int aTimeUntilNextSound, float aSoundStrength, + double aX, double aY, double aZ) { + return doSoundAtClient(aSound.resourceLocation, aTimeUntilNextSound, aSoundStrength, aX, aY, aZ); + } + + public static boolean doSoundAtClient(SoundResource aSound, int aTimeUntilNextSound, float aSoundStrength, + float aSoundModulation, double aX, double aY, double aZ) { + return doSoundAtClient( + aSound.resourceLocation, + aTimeUntilNextSound, + aSoundStrength, + aSoundModulation, + aX, + aY, + aZ); + } + + public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, + float aSoundStrength, float aSoundModulation, double aX, double aY, double aZ) { + if (!FMLCommonHandler.instance() + .getEffectiveSide() + .isClient() || GT.getThePlayer() == null || !GT.getThePlayer().worldObj.isRemote) return false; + if (GregTechAPI.sMultiThreadedSounds) new Thread( + new RunnableSound( + GT.getThePlayer().worldObj, + aX, + aY, + aZ, + aTimeUntilNextSound, + aSoundResourceLocation, + aSoundStrength, + aSoundModulation), + "Sound Effect").start(); + else new RunnableSound( + GT.getThePlayer().worldObj, + aX, + aY, + aZ, + aTimeUntilNextSound, + aSoundResourceLocation, + aSoundStrength, + aSoundModulation).run(); + return true; + } + + public static boolean sendSoundToPlayers(World aWorld, String aSoundName, float aSoundStrength, + float aSoundModulation, int aX, int aY, int aZ) { + if (isStringInvalid(aSoundName) || aWorld == null || aWorld.isRemote) return false; + NW.sendPacketToAllPlayersInRange( + aWorld, + new GTPacketSound(aSoundName, aSoundStrength, aSoundModulation, aX, (short) aY, aZ), + aX, + aZ); + return true; + } + + public static boolean sendSoundToPlayers(World aWorld, SoundResource sound, float aSoundStrength, + float aSoundModulation, int aX, int aY, int aZ) { + if (aWorld == null || aWorld.isRemote) return false; + NW.sendPacketToAllPlayersInRange( + aWorld, + new GTPacketSound(sound.resourceLocation.toString(), aSoundStrength, aSoundModulation, aX, (short) aY, aZ), + aX, + aZ); + return true; + } + + public static int stackToInt(ItemStack aStack) { + if (isStackInvalid(aStack)) return 0; + return itemToInt(aStack.getItem(), Items.feather.getDamage(aStack)); + } + + public static int itemToInt(Item aItem, int aMeta) { + return Item.getIdFromItem(aItem) | (aMeta << 16); + } + + public static int stackToWildcard(ItemStack aStack) { + if (isStackInvalid(aStack)) return 0; + return Item.getIdFromItem(aStack.getItem()) | (W << 16); + } + + public static ItemStack intToStack(int aStack) { + int tID = aStack & (~0 >>> 16), tMeta = aStack >>> 16; + Item tItem = Item.getItemById(tID); + if (tItem != null) return new ItemStack(tItem, 1, tMeta); + return null; + } + + public static Integer[] stacksToIntegerArray(ItemStack... aStacks) { + Integer[] rArray = new Integer[aStacks.length]; + for (int i = 0; i < rArray.length; i++) { + rArray[i] = stackToInt(aStacks[i]); + } + return rArray; + } + + public static int[] stacksToIntArray(ItemStack... aStacks) { + int[] rArray = new int[aStacks.length]; + for (int i = 0; i < rArray.length; i++) { + rArray[i] = stackToInt(aStacks[i]); + } + return rArray; + } + + public static boolean arrayContains(Object aObject, Object... aObjects) { + return listContains(aObject, Arrays.asList(aObjects)); + } + + public static boolean listContains(Object aObject, Collection aObjects) { + if (aObjects == null) return false; + return aObjects.contains(aObject); + } + + @SafeVarargs + public static boolean arrayContainsNonNull(T... aArray) { + if (aArray != null) for (Object tObject : aArray) if (tObject != null) return true; + return false; + } + + /** + * Note: use {@link ArrayExt#withoutNulls(Object[], IntFunction)} if you want an array as a result. + */ + @SafeVarargs + public static ArrayList getArrayListWithoutNulls(T... aArray) { + if (aArray == null) return new ArrayList<>(); + ArrayList rList = new ArrayList<>(Arrays.asList(aArray)); + for (int i = 0; i < rList.size(); i++) if (rList.get(i) == null) rList.remove(i--); + return rList; + } + + /** + * Note: use {@link ArrayExt#withoutTrailingNulls(Object[], IntFunction)} if you want an array as a result. + */ + @SafeVarargs + public static ArrayList getArrayListWithoutTrailingNulls(T... aArray) { + if (aArray == null) return new ArrayList<>(); + ArrayList rList = new ArrayList<>(Arrays.asList(aArray)); + for (int i = rList.size() - 1; i >= 0 && rList.get(i) == null;) rList.remove(i--); + return rList; + } + + public static Block getBlockFromStack(ItemStack itemStack) { + if (isStackInvalid(itemStack)) return Blocks.air; + return getBlockFromItem(itemStack.getItem()); + } + + public static Block getBlockFromItem(Item item) { + return Block.getBlockFromItem(item); + } + + public static boolean isStringValid(Object aString) { + return aString != null && !aString.toString() + .isEmpty(); + } + + public static boolean isStringInvalid(Object aString) { + return aString == null || aString.toString() + .isEmpty(); + } + + @Deprecated + public static boolean isStackValid(Object aStack) { + return (aStack instanceof ItemStack stack) && isStackValid(stack); + } + + public static boolean isStackValid(ItemStack aStack) { + return (aStack != null) && aStack.getItem() != null && aStack.stackSize >= 0; + } + + @Deprecated + public static boolean isStackInvalid(Object aStack) { + return !(aStack instanceof ItemStack stack) || isStackInvalid(stack); + } + + public static boolean isStackInvalid(ItemStack aStack) { + return aStack == null || aStack.getItem() == null || aStack.stackSize < 0; + } + + public static boolean isDebugItem(ItemStack aStack) { + return /* ItemList.Armor_Cheat.isStackEqual(aStack, T, T) || */ areStacksEqual( + GTModHandler.getIC2Item("debug", 1), + aStack, + true); + } + + public static ItemStack updateItemStack(ItemStack aStack) { + if (isStackValid(aStack) && aStack.getItem() instanceof GTGenericItem) + ((GTGenericItem) aStack.getItem()).isItemStackUsable(aStack); + return aStack; + } + + public static boolean isOpaqueBlock(World aWorld, int aX, int aY, int aZ) { + return aWorld.getBlock(aX, aY, aZ) + .isOpaqueCube(); + } + + public static boolean isBlockAir(World aWorld, int aX, int aY, int aZ) { + return aWorld.getBlock(aX, aY, aZ) + .isAir(aWorld, aX, aY, aZ); + } + + public static boolean hasBlockHitBox(World aWorld, int aX, int aY, int aZ) { + return aWorld.getBlock(aX, aY, aZ) + .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ) != null; + } + + public static void setCoordsOnFire(World aWorld, int aX, int aY, int aZ, boolean aReplaceCenter) { + if (aReplaceCenter) if (aWorld.getBlock(aX, aY, aZ) + .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ) == null) aWorld.setBlock(aX, aY, aZ, Blocks.fire); + if (aWorld.getBlock(aX + 1, aY, aZ) + .getCollisionBoundingBoxFromPool(aWorld, aX + 1, aY, aZ) == null) + aWorld.setBlock(aX + 1, aY, aZ, Blocks.fire); + if (aWorld.getBlock(aX - 1, aY, aZ) + .getCollisionBoundingBoxFromPool(aWorld, aX - 1, aY, aZ) == null) + aWorld.setBlock(aX - 1, aY, aZ, Blocks.fire); + if (aWorld.getBlock(aX, aY + 1, aZ) + .getCollisionBoundingBoxFromPool(aWorld, aX, aY + 1, aZ) == null) + aWorld.setBlock(aX, aY + 1, aZ, Blocks.fire); + if (aWorld.getBlock(aX, aY - 1, aZ) + .getCollisionBoundingBoxFromPool(aWorld, aX, aY - 1, aZ) == null) + aWorld.setBlock(aX, aY - 1, aZ, Blocks.fire); + if (aWorld.getBlock(aX, aY, aZ + 1) + .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ + 1) == null) + aWorld.setBlock(aX, aY, aZ + 1, Blocks.fire); + if (aWorld.getBlock(aX, aY, aZ - 1) + .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ - 1) == null) + aWorld.setBlock(aX, aY, aZ - 1, Blocks.fire); + } + + public static ItemStack getProjectile(SubTag aProjectileType, IInventory aInventory) { + if (aInventory != null) for (int i = 0, j = aInventory.getSizeInventory(); i < j; i++) { + ItemStack rStack = aInventory.getStackInSlot(i); + if (isStackValid(rStack) && rStack.getItem() instanceof IProjectileItem + && ((IProjectileItem) rStack.getItem()).hasProjectile(aProjectileType, rStack)) + return updateItemStack(rStack); + } + return null; + } + + public static void removeNullStacksFromInventory(IInventory aInventory) { + if (aInventory != null) for (int i = 0, j = aInventory.getSizeInventory(); i < j; i++) { + ItemStack tStack = aInventory.getStackInSlot(i); + if (tStack != null && (tStack.stackSize == 0 || tStack.getItem() == null)) + aInventory.setInventorySlotContents(i, null); + } + } + + /** + * Initializes new empty texture page for casings page 0 is old CASING_BLOCKS + *

+ * Then casings should be registered like this: for (byte i = MIN_USED_META; i < MAX_USED_META; i = (byte) (i + 1)) + * { Textures.BlockIcons.casingTexturePages[PAGE][i+START_INDEX] = new GT_CopiedBlockTexture(this, 6, i); } + * + * @param page 0 to 127 + * @return true if it made empty page, false if one already existed... + */ + public static boolean addTexturePage(byte page) { + if (Textures.BlockIcons.casingTexturePages[page] == null) { + Textures.BlockIcons.casingTexturePages[page] = new ITexture[128]; + return true; + } + return false; + } + + /** + * Return texture id from page and index, for use when determining hatches, but can also be precomputed from: + * (page<<7)+index + * + * @param page 0 to 127 page + * @param index 0 to 127 texture index + * @return casing texture 0 to 16383 + */ + public static int getTextureId(byte page, byte index) { + if (page >= 0 && index >= 0) { + return (page << 7) + index; + } + throw new RuntimeException("Index out of range: [" + page + "][" + index + "]"); + } + + /** + * Return texture id from page and index, for use when determining hatches, but can also be precomputed from: + * (page<<7)+index + * + * @param page 0 to 127 page + * @param startIndex 0 to 127 start texture index + * @param blockMeta meta of the block + * @return casing texture 0 to 16383 + */ + public static int getTextureId(byte page, byte startIndex, byte blockMeta) { + if (page >= 0 && startIndex >= 0 && blockMeta >= 0 && (startIndex + blockMeta) <= 127) { + return (page << 7) + (startIndex + blockMeta); + } + throw new RuntimeException( + "Index out of range: [" + page + + "][" + + startIndex + + "+" + + blockMeta + + "=" + + (startIndex + blockMeta) + + "]"); + } + + /** + * Return texture id from item stack, unoptimized but readable? + * + * @return casing texture 0 to 16383 + */ + public static int getTextureId(Block blockFromBlock, byte metaFromBlock) { + for (int page = 0; page < Textures.BlockIcons.casingTexturePages.length; page++) { + ITexture[] casingTexturePage = Textures.BlockIcons.casingTexturePages[page]; + if (casingTexturePage != null) { + for (int index = 0; index < casingTexturePage.length; index++) { + ITexture iTexture = casingTexturePage[index]; + if (iTexture instanceof IBlockContainer) { + Block block = ((IBlockContainer) iTexture).getBlock(); + byte meta = ((IBlockContainer) iTexture).getMeta(); + if (meta == metaFromBlock && blockFromBlock == block) { + return (page << 7) + index; + } + } + } + } + } + throw new RuntimeException( + "Probably missing mapping or different texture class used for: " + blockFromBlock.getUnlocalizedName() + + " meta:" + + metaFromBlock); + } + + /** + * Converts a Number to a String + */ + public static String parseNumberToString(int aNumber) { + boolean temp = true, negative = false; + + if (aNumber < 0) { + aNumber *= -1; + negative = true; + } + + StringBuilder tStringB = new StringBuilder(); + for (int i = 1000000000; i > 0; i /= 10) { + int tDigit = (aNumber / i) % 10; + if (temp && tDigit != 0) temp = false; + if (!temp) { + tStringB.append(tDigit); + if (i != 1) for (int j = i; j > 0; j /= 1000) if (j == 1) tStringB.append(","); + } + } + + String tString = tStringB.toString(); + + if (tString.equals(E)) tString = "0"; + + return negative ? "-" + tString : tString; + } + + public static NBTTagCompound getNBTContainingBoolean(NBTTagCompound aNBT, Object aTag, boolean aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + aNBT.setBoolean(aTag.toString(), aValue); + return aNBT; + } + + public static NBTTagCompound getNBTContainingByte(NBTTagCompound aNBT, Object aTag, byte aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + aNBT.setByte(aTag.toString(), aValue); + return aNBT; + } + + public static NBTTagCompound getNBTContainingShort(NBTTagCompound aNBT, Object aTag, short aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + aNBT.setShort(aTag.toString(), aValue); + return aNBT; + } + + public static NBTTagCompound getNBTContainingInteger(NBTTagCompound aNBT, Object aTag, int aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + aNBT.setInteger(aTag.toString(), aValue); + return aNBT; + } + + public static NBTTagCompound getNBTContainingFloat(NBTTagCompound aNBT, Object aTag, float aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + aNBT.setFloat(aTag.toString(), aValue); + return aNBT; + } + + public static NBTTagCompound getNBTContainingDouble(NBTTagCompound aNBT, Object aTag, double aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + aNBT.setDouble(aTag.toString(), aValue); + return aNBT; + } + + public static NBTTagCompound getNBTContainingString(NBTTagCompound aNBT, Object aTag, Object aValue) { + if (aNBT == null) aNBT = new NBTTagCompound(); + if (aValue == null) return aNBT; + aNBT.setString(aTag.toString(), aValue.toString()); + return aNBT; + } + + public static boolean isWearingFullFrostHazmat(EntityLivingBase aEntity) { + for (byte i = 1; i < 5; i++) { + ItemStack tStack = aEntity.getEquipmentInSlot(i); + + if (!isStackInList(tStack, GregTechAPI.sFrostHazmatList) && !hasHazmatEnchant(tStack)) { + return false; + } + } + return true; + } + + public static boolean isWearingFullHeatHazmat(EntityLivingBase aEntity) { + for (byte i = 1; i < 5; i++) { + ItemStack tStack = aEntity.getEquipmentInSlot(i); + + if (!isStackInList(tStack, GregTechAPI.sHeatHazmatList) && !hasHazmatEnchant(tStack)) { + return false; + } + } + + return true; + } + + public static boolean isWearingFullBioHazmat(EntityLivingBase aEntity) { + for (byte i = 1; i < 5; i++) { + ItemStack tStack = aEntity.getEquipmentInSlot(i); + + if (!isStackInList(tStack, GregTechAPI.sBioHazmatList) && !hasHazmatEnchant(tStack)) { + return false; + } + } + return true; + } + + public static boolean isWearingFullRadioHazmat(EntityLivingBase aEntity) { + for (byte i = 1; i < 5; i++) { + ItemStack tStack = aEntity.getEquipmentInSlot(i); + + if (!isStackInList(tStack, GregTechAPI.sRadioHazmatList) && !hasHazmatEnchant(tStack)) { + return false; + } + } + return true; + } + + public static boolean isWearingFullElectroHazmat(EntityLivingBase aEntity) { + for (byte i = 1; i < 5; i++) { + ItemStack tStack = aEntity.getEquipmentInSlot(i); + + if (!isStackInList(tStack, GregTechAPI.sElectroHazmatList) && !hasHazmatEnchant(tStack)) { + return false; + } + } + return true; + } + + public static boolean isWearingFullGasHazmat(EntityLivingBase aEntity) { + for (byte i = 1; i < 5; i++) { + ItemStack tStack = aEntity.getEquipmentInSlot(i); + + if (!isStackInList(tStack, GregTechAPI.sGasHazmatList) && !hasHazmatEnchant(tStack)) { + return false; + } + } + return true; + } + + public static boolean hasHazmatEnchant(ItemStack aStack) { + if (aStack == null) return false; + Map tEnchantments = EnchantmentHelper.getEnchantments(aStack); + Integer tLevel = tEnchantments.get(EnchantmentHazmat.INSTANCE.effectId); + + return tLevel != null && tLevel >= 1; + } + + public static float getHeatDamageFromItem(ItemStack aStack) { + ItemData tData = GTOreDictUnificator.getItemData(aStack); + return tData == null ? 0 + : (tData.mPrefix == null ? 0 : tData.mPrefix.mHeatDamage) + + (tData.hasValidMaterialData() ? tData.mMaterial.mMaterial.mHeatDamage : 0); + } + + public static int getRadioactivityLevel(ItemStack aStack) { + ItemData tData = GTOreDictUnificator.getItemData(aStack); + if (tData != null && tData.hasValidMaterialData()) { + if (tData.mMaterial.mMaterial.mEnchantmentArmors instanceof EnchantmentRadioactivity) + return tData.mMaterial.mMaterial.mEnchantmentArmorsLevel; + if (tData.mMaterial.mMaterial.mEnchantmentTools instanceof EnchantmentRadioactivity) + return tData.mMaterial.mMaterial.mEnchantmentToolsLevel; + } + return EnchantmentHelper.getEnchantmentLevel(EnchantmentRadioactivity.INSTANCE.effectId, aStack); + } + + public static boolean isImmuneToBreathingGasses(EntityLivingBase aEntity) { + return isWearingFullGasHazmat(aEntity); + } + + public static boolean applyHeatDamage(EntityLivingBase entity, float damage) { + return applyHeatDamage(entity, damage, GTDamageSources.getHeatDamage()); + } + + public static boolean applyHeatDamageFromItem(EntityLivingBase entity, float damage, ItemStack item) { + return applyHeatDamage(entity, damage, new DamageSourceHotItem(item)); + } + + private static boolean applyHeatDamage(EntityLivingBase aEntity, float aDamage, DamageSource source) { + if (aDamage > 0 && aEntity != null && !isWearingFullHeatHazmat(aEntity)) { + return aEntity.attackEntityFrom(source, aDamage); + } + return false; + } + + public static boolean applyFrostDamage(EntityLivingBase aEntity, float aDamage) { + if (aDamage > 0 && aEntity != null && !isWearingFullFrostHazmat(aEntity)) { + return aEntity.attackEntityFrom(GTDamageSources.getFrostDamage(), aDamage); + } + return false; + } + + public static boolean applyElectricityDamage(EntityLivingBase aEntity, long aVoltage, long aAmperage) { + long aDamage = getTier(aVoltage) * aAmperage * 4; + if (aDamage > 0 && aEntity != null && !isWearingFullElectroHazmat(aEntity)) { + return aEntity.attackEntityFrom(GTDamageSources.getElectricDamage(), aDamage); + } + return false; + } + + public static boolean applyRadioactivity(EntityLivingBase aEntity, int aLevel, int aAmountOfItems) { + if (aLevel > 0 && aEntity != null + && aEntity.getCreatureAttribute() != EnumCreatureAttribute.UNDEAD + && aEntity.getCreatureAttribute() != EnumCreatureAttribute.ARTHROPOD + && !isWearingFullRadioHazmat(aEntity)) { + PotionEffect tEffect = null; + aEntity.addPotionEffect( + new PotionEffect( + Potion.moveSlowdown.id, + aLevel * 140 * aAmountOfItems + Math.max( + 0, + ((tEffect = aEntity.getActivePotionEffect(Potion.moveSlowdown)) == null ? 0 + : tEffect.getDuration())), + Math.max(0, (5 * aLevel) / 7))); + aEntity.addPotionEffect( + new PotionEffect( + Potion.digSlowdown.id, + aLevel * 150 * aAmountOfItems + Math.max( + 0, + ((tEffect = aEntity.getActivePotionEffect(Potion.digSlowdown)) == null ? 0 + : tEffect.getDuration())), + Math.max(0, (5 * aLevel) / 7))); + aEntity.addPotionEffect( + new PotionEffect( + Potion.confusion.id, + aLevel * 130 * aAmountOfItems + Math.max( + 0, + ((tEffect = aEntity.getActivePotionEffect(Potion.confusion)) == null ? 0 + : tEffect.getDuration())), + Math.max(0, (5 * aLevel) / 7))); + aEntity.addPotionEffect( + new PotionEffect( + Potion.weakness.id, + aLevel * 150 * aAmountOfItems + Math.max( + 0, + ((tEffect = aEntity.getActivePotionEffect(Potion.weakness)) == null ? 0 + : tEffect.getDuration())), + Math.max(0, (5 * aLevel) / 7))); + aEntity.addPotionEffect( + new PotionEffect( + Potion.hunger.id, + aLevel * 130 * aAmountOfItems + Math.max( + 0, + ((tEffect = aEntity.getActivePotionEffect(Potion.hunger)) == null ? 0 : tEffect.getDuration())), + Math.max(0, (5 * aLevel) / 7))); + aEntity.addPotionEffect( + new PotionEffect( + 24 /* IC2 Radiation */, + aLevel * 180 * aAmountOfItems + Math.max( + 0, + ((tEffect = aEntity.getActivePotionEffect(Potion.potionTypes[24])) == null ? 0 + : tEffect.getDuration())), + Math.max(0, (5 * aLevel) / 7))); + return true; + } + return false; + } + + public static ItemStack setStack(ItemStack aSetStack, ItemStack aToStack) { + if (isStackInvalid(aSetStack) || isStackInvalid(aToStack)) return null; + aSetStack.func_150996_a(aToStack.getItem()); + aSetStack.stackSize = aToStack.stackSize; + Items.feather.setDamage(aSetStack, Items.feather.getDamage(aToStack)); + aSetStack.setTagCompound(aToStack.getTagCompound()); + return aSetStack; + } + + public static FluidStack[] copyFluidArray(FluidStack... aStacks) { + if (aStacks == null) return null; + FluidStack[] rStacks = new FluidStack[aStacks.length]; + for (int i = 0; i < aStacks.length; i++) if (aStacks[i] != null) rStacks[i] = aStacks[i].copy(); + return rStacks; + } + + public static ItemStack[] copyItemArray(ItemStack... aStacks) { + if (aStacks == null) return null; + ItemStack[] rStacks = new ItemStack[aStacks.length]; + for (int i = 0; i < aStacks.length; i++) rStacks[i] = copy(aStacks[i]); + return rStacks; + } + + /** + * @deprecated use {@link #copy(ItemStack)} instead + */ + @Deprecated + public static ItemStack copy(Object... aStacks) { + for (Object tStack : aStacks) if (isStackValid(tStack)) return ((ItemStack) tStack).copy(); + return null; + } + + public static ItemStack copy(ItemStack aStack) { + if (isStackValid(aStack)) return aStack.copy(); + return null; + } + + @Deprecated + private static ItemStack firstStackOrNull(Object... aStacks) { + for (Object tStack : aStacks) if (tStack instanceof ItemStack stack) return stack; + return null; + } + + @Nullable + public static ItemStack copyOrNull(@Nullable ItemStack stack) { + if (isStackValid(stack)) return stack.copy(); + return null; + } + + public static FluidStack copyAmount(int aAmount, FluidStack aStack) { + if (aStack == null) return null; + FluidStack rStack = aStack.copy(); + rStack.amount = aAmount; + return rStack; + } + + /** + * @deprecated use {@link #copyAmount(int, ItemStack)} instead + */ + @Deprecated + public static ItemStack copyAmount(long aAmount, Object... aStacks) { + return copyAmount(aAmount, firstStackOrNull(aStacks)); + } + + /** + * @deprecated use {@link #copyAmount(int, ItemStack)} instead + */ + @Deprecated + public static ItemStack copyAmount(long aAmount, ItemStack aStack) { + return copyAmount((int) aAmount, aStack); + } + + public static ItemStack copyAmount(int aAmount, ItemStack aStack) { + ItemStack rStack = copy(aStack); + if (isStackInvalid(rStack)) return null; + if (aAmount > 64) aAmount = 64; + else if (aAmount == -1) aAmount = 111; + else if (aAmount < 0) aAmount = 0; + rStack.stackSize = (byte) aAmount; + return rStack; + } + + public static ItemStack multiplyStack(int aMultiplier, ItemStack aStack) { + ItemStack rStack = copy(aStack); + if (isStackInvalid(rStack)) return null; + int tAmount = rStack.stackSize * aMultiplier; + if (tAmount > 64) tAmount = 64; + else if (tAmount == -1) tAmount = 111; + else if (tAmount < 0) tAmount = 0; + rStack.stackSize = (byte) tAmount; + return rStack; + } + + /** + * Unlike {@link #copyAmount(int, ItemStack)}, this method does not restrict stack size by 64. + */ + public static ItemStack copyAmountUnsafe(int aAmount, ItemStack aStack) { + ItemStack rStack = copy(aStack); + if (isStackInvalid(rStack)) return null; + else if (aAmount < 0) aAmount = 0; + rStack.stackSize = (int) aAmount; + return rStack; + } + + public static ItemStack copyMetaData(int aMetaData, ItemStack aStack) { + ItemStack rStack = copy(aStack); + if (isStackInvalid(rStack)) return null; + Items.feather.setDamage(rStack, aMetaData); + return rStack; + } + + /** + * @deprecated use {@link #copyAmountAndMetaData(int, int, ItemStack)} instead + */ + @Deprecated + public static ItemStack copyAmountAndMetaData(long aAmount, long aMetaData, ItemStack aStack) { + return copyAmountAndMetaData((int) aAmount, (int) aMetaData, aStack); + } + + public static ItemStack copyAmountAndMetaData(int aAmount, int aMetaData, ItemStack aStack) { + ItemStack rStack = copyAmount(aAmount, aStack); + if (isStackInvalid(rStack)) return null; + Items.feather.setDamage(rStack, aMetaData); + return rStack; + } + + /** + * returns a copy of an ItemStack with its Stacksize being multiplied by aMultiplier + */ + public static ItemStack mul(int aMultiplier, ItemStack aStack) { + ItemStack rStack = copy(aStack); + if (rStack == null) return null; + rStack.stackSize *= aMultiplier; + return rStack; + } + + /** + * Loads an ItemStack properly. + */ + public static ItemStack loadItem(NBTTagCompound aNBT, String aTagName) { + return loadItem(aNBT.getCompoundTag(aTagName)); + } + + public static FluidStack loadFluid(NBTTagCompound aNBT, String aTagName) { + return loadFluid(aNBT.getCompoundTag(aTagName)); + } + + /** + * Loads an ItemStack properly. + */ + public static ItemStack loadItem(NBTTagCompound aNBT) { + if (aNBT == null) return null; + ItemStack tRawStack = ItemStack.loadItemStackFromNBT(aNBT); + int tRealStackSize = 0; + if (tRawStack != null && aNBT.hasKey("Count", Constants.NBT.TAG_INT)) { + tRealStackSize = aNBT.getInteger("Count"); + tRawStack.stackSize = tRealStackSize; + } else if (tRawStack != null) { + tRealStackSize = tRawStack.stackSize; + } + ItemStack tRet = GTOreDictUnificator.get(true, tRawStack); + if (tRet != null) tRet.stackSize = tRealStackSize; + return tRet; + } + + public static void saveItem(NBTTagCompound aParentTag, String aTagName, ItemStack aStack) { + if (aStack != null) aParentTag.setTag(aTagName, saveItem(aStack)); + } + + public static NBTTagCompound saveItem(ItemStack aStack) { + if (aStack == null) return new NBTTagCompound(); + NBTTagCompound t = new NBTTagCompound(); + aStack.writeToNBT(t); + if (aStack.stackSize > Byte.MAX_VALUE) t.setInteger("Count", aStack.stackSize); + return t; + } + + /** + * Loads an FluidStack properly. + */ + public static FluidStack loadFluid(NBTTagCompound aNBT) { + if (aNBT == null) return null; + return FluidStack.loadFluidStackFromNBT(aNBT); + } + + public static E selectItemInList(int aIndex, E aReplacement, List aList) { + if (aList == null || aList.isEmpty()) return aReplacement; + if (aList.size() <= aIndex) return aList.get(aList.size() - 1); + if (aIndex < 0) return aList.get(0); + return aList.get(aIndex); + } + + @SafeVarargs + public static E selectItemInList(int aIndex, E aReplacement, E... aList) { + if (aList == null || aList.length == 0) return aReplacement; + if (aList.length <= aIndex) return aList[aList.length - 1]; + if (aIndex < 0) return aList[0]; + return aList[aIndex]; + } + + public static boolean isStackInStackSet(ItemStack aStack, Set aSet) { + if (aStack == null) return false; + if (aSet.contains(aStack)) return true; + + return aSet.contains(GTItemStack.internalCopyStack(aStack, true)); + } + + public static boolean isStackInList(ItemStack aStack, Collection aList) { + if (aStack == null) { + return false; + } + return isStackInList(new GTItemStack(aStack), aList); + } + + public static boolean isStackInList(ItemStack aStack, Set aList) { + if (aStack == null) { + return false; + } + return isStackInList(new GTItemStack2(aStack), aList); + } + + public static boolean isStackInList(GTItemStack aStack, Collection aList) { + return aStack != null + && (aList.contains(aStack) || aList.contains(new GTItemStack(aStack.mItem, aStack.mStackSize, W))); + } + + public static boolean isStackInList(GTItemStack2 aStack, Set aList) { + return aStack != null + && (aList.contains(aStack) || aList.contains(new GTItemStack2(aStack.mItem, aStack.mStackSize, W))); + } + + /** + * re-maps all Keys of a Map after the Keys were weakened. + */ + public static Map reMap(Map aMap) { + Map tMap = null; + // We try to clone the Map first (most Maps are Cloneable) in order to retain as much state of the Map as + // possible when rehashing. For example, "Custom" HashMaps from fastutil may have a custom hash function which + // would not be used to rehash if we just create a new HashMap. + if (aMap instanceof Cloneable) { + try { + tMap = (Map) aMap.getClass() + .getMethod("clone") + .invoke(aMap); + } catch (Throwable e) { + GTLog.err.println("Failed to clone Map of type " + aMap.getClass()); + e.printStackTrace(GTLog.err); + } + } + + if (tMap == null) { + tMap = new HashMap<>(aMap); + } + + aMap.clear(); + aMap.putAll(tMap); + return aMap; + } + + /** + * re-maps all Keys of a Map after the Keys were weakened. + */ + public static SetMultimap reMap(SetMultimap aMap) { + @SuppressWarnings("unchecked") + Map.Entry[] entries = aMap.entries() + .toArray(new Map.Entry[0]); + aMap.clear(); + for (Map.Entry entry : entries) { + aMap.put(entry.getKey(), entry.getValue()); + } + return aMap; + } + + public static > LinkedHashMap sortMapByValuesAcending(Map map) { + return map.entrySet() + .stream() + .sorted(Map.Entry.comparingByValue()) + .collect(CollectorUtils.entriesToMap(LinkedHashMap::new)); + } + + /** + * Why the fuck do neither Java nor Guava have a Function to do this? + */ + public static > LinkedHashMap sortMapByValuesDescending(Map aMap) { + List> tEntrySet = new LinkedList<>(aMap.entrySet()); + tEntrySet.sort((aValue1, aValue2) -> { + return aValue2.getValue() + .compareTo(aValue1.getValue()); // FB: RV - RV_NEGATING_RESULT_OF_COMPARETO + }); + LinkedHashMap rMap = new LinkedHashMap<>(); + for (Map.Entry tEntry : tEntrySet) rMap.put(tEntry.getKey(), tEntry.getValue()); + return rMap; + } + + /** + * Translates a Material Amount into an Amount of Fluid in Fluid Material Units. + */ + public static long translateMaterialToFluidAmount(long aMaterialAmount, boolean aRoundUp) { + return translateMaterialToAmount(aMaterialAmount, L, aRoundUp); + } + + /** + * Translates a Material Amount into an Amount of Fluid. Second Parameter for things like Bucket Amounts (1000) and + * similar + */ + public static long translateMaterialToAmount(long aMaterialAmount, long aAmountPerUnit, boolean aRoundUp) { + return Math.max( + 0, + ((aMaterialAmount * aAmountPerUnit) / M) + + (aRoundUp && (aMaterialAmount * aAmountPerUnit) % M > 0 ? 1 : 0)); + } + + /** + * This checks if the Dimension is really a Dimension and not another Planet or something. Used for my Teleporter. + */ + public static boolean isRealDimension(int aDimensionID) { + if (aDimensionID <= 1 && aDimensionID >= -1 && !GregTechAPI.sDimensionalList.contains(aDimensionID)) + return true; + return !GregTechAPI.sDimensionalList.contains(aDimensionID) + && DimensionManager.isDimensionRegistered(aDimensionID); + } + + public static boolean moveEntityToDimensionAtCoords(Entity entity, int aDimension, double aX, double aY, + double aZ) { + // Credit goes to BrandonCore Author :!: + + if (entity == null || entity.worldObj.isRemote) return false; + if (entity.ridingEntity != null) entity.mountEntity(null); + if (entity.riddenByEntity != null) entity.riddenByEntity.mountEntity(null); + + World startWorld = entity.worldObj; + WorldServer destinationWorld = FMLCommonHandler.instance() + .getMinecraftServerInstance() + .worldServerForDimension(aDimension); + + if (destinationWorld == null) { + return false; + } + + boolean interDimensional = startWorld.provider.dimensionId != destinationWorld.provider.dimensionId; + if (!interDimensional) return false; + startWorld.updateEntityWithOptionalForce(entity, false); // added + + if (entity instanceof EntityPlayerMP player) { + player.closeScreen(); // added + player.dimension = aDimension; + player.playerNetServerHandler.sendPacket( + new S07PacketRespawn( + player.dimension, + player.worldObj.difficultySetting, + destinationWorld.getWorldInfo() + .getTerrainType(), + player.theItemInWorldManager.getGameType())); + ((WorldServer) startWorld).getPlayerManager() + .removePlayer(player); + + startWorld.playerEntities.remove(player); + startWorld.updateAllPlayersSleepingFlag(); + int i = entity.chunkCoordX; + int j = entity.chunkCoordZ; + if ((entity.addedToChunk) && (startWorld.getChunkProvider() + .chunkExists(i, j))) { + startWorld.getChunkFromChunkCoords(i, j) + .removeEntity(entity); + startWorld.getChunkFromChunkCoords(i, j).isModified = true; + } + startWorld.loadedEntityList.remove(entity); + startWorld.onEntityRemoved(entity); + } + + entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); + + destinationWorld.theChunkProviderServer.loadChunk((int) aX >> 4, (int) aZ >> 4); + + destinationWorld.theProfiler.startSection("placing"); + if (!(entity instanceof EntityPlayer)) { + NBTTagCompound entityNBT = new NBTTagCompound(); + entity.isDead = false; + entityNBT.setString("id", EntityList.getEntityString(entity)); + entity.writeToNBT(entityNBT); + entity.isDead = true; + entity = EntityList.createEntityFromNBT(entityNBT, destinationWorld); + if (entity == null) { + return false; + } + entity.dimension = destinationWorld.provider.dimensionId; + } + destinationWorld.spawnEntityInWorld(entity); + entity.setWorld(destinationWorld); + entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); + + destinationWorld.updateEntityWithOptionalForce(entity, false); + entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); + + if ((entity instanceof EntityPlayerMP player)) { + player.mcServer.getConfigurationManager() + .func_72375_a(player, destinationWorld); + player.playerNetServerHandler.setPlayerLocation(aX, aY, aZ, player.rotationYaw, player.rotationPitch); + } + + destinationWorld.updateEntityWithOptionalForce(entity, false); + + if (entity instanceof EntityPlayerMP player) { + player.theItemInWorldManager.setWorld(destinationWorld); + player.mcServer.getConfigurationManager() + .updateTimeAndWeatherForPlayer(player, destinationWorld); + player.mcServer.getConfigurationManager() + .syncPlayerInventory(player); + + for (PotionEffect potionEffect : player.getActivePotionEffects()) { + player.playerNetServerHandler.sendPacket(new S1DPacketEntityEffect(player.getEntityId(), potionEffect)); + } + + player.playerNetServerHandler.sendPacket( + new S1FPacketSetExperience(player.experience, player.experienceTotal, player.experienceLevel)); + FMLCommonHandler.instance() + .firePlayerChangedDimensionEvent( + player, + startWorld.provider.dimensionId, + destinationWorld.provider.dimensionId); + } + entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); + + destinationWorld.theProfiler.endSection(); + entity.fallDistance = 0; + return true; + } + + public static int getScaleCoordinates(double aValue, int aScale) { + return (int) Math.floor(aValue / aScale); + } + + public static int getCoordinateScan(ArrayList aList, EntityPlayer aPlayer, World aWorld, int aScanLevel, + int aX, int aY, int aZ, ForgeDirection side, float aClickX, float aClickY, float aClickZ) { + if (aList == null) return 0; + + ArrayList tList = new ArrayList<>(); + int rEUAmount = 0; + + TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ); + + final Block tBlock = aWorld.getBlock(aX, aY, aZ); + + addBaseInfo(aPlayer, aWorld, aX, aY, aZ, tList, tTileEntity, tBlock); + + if (tTileEntity != null) { + rEUAmount += addFluidHandlerInfo(side, tList, tTileEntity); + + try { + if (tTileEntity instanceof ic2.api.reactor.IReactorChamber chamber) { + rEUAmount += 500; + // Redirect the rest of the scans to the reactor itself + tTileEntity = (TileEntity) chamber.getReactor(); + } + } catch (Throwable e) { + if (D1) e.printStackTrace(GTLog.err); + } + rEUAmount += addReactorInfo(tList, tTileEntity); + rEUAmount += addAlignmentInfo(tList, tTileEntity); + rEUAmount += addIC2WrenchableInfo(aPlayer, tList, tTileEntity); + rEUAmount += addIC2EnergyConductorInfo(tList, tTileEntity); + rEUAmount += addIC2EnergyStorageInfo(tList, tTileEntity); + rEUAmount += addUpgradableMachineInfo(tList, tTileEntity); + rEUAmount += addMachineProgressInfo(tList, tTileEntity); + rEUAmount += addCoverableInfo(side, tList, tTileEntity); + addEnergyContainerInfo(tList, tTileEntity); + addOwnerInfo(tList, tTileEntity); + addDeviceInfo(tList, tTileEntity); + + rEUAmount += addIC2CropInfo(tList, tTileEntity); + + rEUAmount += addForestryLeavesInfo(tList, tTileEntity); + } + + final Chunk currentChunk = aWorld.getChunkFromBlockCoords(aX, aZ); + addUndergroundFluidInfo(aPlayer, tList, currentChunk); + addPollutionInfo(tList, currentChunk); + + rEUAmount += addDebuggableBlockInfo(aPlayer, aX, aY, aZ, tList, tBlock); + + final BlockScanningEvent tEvent = new BlockScanningEvent( + aWorld, + aPlayer, + aX, + aY, + aZ, + side, + aScanLevel, + tBlock, + tTileEntity, + tList, + aClickX, + aClickY, + aClickZ); + tEvent.mEUCost = rEUAmount; + MinecraftForge.EVENT_BUS.post(tEvent); + if (!tEvent.isCanceled()) aList.addAll(tList); + return tEvent.mEUCost; + } + + private static void addBaseInfo(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, ArrayList tList, + TileEntity tTileEntity, Block tBlock) { + tList.add( + "----- X: " + EnumChatFormatting.AQUA + + formatNumbers(aX) + + EnumChatFormatting.RESET + + " Y: " + + EnumChatFormatting.AQUA + + formatNumbers(aY) + + EnumChatFormatting.RESET + + " Z: " + + EnumChatFormatting.AQUA + + formatNumbers(aZ) + + EnumChatFormatting.RESET + + " D: " + + EnumChatFormatting.AQUA + + aWorld.provider.dimensionId + + EnumChatFormatting.RESET + + " -----"); + try { + tList.add( + GTUtility.trans("162", "Name: ") + EnumChatFormatting.BLUE + + ((tTileEntity instanceof IInventory inv) ? inv.getInventoryName() : tBlock.getUnlocalizedName()) + + EnumChatFormatting.RESET + + GTUtility.trans("163", " MetaData: ") + + EnumChatFormatting.AQUA + + aWorld.getBlockMetadata(aX, aY, aZ) + + EnumChatFormatting.RESET); + tList.add( + GTUtility.trans("164", "Hardness: ") + EnumChatFormatting.YELLOW + + tBlock.getBlockHardness(aWorld, aX, aY, aZ) + + EnumChatFormatting.RESET + + GTUtility.trans("165", " Blast Resistance: ") + + EnumChatFormatting.YELLOW + + tBlock + .getExplosionResistance(aPlayer, aWorld, aX, aY, aZ, aPlayer.posX, aPlayer.posY, aPlayer.posZ) + + EnumChatFormatting.RESET); + if (tBlock.isBeaconBase(aWorld, aX, aY, aZ, aX, aY + 1, aZ)) tList.add( + EnumChatFormatting.GOLD + GTUtility.trans("166", "Is valid Beacon Pyramid Material") + + EnumChatFormatting.RESET); + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this block's info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + } + + private static int addFluidHandlerInfo(ForgeDirection side, ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof IFluidHandler fluidHandler) { + rEUAmount += 500; + final FluidTankInfo[] tTanks = fluidHandler.getTankInfo(side); + if (tTanks != null) for (byte i = 0; i < tTanks.length; i++) { + tList.add( + GTUtility.trans("167", "Tank ") + i + + ": " + + EnumChatFormatting.GREEN + + formatNumbers((tTanks[i].fluid == null ? 0 : tTanks[i].fluid.amount)) + + EnumChatFormatting.RESET + + " L / " + + EnumChatFormatting.YELLOW + + formatNumbers(tTanks[i].capacity) + + EnumChatFormatting.RESET + + " L " + + EnumChatFormatting.GOLD + + getFluidName(tTanks[i].fluid, true) + + EnumChatFormatting.RESET); + } + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this tile's fluid tank info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addDebuggableBlockInfo(EntityPlayer aPlayer, int aX, int aY, int aZ, ArrayList tList, + Block tBlock) { + int rEUAmount = 0; + try { + if (tBlock instanceof IDebugableBlock debugableBlock) { + rEUAmount += 500; + final ArrayList temp = debugableBlock.getDebugInfo(aPlayer, aX, aY, aZ, 3); + if (temp != null) tList.addAll(temp); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this block's debug info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static void addPollutionInfo(ArrayList tList, Chunk currentChunk) { + if (Pollution.hasPollution(currentChunk)) { + tList.add( + GTUtility.trans("202", "Pollution in Chunk: ") + EnumChatFormatting.RED + + formatNumbers(Pollution.getPollution(currentChunk)) + + EnumChatFormatting.RESET + + GTUtility.trans("203", " gibbl")); + } else { + tList.add( + EnumChatFormatting.GREEN + GTUtility.trans("204", "No Pollution in Chunk! HAYO!") + + EnumChatFormatting.RESET); + } + } + + private static void addUndergroundFluidInfo(EntityPlayer aPlayer, ArrayList tList, Chunk currentChunk) { + if (aPlayer.capabilities.isCreativeMode) { + final FluidStack tFluid = undergroundOilReadInformation(currentChunk); // -# to only read + if (tFluid != null) tList.add( + EnumChatFormatting.GOLD + tFluid.getLocalizedName() + + EnumChatFormatting.RESET + + ": " + + EnumChatFormatting.YELLOW + + formatNumbers(tFluid.amount) + + EnumChatFormatting.RESET + + " L"); + else tList.add( + EnumChatFormatting.GOLD + GTUtility.trans("201", "Nothing") + + EnumChatFormatting.RESET + + ": " + + EnumChatFormatting.YELLOW + + '0' + + EnumChatFormatting.RESET + + " L"); + } + } + + private static int addForestryLeavesInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (Mods.Forestry.isModLoaded() + && tTileEntity instanceof forestry.arboriculture.tiles.TileLeaves tileLeaves) { + final forestry.api.arboriculture.ITree tree = tileLeaves.getTree(); + if (tree != null) { + rEUAmount += 1000; + if (!tree.isAnalyzed()) tree.analyze(); + tree.addTooltip(tList); + } + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this leaves' info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addIC2CropInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof ic2.api.crops.ICropTile crop) { + rEUAmount += 1000; + if (crop.getScanLevel() < 4) crop.setScanLevel((byte) 4); + if (crop.getCrop() != null) { + tList.add( + GTUtility.trans("187", "Type -- Crop-Name: ") + crop.getCrop() + .name() + + GTUtility.trans("188", " Growth: ") + + crop.getGrowth() + + GTUtility.trans("189", " Gain: ") + + crop.getGain() + + GTUtility.trans("190", " Resistance: ") + + crop.getResistance()); + } + tList.add( + GTUtility.trans("191", "Plant -- Fertilizer: ") + crop.getNutrientStorage() + + GTUtility.trans("192", " Water: ") + + crop.getHydrationStorage() + + GTUtility.trans("193", " Weed-Ex: ") + + crop.getWeedExStorage() + + GTUtility.trans("194", " Scan-Level: ") + + crop.getScanLevel()); + tList.add( + GTUtility.trans("195", "Environment -- Nutrients: ") + crop.getNutrients() + + GTUtility.trans("196", " Humidity: ") + + crop.getHumidity() + + GTUtility.trans("197", " Air-Quality: ") + + crop.getAirQuality()); + if (crop.getCrop() != null) { + final StringBuilder tStringB = new StringBuilder(); + for (final String tAttribute : crop.getCrop() + .attributes()) { + tStringB.append(", ") + .append(tAttribute); + } + final String tString = tStringB.toString(); + tList.add(GTUtility.trans("198", "Attributes:") + tString.replaceFirst(",", E)); + tList.add( + GTUtility.trans("199", "Discovered by: ") + crop.getCrop() + .discoveredBy()); + } + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this crop's info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static void addDeviceInfo(ArrayList tList, TileEntity tTileEntity) { + try { + if (tTileEntity instanceof IGregTechDeviceInformation info && info.isGivingInformation()) { + tList.addAll(Arrays.asList(info.getInfoData())); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + } + + private static void addOwnerInfo(ArrayList tList, TileEntity tTileEntity) { + try { + if (tTileEntity instanceof IGregTechTileEntity gtTE) { + tList.add( + GTUtility.trans("186", "Owned by: ") + EnumChatFormatting.BLUE + + gtTE.getOwnerName() + + EnumChatFormatting.RESET); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's owner.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + } + + private static void addEnergyContainerInfo(ArrayList tList, TileEntity tTileEntity) { + try { + if (tTileEntity instanceof IBasicEnergyContainer energyContainer && energyContainer.getEUCapacity() > 0) { + tList.add( + GTUtility.trans("179", "Max IN: ") + EnumChatFormatting.RED + + formatNumbers(energyContainer.getInputVoltage()) + + " (" + + GTValues.VN[getTier(energyContainer.getInputVoltage())] + + ") " + + EnumChatFormatting.RESET + + GTUtility.trans("182", " EU at ") + + EnumChatFormatting.RED + + formatNumbers(energyContainer.getInputAmperage()) + + EnumChatFormatting.RESET + + GTUtility.trans("183", " A")); + tList.add( + GTUtility.trans("181", "Max OUT: ") + EnumChatFormatting.RED + + formatNumbers(energyContainer.getOutputVoltage()) + + " (" + + GTValues.VN[getTier(energyContainer.getOutputVoltage())] + + ") " + + EnumChatFormatting.RESET + + GTUtility.trans("182", " EU at ") + + EnumChatFormatting.RED + + formatNumbers(energyContainer.getOutputAmperage()) + + EnumChatFormatting.RESET + + GTUtility.trans("183", " A")); + tList.add( + GTUtility.trans("184", "Energy: ") + EnumChatFormatting.GREEN + + formatNumbers(energyContainer.getStoredEU()) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + formatNumbers(energyContainer.getEUCapacity()) + + EnumChatFormatting.RESET + + " EU"); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's energy info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + } + + private static int addCoverableInfo(ForgeDirection side, ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof ICoverable coverable) { + rEUAmount += 300; + final String tString = coverable.getCoverInfoAtSide(side) + .getBehaviorDescription(); + if (tString != null && !tString.equals(E)) tList.add(tString); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's covers.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addMachineProgressInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof IMachineProgress progress) { + if (progress.isAllowedToWork() && !progress.hasThingsToDo()) { + tList.add(EnumChatFormatting.RED + "Disabled." + EnumChatFormatting.RESET); + } + if (progress.wasShutdown() && isStringValid( + progress.getLastShutDownReason() + .getDisplayString())) { + tList.add( + progress.getLastShutDownReason() + .getDisplayString()); + } + rEUAmount += 400; + int tValue = 0; + if (0 < (tValue = progress.getMaxProgress())) tList.add( + GTUtility.trans("178", "Progress/Load: ") + EnumChatFormatting.GREEN + + formatNumbers(progress.getProgress()) + + EnumChatFormatting.RESET + + " / " + + EnumChatFormatting.YELLOW + + formatNumbers(tValue) + + EnumChatFormatting.RESET); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's progress.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addUpgradableMachineInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof IUpgradableMachine upgradableMachine) { + rEUAmount += 500; + if (upgradableMachine.hasMufflerUpgrade()) tList.add( + EnumChatFormatting.GREEN + GTUtility.trans("177", "Has Muffler Upgrade") + + EnumChatFormatting.RESET); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's upgrades.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addIC2EnergyStorageInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof ic2.api.tile.IEnergyStorage storage) { + rEUAmount += 200; + tList.add( + GTUtility.trans("176", "Contained Energy: ") + EnumChatFormatting.YELLOW + + formatNumbers(storage.getStored()) + + EnumChatFormatting.RESET + + " EU / " + + EnumChatFormatting.YELLOW + + formatNumbers(storage.getCapacity()) + + EnumChatFormatting.RESET + + " EU"); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's IC2 energy info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addIC2EnergyConductorInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof ic2.api.energy.tile.IEnergyConductor conductor) { + rEUAmount += 200; + tList.add( + GTUtility.trans("175", "Conduction Loss: ") + EnumChatFormatting.YELLOW + + conductor.getConductionLoss() + + EnumChatFormatting.RESET); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's EU conduction info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addIC2WrenchableInfo(EntityPlayer aPlayer, ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof ic2.api.tile.IWrenchable wrenchable) { + rEUAmount += 100; + tList.add( + GTUtility.trans("171", "Facing: ") + EnumChatFormatting.GREEN + + wrenchable.getFacing() + + EnumChatFormatting.RESET + + GTUtility.trans("172", " / Chance: ") + + EnumChatFormatting.YELLOW + + (wrenchable.getWrenchDropRate() * 100) + + EnumChatFormatting.RESET + + "%"); + tList.add( + wrenchable.wrenchCanRemove(aPlayer) + ? EnumChatFormatting.GREEN + GTUtility.trans("173", "You can remove this with a Wrench") + + EnumChatFormatting.RESET + : EnumChatFormatting.RED + GTUtility.trans("174", "You can NOT remove this with a Wrench") + + EnumChatFormatting.RESET); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's IC@ wrenchability.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addAlignmentInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof IAlignmentProvider alignmentProvider) { + final IAlignment tAlignment = alignmentProvider.getAlignment(); + if (tAlignment != null) { + rEUAmount += 100; + tList.add( + GTUtility.trans("219", "Extended Facing: ") + EnumChatFormatting.GREEN + + tAlignment.getExtendedFacing() + + EnumChatFormatting.RESET); + } + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this device's alignment info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + private static int addReactorInfo(ArrayList tList, TileEntity tTileEntity) { + int rEUAmount = 0; + try { + if (tTileEntity instanceof ic2.api.reactor.IReactor reactor) { + rEUAmount += 500; + tList.add( + GTUtility.trans("168", "Heat: ") + EnumChatFormatting.GREEN + + formatNumbers(reactor.getHeat()) + + EnumChatFormatting.RESET + + " / " + + EnumChatFormatting.YELLOW + + formatNumbers(reactor.getMaxHeat()) + + EnumChatFormatting.RESET); + tList.add( + GTUtility.trans("169", "HEM: ") + EnumChatFormatting.YELLOW + + reactor.getHeatEffectModifier() + + EnumChatFormatting.RESET); + } + } catch (Throwable e) { + tList.add(String.format("§cAn exception was thrown while fetching this reactor's info.§r")); + if (D1) e.printStackTrace(GTLog.err); + } + return rEUAmount; + } + + public static String trans(String aKey, String aEnglish) { + return GTLanguageManager.addStringLocalization("Interaction_DESCRIPTION_Index_" + aKey, aEnglish); + } + + public static String getTrans(String aKey) { + return GTLanguageManager.getTranslation("Interaction_DESCRIPTION_Index_" + aKey); + } + + /** + * @return an Array containing the X and the Y Coordinate of the clicked Point, with the top left Corner as Origin, + * like on the Texture Sheet. return values should always be between [0.0F and 0.99F]. + */ + // TODO: use clamp() + public static float[] getClickedFacingCoords(ForgeDirection side, float aX, float aY, float aZ) { + return switch (side) { + case DOWN -> new float[] { Math.min(0.99F, Math.max(0, 1 - aX)), Math.min(0.99F, Math.max(0, aZ)) }; + case UP -> new float[] { Math.min(0.99F, Math.max(0, aX)), Math.min(0.99F, Math.max(0, aZ)) }; + case NORTH -> new float[] { Math.min(0.99F, Math.max(0, 1 - aX)), Math.min(0.99F, Math.max(0, 1 - aY)) }; + case SOUTH -> new float[] { Math.min(0.99F, Math.max(0, aX)), Math.min(0.99F, Math.max(0, 1 - aY)) }; + case WEST -> new float[] { Math.min(0.99F, Math.max(0, aZ)), Math.min(0.99F, Math.max(0, 1 - aY)) }; + case EAST -> new float[] { Math.min(0.99F, Math.max(0, 1 - aZ)), Math.min(0.99F, Math.max(0, 1 - aY)) }; + default -> new float[] { 0.5F, 0.5F }; + }; + } + + /** + * This Function determines the direction a Block gets when being Wrenched. returns -1 if invalid. Even though that + * could never happen. + */ + public static ForgeDirection determineWrenchingSide(ForgeDirection side, float aX, float aY, float aZ) { + ForgeDirection tBack = side.getOpposite(); + switch (side) { + case DOWN, UP -> { + if (aX < 0.25) { + if (aZ < 0.25) return tBack; + if (aZ > 0.75) return tBack; + return WEST; + } + if (aX > 0.75) { + if (aZ < 0.25) return tBack; + if (aZ > 0.75) return tBack; + return EAST; + } + if (aZ < 0.25) return NORTH; + if (aZ > 0.75) return SOUTH; + return side; + } + case NORTH, SOUTH -> { + if (aX < 0.25) { + if (aY < 0.25) return tBack; + if (aY > 0.75) return tBack; + return WEST; + } + if (aX > 0.75) { + if (aY < 0.25) return tBack; + if (aY > 0.75) return tBack; + return EAST; + } + if (aY < 0.25) return DOWN; + if (aY > 0.75) return UP; + return side; + } + case WEST, EAST -> { + if (aZ < 0.25) { + if (aY < 0.25) return tBack; + if (aY > 0.75) return tBack; + return NORTH; + } + if (aZ > 0.75) { + if (aY < 0.25) return tBack; + if (aY > 0.75) return tBack; + return SOUTH; + } + if (aY < 0.25) return DOWN; + if (aY > 0.75) return UP; + return side; + } + } + return UNKNOWN; + } + + private static DecimalFormat getDecimalFormat() { + return decimalFormatters.computeIfAbsent(Locale.getDefault(Locale.Category.FORMAT), locale -> { + DecimalFormat numberFormat = new DecimalFormat(); // uses the necessary locale inside anyway + numberFormat.setGroupingUsed(true); + numberFormat.setMaximumFractionDigits(2); + numberFormat.setRoundingMode(RoundingMode.HALF_UP); + DecimalFormatSymbols decimalFormatSymbols = numberFormat.getDecimalFormatSymbols(); + decimalFormatSymbols.setGroupingSeparator(','); // Use sensible separator for best clarity. + numberFormat.setDecimalFormatSymbols(decimalFormatSymbols); + return numberFormat; + }); + } + + public static String formatNumbers(BigInteger aNumber) { + return getDecimalFormat().format(aNumber); + } + + public static String formatNumbers(long aNumber) { + return getDecimalFormat().format(aNumber); + } + + public static String formatNumbers(double aNumber) { + return getDecimalFormat().format(aNumber); + } + + /* + * Check if stack has enough items of given type and subtract from stack, if there's no creative or 111 stack. + */ + public static boolean consumeItems(EntityPlayer player, ItemStack stack, Item item, int count) { + if (stack != null && stack.getItem() == item && stack.stackSize >= count) { + if ((!player.capabilities.isCreativeMode) && (stack.stackSize != 111)) stack.stackSize -= count; + return true; + } + return false; + } + + /* + * Check if stack has enough items of given gregtech material (will be oredicted) and subtract from stack, if + * there's no creative or 111 stack. + */ + public static boolean consumeItems(EntityPlayer player, ItemStack stack, gregtech.api.enums.Materials mat, + int count) { + if (stack != null && GTOreDictUnificator.getItemData(stack).mMaterial.mMaterial == mat + && stack.stackSize >= count) { + if ((!player.capabilities.isCreativeMode) && (stack.stackSize != 111)) stack.stackSize -= count; + return true; + } + return false; + } + + public static ArrayList sortByValueToList(Map map) { + List> list = new LinkedList<>(map.entrySet()); + list.sort((o1, o2) -> o2.getValue() - o1.getValue()); + + ArrayList result = new ArrayList<>(); + for (Map.Entry e : list) result.add(e.getKey()); + return result; + } + + public static String joinListToString(List list) { + StringBuilder result = new StringBuilder(32); + for (String s : list) result.append(result.length() == 0 ? s : '|' + s); + return result.toString(); + } + + public static ItemStack getIntegratedCircuit(int config) { + return ItemList.Circuit_Integrated.getWithDamage(0, config); + } + + public static float getBlockHardnessAt(World aWorld, int aX, int aY, int aZ) { + return aWorld.getBlock(aX, aY, aZ) + .getBlockHardness(aWorld, aX, aY, aZ); + } + + public static FakePlayer getFakePlayer(IGregTechTileEntity aBaseMetaTileEntity) { + if (aBaseMetaTileEntity.getWorld() instanceof WorldServer) { + return FakePlayerFactory.get( + (WorldServer) aBaseMetaTileEntity.getWorld(), + new GameProfile(aBaseMetaTileEntity.getOwnerUuid(), aBaseMetaTileEntity.getOwnerName())); + } + return null; + } + + public static boolean eraseBlockByFakePlayer(FakePlayer aPlayer, int aX, int aY, int aZ, boolean isSimulate) { + if (aPlayer == null) return false; + World aWorld = aPlayer.worldObj; + BlockEvent.BreakEvent event = new BlockEvent.BreakEvent( + aX, + aY, + aZ, + aWorld, + aWorld.getBlock(aX, aY, aZ), + aWorld.getBlockMetadata(aX, aY, aZ), + aPlayer); + MinecraftForge.EVENT_BUS.post(event); + if (!event.isCanceled()) { + if (!isSimulate) return aWorld.setBlockToAir(aX, aY, aZ); + return true; + } + return false; + } + + public static boolean setBlockByFakePlayer(FakePlayer aPlayer, int aX, int aY, int aZ, Block aBlock, int aMeta, + boolean isSimulate) { + if (aPlayer == null) return false; + World aWorld = aPlayer.worldObj; + BlockEvent.PlaceEvent event = ForgeEventFactory + .onPlayerBlockPlace(aPlayer, new BlockSnapshot(aWorld, aX, aY, aZ, aBlock, aMeta), UNKNOWN); + if (!event.isCanceled()) { + if (!isSimulate) return aWorld.setBlock(aX, aY, aZ, aBlock, aMeta, 3); + return true; + } + return false; + } + + public static int findMatchingStackInList(List aStacks, ItemStack aStack) { + if (isStackInvalid(aStack)) return -1; + for (int i = 0, aStacksSize = aStacks.size(); i < aStacksSize; i++) { + ItemStack tStack = aStacks.get(i); + if (areStacksEqual(aStack, tStack)) return i; + } + return -1; + } + + public static Map convertItemListToMap(Collection itemStacks) { + Map result = new Object2LongOpenHashMap<>(); + for (ItemStack itemStack : itemStacks) { + if (itemStack != null && itemStack.stackSize > 0) { + GTUtility.ItemId itemId = GTUtility.ItemId.createNoCopy(itemStack); + result.merge(itemId, (long) itemStack.stackSize, Long::sum); + } + } + return result; + } + + public static Map convertFluidListToMap(Collection fluidStacks) { + Map result = new Reference2LongOpenHashMap<>(); + for (FluidStack fluidStack : fluidStacks) { + if (fluidStack != null && fluidStack.amount > 0) { + result.merge(fluidStack.getFluid(), (long) fluidStack.amount, Long::sum); + } + } + return result; + } + + /** + * @return Supplied collection that doesn't contain invalid MetaTileEntities + */ + public static , E extends MetaTileEntity> T filterValidMTEs(T metaTileEntities) { + metaTileEntities.removeIf(mte -> mte == null || !mte.isValid()); + return metaTileEntities; + } + + public static ForgeDirection getSideFromPlayerFacing(Entity player) { + if (player == null) return ForgeDirection.UNKNOWN; + if (player.rotationPitch >= 65) return ForgeDirection.UP; + if (player.rotationPitch <= -65) return ForgeDirection.DOWN; + final byte facing = COMPASS_DIRECTIONS[MathHelper.floor_double(0.5D + 4.0F * player.rotationYaw / 360.0F) + & 0x3]; + return ForgeDirection.getOrientation(facing); + } + + public static class ItemNBT { + + public static void setNBT(ItemStack aStack, NBTTagCompound aNBT) { + if (aNBT == null) { + aStack.setTagCompound(null); + return; + } + ArrayList tTagsToRemove = new ArrayList<>(); + for (String tKey : aNBT.func_150296_c()) { + NBTBase tValue = aNBT.getTag(tKey); + if (tValue == null || (tValue instanceof NBTPrimitive && ((NBTPrimitive) tValue).func_150291_c() == 0) + || (tValue instanceof NBTTagString && isStringInvalid(((NBTTagString) tValue).func_150285_a_()))) + tTagsToRemove.add(tKey); + } + for (String tKey : tTagsToRemove) aNBT.removeTag(tKey); + aStack.setTagCompound(aNBT.hasNoTags() ? null : aNBT); + } + + public static NBTTagCompound getNBT(ItemStack aStack) { + NBTTagCompound rNBT = aStack.getTagCompound(); + return rNBT == null ? new NBTTagCompound() : rNBT; + } + + public static void setPunchCardData(ItemStack aStack, String aPunchCardData) { + NBTTagCompound tNBT = getNBT(aStack); + tNBT.setString("GT.PunchCardData", aPunchCardData); + setNBT(aStack, tNBT); + } + + public static String getPunchCardData(ItemStack aStack) { + NBTTagCompound tNBT = getNBT(aStack); + return tNBT.getString("GT.PunchCardData"); + } + + public static void setLighterFuel(ItemStack aStack, long aFuel) { + NBTTagCompound tNBT = getNBT(aStack); + tNBT.setLong("GT.LighterFuel", aFuel); + setNBT(aStack, tNBT); + } + + public static long getLighterFuel(ItemStack aStack) { + NBTTagCompound tNBT = getNBT(aStack); + return tNBT.getLong("GT.LighterFuel"); + } + + public static void setMapID(ItemStack aStack, short aMapID) { + NBTTagCompound tNBT = getNBT(aStack); + tNBT.setShort("map_id", aMapID); + setNBT(aStack, tNBT); + } + + public static short getMapID(ItemStack aStack) { + NBTTagCompound tNBT = getNBT(aStack); + if (!tNBT.hasKey("map_id")) return -1; + return tNBT.getShort("map_id"); + } + + public static void setBookTitle(ItemStack aStack, String aTitle) { + NBTTagCompound tNBT = getNBT(aStack); + tNBT.setString("title", aTitle); + setNBT(aStack, tNBT); + } + + public static String getBookTitle(ItemStack aStack) { + NBTTagCompound tNBT = getNBT(aStack); + return tNBT.getString("title"); + } + + public static void setBookAuthor(ItemStack aStack, String aAuthor) { + NBTTagCompound tNBT = getNBT(aStack); + tNBT.setString("author", aAuthor); + setNBT(aStack, tNBT); + } + + public static String getBookAuthor(ItemStack aStack) { + NBTTagCompound tNBT = getNBT(aStack); + return tNBT.getString("author"); + } + + public static void setProspectionData(ItemStack aStack, int aX, int aY, int aZ, int aDim, FluidStack aFluid, + String... aOres) { + NBTTagCompound tNBT = getNBT(aStack); + StringBuilder tData = new StringBuilder(aX + "," + aY + "," + aZ + "," + aDim + ","); + if (aFluid != null) tData.append(aFluid.amount) + .append(",") + .append(aFluid.getLocalizedName()) + .append(","); // TODO + // CHECK + // IF + // THAT + // /5000 + // is + // needed + // (Not + // needed) + for (String tString : aOres) { + tData.append(tString) + .append(","); + } + tNBT.setString("prospection", tData.toString()); + setNBT(aStack, tNBT); + } + + public static void setAdvancedProspectionData(byte aTier, ItemStack aStack, int aX, short aY, int aZ, int aDim, + ArrayList aOils, ArrayList aOres, int aRadius) { + + setBookTitle(aStack, "Raw Prospection Data"); + + NBTTagCompound tNBT = getNBT(aStack); + + tNBT.setByte("prospection_tier", aTier); + tNBT.setString("prospection_pos", "Dim: " + aDim + "\nX: " + aX + " Y: " + aY + " Z: " + aZ); + + // ores + Collections.sort(aOres); + tNBT.setString("prospection_ores", joinListToString(aOres)); + + // oils + ArrayList tOilsTransformed = new ArrayList<>(aOils.size()); + for (String aStr : aOils) { + String[] aStats = aStr.split(","); + tOilsTransformed.add(aStats[0] + ": " + aStats[1] + "L " + aStats[2]); + } + + tNBT.setString("prospection_oils", joinListToString(tOilsTransformed)); + + String tOilsPosStr = "X: " + Math.floorDiv(aX, 16 * 8) * 16 * 8 + + " Z: " + + Math.floorDiv(aZ, 16 * 8) * 16 * 8 + + "\n"; + int xOff = aX - Math.floorDiv(aX, 16 * 8) * 16 * 8; + xOff = xOff / 16; + int xOffRemain = 7 - xOff; + + int zOff = aZ - Math.floorDiv(aZ, 16 * 8) * 16 * 8; + zOff = zOff / 16; + int zOffRemain = 7 - zOff; + + for (; zOff > 0; zOff--) { + tOilsPosStr = tOilsPosStr.concat("--------\n"); + } + for (; xOff > 0; xOff--) { + tOilsPosStr = tOilsPosStr.concat("-"); + } + + tOilsPosStr = tOilsPosStr.concat("P"); + + for (; xOffRemain > 0; xOffRemain--) { + tOilsPosStr = tOilsPosStr.concat("-"); + } + tOilsPosStr = tOilsPosStr.concat("\n"); + for (; zOffRemain > 0; zOffRemain--) { + tOilsPosStr = tOilsPosStr.concat("--------\n"); + } + tOilsPosStr = tOilsPosStr.concat( + " X: " + (Math.floorDiv(aX, 16 * 8) + 1) * 16 * 8 + + " Z: " + + (Math.floorDiv(aZ, 16 * 8) + 1) * 16 * 8); // +1 oilfied to find bottomright of [5] + + tNBT.setString("prospection_oils_pos", tOilsPosStr); + + tNBT.setString("prospection_radius", String.valueOf(aRadius)); + + setNBT(aStack, tNBT); + } + + public static void convertProspectionData(ItemStack aStack) { + NBTTagCompound tNBT = getNBT(aStack); + byte tTier = tNBT.getByte("prospection_tier"); + + if (tTier == 0) { // basic prospection data + String tData = tNBT.getString("prospection"); + String[] tDataArray = tData.split(","); + if (tDataArray.length > 6) { + tNBT.setString( + "author", + " Dim: " + tDataArray[3] + + "X: " + + tDataArray[0] + + " Y: " + + tDataArray[1] + + " Z: " + + tDataArray[2]); + NBTTagList tNBTList = new NBTTagList(); + StringBuilder tOres = new StringBuilder(" Prospected Ores: "); + for (int i = 6; tDataArray.length > i; i++) { + tOres.append(tDataArray[i]) + .append(" "); + } + tNBTList.appendTag( + new NBTTagString( + "Tier " + tTier + + " Prospecting Data From: X" + + tDataArray[0] + + " Z:" + + tDataArray[2] + + " Dim:" + + tDataArray[3] + + " Produces " + + tDataArray[4] + + "L " + + tDataArray[5] + + " " + + tOres)); + tNBT.setTag("pages", tNBTList); + } + } else { // advanced prospection data + String tPos = tNBT.getString("prospection_pos"); + String tRadius = tNBT.getString("prospection_radius"); + + String tOresStr = tNBT.getString("prospection_ores"); + String tOilsStr = tNBT.getString("prospection_oils"); + String tOilsPosStr = tNBT.getString("prospection_oils_pos"); + + String[] tOres = tOresStr.isEmpty() ? null : tOresStr.split("\\|"); + String[] tOils = tOilsStr.isEmpty() ? null : tOilsStr.split("\\|"); + + NBTTagList tNBTList = new NBTTagList(); + + String tPageText = "Prospector report\n" + tPos + + "\n\n" + + "Oils: " + + (tOils != null ? tOils.length : 0) + + "\n\n" + + "Ores within " + + tRadius + + " blocks\n\n" + + "Location is center of orevein\n\n" + + "Check NEI to confirm orevein type"; + tNBTList.appendTag(new NBTTagString(tPageText)); + + if (tOres != null) fillBookWithList(tNBTList, "Ores Found %s\n\n", "\n", 7, tOres); + + if (tOils != null) fillBookWithList(tNBTList, "Oils%s\n\n", "\n", 9, tOils); + + tPageText = """ + Oil notes + + Prospects from NW to SE 576 chunks(9 8x8 oilfields) + around and gives min-max amount + + [1][2][3] + [4][5][6] + [7][8][9] + + [5] - Prospector in this 8x8 area"""; + tNBTList.appendTag(new NBTTagString(tPageText)); + + tPageText = "Corners of [5] are \n" + tOilsPosStr + "\n" + "P - Prospector in 8x8 field"; + tNBTList.appendTag(new NBTTagString(tPageText)); + + tNBT.setString("author", tPos.replace("\n", " ")); + tNBT.setTag("pages", tNBTList); + } + setNBT(aStack, tNBT); + } + + public static void fillBookWithList(NBTTagList aBook, String aPageHeader, String aListDelimiter, + int aItemsPerPage, String[] list) { + String aPageFormatter = " %d/%d"; + int tTotalPages = list.length / aItemsPerPage + (list.length % aItemsPerPage > 0 ? 1 : 0); + int tPage = 0; + StringBuilder tPageText; + do { + tPageText = new StringBuilder(); + for (int i = tPage * aItemsPerPage; i < (tPage + 1) * aItemsPerPage && i < list.length; i += 1) + tPageText.append((tPageText.length() == 0) ? "" : aListDelimiter) + .append(list[i]); + + if (tPageText.length() > 0) { + String tPageCounter = tTotalPages > 1 ? String.format(aPageFormatter, tPage + 1, tTotalPages) : ""; + NBTTagString tPageTag = new NBTTagString(String.format(aPageHeader, tPageCounter) + tPageText); + aBook.appendTag(tPageTag); + } + + ++tPage; + } while (tPageText.length() > 0); + } + + public static void addEnchantment(ItemStack aStack, Enchantment aEnchantment, int aLevel) { + NBTTagCompound tNBT = getNBT(aStack), tEnchantmentTag; + if (!tNBT.hasKey("ench", 9)) tNBT.setTag("ench", new NBTTagList()); + NBTTagList tList = tNBT.getTagList("ench", 10); + + boolean temp = true; + + for (int i = 0; i < tList.tagCount(); i++) { + tEnchantmentTag = tList.getCompoundTagAt(i); + if (tEnchantmentTag.getShort("id") == aEnchantment.effectId) { + tEnchantmentTag.setShort("id", (short) aEnchantment.effectId); + tEnchantmentTag.setShort("lvl", (byte) aLevel); + temp = false; + break; + } + } + + if (temp) { + tEnchantmentTag = new NBTTagCompound(); + tEnchantmentTag.setShort("id", (short) aEnchantment.effectId); + tEnchantmentTag.setShort("lvl", (byte) aLevel); + tList.appendTag(tEnchantmentTag); + } + aStack.setTagCompound(tNBT); + } + } + + public static String toSubscript(long no) { + char[] chars = Long.toString(no) + .toCharArray(); + for (int i = 0; i < chars.length; i++) { + chars[i] += 8272; + } + return new String(chars); + } + + public static boolean isPartOfMaterials(ItemStack aStack, Materials aMaterials) { + return GTOreDictUnificator.getAssociation(aStack) != null + && GTOreDictUnificator.getAssociation(aStack).mMaterial.mMaterial.equals(aMaterials); + } + + public static boolean isPartOfOrePrefix(ItemStack aStack, OrePrefixes aPrefix) { + return GTOreDictUnificator.getAssociation(aStack) != null + && GTOreDictUnificator.getAssociation(aStack).mPrefix.equals(aPrefix); + } + + public static final ImmutableSet ORE_BLOCK_CLASSES = ImmutableSet.of( + "bartworks.system.material.BWMetaGeneratedOres", + "bartworks.system.material.BWMetaGeneratedSmallOres", + "gtPlusPlus.core.block.base.BlockBaseOre"); + + public static boolean isOre(Block aBlock, int aMeta) { + return (aBlock instanceof BlockOresAbstract) || isOre(new ItemStack(aBlock, 1, aMeta)) + || ORE_BLOCK_CLASSES.contains( + aBlock.getClass() + .getName()); + } + + public static boolean isOre(ItemStack aStack) { + int tItem = GTUtility.stackToInt(aStack); + if (sOreTable.containsKey(tItem)) { + return sOreTable.get(tItem); + } + for (int id : OreDictionary.getOreIDs(aStack)) { + if (OreDictionary.getOreName(id) + .startsWith("ore")) { + sOreTable.put(tItem, true); + return true; + } + } + sOreTable.put(tItem, false); + return false; + } + + /** + * Do NOT mutate the returned {@code ItemStack}! We return {@code ItemStack} instead of {@code Block} so that + * we can include metadata. + */ + public static ItemStack getCobbleForOre(Block ore, short metaData) { + // We need to convert small ores to regular ores because small ores don't have associated ItemData. + // We take the modulus of the metadata by 16000 because that is the magic number to convert small ores to + // regular ores. + // See: GT_TileEntity_Ores.java + ItemData association = GTOreDictUnificator + .getAssociation(new ItemStack(Item.getItemFromBlock(ore), 1, metaData % 16000)); + if (association != null) { + Supplier supplier = sOreToCobble.get(association.mPrefix); + if (supplier != null) { + return supplier.get(); + } + } + return new ItemStack(Blocks.cobblestone); + } + + public static Optional reverseShapelessRecipe(ItemStack output, Object... aRecipe) { + if (output == null) { + return Optional.empty(); + } + + List inputs = new ArrayList<>(); + + for (Object o : aRecipe) { + if (o instanceof ItemStack) { + ItemStack toAdd = ((ItemStack) o).copy(); + inputs.add(toAdd); + } else if (o instanceof String) { + ItemStack stack = GTOreDictUnificator.get(o, 1); + if (stack == null) { + Optional oStack = OreDictionary.getOres((String) o) + .stream() + .findAny(); + if (oStack.isPresent()) { + ItemStack copy = oStack.get() + .copy(); + inputs.add(copy); + } + } else { + ItemStack copy = stack.copy(); + inputs.add(copy); + } + } else if (o instanceof Item) inputs.add(new ItemStack((Item) o)); + else if (o instanceof Block) inputs.add(new ItemStack((Block) o)); + else throw new IllegalStateException("A Recipe contains an invalid input! Output: " + output); + } + + inputs.removeIf(x -> x.getItem() instanceof MetaGeneratedTool); + + return Optional.of( + new GTRecipe( + false, + new ItemStack[] { output }, + inputs.toArray(new ItemStack[0]), + null, + null, + null, + null, + 300, + 30, + 0)); + } + + public static Optional reverseShapedRecipe(ItemStack output, Object... aRecipe) { + if (output == null) { + return Optional.empty(); + } + + Map recipeAsMap = new HashMap<>(); + Map ingridients = new HashMap<>(); + Map amounts = new HashMap<>(); + boolean startFound = false; + for (int i = 0, aRecipeLength = aRecipe.length; i < aRecipeLength; i++) { + Object o = aRecipe[i]; + if (!startFound) { + if (o instanceof String) { + for (Character c : ((String) o).toCharArray()) amounts.merge(c, 1, (a, b) -> ++a); + } else if (o instanceof Character) startFound = true; + } else if (!(o instanceof Character)) ingridients.put((Character) aRecipe[i - 1], o); + } + for (Map.Entry characterObjectEntry : ingridients.entrySet()) { + for (Map.Entry characterIntegerEntry : amounts.entrySet()) { + if (characterObjectEntry.getKey() != characterIntegerEntry.getKey()) continue; + recipeAsMap.put(characterObjectEntry.getValue(), characterIntegerEntry.getValue()); + } + } + List inputs = new ArrayList<>(); + + for (Map.Entry o : recipeAsMap.entrySet()) { + final int amount = o.getValue(); + if (o.getKey() instanceof ItemStack) { + ItemStack toAdd = ((ItemStack) o.getKey()).copy(); + toAdd.stackSize = amount; + inputs.add(toAdd); + } else if (o.getKey() instanceof String dictName) { + // Do not register tools dictName in inputs + if (ToolDictNames.contains(dictName)) continue; + ItemStack stack = GTOreDictUnificator.get(dictName, null, amount, false, true); + if (stack == null) { + Optional oStack = OreDictionary.getOres(dictName) + .stream() + .findAny(); + if (oStack.isPresent()) { + ItemStack copy = oStack.get() + .copy(); + copy.stackSize = amount; + inputs.add(copy); + } + } else { + ItemStack copy = stack.copy(); + copy.stackSize = amount; + inputs.add(copy); + } + } else if (o.getKey() instanceof Item) inputs.add(new ItemStack((Item) o.getKey(), amount)); + else if (o.getKey() instanceof Block) inputs.add(new ItemStack((Block) o.getKey(), amount)); + else throw new IllegalStateException("A Recipe contains an invalid input! Output: " + output); + } + + // Remove tools from inputs in case a recipe has one as a direct Item or ItemStack reference + inputs.removeIf(x -> x.getItem() instanceof MetaGeneratedTool); + + return Optional.of( + new GTRecipe( + false, + new ItemStack[] { output }, + inputs.toArray(new ItemStack[0]), + null, + null, + null, + null, + 300, + 30, + 0)); + } + + /** + * Add an itemstack to player inventory, or drop on ground if full. Can be called on client but it probably won't + * work very well. + */ + public static void addItemToPlayerInventory(EntityPlayer aPlayer, ItemStack aStack) { + if (isStackInvalid(aStack)) return; + if (!aPlayer.inventory.addItemStackToInventory(aStack) && !aPlayer.worldObj.isRemote) { + EntityItem dropItem = aPlayer.entityDropItem(aStack, 0); + dropItem.delayBeforeCanPickup = 0; + } + } + + public static long getNonnullElementCount(Object[] tArray) { + return Arrays.stream(tArray) + .filter(Objects::nonNull) + .count(); + } + + public static int clamp(int val, int lo, int hi) { + return MathHelper.clamp_int(val, lo, hi); + } + + public static int ceilDiv(int lhs, int rhs) { + return (lhs + rhs - 1) / rhs; + } + + public static long ceilDiv(long lhs, long rhs) { + return (lhs + rhs - 1) / rhs; + } + + /** + * Hash an item stack for the purpose of storing hash across launches + */ + public static int persistentHash(ItemStack aStack, boolean aUseStackSize, boolean aUseNBT) { + if (aStack == null) return 0; + int result = Objects.hashCode(GameRegistry.findUniqueIdentifierFor(aStack.getItem())); + result = result * 31 + Items.feather.getDamage(aStack); + + if (aUseStackSize) result = result * 31 + aStack.stackSize; + if (aUseNBT) result = result * 31 + Objects.hashCode(aStack.stackTagCompound); + return result; + } + + /** + * Hash an item stack for the purpose of storing hash across launches + */ + public static int persistentHash(FluidStack aStack, boolean aUseStackSize, boolean aUseNBT) { + if (aStack == null) return 0; + int base = Objects.hashCode( + aStack.getFluid() + .getName()); + + if (aUseStackSize) base = base * 31 + aStack.amount; + if (aUseNBT) base = base * 31 + Objects.hashCode(aStack.tag); + return base; + } + + public static int getCasingTextureIndex(Block block, int meta) { + if (block instanceof IHasIndexedTexture) return ((IHasIndexedTexture) block).getTextureIndex(meta); + return Textures.BlockIcons.ERROR_TEXTURE_INDEX; + } + + public static boolean isCellEmpty(ItemStack itemStack) { + if (itemStack == null) return false; + ItemStack tStack = ItemList.Cell_Empty.get(1); + tStack.stackSize = itemStack.stackSize; + return GTUtility.areStacksEqual(itemStack, tStack); + } + + /** + * Convert a cell to fluid. If given itemstack does not contain any fluid, return null. Will correctly multiple + * output fluid amount if input stack size is greater than 1. + */ + public static FluidStack convertCellToFluid(ItemStack itemStack) { + if (itemStack == null) return null; + if (getFluidForFilledItem(itemStack, true) != null) { + FluidStack fluidStack = getFluidForFilledItem(itemStack, true); + if (fluidStack != null) fluidStack.amount = fluidStack.amount * itemStack.stackSize; + return fluidStack; + } + return null; + } + + public static boolean isAnyIntegratedCircuit(ItemStack itemStack) { + if (itemStack == null) return false; + return itemStack.getItem() == ItemList.Circuit_Integrated.getItem() && 0 <= itemStack.getItemDamage() + && itemStack.getItemDamage() < 25; + } + + public static byte convertRatioToRedstone(long used, long max, int threshold, boolean inverted) { + byte signal; + if (used <= 0) { // Empty + signal = 0; + } else if (used >= max) { // Full + signal = 15; + } else { // Range 1-14 + signal = (byte) (1 + (14 * used) / max); + } + + if (inverted) { + signal = (byte) (15 - signal); + } + + if (threshold > 0) { + if (inverted && used >= threshold) { + return 0; + } else if (!inverted && used < threshold) { + return 0; + } + } + + return signal; + } + + public static ItemStack getNaniteAsCatalyst(Materials material) { + ItemStack aItem = material.getNanite(1); + return new ItemStack(aItem.getItem(), 0, aItem.getItemDamage()); + } + + public static Stream streamCompounds(NBTTagList list) { + if (list == null) return Stream.empty(); + return IntStream.range(0, list.tagCount()) + .mapToObj(list::getCompoundTagAt); + } + + public static boolean equals(ItemStack[] a, ItemStack[] b) { + // because stupid mojang didn't override equals for us + if (a == null && b == null) return true; + if ((a == null) != (b == null)) return false; + if (a.length != b.length) return false; + for (int i = 0; i < a.length; i++) { + if (!areStacksEqual(a[i], b[i], false)) return false; + } + return true; + } + + /** + * Guava ImmutableMap variant of Collectors.toMap. Optimized for serial streams. + */ + public static Collector> toImmutableMapSerial( + Function keyMapper, Function valueMapper) { + // petty type inference cannot work out the correct type parameter + return Collector., ImmutableMap>of( + ImmutableMap::builder, + (b, t) -> b.put(keyMapper.apply(t), valueMapper.apply(t)), + (b1, b2) -> b1.putAll(b2.build()), + ImmutableMap.Builder::build); + } + + public static boolean isArrayEmptyOrNull(Object[] arr) { + return arr == null || arr.length == 0; + } + + public static boolean isArrayOfLength(Object[] arr, int expectedLength) { + return arr != null && arr.length == expectedLength; + } + + @SafeVarargs + public static Collection concat(Collection... colls) { + return concat(Arrays.asList(colls)); + } + + public static Collection concat(Collection> colls) { + return new ConcatCollection<>(colls); + } + + private static class ConcatCollection extends AbstractCollection { + + private final Collection> colls; + private final int size; + + public ConcatCollection(Collection> lists) { + Collection> colls1 = null; + for (Collection list : lists) { + if (list == null || list.isEmpty()) { + colls1 = lists.stream() + .filter(c -> c != null && !c.isEmpty()) + .collect(Collectors.toList()); + break; + } + } + if (colls1 == null) colls1 = lists; + colls = colls1; + int sum = 0; + for (Collection list : colls) { + sum += list.size(); + } + size = sum; + } + + @Nonnull + @Override + public Iterator iterator() { + return colls.stream() + .flatMap(Collection::stream) + .iterator(); + } + + @Override + public int size() { + return size; + } + } + + @AutoValue + public abstract static class ItemId { + + public static ItemId create(NBTTagCompound tag) { + return new AutoValue_GTUtility_ItemId( + Item.getItemById(tag.getShort("item")), + tag.getShort("meta"), + tag.hasKey("tag", Constants.NBT.TAG_COMPOUND) ? tag.getCompoundTag("tag") : null); + } + + /** + * This method copies NBT, as it is mutable. + */ + public static ItemId create(ItemStack itemStack) { + NBTTagCompound nbt = itemStack.getTagCompound(); + if (nbt != null) { + nbt = (NBTTagCompound) nbt.copy(); + } + + return new AutoValue_GTUtility_ItemId(itemStack.getItem(), Items.feather.getDamage(itemStack), nbt); + } + + /** + * This method copies NBT, as it is mutable. + */ + public static ItemId create(Item item, int metaData, @Nullable NBTTagCompound nbt) { + if (nbt != null) { + nbt = (NBTTagCompound) nbt.copy(); + } + return new AutoValue_GTUtility_ItemId(item, metaData, nbt); + } + + /** + * This method stores metadata as wildcard and NBT as null. + */ + public static ItemId createAsWildcard(ItemStack itemStack) { + return new AutoValue_GTUtility_ItemId(itemStack.getItem(), W, null); + } + + /** + * This method stores NBT as null. + */ + public static ItemId createWithoutNBT(ItemStack itemStack) { + return new AutoValue_GTUtility_ItemId(itemStack.getItem(), Items.feather.getDamage(itemStack), null); + } + + /** + * This method does not copy NBT in order to save time. Make sure not to mutate it! + */ + public static ItemId createNoCopy(ItemStack itemStack) { + return new AutoValue_GTUtility_ItemId( + itemStack.getItem(), + Items.feather.getDamage(itemStack), + itemStack.getTagCompound()); + } + + /** + * This method does not copy NBT in order to save time. Make sure not to mutate it! + */ + public static ItemId createNoCopy(Item item, int metaData, @Nullable NBTTagCompound nbt) { + return new AutoValue_GTUtility_ItemId(item, metaData, nbt); + } + + protected abstract Item item(); + + protected abstract int metaData(); + + @Nullable + protected abstract NBTTagCompound nbt(); + + public NBTTagCompound writeToNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setShort("item", (short) Item.getIdFromItem(item())); + tag.setShort("meta", (short) metaData()); + if (nbt() != null) tag.setTag("tag", nbt()); + return tag; + } + + @Nonnull + public ItemStack getItemStack() { + ItemStack itemStack = new ItemStack(item(), 1, metaData()); + itemStack.setTagCompound(nbt()); + return itemStack; + } + } + + public static int getPlasmaFuelValueInEUPerLiterFromMaterial(Materials material) { + return getPlasmaFuelValueInEUPerLiterFromFluid(material.getPlasma(1)); + } + + public static int getPlasmaFuelValueInEUPerLiterFromFluid(FluidStack aLiquid) { + if (aLiquid == null) return 0; + GTRecipe tFuel = RecipeMaps.plasmaFuels.getBackend() + .findFuel(aLiquid); + if (tFuel != null) return tFuel.mSpecialValue; + return 0; + } + + public static MovingObjectPosition getPlayerLookingTarget(EntityPlayer viewpoint) { + double reachDistance = viewpoint instanceof EntityPlayerMP mp ? mp.theItemInWorldManager.getBlockReachDistance() + : getClientReachDistance(); + Vec3 posVec = Vec3.createVectorHelper( + viewpoint.posX, + viewpoint.posY + (viewpoint.getEyeHeight() - viewpoint.getDefaultEyeHeight()), + viewpoint.posZ); + Vec3 lookVec = viewpoint.getLook(0); + Vec3 modifiedPosVec = posVec + .addVector(lookVec.xCoord * reachDistance, lookVec.yCoord * reachDistance, lookVec.zCoord * reachDistance); + + return viewpoint.worldObj.rayTraceBlocks(posVec, modifiedPosVec); + } + + public static float getClientReachDistance() { + return Minecraft.getMinecraft().playerController.getBlockReachDistance(); + } +} diff --git a/src/main/java/gregtech/api/util/GTUtilityClient.java b/src/main/java/gregtech/api/util/GTUtilityClient.java new file mode 100644 index 0000000000..a6039e10d3 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTUtilityClient.java @@ -0,0 +1,52 @@ +package gregtech.api.util; + +import java.lang.reflect.Field; +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; + +import com.google.common.collect.Lists; + +import cpw.mods.fml.relauncher.ReflectionHelper; + +public class GTUtilityClient { + + private static final Field isDrawingField = ReflectionHelper + .findField(Tessellator.class, "isDrawing", "field_78415_z"); + + public static boolean isDrawing(Tessellator tess) { + try { + return isDrawingField.getBoolean(tess); + } catch (IllegalAccessException e) { + e.printStackTrace(); + return false; + } + } + + public static List getTooltip(ItemStack aStack, boolean aGuiStyle) { + try { + List tooltip = aStack.getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips); + if (aGuiStyle) { + tooltip.set( + 0, + (aStack.getRarity() == null ? EnumRarity.common : aStack.getRarity()).rarityColor + tooltip.get(0)); + for (int i = 1; i < tooltip.size(); i++) { + tooltip.set(i, EnumChatFormatting.GRAY + tooltip.get(i)); + } + } + return tooltip; + } catch (RuntimeException e) { + // Collections.singletonList() can not be added to. we don't want that + if (aGuiStyle) return Lists.newArrayList( + (aStack.getRarity() == null ? EnumRarity.common : aStack.getRarity()).rarityColor + + aStack.getDisplayName()); + return Lists.newArrayList(aStack.getDisplayName()); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTWaila.java b/src/main/java/gregtech/api/util/GTWaila.java new file mode 100644 index 0000000000..a52dd2e459 --- /dev/null +++ b/src/main/java/gregtech/api/util/GTWaila.java @@ -0,0 +1,23 @@ +package gregtech.api.util; + +public abstract class GTWaila { + + public static String getMachineProgressString(boolean isActive, int maxProgresstime, int progresstime) { + return getMachineProgressString(isActive, (long) maxProgresstime, (long) progresstime); + } + + public static String getMachineProgressString(boolean isActive, long maxProgresstime, long progresstime) { + + if (!isActive) return "Idle"; + + StringBuilder ret = new StringBuilder("In progress: ") + .append(String.format("%,.2f", (double) progresstime / 20)) + .append("s / ") + .append(String.format("%,.2f", (double) maxProgresstime / 20)) + .append("s (") + .append(GTUtility.formatNumbers((Math.round((double) progresstime / maxProgresstime * 1000) / 10.0))) + .append("%)"); + + return ret.toString(); + } +} diff --git a/src/main/java/gregtech/api/util/GT_ApiaryModifier.java b/src/main/java/gregtech/api/util/GT_ApiaryModifier.java deleted file mode 100644 index 4a89345670..0000000000 --- a/src/main/java/gregtech/api/util/GT_ApiaryModifier.java +++ /dev/null @@ -1,24 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.world.biome.BiomeGenBase; - -public class GT_ApiaryModifier { - - public float territory = 1f; - public float mutation = 1f; - public float lifespan = 1f; - public float production = 2f; - public float flowering = 1f; - public float geneticDecay = 1f; - public boolean isSealed = false; - public boolean isSelfLighted = false; - public boolean isSelfUnlighted = false; - public boolean isSunlightSimulated = false; - public boolean isAutomated = false; - public boolean isCollectingPollen = false; - public BiomeGenBase biomeOverride = null; - public float energy = 1f; - public float temperature = 0f; - public float humidity = 0f; - public int maxSpeed = 0; -} diff --git a/src/main/java/gregtech/api/util/GT_ApiaryUpgrade.java b/src/main/java/gregtech/api/util/GT_ApiaryUpgrade.java deleted file mode 100644 index 9ed7a56e1e..0000000000 --- a/src/main/java/gregtech/api/util/GT_ApiaryUpgrade.java +++ /dev/null @@ -1,225 +0,0 @@ -package gregtech.api.util; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -import net.minecraft.item.ItemStack; -import net.minecraft.world.biome.BiomeGenBase; - -import gregtech.api.enums.OrePrefixes; -import gregtech.common.items.GT_MetaGenerated_Item_03; - -/** - * Actual items are defined in {@link GT_MetaGenerated_Item_03} - */ -public enum GT_ApiaryUpgrade { - - speed1(UNIQUE_INDEX.SPEED_UPGRADE, 32200, 1, (mods, n) -> mods.maxSpeed = 1), - speed2(UNIQUE_INDEX.SPEED_UPGRADE, 32201, 1, (mods, n) -> mods.maxSpeed = 2), - speed3(UNIQUE_INDEX.SPEED_UPGRADE, 32202, 1, (mods, n) -> mods.maxSpeed = 3), - speed4(UNIQUE_INDEX.SPEED_UPGRADE, 32203, 1, (mods, n) -> mods.maxSpeed = 4), - speed5(UNIQUE_INDEX.SPEED_UPGRADE, 32204, 1, (mods, n) -> mods.maxSpeed = 5), - speed6(UNIQUE_INDEX.SPEED_UPGRADE, 32205, 1, (mods, n) -> mods.maxSpeed = 6), - speed7(UNIQUE_INDEX.SPEED_UPGRADE, 32206, 1, (mods, n) -> mods.maxSpeed = 7), - speed8(UNIQUE_INDEX.SPEED_UPGRADE, 32207, 1, (mods, n) -> mods.maxSpeed = 8), - speed8upgraded(UNIQUE_INDEX.SPEED_UPGRADE, 32208, 1, (mods, n) -> { - mods.maxSpeed = 8; - mods.production = 17.19926784f; - mods.energy *= 14.75; - }), - production(UNIQUE_INDEX.PRODUCTION_UPGRADE, 32209, 8, (mods, n) -> { - mods.production = 4.f * (float) Math.pow(1.2d, n); - mods.energy *= Math.pow(1.4f, n); - }), - plains(UNIQUE_INDEX.PLAINS_UPGRADE, 32210, 1, (mods, n) -> { - mods.biomeOverride = BiomeGenBase.plains; - mods.energy *= 1.2f; - }), - light(UNIQUE_INDEX.LIGHT_UPGRADE, 32211, 1, (mods, n) -> { - mods.isSelfLighted = true; - mods.energy *= 1.05f; - }), - flowering(UNIQUE_INDEX.FLOWERING_UPGRADE, 32212, 8, (mods, n) -> { - mods.flowering *= Math.pow(1.2f, n); - mods.energy *= Math.pow(1.1f, n); - }), - winter(UNIQUE_INDEX.WINTER_UPGRADE, 32213, 1, (mods, n) -> { - mods.biomeOverride = BiomeGenBase.taiga; - mods.energy *= 1.5f; - }), - dryer(UNIQUE_INDEX.DRYER_UPGRADE, 32214, 16, (mods, n) -> { - mods.humidity -= 0.125f * n; - mods.energy *= Math.pow(1.025f, n); - }), - automation(UNIQUE_INDEX.AUTOMATION_UPGRADE, 32215, 1, (mods, n) -> { - mods.isAutomated = true; - mods.energy *= 1.1f; - }), - humidifier(UNIQUE_INDEX.HUMIDIFIER_UPGRADE, 32216, 16, (mods, n) -> { - mods.humidity += 0.125f * n; - mods.energy *= Math.pow(1.05f, n); - }), - hell(UNIQUE_INDEX.HELL_UPGRADE, 32217, 1, (mods, n) -> { - mods.biomeOverride = BiomeGenBase.hell; - mods.energy *= 1.5f; - }), - pollen(UNIQUE_INDEX.POLLEN_UPGRADE, 32218, 1, (mods, n) -> { - mods.flowering = 0f; - mods.energy *= 1.3f; - }), - desert(UNIQUE_INDEX.DESERT_UPGRADE, 32219, 1, (mods, n) -> { - mods.biomeOverride = BiomeGenBase.desert; - mods.energy *= 1.2f; - }), - cooler(UNIQUE_INDEX.COOLER_UPGRADE, 32220, 16, (mods, n) -> { - mods.temperature -= 0.125f * n; - mods.energy *= Math.pow(1.025f, n); - }), - lifespan(UNIQUE_INDEX.LIFESPAN_UPGRADE, 32221, 4, (mods, n) -> { - mods.lifespan /= Math.pow(1.5f, n); - mods.energy *= Math.pow(1.05f, n); - }), - seal(UNIQUE_INDEX.SEAL_UPGRADE, 32222, 1, (mods, n) -> { - mods.isSealed = true; - mods.energy *= 1.05f; - }), - stabilizer(UNIQUE_INDEX.STABILIZER_UPGRADE, 32223, 1, (mods, n) -> { - mods.geneticDecay = 0f; - mods.energy *= 2.50f; - }), - jungle(UNIQUE_INDEX.JUNGLE_UPGRADE, 32224, 1, (mods, n) -> { - mods.biomeOverride = BiomeGenBase.jungle; - mods.energy *= 1.20f; - }), - territory(UNIQUE_INDEX.TERRITORY_UPGRADE, 32225, 4, (mods, n) -> { - mods.territory *= Math.pow(1.5f, n); - mods.energy *= Math.pow(1.05f, n); - }), - ocean(UNIQUE_INDEX.OCEAN_UPGRADE, 32226, 1, (mods, n) -> { - mods.biomeOverride = BiomeGenBase.ocean; - mods.energy *= 1.20f; - }), - sky(UNIQUE_INDEX.SKY_UPGRADE, 32227, 1, (mods, n) -> { - mods.isSunlightSimulated = true; - mods.energy *= 1.05f; - }), - heater(UNIQUE_INDEX.HEATER_UPGRADE, 32228, 16, (mods, n) -> { - mods.temperature += 0.125f * n; - mods.energy *= Math.pow(1.025f, n); - }), - sieve(UNIQUE_INDEX.SIEVE_UPGRADE, 32229, 1, (mods, n) -> { - mods.isCollectingPollen = true; - mods.energy *= 1.05f; - }), - unlight(UNIQUE_INDEX.LIGHT_UPGRADE, 32231, 1, (mods, n) -> { - mods.isSelfUnlighted = true; - mods.energy *= 1.05f; - }),; - - private enum UNIQUE_INDEX { - - SPEED_UPGRADE, - PRODUCTION_UPGRADE, - PLAINS_UPGRADE, - LIGHT_UPGRADE, // also unlight - FLOWERING_UPGRADE, - WINTER_UPGRADE, - DRYER_UPGRADE, - AUTOMATION_UPGRADE, - HUMIDIFIER_UPGRADE, - HELL_UPGRADE, - POLLEN_UPGRADE, - DESERT_UPGRADE, - COOLER_UPGRADE, - LIFESPAN_UPGRADE, - SEAL_UPGRADE, - STABILIZER_UPGRADE, - JUNGLE_UPGRADE, - TERRITORY_UPGRADE, - OCEAN_UPGRADE, - SKY_UPGRADE, - HEATER_UPGRADE, - SIEVE_UPGRADE,; - - void apply(Consumer fn) { - UNIQUE_UPGRADE_LIST.get(this) - .forEach(fn); - } - } - - private static final EnumMap> UNIQUE_UPGRADE_LIST = new EnumMap<>( - UNIQUE_INDEX.class); - - private int meta = 0; - private int maxnumber = 1; - - private final GT_Utility.ItemId id; - private final UNIQUE_INDEX unique_index; - private final BiConsumer applier; - - private final HashSet blacklistedUpgrades = new HashSet<>(); - - GT_ApiaryUpgrade(UNIQUE_INDEX unique_index, int meta, int maxnumber, - BiConsumer applier) { - this.unique_index = unique_index; - this.meta = meta; - this.maxnumber = maxnumber; - this.applier = applier; - this.id = GT_Utility.ItemId.createNoCopy(get(1)); - } - - private void setup_static_variables() { - quickLookup.put(this.meta, this); - ArrayList un = UNIQUE_UPGRADE_LIST.get(this.unique_index); - if (un != null) un.forEach((u) -> { - u.blacklistedUpgrades.add(this.id); - this.blacklistedUpgrades.add(u.id); - }); - else { - un = new ArrayList<>(1); - UNIQUE_UPGRADE_LIST.put(this.unique_index, un); - } - un.add(this); - } - - public static GT_ApiaryUpgrade getUpgrade(ItemStack s) { - if (s == null) return null; - if (!isUpgrade(s)) return null; - return quickLookup.get(s.getItemDamage()); - } - - public boolean isAllowedToWorkWith(ItemStack s) { - GT_Utility.ItemId id = GT_Utility.ItemId.createNoCopy(s); - return !blacklistedUpgrades.contains(id); - } - - public int getMaxNumber() { - return maxnumber; - } - - public void applyModifiers(GT_ApiaryModifier mods, ItemStack stack) { - if (applier != null) applier.accept(mods, stack.stackSize); - } - - public ItemStack get(int count) { - return new ItemStack(GT_MetaGenerated_Item_03.INSTANCE, count, meta); - } - - public static boolean isUpgrade(ItemStack s) { - return OrePrefixes.apiaryUpgrade.contains(s); - } - - private static final HashMap quickLookup = new HashMap<>(); - - static { - EnumSet.allOf(GT_ApiaryUpgrade.class) - .forEach(GT_ApiaryUpgrade::setup_static_variables); - speed8upgraded.blacklistedUpgrades.add(production.id); - production.blacklistedUpgrades.add(speed8upgraded.id); - } -} diff --git a/src/main/java/gregtech/api/util/GT_AssemblyLineUtils.java b/src/main/java/gregtech/api/util/GT_AssemblyLineUtils.java deleted file mode 100644 index dbe0ff2c40..0000000000 --- a/src/main/java/gregtech/api/util/GT_AssemblyLineUtils.java +++ /dev/null @@ -1,559 +0,0 @@ -package gregtech.api.util; - -import static gregtech.GT_Mod.GT_FML_LOGGER; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Objects; - -import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; -import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.fluids.FluidStack; - -import cpw.mods.fml.common.FMLCommonHandler; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.ItemList; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.util.GT_Recipe.GT_Recipe_AssemblyLine; - -public class GT_AssemblyLineUtils { - - /** - * A cache of Recipes using the Output as Key. - */ - private static final HashMap sRecipeCacheByOutput = new HashMap<>(); - /** - * A cache of Recipes using the Recipe Hash String as Key. - */ - private static final HashMap sRecipeCacheByRecipeHash = new HashMap<>(); - - /** - * Checks the DataStick for deprecated/invalid recipes, updating them as required. - * - * @param aDataStick - The DataStick to process - * @return Is this DataStick now valid with a current recipe? - */ - public static GT_Recipe_AssemblyLine processDataStick(ItemStack aDataStick) { - if (!isItemDataStick(aDataStick)) { - return null; - } - if (doesDataStickNeedUpdate(aDataStick)) { - ItemStack aStickOutput = getDataStickOutput(aDataStick); - if (aStickOutput != null) { - GT_Recipe_AssemblyLine aIntendedRecipe = findAssemblyLineRecipeByOutput(aStickOutput); - if (aIntendedRecipe != null && setAssemblyLineRecipeOnDataStick(aDataStick, aIntendedRecipe)) - return aIntendedRecipe; - } - } - return null; - } - - /** - * Finds an Assembly Line recipe from a DataStick. - * - * @param aDataStick - The DataStick to check. - * @return The GT_Recipe_AssemblyLine recipe contained on the DataStick, if any. - */ - public static GT_Recipe_AssemblyLine findAssemblyLineRecipeFromDataStick(ItemStack aDataStick) { - return findAssemblyLineRecipeFromDataStick(aDataStick, false).getRecipe(); - } - - /** - * Finds an Assembly Line recipe from a DataStick. - * - * @param aDataStick - The DataStick to check. - * @param aReturnBuiltRecipe - Do we return a GT_Recipe_AssemblyLine built from the data on the Data Stick instead - * of searching the Recipe Map? - * @return The GT_Recipe_AssemblyLine recipe contained on the DataStick, if any. - */ - @Nonnull - public static LookupResult findAssemblyLineRecipeFromDataStick(ItemStack aDataStick, boolean aReturnBuiltRecipe) { - if (!isItemDataStick(aDataStick) || !doesDataStickHaveOutput(aDataStick)) { - return LookupResultType.INVALID_STICK.getResult(); - } - List aInputs = new ArrayList<>(16); - ItemStack aOutput = getDataStickOutput(aDataStick); - List> mOreDictAlt = new ArrayList<>(16); - List aFluidInputs = new ArrayList<>(4); - - NBTTagCompound aTag = aDataStick.getTagCompound(); - if (aTag == null) { - return LookupResultType.INVALID_STICK.getResult(); - } - - // Get From Cache - if (doesDataStickHaveRecipeHash(aDataStick)) { - GT_Recipe_AssemblyLine aRecipeFromCache = sRecipeCacheByRecipeHash.get(getHashFromDataStack(aDataStick)); - if (aRecipeFromCache != null && GT_Utility.areStacksEqual(aOutput, aRecipeFromCache.mOutput)) { - return LookupResultType.VALID_STACK_AND_VALID_HASH.getResult(aRecipeFromCache); - } // else: no cache, or the old recipe run into a hash collision with a different new recipe - } - - for (int i = 0; i < 16; i++) { - int count = aTag.getInteger("a" + i); - if (!aTag.hasKey("" + i) && count <= 0) { - continue; - } - - List tAltCurrent = new ArrayList<>(); - for (int j = 0; j < count; j++) { - ItemStack tLoaded = GT_Utility.loadItem(aTag, "a" + i + ":" + j); - if (tLoaded == null) { - continue; - } - tAltCurrent.add(tLoaded); - if (GT_Values.D1) { - GT_FML_LOGGER.info("Item Alt " + i + " : " + tLoaded.getUnlocalizedName()); - } - } - mOreDictAlt.add(tAltCurrent); - ItemStack tLoaded = GT_Utility.loadItem(aTag, "" + i); - if (tLoaded == null) { - continue; - } - aInputs.add(tLoaded); - if (GT_Values.D1) { - GT_FML_LOGGER.info("Item " + i + " : " + tLoaded.getUnlocalizedName()); - } - } - - if (GT_Values.D1) { - GT_FML_LOGGER.info("All Items done, start fluid check"); - } - for (int i = 0; i < 4; i++) { - if (!aTag.hasKey("f" + i)) continue; - FluidStack tLoaded = GT_Utility.loadFluid(aTag, "f" + i); - if (tLoaded == null) continue; - aFluidInputs.add(tLoaded); - if (GT_Values.D1) { - GT_FML_LOGGER.info("Fluid " + i + " " + tLoaded.getUnlocalizedName()); - } - } - if (!aTag.hasKey("output") || !aTag.hasKey("time") - || aTag.getInteger("time") <= 0 - || !aTag.hasKey("eu") - || !GT_Utility.isStackValid(aOutput)) { - return LookupResultType.INVALID_STICK.getResult(); - } - if (GT_Values.D1) { - GT_FML_LOGGER.info("Found Data Stick recipe"); - } - - int aTime = aTag.getInteger("time"); - int aEU = aTag.getInteger("eu"); - - // Try build a recipe instance - if (aReturnBuiltRecipe) { - return LookupResultType.VALID_STACK_AND_VALID_HASH.getResult( - new GT_Recipe_AssemblyLine( - null, - 0, - aInputs.toArray(new ItemStack[0]), - aFluidInputs.toArray(new FluidStack[0]), - aOutput, - aTime, - aEU)); - } - - for (GT_Recipe_AssemblyLine aRecipe : GT_Recipe.GT_Recipe_AssemblyLine.sAssemblylineRecipes) { - if (aRecipe.mEUt != aEU || aRecipe.mDuration != aTime) continue; - if (!GT_Utility.areStacksEqual(aOutput, aRecipe.mOutput, true)) continue; - if (!GT_Utility.areStackListsEqual(Arrays.asList(aRecipe.mInputs), aInputs, false, true)) continue; - if (!Objects.equals(Arrays.asList(aRecipe.mFluidInputs), aFluidInputs)) continue; - if (!areStacksEqual(aRecipe.mOreDictAlt, mOreDictAlt)) continue; - - // Cache it - String aRecipeHash = generateRecipeHash(aRecipe); - sRecipeCacheByRecipeHash.put(aRecipeHash, aRecipe); - sRecipeCacheByOutput.put(new GT_ItemStack(aRecipe.mOutput), aRecipe); - if (doesDataStickHaveRecipeHash(aDataStick)) { - String aStickHash = getHashFromDataStack(aDataStick); - if (aRecipeHash.equals(aStickHash)) - return LookupResultType.VALID_STACK_AND_VALID_HASH.getResult(aRecipe); - } - return LookupResultType.VALID_STACK_AND_VALID_RECIPE.getResult(aRecipe); - } - return LookupResultType.VALID_STACK_BUT_INVALID_RECIPE.getResult(); - } - - private static boolean areStacksEqual(ItemStack[][] lhs, List> rhs) { - for (int i = 0; i < lhs.length; i++) { - if (!areStacksEqual(lhs[i], rhs.get(i))) return false; - } - return true; - } - - private static boolean areStacksEqual(ItemStack[] lhs, List rhs) { - return lhs == null ? rhs.isEmpty() - : !rhs.isEmpty() && GT_Utility.areStackListsEqual(Arrays.asList(lhs), rhs, false, true); - } - - /** - * Finds a GT_Recipe_AssemblyLine based on the expected output ItemStack. - * - * @param aOutput - The Output of a GT_Recipe_AssemblyLine. - * @return First found GT_Recipe_AssemblyLine with matching output. - */ - public static GT_Recipe_AssemblyLine findAssemblyLineRecipeByOutput(ItemStack aOutput) { - if (aOutput == null) { - return null; - } - - // Check the cache - GT_ItemStack aCacheStack = new GT_ItemStack(aOutput); - GT_Recipe_AssemblyLine aRecipeFromCache = sRecipeCacheByOutput.get(aCacheStack); - if (aRecipeFromCache != null) { - return aRecipeFromCache; - } - - // Iterate all recipes and return the first matching based on Output. - for (GT_Recipe_AssemblyLine aRecipe : GT_Recipe.GT_Recipe_AssemblyLine.sAssemblylineRecipes) { - ItemStack aRecipeOutput = aRecipe.mOutput; - if (GT_Utility.areStacksEqual(aRecipeOutput, aOutput)) { - // Cache it to prevent future iterations of all recipes - sRecipeCacheByOutput.put(aCacheStack, aRecipe); - sRecipeCacheByRecipeHash.put(generateRecipeHash(aRecipe), aRecipe); - return aRecipe; - } - } - return null; - } - - /** - * @param aRecipe - The recipe to generate a Recipe Hash String from. - * @return The Recipe Hash String. - */ - public static String generateRecipeHash(GT_Recipe_AssemblyLine aRecipe) { - String aHash = "Invalid.Recipe.Hash"; - if (aRecipe != null) { - aHash = "Hash." + aRecipe.getPersistentHash(); - } - return aHash; - } - - /** - * @param aRecipe - The recipe to add to internal caches - * @throws IllegalArgumentException if given recipe collide with any existing recipe in the cache - */ - public static void addRecipeToCache(GT_Recipe_AssemblyLine aRecipe) { - if (aRecipe != null) { - String aHash = "Hash." + aRecipe.getPersistentHash(); - GT_Recipe_AssemblyLine existing = sRecipeCacheByOutput.put(new GT_ItemStack(aRecipe.mOutput), aRecipe); - if (existing != null) throw new IllegalArgumentException("Duplicate assline recipe for " + aRecipe.mOutput); - existing = sRecipeCacheByRecipeHash.put(aHash, aRecipe); - if (existing != null && !existing.equals(aRecipe)) - throw new IllegalArgumentException("Recipe hash collision for " + aRecipe + " and " + existing); - } - } - - /** - * @param aHash - Recipe hash String, may be null but will just be treated as invalid. - * @return Is this Recipe Hash String valid? - */ - public static boolean isValidHash(String aHash) { - if (aHash != null && aHash.length() > 0) { - // persistent hash can never be 0 - return !aHash.equals("Invalid.Recipe.Hash") && !aHash.equals("Hash.0"); - } - return false; - } - - /** - * @param aStack - The ItemStack to check. - * @return Is this ItemStack a Data Stick? - */ - public static boolean isItemDataStick(ItemStack aStack) { - return GT_Utility.isStackValid(aStack) && ItemList.Tool_DataStick.isStackEqual(aStack, false, true); - } - - /** - * @param aDataStick - The Data Stick to check. - * @return Does this Data Stick have a valid output ItemStack? - */ - public static boolean doesDataStickHaveOutput(ItemStack aDataStick) { - return isItemDataStick(aDataStick) && aDataStick.hasTagCompound() - && aDataStick.getTagCompound() - .hasKey("output"); - } - - /** - * @param aDataStick - The Data Stick to check. - * @return Does this Data Stick need recipe data updated. - */ - public static boolean doesDataStickNeedUpdate(ItemStack aDataStick) { - if (isItemDataStick(aDataStick) && doesDataStickHaveRecipeHash(aDataStick)) { - String aStickHash = getHashFromDataStack(aDataStick); - if (isValidHash(aStickHash) && doesDataStickHaveOutput(aDataStick)) { - ItemStack aStickOutput = getDataStickOutput(aDataStick); - GT_Recipe_AssemblyLine aIntendedRecipe = findAssemblyLineRecipeByOutput(aStickOutput); - return !aStickHash.equals(generateRecipeHash(aIntendedRecipe)); - } - } - return true; - } - - /** - * @param aDataStick - The Data Stick to check. - * @return Does this have a Recipe Hash String at all? - */ - public static boolean doesDataStickHaveRecipeHash(ItemStack aDataStick) { - if (isItemDataStick(aDataStick) && aDataStick.hasTagCompound()) { - NBTTagCompound aNBT = aDataStick.getTagCompound(); - return aNBT.hasKey("Data.Recipe.Hash") && !aNBT.getString("Data.Recipe.Hash") - .equals("Hash.0"); - } - return false; - } - - /** - * Get the Output ItemStack from a Data Stick. - * - * @param aDataStick - The Data Stick to check. - * @return Output ItemStack contained on the Data Stick. - */ - public static ItemStack getDataStickOutput(ItemStack aDataStick) { - if (doesDataStickHaveOutput(aDataStick)) { - return GT_Utility.loadItem(aDataStick.getTagCompound(), "output"); - } - return null; - } - - /** - * @param aDataStick - The Data Stick to process. - * @return The stored Recipe Hash String on the Data Stick, will return an invalid Hash if one is not found. - *

- * The hash will be guaranteed to pass isValidHash(). - *

- * Will not return Null. - */ - public static String getHashFromDataStack(ItemStack aDataStick) { - if (isItemDataStick(aDataStick) && aDataStick.hasTagCompound()) { - NBTTagCompound aNBT = aDataStick.getTagCompound(); - if (aNBT.hasKey("Data.Recipe.Hash", NBT.TAG_STRING)) { - String hash = aNBT.getString("Data.Recipe.Hash"); - if (isValidHash(hash)) return hash; - } - } - return "Invalid.Recipe.Hash"; - } - - /** - * - * @param aDataStick - The Data Stick to update. - * @param aRecipeHash - The Recipe Hash String to update with. - * @return Did we update the Recipe Hash String on the Data Stick? - */ - public static boolean setRecipeHashOnDataStick(ItemStack aDataStick, String aRecipeHash) { - if (isItemDataStick(aDataStick) && aDataStick.hasTagCompound()) { - NBTTagCompound aNBT = aDataStick.getTagCompound(); - aNBT.setString("Data.Recipe.Hash", aRecipeHash); - aDataStick.setTagCompound(aNBT); - return true; - } - return false; - } - - /** - * - * @param aDataStick - The Data Stick to update. - * @param aNewRecipe - The New GT_Recipe_AssemblyLine recipe to update it with. - * @return Did we set the new recipe data & Recipe Hash String on the Data Stick? - */ - public static boolean setAssemblyLineRecipeOnDataStick(ItemStack aDataStick, GT_Recipe_AssemblyLine aNewRecipe) { - return setAssemblyLineRecipeOnDataStick(aDataStick, aNewRecipe, true); - } - - public static boolean setAssemblyLineRecipeOnDataStick(ItemStack aDataStick, GT_Recipe_AssemblyLine aNewRecipe, - boolean setUpdateTime) { - if (isItemDataStick(aDataStick) && aNewRecipe.mOutput != null) { - String s = aNewRecipe.mOutput.getDisplayName(); - if (FMLCommonHandler.instance() - .getEffectiveSide() - .isServer()) { - s = GT_Assemblyline_Server.lServerNames.get(aNewRecipe.mOutput.getDisplayName()); - if (s == null) { - s = aNewRecipe.mOutput.getDisplayName(); - } - } - - String aHash = generateRecipeHash(aNewRecipe); - if (GT_Values.D1) { - GT_Recipe_AssemblyLine aOldRecipe = findAssemblyLineRecipeFromDataStick(aDataStick, true).recipe; - GT_FML_LOGGER.info( - "Updating data stick: " + aDataStick.getDisplayName() - + " | Old Recipe Hash: " - + generateRecipeHash(aOldRecipe) - + ", New Recipe Hash: " - + aHash); - } - - String author = "Assembling Line Recipe Generator"; - String displayName = null; - if (aDataStick.hasTagCompound()) { - NBTTagCompound tag = aDataStick.getTagCompound(); - if (tag.hasKey("author", NBT.TAG_STRING)) { - author = tag.getString("author"); - } - if (tag.hasKey("display", NBT.TAG_COMPOUND)) { - NBTTagCompound displayTag = tag.getCompoundTag("display"); - if (displayTag.hasKey("Name", NBT.TAG_STRING)) displayName = displayTag.getString("Name"); - } - } - - // remove possible old NBTTagCompound - aDataStick.setTagCompound(new NBTTagCompound()); - if (displayName != null) aDataStick.setStackDisplayName(displayName); - if (GT_Values.D1) { - GT_Utility.ItemNBT.setBookTitle(aDataStick, s + " Construction Data (" + aHash + ")"); - } else { - GT_Utility.ItemNBT.setBookTitle(aDataStick, s + " Construction Data"); - } - - NBTTagCompound tNBT = aDataStick.getTagCompound(); - if (tNBT == null) { - tNBT = new NBTTagCompound(); - } - - tNBT.setTag("output", aNewRecipe.mOutput.writeToNBT(new NBTTagCompound())); - tNBT.setInteger("time", aNewRecipe.mDuration); - tNBT.setInteger("eu", aNewRecipe.mEUt); - tNBT.setString("author", author); - NBTTagList tNBTList = new NBTTagList(); - tNBTList.appendTag( - new NBTTagString( - "Construction plan for " + aNewRecipe.mOutput.stackSize - + " " - + s - + ". Needed EU/t: " - + aNewRecipe.mEUt - + " Production time: " - + (aNewRecipe.mDuration / 20))); - for (int i = 0; i < aNewRecipe.mInputs.length; i++) { - boolean hasSetOreDictAlt = false; - - if (aNewRecipe.mOreDictAlt[i] != null && aNewRecipe.mOreDictAlt[i].length > 0) { - tNBT.setInteger("a" + i, aNewRecipe.mOreDictAlt[i].length); - int count = 0; - StringBuilder tBuilder = new StringBuilder("Input Bus " + (i + 1) + ": "); - for (int j = 0; j < aNewRecipe.mOreDictAlt[i].length; j++) { - ItemStack tStack = aNewRecipe.mOreDictAlt[i][j]; - if (tStack != null) { - tNBT.setTag("a" + i + ":" + j, tStack.writeToNBT(new NBTTagCompound())); - - s = tStack.getDisplayName(); - if (FMLCommonHandler.instance() - .getEffectiveSide() - .isServer()) { - s = GT_Assemblyline_Server.lServerNames.get(tStack.getDisplayName()); - if (s == null) s = tStack.getDisplayName(); - } - - tBuilder.append(count == 0 ? "" : "\nOr ") - .append(tStack.stackSize) - .append(" ") - .append(s); - count++; - } - } - if (count > 0) { - tNBTList.appendTag(new NBTTagString(tBuilder.toString())); - hasSetOreDictAlt = true; - } - } - - if (aNewRecipe.mInputs[i] != null) { - tNBT.setTag("" + i, aNewRecipe.mInputs[i].writeToNBT(new NBTTagCompound())); - - if (!hasSetOreDictAlt) { - s = aNewRecipe.mInputs[i].getDisplayName(); - if (FMLCommonHandler.instance() - .getEffectiveSide() - .isServer()) { - s = GT_Assemblyline_Server.lServerNames.get(aNewRecipe.mInputs[i].getDisplayName()); - if (s == null) s = aNewRecipe.mInputs[i].getDisplayName(); - } - tNBTList.appendTag( - new NBTTagString( - "Input Bus " + (i + 1) + ": " + aNewRecipe.mInputs[i].stackSize + " " + s)); - } - } - } - for (int i = 0; i < aNewRecipe.mFluidInputs.length; i++) { - if (aNewRecipe.mFluidInputs[i] != null) { - tNBT.setTag("f" + i, aNewRecipe.mFluidInputs[i].writeToNBT(new NBTTagCompound())); - - s = aNewRecipe.mFluidInputs[i].getLocalizedName(); - if (FMLCommonHandler.instance() - .getEffectiveSide() - .isServer()) { - s = GT_Assemblyline_Server.lServerNames.get(aNewRecipe.mFluidInputs[i].getLocalizedName()); - if (s == null) s = aNewRecipe.mFluidInputs[i].getLocalizedName(); - } - tNBTList.appendTag( - new NBTTagString( - "Input Hatch " + (i + 1) + ": " + aNewRecipe.mFluidInputs[i].amount + "L " + s)); - } - } - tNBT.setTag("pages", tNBTList); - if (setUpdateTime) tNBT.setLong("lastUpdate", System.currentTimeMillis()); - aDataStick.setTagCompound(tNBT); - // Set recipe hash - setRecipeHashOnDataStick(aDataStick, aHash); - return true; - } - return false; - } - - public enum LookupResultType { - - INVALID_STICK(true), - VALID_STACK_BUT_INVALID_RECIPE(true), - VALID_STACK_AND_VALID_RECIPE(false), - VALID_STACK_AND_VALID_HASH(false); - - private final boolean recipeNull; - private LookupResult singletonResult; - - LookupResultType(boolean recipeNull) { - this.recipeNull = recipeNull; - } - - public LookupResult getResult() { - if (!recipeNull) throw new IllegalArgumentException("This result type require a nonnull recipe"); - if (singletonResult == null) singletonResult = new LookupResult(null, this); - return singletonResult; - } - - public LookupResult getResult(GT_Recipe_AssemblyLine recipe) { - if ((recipe == null) != recipeNull) - throw new IllegalArgumentException("This result type does not allow given input"); - return new LookupResult(recipe, this); - } - } - - public static class LookupResult { - - private final GT_Recipe_AssemblyLine recipe; - private final LookupResultType type; - - LookupResult(GT_Recipe_AssemblyLine recipe, LookupResultType type) { - this.recipe = recipe; - this.type = type; - } - - public GT_Recipe_AssemblyLine getRecipe() { - return recipe; - } - - public LookupResultType getType() { - return type; - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_Assemblyline_Server.java b/src/main/java/gregtech/api/util/GT_Assemblyline_Server.java deleted file mode 100644 index 4c0348683a..0000000000 --- a/src/main/java/gregtech/api/util/GT_Assemblyline_Server.java +++ /dev/null @@ -1,297 +0,0 @@ -package gregtech.api.util; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import net.minecraftforge.common.config.ConfigCategory; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.common.config.Property; - -import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import gregtech.api.GregTech_API; -import gregtech.api.enums.Materials; -import gregtech.api.enums.MaterialsBotania; - -public class GT_Assemblyline_Server { - - public static LinkedHashMap lServerNames = new LinkedHashMap<>(); - private static LinkedHashMap internal2 = new LinkedHashMap<>(), internal3 = new LinkedHashMap<>(), - internal4 = new LinkedHashMap<>(); - private static HashMap internal = new HashMap<>(); - - public static void fillMap(FMLPreInitializationEvent aEvent) { - Configuration conf = GT_LanguageManager.sEnglishFile; - - ConfigCategory cat = conf.getCategory("languagefile"); - internal.putAll(cat.getValues()); - for (Map.Entry entry : internal.entrySet()) { - try { - String s = entry.getValue() - .getString() - .replaceAll("%", ""); - - if (entry.getKey() - .contains("metaitem") && s.contains("material")) internal2.put(entry.getKey(), s); - else if (entry.getKey() - .contains("blockmachines") && s.contains("material")) internal3.put(entry.getKey(), s); - else if ((entry.getKey() - .contains("blockores") - || (entry.getKey() - .contains("blockmetal") - || entry.getKey() - .contains("blockgem"))) - && s.contains("material")) internal4.put(entry.getKey(), s); - else lServerNames.put(entry.getKey(), s); - } catch (Exception ignored) {} - } - for (Map.Entry entry : internal2.entrySet()) { - try { - if (entry.getKey() - .contains("name")) { - int i = Integer.parseInt( - entry.getKey() - .substring( - "gt.metaitem.01.".length(), - entry.getKey() - .length() - ".name".length())); - i = i % 1000; - if (GregTech_API.sGeneratedMaterials[i] != null) lServerNames.put( - entry.getKey(), - entry.getValue() - .replace("material", GregTech_API.sGeneratedMaterials[i].toString())); - else lServerNames.put(entry.getKey(), null); - } - } catch (Exception ignored) {} - } - for (Map.Entry entry : internal3.entrySet()) { - try { - if (entry.getKey() - .contains("cable")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.cable.".length(), - entry.getKey() - .length() - ".01.name".length()))); - else if (entry.getKey() - .contains("gt_frame_")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.gt_frame_".length(), - entry.getKey() - .length() - ".name".length()))); - else if (entry.getKey() - .contains("gt_pipe_")) { - if (!entry.getKey() - .contains("_huge") - && !entry.getKey() - .contains("_large") - && !entry.getKey() - .contains("_nonuple") - && !entry.getKey() - .contains("_quadruple") - && !entry.getKey() - .contains("_small") - && !entry.getKey() - .contains("_tiny")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.gt_pipe_".length(), - entry.getKey() - .length() - ".name".length()))); - else if (entry.getKey() - .contains("_huge") - || entry.getKey() - .contains("_tiny")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.gt_pipe_".length(), - entry.getKey() - .length() - "_tiny.name".length()))); - else if (entry.getKey() - .contains("_large") - || entry.getKey() - .contains("_small")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.gt_pipe_".length(), - entry.getKey() - .length() - "_large.name".length()))); - else if (entry.getKey() - .contains("_nonuple")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.gt_pipe_".length(), - entry.getKey() - .length() - "_nonuple.name".length()))); - else if (entry.getKey() - .contains("_quadruple")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.gt_pipe_".length(), - entry.getKey() - .length() - "_quadruple.name".length()))); - } else if (entry.getKey() - .contains("wire")) - lServerNames.put( - entry.getKey(), - entry.getValue() - .replace( - "material", - entry.getKey() - .substring( - "gt.blockmachines.wire.".length(), - entry.getKey() - .length() - ".01.name".length()))); - else lServerNames.put(entry.getKey(), entry.getValue()); - } catch (Exception ignored) {} - } - for (Map.Entry entry : internal4.entrySet()) { - try { - if (entry.getKey() - .contains("blockores")) { - int i = Integer.parseInt( - entry.getKey() - .substring( - "gt.blockores.".length(), - entry.getKey() - .length() - ".name".length())); - i = i % 1000; - if (GregTech_API.sGeneratedMaterials[i] != null) lServerNames.put( - entry.getKey(), - entry.getValue() - .replace("material", GregTech_API.sGeneratedMaterials[i].toString())); - else lServerNames.put(entry.getKey(), null); - } else if (entry.getKey() - .contains("blockmetal")) { - Materials[] mMats = null; - String t = entry.getKey() - .substring("gt.blockmetal".length()); - t = t.substring(0, 1); - int i = Integer.parseInt(t); - switch (i) { - case 1 -> mMats = new Materials[] { Materials.Adamantium, Materials.Aluminium, - Materials.Americium, Materials.AnnealedCopper, Materials.Antimony, Materials.Arsenic, - Materials.AstralSilver, Materials.BatteryAlloy, Materials.Beryllium, Materials.Bismuth, - Materials.BismuthBronze, Materials.BlackBronze, Materials.BlackSteel, - Materials.BlueAlloy, Materials.BlueSteel, Materials.Brass }; - case 2 -> mMats = new Materials[] { Materials.Bronze, Materials.Caesium, Materials.Cerium, - Materials.Chrome, Materials.ChromiumDioxide, Materials.Cobalt, Materials.CobaltBrass, - Materials.Copper, Materials.Cupronickel, Materials.DamascusSteel, Materials.DarkIron, - Materials.DeepIron, Materials.Desh, Materials.Duranium, Materials.Dysprosium, - Materials.Electrum }; - case 3 -> mMats = new Materials[] { Materials.ElectrumFlux, Materials.Enderium, - Materials.Erbium, Materials.Europium, Materials.FierySteel, Materials.Gadolinium, - Materials.Gallium, Materials.Holmium, Materials.HSLA, Materials.Indium, - Materials.InfusedGold, Materials.Invar, Materials.Iridium, Materials.IronMagnetic, - Materials.IronWood, Materials.Kanthal }; - case 4 -> mMats = new Materials[] { Materials.Knightmetal, Materials.Lanthanum, - Materials.Lead, Materials.Lutetium, Materials.Magnalium, Materials.Magnesium, - Materials.Manganese, Materials.MeteoricIron, Materials.MeteoricSteel, Materials.Trinium, - Materials.Mithril, Materials.Molybdenum, Materials.Naquadah, Materials.NaquadahAlloy, - Materials.NaquadahEnriched, Materials.Naquadria }; - case 5 -> mMats = new Materials[] { Materials.Neodymium, Materials.NeodymiumMagnetic, - Materials.Neutronium, Materials.Nichrome, Materials.Nickel, Materials.Niobium, - Materials.NiobiumNitride, Materials.NiobiumTitanium, Materials.Osmiridium, - Materials.Osmium, Materials.Palladium, Materials.PigIron, Materials.Platinum, - Materials.Plutonium, Materials.Plutonium241, Materials.Praseodymium }; - case 6 -> mMats = new Materials[] { Materials.Promethium, Materials.RedAlloy, - Materials.RedSteel, Materials.RoseGold, Materials.Rubidium, Materials.Samarium, - Materials.Scandium, Materials.ShadowIron, Materials.ShadowSteel, Materials.Silicon, - Materials.Silver, Materials.SolderingAlloy, Materials.StainlessSteel, Materials.Steel, - Materials.SteelMagnetic, Materials.SterlingSilver }; - case 7 -> mMats = new Materials[] { Materials.Sunnarium, Materials.Tantalum, - Materials.Tellurium, Materials.Terbium, Materials.Thaumium, Materials.Thorium, - Materials.Thulium, Materials.Tin, Materials.TinAlloy, Materials.Titanium, - Materials.Tritanium, Materials.Tungsten, Materials.TungstenSteel, Materials.Ultimet, - Materials.Uranium, Materials.Uranium235 }; - case 8 -> mMats = new Materials[] { Materials.Vanadium, Materials.VanadiumGallium, - Materials.WroughtIron, Materials.Ytterbium, Materials.Yttrium, - Materials.YttriumBariumCuprate, Materials.Zinc, Materials.TungstenCarbide, - Materials.VanadiumSteel, Materials.HSSG, Materials.HSSE, Materials.HSSS, - Materials.Steeleaf, Materials.Ichorium, Materials.Firestone }; - } - t = entry.getKey() - .substring( - "gt.blockmetal1.".length(), - entry.getKey() - .length() - ".name".length()); - i = Integer.parseInt(t); - lServerNames.put(entry.getKey(), "Block of " + mMats[i].toString()); - mMats = null; - } else if (entry.getKey() - .contains("blockgem")) { - Materials[] mMats = null; - String t = entry.getKey() - .substring("gt.blockgem".length()); - t = t.substring(0, 1); - int i = Integer.parseInt(t); - switch (i) { - case 1 -> mMats = new Materials[] { Materials.InfusedAir, Materials.Amber, - Materials.Amethyst, Materials.InfusedWater, Materials.BlueTopaz, - Materials.CertusQuartz, Materials.Dilithium, Materials.EnderEye, - Materials.EnderPearl, Materials.FoolsRuby, Materials.Force, Materials.Forcicium, - Materials.Forcillium, Materials.GreenSapphire, Materials.InfusedFire, - Materials.Jasper, MaterialsBotania.ManaDiamond, - MaterialsBotania.BotaniaDragonstone }; - case 2 -> mMats = new Materials[] { Materials.Lazurite, Materials.Lignite, - Materials.Monazite, Materials.Niter, Materials.Olivine, Materials.Opal, - Materials.InfusedOrder, Materials.InfusedEntropy, Materials.Phosphorus, - Materials.Quartzite, Materials.GarnetRed, Materials.Ruby, Materials.Sapphire, - Materials.Sodalite, Materials.Tanzanite, Materials.InfusedEarth }; - case 3 -> mMats = new Materials[] { Materials.Topaz, Materials.Vinteum, - Materials.GarnetYellow, Materials.NetherStar, Materials.Charcoal, Materials.Blaze }; - } - t = entry.getKey() - .substring( - "gt.blockgem1.".length(), - entry.getKey() - .length() - ".name".length()); - i = Integer.parseInt(t); - lServerNames.put(entry.getKey(), "Block of " + mMats[i].toString()); - mMats = null; - } - } catch (Exception ignored) {} - } - - internal = null; - internal2 = null; - internal3 = null; - internal4 = null; - } -} diff --git a/src/main/java/gregtech/api/util/GT_BaseCrop.java b/src/main/java/gregtech/api/util/GT_BaseCrop.java deleted file mode 100644 index d8608c85a0..0000000000 --- a/src/main/java/gregtech/api/util/GT_BaseCrop.java +++ /dev/null @@ -1,311 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.E; -import static gregtech.api.enums.Mods.IC2CropPlugin; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; - -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.ConfigCategories; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.objects.ItemData; -import gregtech.common.blocks.GT_Block_Ores_Abstract; -import gregtech.common.blocks.GT_TileEntity_Ores; -import ic2.api.crops.CropCard; -import ic2.api.crops.Crops; -import ic2.api.crops.ICropTile; -import speiger.src.crops.api.ICropCardInfo; - -public class GT_BaseCrop extends CropCard implements ICropCardInfo { - - public static ArrayList sCropList = new ArrayList<>(); - private String mName = E; - private String mDiscoveredBy = "Gregorius Techneticies"; - private String[] mAttributes; - private int mTier = 0; - private int mMaxSize = 0; - private int mAfterHarvestSize = 0; - private int mHarvestSize = 0; - private final int[] mStats = new int[5]; - private final int mGrowthSpeed = 0; - private ItemStack mDrop = null; - private ItemStack[] mSpecialDrops = null; - private Materials mBlock = null; - private static boolean bIc2NeiLoaded = IC2CropPlugin.isModLoaded(); - - /** - * To create new Crops - * - * @param aID Default ID - * @param aCropName Name of the Crop - * @param aDiscoveredBy The one who discovered the Crop - * @param aDrop The Item which is dropped by the Crop. must be != null - * @param aBaseSeed Baseseed to plant this Crop. null == crossbreed only - * @param aTier tier of the Crop. forced to be >= 1 - * @param aMaxSize maximum Size of the Crop. forced to be >= 3 - * @param aGrowthSpeed how fast the Crop grows. if < 0 then its set to Tier*300 - * @param aHarvestSize the size the Crop needs to be harvested. forced to be between 2 and max size - */ - public GT_BaseCrop(int aID, String aCropName, String aDiscoveredBy, ItemStack aBaseSeed, int aTier, int aMaxSize, - int aGrowthSpeed, int aAfterHarvestSize, int aHarvestSize, int aStatChemical, int aStatFood, int aStatDefensive, - int aStatColor, int aStatWeed, String[] aAttributes, ItemStack aDrop, ItemStack[] aSpecialDrops) { - new GT_BaseCrop( - aID, - aCropName, - aDiscoveredBy, - aBaseSeed, - aTier, - aMaxSize, - aGrowthSpeed, - aAfterHarvestSize, - aHarvestSize, - aStatChemical, - aStatFood, - aStatDefensive, - aStatColor, - aStatWeed, - aAttributes, - null, - aDrop, - aSpecialDrops); - } - - /** - * To create new Crops - * - * @param aID Default ID - * @param aCropName Name of the Crop - * @param aDiscoveredBy The one who discovered the Crop - * @param aDrop The Item which is dropped by the Crop. must be != null - * @param aBaseSeed Baseseed to plant this Crop. null == crossbreed only - * @param aTier tier of the Crop. forced to be >= 1 - * @param aMaxSize maximum Size of the Crop. forced to be >= 3 - * @param aGrowthSpeed how fast the Crop grows. if < 0 then its set to Tier*300 - * @param aHarvestSize the size the Crop needs to be harvested. forced to be between 2 and max size - * @param aBlock the block below needed for crop to grow. If null no block needed - */ - public GT_BaseCrop(int aID, String aCropName, String aDiscoveredBy, ItemStack aBaseSeed, int aTier, int aMaxSize, - int aGrowthSpeed, int aAfterHarvestSize, int aHarvestSize, int aStatChemical, int aStatFood, int aStatDefensive, - int aStatColor, int aStatWeed, String[] aAttributes, Materials aBlock, ItemStack aDrop, - ItemStack[] aSpecialDrops) { - mName = aCropName; - aID = GT_Config.addIDConfig(ConfigCategories.IDs.crops, mName.replaceAll(" ", "_"), aID); - if (aDiscoveredBy != null && !aDiscoveredBy.equals(E)) mDiscoveredBy = aDiscoveredBy; - if (aDrop != null && aID > 0 && aID < 256) { - mDrop = GT_Utility.copyOrNull(aDrop); - mSpecialDrops = aSpecialDrops; - mTier = Math.max(1, aTier); - mMaxSize = Math.max(3, aMaxSize); - mHarvestSize = Math.min(Math.max(aHarvestSize, 2), mMaxSize); - mAfterHarvestSize = Math.min(Math.max(aAfterHarvestSize, 1), mMaxSize - 1); - mStats[0] = aStatChemical; - mStats[1] = aStatFood; - mStats[2] = aStatDefensive; - mStats[3] = aStatColor; - mStats[4] = aStatWeed; - mAttributes = aAttributes; - mBlock = aBlock; - if (!Crops.instance.registerCrop(this, aID)) - throw new GT_ItsNotMyFaultException("Make sure the Crop ID is valid!"); - if (aBaseSeed != null) Crops.instance.registerBaseSeed(aBaseSeed, this, 1, 1, 1, 1); - sCropList.add(this); - } - if (bIc2NeiLoaded) { - try { - Class.forName("speiger.src.crops.api.CropPluginAPI") - .getMethod("registerCropInfo", Class.forName("speiger.src.crops.api.ICropCardInfo")) - .invoke( - Class.forName("speiger.src.crops.api.CropPluginAPI") - .getField("instance"), - this); - } catch (IllegalAccessException | ClassNotFoundException | SecurityException | NoSuchMethodException - | NoSuchFieldException | InvocationTargetException | IllegalArgumentException ex) { - bIc2NeiLoaded = false; - } - } - } - - @Override - public byte getSizeAfterHarvest(ICropTile crop) { - return (byte) mAfterHarvestSize; - } - - @Override - public int growthDuration(ICropTile aCrop) { - if (mGrowthSpeed < 200) return super.growthDuration(aCrop); - return tier() * mGrowthSpeed; - } - - @Override - public int getrootslength(ICropTile crop) { - return 5; - } - - @Override - public String[] attributes() { - return mAttributes; - } - - @Override - public String discoveredBy() { - return mDiscoveredBy; - } - - @Override - public final boolean canGrow(ICropTile aCrop) { - // block check is only performed at the last stage of growth - if (this.needsBlockBelow() && aCrop.getSize() == mMaxSize - 1) { - return isBlockBelow(aCrop); - } - return aCrop.getSize() < maxSize(); - } - - @Override - public final boolean canBeHarvested(ICropTile aCrop) { - return aCrop.getSize() >= mHarvestSize; - } - - @Override - public boolean canCross(ICropTile aCrop) { - return aCrop.getSize() + 2 > maxSize(); - } - - @Override - public int stat(int n) { - if (n < 0 || n >= mStats.length) return 0; - return mStats[n]; - } - - @Override - public String name() { - return mName; - } - - @Override - public int tier() { - return mTier; - } - - @Override - public int maxSize() { - return mMaxSize; - } - - @Override - public ItemStack getGain(ICropTile aCrop) { - int tDrop = 0; - if (mSpecialDrops != null && (tDrop = java.util.concurrent.ThreadLocalRandom.current() - .nextInt(0, (mSpecialDrops.length * 2) + 2)) < mSpecialDrops.length && mSpecialDrops[tDrop] != null) { - return GT_Utility.copyOrNull(mSpecialDrops[tDrop]); - } - return GT_Utility.copyOrNull(mDrop); - } - - @Override - public boolean rightclick(ICropTile aCrop, EntityPlayer aPlayer) { - if (!canBeHarvested(aCrop)) return false; - return aCrop.harvest(aPlayer instanceof EntityPlayerMP); - } - - @Override - public int getOptimalHavestSize(ICropTile crop) { - return maxSize(); - } - - /** - * Checks if the crop needs a block below it - * - * @return True if the crop needs a block below it to grow to its max size - */ - public boolean needsBlockBelow() { - return GT_Mod.gregtechproxy.mCropNeedBlock && this.mBlock != null; - } - - public boolean isBlockBelow(ICropTile aCrop) { - if (aCrop == null) { - return false; - } - for (int i = 1; i < this.getrootslength(aCrop); i++) { - Block tBlock = aCrop.getWorld() - .getBlock(aCrop.getLocation().posX, aCrop.getLocation().posY - i, aCrop.getLocation().posZ); - if ((tBlock instanceof GT_Block_Ores_Abstract)) { - TileEntity tTileEntity = aCrop.getWorld() - .getTileEntity(aCrop.getLocation().posX, aCrop.getLocation().posY - i, aCrop.getLocation().posZ); - if ((tTileEntity instanceof GT_TileEntity_Ores)) { - Materials tMaterial = GregTech_API.sGeneratedMaterials[(((GT_TileEntity_Ores) tTileEntity).mMetaData - % 1000)]; - if ((tMaterial != null) && (tMaterial != Materials._NULL)) { - return tMaterial == mBlock; - } - } - } else { - int tMetaID = aCrop.getWorld() - .getBlockMetadata(aCrop.getLocation().posX, aCrop.getLocation().posY - i, aCrop.getLocation().posZ); - if (isBlockBelow(new ItemStack(tBlock, 1, tMetaID))) { - return true; - } - } - } - return false; - } - - /** - * An isolated function to check if an item stack is a block that should be below this crop - * - * @param aItem a stack of the block placed under the crop - * @return The result of the check - */ - public boolean isBlockBelow(ItemStack aItem) { - // safety in case someone calls this without checking if we have a block - if (!this.needsBlockBelow()) return true; - - // get material from stack - ItemData tAssociation = GT_OreDictUnificator.getAssociation(aItem); - if (tAssociation == null) return false; - - // return true if it's an ore of the material - // note: some ores don't appear to have associations in testing, naq ore is an example of that - if (tAssociation.mPrefix.toString() - .startsWith("ore") && tAssociation.mMaterial.mMaterial == mBlock) { - return true; - } - - // return true if it's a block of the material - if (tAssociation.mPrefix == OrePrefixes.block && tAssociation.mMaterial.mMaterial == mBlock) { - return true; - } - return false; - } - - @Override - public List getCropInformation() { - if (mBlock != null) { - ArrayList result = new ArrayList<>(1); - result.add( - String.format( - "Requires %s Ore or Block of %s as soil block to reach full growth.", - mBlock.mName, - mBlock.mName)); - return result; - } - return null; - } - - @Override - public ItemStack getDisplayItem() { - if (mSpecialDrops != null && mSpecialDrops[mSpecialDrops.length - 1] != null) { - return GT_Utility.copyOrNull(mSpecialDrops[mSpecialDrops.length - 1]); - } - return GT_Utility.copyOrNull(mDrop); - } -} diff --git a/src/main/java/gregtech/api/util/GT_BlockMap.java b/src/main/java/gregtech/api/util/GT_BlockMap.java deleted file mode 100644 index 9ffe273cac..0000000000 --- a/src/main/java/gregtech/api/util/GT_BlockMap.java +++ /dev/null @@ -1,134 +0,0 @@ -package gregtech.api.util; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; - -import net.minecraft.block.Block; - -import gnu.trove.map.TByteObjectMap; -import gnu.trove.map.hash.TByteObjectHashMap; - -public class GT_BlockMap { - - public static final byte WILDCARD = -1; - private final ConcurrentHashMap> backing = new ConcurrentHashMap<>(); - private int size = 0; - - private TByteObjectMap getSubmap(Block block) { - return backing.computeIfAbsent(block, b -> new TByteObjectHashMap<>()); - } - - /** - * Associate a value with that union key - * - * @param block block - * @param meta meta - * @return old mapping, or null if that doesn't exist - */ - public V put(Block block, byte meta, V value) { - V v = getSubmap(block).put(meta, value); - if (v == null) size++; - return v; - } - - /** - * Associate a value with that union key ONLY IF there isn't a prior EXACT mapping - * - * @param block block - * @param meta meta - * @return old mapping, or null if that doesn't exist - */ - public V putIfAbsent(Block block, byte meta, V value) { - V v = getSubmap(block).putIfAbsent(meta, value); - if (v == null) size++; - return v; - } - - /** - * Associate a value with that union key ONLY IF there isn't a prior EXACT mapping - * - * @param block block - * @param meta meta - * @return old mapping, or null if that doesn't exist - */ - public V computeIfAbsent(Block block, byte meta, BiFunction function) { - TByteObjectMap submap = getSubmap(block); - V v = submap.get(meta); - if (v == null) { - v = function.apply(block, meta); - submap.put(meta, v); - size++; - } - return v; - } - - /** - * Contains an associated value - * - * @param block block - * @param meta meta - * @return current mapping OR wildcard of that mapping exists - */ - public boolean containsKey(Block block, byte meta) { - TByteObjectMap submap = backing.get(block); - if (submap == null) return false; - return submap.containsKey(meta) || submap.containsKey(WILDCARD); - } - - /** - * Get the associated value - * - * @param block block - * @param meta meta - * @return current mapping OR wildcard of that block. null if neither exists - */ - public V get(Block block, byte meta) { - TByteObjectMap submap = backing.get(block); - if (submap == null) return null; - V v = submap.get(meta); - if (v != null) return v; - return submap.get(WILDCARD); - } - - /** - * Remove a mapping - * - * @param block block - * @param meta meta - * @return old value, or null if none - */ - public V remove(Block block, byte meta) { - TByteObjectMap submap = backing.get(block); - if (submap == null) return null; - V v = submap.remove(meta); - if (v != null) { - size--; - if (submap.isEmpty()) backing.remove(block); - } - return v; - } - - /** - * Size of all mappings - * - * @return size - */ - public int size() { - return size; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - GT_BlockMap that = (GT_BlockMap) o; - - return backing.equals(that.backing); - } - - @Override - public int hashCode() { - return backing.hashCode(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_BlockSet.java b/src/main/java/gregtech/api/util/GT_BlockSet.java deleted file mode 100644 index 1d13afd056..0000000000 --- a/src/main/java/gregtech/api/util/GT_BlockSet.java +++ /dev/null @@ -1,39 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.block.Block; - -public class GT_BlockSet { - - private final GT_BlockMap backing = new GT_BlockMap<>(); - - public boolean add(Block block, byte meta) { - return backing.put(block, meta, this) != this; - } - - public boolean contains(Block block, byte meta) { - return backing.get(block, meta) == this; - } - - public boolean remove(Block block, byte meta) { - return backing.remove(block, meta) == this; - } - - public int size() { - return backing.size(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - GT_BlockSet that = (GT_BlockSet) o; - - return backing.equals(that.backing); - } - - @Override - public int hashCode() { - return backing.hashCode(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_CLS_Compat.java b/src/main/java/gregtech/api/util/GT_CLS_Compat.java deleted file mode 100644 index c560435e30..0000000000 --- a/src/main/java/gregtech/api/util/GT_CLS_Compat.java +++ /dev/null @@ -1,157 +0,0 @@ -package gregtech.api.util; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Function; - -import cpw.mods.fml.common.ProgressManager; -import gregtech.GT_Mod; -import gregtech.api.enums.Materials; -import gregtech.common.GT_Proxy; -import gregtech.loaders.postload.GT_PostLoad; - -@SuppressWarnings("rawtypes, unchecked, deprecation") -public class GT_CLS_Compat { - - private static Class alexiilMinecraftDisplayer; - private static Class alexiilProgressDisplayer; - private static Class cpwProgressBar; - - private static Method getLastPercent; - private static Method displayProgress; - - private static Field isReplacingVanillaMaterials; - private static Field isRegisteringGTmaterials; - private static Field progressBarStep; - - static { - // CLS - try { - alexiilMinecraftDisplayer = Class.forName("alexiil.mods.load.MinecraftDisplayer"); - alexiilProgressDisplayer = Class.forName("alexiil.mods.load.ProgressDisplayer"); - } catch (ClassNotFoundException ex) { - GT_Mod.GT_FML_LOGGER.catching(ex); - } - - try { - cpwProgressBar = Class.forName("cpw.mods.fml.common.ProgressManager$ProgressBar"); - } catch (ClassNotFoundException ex) { - GT_Mod.GT_FML_LOGGER.catching(ex); - } - - Optional.ofNullable(alexiilMinecraftDisplayer) - .ifPresent(e -> { - try { - getLastPercent = e.getMethod("getLastPercent"); - isReplacingVanillaMaterials = e.getField("isReplacingVanillaMaterials"); - isRegisteringGTmaterials = e.getField("isRegisteringGTmaterials"); - } catch (NoSuchMethodException | NoSuchFieldException ex) { - GT_Mod.GT_FML_LOGGER.catching(ex); - } - }); - - Optional.ofNullable(alexiilProgressDisplayer) - .ifPresent(e -> { - try { - displayProgress = e.getMethod("displayProgress", String.class, float.class); - } catch (NoSuchMethodException ex) { - GT_Mod.GT_FML_LOGGER.catching(ex); - } - }); - - try { - progressBarStep = cpwProgressBar.getDeclaredField("step"); - progressBarStep.setAccessible(true); - } catch (NoSuchFieldException ex) { - GT_Mod.GT_FML_LOGGER.catching(ex); - } - } - - private GT_CLS_Compat() {} - - private static void registerAndReportProgression(String materialsType, Collection materials, - ProgressManager.ProgressBar progressBar, Function getName, Consumer action) { - int sizeStep = materials.size(); - final long progressionReportsEvery = 100; - final long bakingMsgEvery = 1000; - long nextProgressionReportAt = 0; - long nextBakingMsgAt = 0; - int currentStep = 0; - - for (T m : materials) { - long now = System.currentTimeMillis(); - - if (nextProgressionReportAt < now) { - nextProgressionReportAt = now + progressionReportsEvery; - String materialName = getName.apply(m) - .toString(); - try { - displayProgress.invoke(null, materialName, (float) currentStep / sizeStep); - } catch (IllegalAccessException | InvocationTargetException iae) { - GT_Mod.GT_FML_LOGGER.error("While updating progression", iae); - } - try { - progressBarStep.set(progressBar, currentStep); - } catch (IllegalAccessException iae) { - GT_Mod.GT_FML_LOGGER.error("While updating intermediate progression steps number", iae); - } - progressBar.step(materialName); - } - if (nextBakingMsgAt < now) { - nextBakingMsgAt = now + bakingMsgEvery; - GT_Mod.GT_FML_LOGGER - .info(String.format("%s - Baking: %d%%", materialsType, currentStep * 100 / sizeStep)); - } - action.accept(m); - currentStep += 1; - } - GT_Mod.GT_FML_LOGGER.info(String.format("%s - Baking: Done", materialsType)); - try { - progressBarStep.set(progressBar, currentStep); - } catch (IllegalAccessException iae) { - GT_Mod.GT_FML_LOGGER.error("While updating final progression steps number", iae); - } - } - - public static void stepMaterialsCLS(Collection mEvents, - ProgressManager.ProgressBar progressBar) throws IllegalAccessException { - try { - isRegisteringGTmaterials.set(null, true); - } catch (IllegalArgumentException | IllegalAccessException e) { - GT_Mod.GT_FML_LOGGER.catching(e); - } - registerAndReportProgression( - "GregTech materials", - mEvents, - progressBar, - m -> m.mMaterial, - GT_Proxy::registerRecipes); - ProgressManager.pop(progressBar); - isRegisteringGTmaterials.set(null, false); - } - - public static void doActualRegistrationCLS(ProgressManager.ProgressBar progressBar, - Set replacedVanillaItemsSet) { - try { - isReplacingVanillaMaterials.set(null, true); - } catch (IllegalArgumentException | IllegalAccessException e) { - GT_Mod.GT_FML_LOGGER.catching(e); - } - registerAndReportProgression( - "Vanilla materials", - replacedVanillaItemsSet, - progressBar, - m -> m.mDefaultLocalName, - GT_PostLoad::doActualRegistration); - } - - public static void pushToDisplayProgress() throws InvocationTargetException, IllegalAccessException { - isReplacingVanillaMaterials.set(null, false); - displayProgress.invoke(null, "Post Initialization: loading GregTech", getLastPercent.invoke(null)); - } -} diff --git a/src/main/java/gregtech/api/util/GT_ChunkAssociatedData.java b/src/main/java/gregtech/api/util/GT_ChunkAssociatedData.java deleted file mode 100644 index bb73cf77ed..0000000000 --- a/src/main/java/gregtech/api/util/GT_ChunkAssociatedData.java +++ /dev/null @@ -1,494 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.Mods.GregTech; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.lang.ref.WeakReference; -import java.lang.reflect.Array; -import java.nio.file.AtomicMoveNotSupportedException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.Arrays; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import javax.annotation.ParametersAreNonnullByDefault; - -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.world.WorldEvent; - -import org.apache.commons.io.FileUtils; - -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import gregtech.api.enums.GT_Values; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -/** - * A utility to save all kinds of data that is a function of any chunk. - *

- * GregTech takes care of saving and loading the data from disk, and an efficient mechanism to locate it. Subclass only - * need to define the exact scheme of each element data (by overriding the three protected abstract method) - *

- * Oh, there is no limit on how large your data is, though you'd not have the familiar NBT interface, but DataOutput - * should be reasonably common anyway. - *

- * It should be noted this class is NOT thread safe. - *

- * Element cannot be null. - *

- * TODO: Implement automatic region unloading. - * - * @param data element type - * @author glease - */ -@ParametersAreNonnullByDefault -public abstract class GT_ChunkAssociatedData { - - private static final Map> instances = new ConcurrentHashMap<>(); - private static final int IO_PARALLELISM = Math.min( - 8, - Math.max( - 1, - Runtime.getRuntime() - .availableProcessors() * 2 - / 3)); - private static final ExecutorService IO_WORKERS = Executors.newWorkStealingPool(IO_PARALLELISM); - private static final Pattern FILE_PATTERN = Pattern.compile("(.+)\\.(-?\\d+)\\.(-?\\d+)\\.dat"); - - static { - // register event handler - new EventHandler(); - } - - protected final String mId; - protected final Class elementtype; - private final int regionLength; - private final int version; - private final boolean saveDefaults; - /** - * Data is stored as a `(world id -> (super region id -> super region data))` hash map. where super region's size is - * determined by regionSize. Here it is called super region, to not confuse with vanilla's regions. - */ - private final Map> masterMap = new ConcurrentHashMap<>(); - - /** - * Initialize this instance. - * - * @param aId An arbitrary, but globally unique identifier for what this data is - * @param elementType The class of this element type. Used to create arrays. - * @param regionLength The length of one super region. Each super region will contain - * {@code regionLength * regionLength} chunks - * @param version An integer marking the version of this data. Useful later when the data's serialized form - * changed. - */ - protected GT_ChunkAssociatedData(String aId, Class elementType, int regionLength, byte version, - boolean saveDefaults) { - if (regionLength * regionLength > Short.MAX_VALUE || regionLength <= 0) - throw new IllegalArgumentException("Region invalid: " + regionLength); - if (!IData.class.isAssignableFrom(elementType)) throw new IllegalArgumentException("Data type invalid"); - if (aId.contains(".")) throw new IllegalArgumentException("ID cannot contains dot"); - this.mId = aId; - this.elementtype = elementType; - this.regionLength = regionLength; - this.version = version; - this.saveDefaults = saveDefaults; - if (instances.putIfAbsent(aId, this) != null) - throw new IllegalArgumentException("Duplicate GT_ChunkAssociatedData: " + aId); - } - - private ChunkCoordIntPair getRegionID(int aChunkX, int aChunkZ) { - return new ChunkCoordIntPair(Math.floorDiv(aChunkX, regionLength), Math.floorDiv(aChunkZ, regionLength)); - } - - /** - * Get a reference to data of the chunk that tile entity is in. The returned reference should be mutable. - */ - public final T get(IGregTechTileEntity tileEntity) { - return get(tileEntity.getWorld(), tileEntity.getXCoord() >> 4, tileEntity.getZCoord() >> 4); - } - - public final T get(Chunk chunk) { - return get(chunk.worldObj, chunk.xPosition, chunk.zPosition); - } - - public final T get(World world, ChunkCoordIntPair coord) { - return get(world, coord.chunkXPos, coord.chunkZPos); - } - - public final T get(World world, int chunkX, int chunkZ) { - SuperRegion region = masterMap.computeIfAbsent(world.provider.dimensionId, ignored -> new ConcurrentHashMap<>()) - .computeIfAbsent(getRegionID(chunkX, chunkZ), c -> new SuperRegion(world, c)); - return region.get(Math.floorMod(chunkX, regionLength), Math.floorMod(chunkZ, regionLength)); - } - - protected final void set(World world, int chunkX, int chunkZ, T data) { - SuperRegion region = masterMap.computeIfAbsent(world.provider.dimensionId, ignored -> new ConcurrentHashMap<>()) - .computeIfAbsent(getRegionID(chunkX, chunkZ), c -> new SuperRegion(world, c)); - region.set(Math.floorMod(chunkX, regionLength), Math.floorMod(chunkZ, regionLength), data); - } - - protected final boolean isCreated(int dimId, int chunkX, int chunkZ) { - Map dimData = masterMap.getOrDefault(dimId, null); - if (dimData == null) return false; - - SuperRegion region = dimData.getOrDefault(getRegionID(chunkX, chunkZ), null); - if (region == null) return false; - - return region.isCreated(Math.floorMod(chunkX, regionLength), Math.floorMod(chunkZ, regionLength)); - } - - public void clear() { - if (GT_Values.debugWorldData) { - long dirtyRegionCount = masterMap.values() - .stream() - .flatMap( - m -> m.values() - .stream()) - .filter(SuperRegion::isDirty) - .count(); - if (dirtyRegionCount > 0) GT_Log.out.println( - "Clearing ChunkAssociatedData with " + dirtyRegionCount + " regions dirty. Data might have been lost!"); - } - masterMap.clear(); - } - - public void save() { - saveRegions( - masterMap.values() - .stream() - .flatMap( - m -> m.values() - .stream())); - } - - public void save(World world) { - Map map = masterMap.get(world.provider.dimensionId); - if (map != null) saveRegions( - map.values() - .stream()); - } - - private void saveRegions(Stream stream) { - stream.filter(SuperRegion::isDirty) - .map(c -> (Runnable) c::save) - .map(r -> CompletableFuture.runAsync(r, IO_WORKERS)) - .reduce(CompletableFuture::allOf) - .ifPresent(f -> { - try { - f.get(); - } catch (Exception e) { - GT_Log.err.println("Data save error: " + mId); - e.printStackTrace(GT_Log.err); - } - }); - } - - protected abstract void writeElement(DataOutput output, T element, World world, int chunkX, int chunkZ) - throws IOException; - - protected abstract T readElement(DataInput input, int version, World world, int chunkX, int chunkZ) - throws IOException; - - protected abstract T createElement(World world, int chunkX, int chunkZ); - - /** - * Clear all mappings, regardless of whether they are dirty - */ - public static void clearAll() { - for (GT_ChunkAssociatedData d : instances.values()) d.clear(); - } - - /** - * Save all mappings - */ - public static void saveAll() { - for (GT_ChunkAssociatedData d : instances.values()) d.save(); - } - - /** - * Load data for all chunks for a given world. Current data for that world will be discarded. If this is what you - * intended, call {@link #save(World)} beforehand. - *

- * Be aware of the memory consumption though. - */ - protected void loadAll(World w) { - if (GT_Values.debugWorldData && masterMap.containsKey(w.provider.dimensionId)) GT_Log.err.println( - "Reloading ChunkAssociatedData " + mId + " for world " + w.provider.dimensionId + " discards old data!"); - if (!getSaveDirectory(w).isDirectory()) - // nothing to load... - return; - try (Stream stream = Files.list(getSaveDirectory(w).toPath())) { - Map worldData = stream.map(f -> { - Matcher matcher = FILE_PATTERN.matcher( - f.getFileName() - .toString()); - return matcher.matches() ? matcher : null; - }) - .filter(Objects::nonNull) - .filter(m -> mId.equals(m.group(1))) - .map( - m -> CompletableFuture.supplyAsync( - () -> new SuperRegion(w, Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3))), - IO_WORKERS)) - .map(f -> { - try { - return f.get(); - } catch (Exception e) { - GT_Log.err.println("Error loading region"); - e.printStackTrace(GT_Log.err); - return null; - } - }) - .filter(Objects::nonNull) - .collect(Collectors.toMap(SuperRegion::getCoord, Function.identity())); - masterMap.put(w.provider.dimensionId, worldData); - } catch (IOException | UncheckedIOException e) { - GT_Log.err.println("Error loading all region"); - e.printStackTrace(GT_Log.err); - } - } - - protected File getSaveDirectory(World w) { - File base; - if (w.provider.getSaveFolder() == null) base = w.getSaveHandler() - .getWorldDirectory(); - else base = new File( - w.getSaveHandler() - .getWorldDirectory(), - w.provider.getSaveFolder()); - return new File(base, GregTech.ID); - } - - public interface IData { - - /** - * @return Whether the data is different from chunk default - */ - boolean isSameAsDefault(); - } - - protected final class SuperRegion { - - private final T[] data = createData(); - private final File backingStorage; - private final WeakReference world; - /** - * Be aware, this means region coord, not bottom-left chunk coord - */ - private final ChunkCoordIntPair coord; - - private SuperRegion(World world, int regionX, int regionZ) { - this.world = new WeakReference<>(world); - this.coord = new ChunkCoordIntPair(regionX, regionZ); - backingStorage = new File(getSaveDirectory(world), String.format("%s.%d.%d.dat", mId, regionX, regionZ)); - if (backingStorage.isFile()) load(); - } - - private SuperRegion(World world, ChunkCoordIntPair regionCoord) { - this.world = new WeakReference<>(world); - this.coord = regionCoord; - backingStorage = new File( - getSaveDirectory(world), - String.format("%s.%d.%d.dat", mId, regionCoord.chunkXPos, regionCoord.chunkZPos)); - if (backingStorage.isFile()) load(); - } - - @SuppressWarnings("unchecked") - private T[] createData() { - return (T[]) Array.newInstance(elementtype, regionLength * regionLength); - } - - public T get(int subRegionX, int subRegionZ) { - int index = getIndex(subRegionX, subRegionZ); - T datum = data[index]; - if (datum == null) { - World world = Objects.requireNonNull(this.world.get()); - T newElem = createElement( - world, - coord.chunkXPos * regionLength + subRegionX, - coord.chunkZPos * regionLength + subRegionZ); - data[index] = newElem; - return newElem; - } - return datum; - } - - public void set(int subRegionX, int subRegionZ, T data) { - this.data[getIndex(subRegionX, subRegionZ)] = data; - } - - public boolean isCreated(int subRegionX, int subRegionZ) { - return this.data[getIndex(subRegionX, subRegionZ)] != null; - } - - public ChunkCoordIntPair getCoord() { - return coord; - } - - private int getIndex(int subRegionX, int subRegionY) { - return subRegionX * regionLength + subRegionY; - } - - private int getChunkX(int index) { - return index / regionLength + coord.chunkXPos * regionLength; - } - - private int getChunkZ(int index) { - return index % regionLength + coord.chunkZPos * regionLength; - } - - public boolean isDirty() { - for (T datum : data) { - if (datum != null && !datum.isSameAsDefault()) return true; - } - return false; - } - - public void save() { - try { - save0(); - } catch (IOException e) { - GT_Log.err.println("Error saving data " + backingStorage.getPath()); - e.printStackTrace(GT_Log.err); - } - } - - private void save0() throws IOException { - // noinspection ResultOfMethodCallIgnored - backingStorage.getParentFile() - .mkdirs(); - File tmpFile = getTmpFile(); - World world = Objects.requireNonNull(this.world.get(), "Attempting to save region of another world!"); - try (DataOutputStream output = new DataOutputStream(new FileOutputStream(tmpFile))) { - int ptr = 0; - boolean nullRange = data[0] == null; - // write a magic byte as storage format version - output.writeByte(0); - // write a magic byte as data format version - output.writeByte(version); - output.writeBoolean(nullRange); - while (ptr < data.length) { - // work out how long is this range - int rangeStart = ptr; - while (ptr < data.length - && (data[ptr] == null || (!saveDefaults && data[ptr].isSameAsDefault())) == nullRange) ptr++; - // write range length - output.writeShort(ptr - rangeStart); - if (!nullRange) - // write element data - for (int i = rangeStart; i < ptr; i++) - writeElement(output, data[i], world, getChunkX(ptr), getChunkZ(ptr)); - // or not - nullRange = !nullRange; - } - } - // first try to replace the destination file - // since atomic operation, no need to keep the backup in place - try { - Files.move( - tmpFile.toPath(), - backingStorage.toPath(), - StandardCopyOption.REPLACE_EXISTING, - StandardCopyOption.ATOMIC_MOVE); - } catch (AtomicMoveNotSupportedException ignored) { - // in case some dumb system/jre combination would cause this - // or if **somehow** two file inside the same directory belongs two separate filesystem - FileUtils.copyFile(tmpFile, backingStorage); - } - } - - public void load() { - try { - loadFromFile(backingStorage); - } catch (IOException | RuntimeException e) { - GT_Log.err.println("Primary storage file broken in " + backingStorage.getPath()); - e.printStackTrace(GT_Log.err); - // in case the primary storage is broken - try { - loadFromFile(getTmpFile()); - } catch (IOException | RuntimeException e2) { - GT_Log.err.println("Backup storage file broken in " + backingStorage.getPath()); - e2.printStackTrace(GT_Log.err); - } - } - } - - private void loadFromFile(File file) throws IOException { - World world = Objects.requireNonNull(this.world.get(), "Attempting to load region of another world!"); - try (DataInputStream input = new DataInputStream(new FileInputStream(file))) { - byte b = input.readByte(); - if (b == 0) { - loadV0(input, world); - } else { - GT_Log.err.printf("Unknown ChunkAssociatedData version %d\n", b); - } - } - } - - private void loadV0(DataInput input, World world) throws IOException { - int version = input.readByte(); - boolean nullRange = input.readBoolean(); - int ptr = 0; - while (ptr != data.length) { - int rangeEnd = ptr + input.readUnsignedShort(); - if (!nullRange) { - for (; ptr < rangeEnd; ptr++) { - data[ptr] = readElement(input, version, world, getChunkX(ptr), getChunkZ(ptr)); - } - } else { - Arrays.fill(data, ptr, rangeEnd, null); - ptr = rangeEnd; - } - nullRange = !nullRange; - } - } - - private File getTmpFile() { - return new File(backingStorage.getParentFile(), backingStorage.getName() + ".tmp"); - } - } - - public static class EventHandler { - - private EventHandler() { - MinecraftForge.EVENT_BUS.register(this); - } - - @SubscribeEvent - public void onWorldSave(WorldEvent.Save e) { - for (GT_ChunkAssociatedData d : instances.values()) { - d.save(e.world); - } - } - - @SubscribeEvent - public void onWorldUnload(WorldEvent.Unload e) { - for (GT_ChunkAssociatedData d : instances.values()) { - // there is no need to explicitly do a save here - // forge will send a WorldEvent.Save on server thread before this event is distributed - d.masterMap.remove(e.world.provider.dimensionId); - } - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_CircuitryBehavior.java b/src/main/java/gregtech/api/util/GT_CircuitryBehavior.java deleted file mode 100644 index 63fb7d1e70..0000000000 --- a/src/main/java/gregtech/api/util/GT_CircuitryBehavior.java +++ /dev/null @@ -1,212 +0,0 @@ -package gregtech.api.util; - -import net.minecraftforge.common.util.ForgeDirection; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import gregtech.api.GregTech_API; -import gregtech.api.interfaces.IRedstoneCircuitBlock; - -/** - * Redstone Circuit Control Code - *

- * This should make everything possible what a Redstone Computer or BuildCraft Gate could do. It is intended to use this - * similar to BC-Gates (for acquiring Data) and RP Logic Gates. You could write an extremely specified and complex Logic - * Gate, which works only for you Setup, like with ComputerCraft, but you would have to write an extra Mod to add that, - * as it doesn't work Ingame. - *

- * One can make use of the fact, that ItemStacks can be stored as Integer, so that you can scan Inventories for specific - * Items using that. Luckily the Buttons in the GUI enable Copy/Paste of ItemID+MetaData to Integer, including the - * WildCard Damage Value when you use rightclick to place it. You just need to use @GT_Utility.stackToInt(ItemStack - * aStack) to get it. - *

- * All Functions run usually in a seperate try/catch Block, so that failed Logic won't crash the TileEntity. - */ -public abstract class GT_CircuitryBehavior { - - /** - * @param aIndex 0 - 1023 are my own Indices, so use other Numbers! - */ - public GT_CircuitryBehavior(int aIndex) { - GregTech_API.sCircuitryBehaviors.put(aIndex, this); - } - - /** - * returns if there is Redstone applied to any of the valid Inputs (OR) - */ - public static boolean getAnyRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) - .letsRedstoneGoIn( - side, - aRedstoneCircuitBlock.getCoverID(side), - aRedstoneCircuitBlock.getCoverVariable(side), - aRedstoneCircuitBlock.getOwnTileEntity())) { - if (aRedstoneCircuitBlock.getInputRedstone(side) > 0) { - return true; - } - } - } - return false; - } - - /** - * returns if there is Redstone applied to all the valid Inputs (AND) - */ - public static boolean getAllRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) - .letsRedstoneGoIn( - side, - aRedstoneCircuitBlock.getCoverID(side), - aRedstoneCircuitBlock.getCoverVariable(side), - aRedstoneCircuitBlock.getOwnTileEntity())) { - if (aRedstoneCircuitBlock.getInputRedstone(side) == 0) { - return false; - } - } - } - return true; - } - - /** - * returns if there is Redstone applied to exactly one of the valid Inputs (XOR) - */ - public static boolean getOneRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { - int tRedstoneAmount = 0; - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) - .letsRedstoneGoIn( - side, - aRedstoneCircuitBlock.getCoverID(side), - aRedstoneCircuitBlock.getCoverVariable(side), - aRedstoneCircuitBlock.getOwnTileEntity())) { - if (aRedstoneCircuitBlock.getInputRedstone(side) > 0) { - tRedstoneAmount++; - } - } - } - return tRedstoneAmount == 1; - } - - /** - * returns the strongest incoming RS-Power - */ - public static byte getStrongestRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { - byte tRedstoneAmount = 0; - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) - .letsRedstoneGoIn( - side, - aRedstoneCircuitBlock.getCoverID(side), - aRedstoneCircuitBlock.getCoverVariable(side), - aRedstoneCircuitBlock.getOwnTileEntity())) { - tRedstoneAmount = (byte) Math.max(tRedstoneAmount, aRedstoneCircuitBlock.getInputRedstone(side)); - } - } - return tRedstoneAmount; - } - - // region GUI Functions - - /** - * returns the weakest incoming non-zero RS-Power - */ - public static byte getWeakestNonZeroRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { - if (!getAnyRedstone(aRedstoneCircuitBlock)) return 0; - byte tRedstoneAmount = 15; - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) - .letsRedstoneGoIn( - side, - aRedstoneCircuitBlock.getCoverID(side), - aRedstoneCircuitBlock.getCoverVariable(side), - aRedstoneCircuitBlock.getOwnTileEntity())) { - if (aRedstoneCircuitBlock.getInputRedstone(side) > 0) - tRedstoneAmount = (byte) Math.min(tRedstoneAmount, aRedstoneCircuitBlock.getInputRedstone(side)); - } - } - return tRedstoneAmount; - } - - /** - * returns the weakest incoming RS-Power - */ - public static byte getWeakestRedstone(IRedstoneCircuitBlock aRedstoneCircuitBlock) { - if (!getAnyRedstone(aRedstoneCircuitBlock)) return 0; - byte tRedstoneAmount = 15; - for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { - if (side != aRedstoneCircuitBlock.getOutputFacing() && aRedstoneCircuitBlock.getCover(side) - .letsRedstoneGoIn( - side, - aRedstoneCircuitBlock.getCoverID(side), - aRedstoneCircuitBlock.getCoverVariable(side), - aRedstoneCircuitBlock.getOwnTileEntity())) { - tRedstoneAmount = (byte) Math.min(tRedstoneAmount, aRedstoneCircuitBlock.getInputRedstone(side)); - } - } - return tRedstoneAmount; - } - - /** - * Initializes the Parameters of this Circuit, all Parameters have been set to 0 right before calling this - * - * @param aCircuitData, The Data Storage you can use (8 Slots) - * @param aRedstoneCircuitBlock, The Circuit Block MetaTileEntity itself - */ - public abstract void initParameters(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock); - - /** - * Validates the Parameters of this Circuit when a value has been changed by the GUI Also called right - * after @initParameters and when the Chunk reloads - * - * @param aCircuitData, The Data Storage you can use (8 Slots and only the first 4 are User definable) - * @param aRedstoneCircuitBlock, The Circuit Block MetaTileEntity itself - */ - public abstract void validateParameters(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock); - - // endregion - - // region Utility Functions - - /** - * Called every tick if the Block has enough Energy and if the Block is Active - * - * @param aCircuitData, The Data Storage you can use (8 Slots) - * @param aRedstoneCircuitBlock, The Circuit Block MetaTileEntity itself - */ - public abstract void onTick(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock); - - /** - * If the ItemStack should be displayed. Parameters are between 0 and 3. - */ - public abstract boolean displayItemStack(int[] aCircuitData, IRedstoneCircuitBlock aRedstoneCircuitBlock, - int aIndex); - - /** - * The Name of the Gate for the GUI - */ - @SideOnly(Side.CLIENT) - public abstract String getName(); - - /** - * The Description of the Gate for the GUI - */ - @SideOnly(Side.CLIENT) - public abstract String getDescription(); - - /** - * The Description of the Data Field for the GUI - */ - @SideOnly(Side.CLIENT) - public abstract String getDataDescription(int[] aCircuitData, int aCircuitDataIndex); - - /** - * How the Integer should be displayed in the GUI. null means, that it just displays as regular Number. - */ - @SideOnly(Side.CLIENT) - public String getDataDisplay(int[] aCircuitData, int aCircuitDataIndex) { - return null; - } - // endregion -} diff --git a/src/main/java/gregtech/api/util/GT_ClientPreference.java b/src/main/java/gregtech/api/util/GT_ClientPreference.java deleted file mode 100644 index 3ea2730a0c..0000000000 --- a/src/main/java/gregtech/api/util/GT_ClientPreference.java +++ /dev/null @@ -1,43 +0,0 @@ -package gregtech.api.util; - -import gregtech.common.config.client.ConfigPreference; -import gregtech.common.config.client.ConfigWaila; - -public class GT_ClientPreference { - - private final boolean mSingleBlockInitialFilter; - private final boolean mSingleBlockInitialMultiStack; - private final boolean mInputBusInitialFilter; - private final boolean wailaAverageNS; - - public GT_ClientPreference(boolean mSingleBlockInitialFilter, boolean mSingleBlockInitialMultiStack, - boolean mInputBusInitialFilter, boolean wailaAverageNS) { - this.mSingleBlockInitialFilter = mSingleBlockInitialFilter; - this.mSingleBlockInitialMultiStack = mSingleBlockInitialMultiStack; - this.mInputBusInitialFilter = mInputBusInitialFilter; - this.wailaAverageNS = wailaAverageNS; - } - - public GT_ClientPreference() { - this.mSingleBlockInitialFilter = ConfigPreference.singleBlockInitialFilter; - this.mSingleBlockInitialMultiStack = ConfigPreference.singleBlockInitialAllowMultiStack; - this.mInputBusInitialFilter = ConfigPreference.inputBusInitialFilter; - this.wailaAverageNS = ConfigWaila.wailaAverageNS; - } - - public boolean isSingleBlockInitialFilterEnabled() { - return mSingleBlockInitialFilter; - } - - public boolean isSingleBlockInitialMultiStackEnabled() { - return mSingleBlockInitialMultiStack; - } - - public boolean isInputBusInitialFilterEnabled() { - return mInputBusInitialFilter; - } - - public boolean isWailaAverageNSEnabled() { - return wailaAverageNS; - } -} diff --git a/src/main/java/gregtech/api/util/GT_Config.java b/src/main/java/gregtech/api/util/GT_Config.java deleted file mode 100644 index e1157febb4..0000000000 --- a/src/main/java/gregtech/api/util/GT_Config.java +++ /dev/null @@ -1,162 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.E; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.common.config.Property; - -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; - -public class GT_Config implements Runnable { - - public static boolean troll = false; - - public static Configuration sConfigFileIDs; - public static Configuration cleanroomFile; - public static Configuration undergroundFluidsFile; - public final Configuration mConfig; - - public GT_Config(Configuration aConfig) { - mConfig = aConfig; - mConfig.load(); - mConfig.save(); - GregTech_API.sAfterGTPreload.add(this); // in case of crash on startup - GregTech_API.sAfterGTLoad.add(this); // in case of crash on startup - GregTech_API.sAfterGTPostload.add(this); - if (GT_Values.lateConfigSave) GregTech_API.sFirstWorldTick.add(this); - } - - private static boolean shouldSave() { - return GT_Values.lateConfigSave ? GT_Values.worldTickHappened : GregTech_API.sPostloadFinished; - } - - public static int addIDConfig(Object aCategory, String aName, int aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = sConfigFileIDs.get( - aCategory.toString() - .replaceAll("\\|", "."), - aName.replaceAll("\\|", "."), - aDefault); - int rResult = tProperty.getInt(aDefault); - sConfigFileIDs.save(); - return rResult; - } - - public static String getStackConfigName(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return E; - Object rName = GT_OreDictUnificator.getAssociation(aStack); - if (rName != null) return rName.toString(); - try { - if (GT_Utility.isStringValid(rName = aStack.getUnlocalizedName())) return rName.toString(); - } catch (Throwable e) { - /* Do nothing */ - } - String sName = aStack.getItem() - .toString(); - String[] tmp = sName.split("@"); - if (tmp.length > 0) sName = tmp[0]; - return sName + "." + aStack.getItemDamage(); - } - - public boolean get(Object aCategory, ItemStack aStack, boolean aDefault) { - String aName = getStackConfigName(aStack); - return get(aCategory, aName, aDefault); - } - - public boolean get(Object aCategory, String aName, boolean aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = mConfig.get( - aCategory.toString() - .replaceAll("\\|", "_"), - (aName + "_" + aDefault).replaceAll("\\|", "_"), - aDefault); - boolean rResult = tProperty.getBoolean(aDefault); - if (!tProperty.wasRead() && shouldSave()) mConfig.save(); - return rResult; - } - - public int get(Object aCategory, ItemStack aStack, int aDefault) { - return get(aCategory, getStackConfigName(aStack), aDefault); - } - - public int get(Object aCategory, String aName, int aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = mConfig.get( - aCategory.toString() - .replaceAll("\\|", "_"), - (aName + "_" + aDefault).replaceAll("\\|", "_"), - aDefault); - int rResult = tProperty.getInt(aDefault); - if (!tProperty.wasRead() && shouldSave()) mConfig.save(); - return rResult; - } - - public double get(Object aCategory, ItemStack aStack, double aDefault) { - return get(aCategory, getStackConfigName(aStack), aDefault); - } - - public double get(Object aCategory, String aName, double aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = mConfig.get( - aCategory.toString() - .replaceAll("\\|", "_"), - (aName + "_" + aDefault).replaceAll("\\|", "_"), - aDefault); - double rResult = tProperty.getDouble(aDefault); - if (!tProperty.wasRead() && shouldSave()) mConfig.save(); - return rResult; - } - - public String get(Object aCategory, ItemStack aStack, String aDefault) { - return get(aCategory, getStackConfigName(aStack), aDefault); - } - - public String get(Object aCategory, String aName, String aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = mConfig.get( - aCategory.toString() - .replaceAll("\\|", "_"), - (aName + "_" + aDefault).replaceAll("\\|", "_"), - aDefault); - String rResult = tProperty.getString(); - if (!tProperty.wasRead() && shouldSave()) mConfig.save(); - return rResult; - } - - public String[] get(Object aCategory, ItemStack aStack, String... aDefault) { - return get(aCategory, getStackConfigName(aStack), aDefault); - } - - public String[] get(Object aCategory, String aName, String... aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = mConfig.get( - aCategory.toString() - .replaceAll("\\|", "_"), - aName.replaceAll("\\|", "_"), - aDefault); - String[] rResult = tProperty.getStringList(); - if (!tProperty.wasRead() && GregTech_API.sPostloadFinished) mConfig.save(); - return rResult; - } - - public String getWithValidValues(Object aCategory, String aName, String[] validValues, String aDefault) { - if (GT_Utility.isStringInvalid(aName)) return aDefault; - Property tProperty = mConfig.get( - aCategory.toString() - .replaceAll("\\|", "_"), - aName.replaceAll("\\|", "_"), - aDefault, - null, - validValues); - String rResult = tProperty.getString(); - if (!tProperty.wasRead() && GregTech_API.sPostloadFinished) mConfig.save(); - return rResult; - } - - @Override - public void run() { - mConfig.save(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_CoverBehavior.java b/src/main/java/gregtech/api/util/GT_CoverBehavior.java deleted file mode 100644 index 9394b3957f..0000000000 --- a/src/main/java/gregtech/api/util/GT_CoverBehavior.java +++ /dev/null @@ -1,402 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.E; - -import java.lang.ref.WeakReference; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.Fluid; - -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.ICoverable; - -/** - * For Covers with a special behavior. Has fixed storage format of 4 byte. Not very convenient... - */ -public abstract class GT_CoverBehavior extends GT_CoverBehaviorBase { - - public boolean mPlayerNotified = false; - - public GT_CoverBehavior() { - this(null); - } - - public GT_CoverBehavior(ITexture coverTexture) { - super(ISerializableObject.LegacyCoverData.class, coverTexture); - } - - protected static int convert(ISerializableObject.LegacyCoverData data) { - return data == null ? 0 : data.get(); - } - - // region bridge the parent call to legacy calls - - @Override - public final ISerializableObject.LegacyCoverData createDataObject() { - return new ISerializableObject.LegacyCoverData(); - } - - @Override - public ISerializableObject.LegacyCoverData createDataObject(int aLegacyData) { - return new ISerializableObject.LegacyCoverData(aLegacyData); - } - - @Override - protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { - return isRedstoneSensitive(side, aCoverID, aCoverVariable.get(), aTileEntity, aTimer); - } - - @Override - protected ISerializableObject.LegacyCoverData doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, - int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, long aTimer) { - if (aCoverVariable == null) aCoverVariable = new ISerializableObject.LegacyCoverData(); - aCoverVariable.set(doCoverThings(side, aInputRedstone, aCoverID, aCoverVariable.get(), aTileEntity, aTimer)); - return aCoverVariable; - } - - @Override - protected boolean onCoverRightClickImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, - float aY, float aZ) { - return onCoverRightclick(side, aCoverID, convert(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ); - } - - @Override - protected ISerializableObject.LegacyCoverData onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, - float aY, float aZ) { - if (aCoverVariable == null) aCoverVariable = new ISerializableObject.LegacyCoverData(); - aCoverVariable - .set(onCoverScrewdriverclick(side, aCoverID, convert(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ)); - return aCoverVariable; - } - - @Override - protected boolean onCoverShiftRightClickImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer) { - return onCoverShiftRightclick(side, aCoverID, convert(aCoverVariable), aTileEntity, aPlayer); - } - - @Override - protected boolean onCoverRemovalImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity, boolean aForced) { - return onCoverRemoval(side, aCoverID, convert(aCoverVariable), aTileEntity, aForced); - } - - @Override - protected void onBaseTEDestroyedImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - onBaseTEDestroyed(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected void onCoverUnloadImpl(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - onCoverUnload(aTileEntity); - } - - @Override - protected String getDescriptionImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return getDescription(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected float getBlastProofLevelImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return getBlastProofLevel(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean letsRedstoneGoInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return letsRedstoneGoIn(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean letsRedstoneGoOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return letsRedstoneGoOut(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return letsEnergyIn(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return letsEnergyOut(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { - return letsFluidIn(side, aCoverID, convert(aCoverVariable), aFluid, aTileEntity); - } - - @Override - protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) { - return letsFluidOut(side, aCoverID, convert(aCoverVariable), aFluid, aTileEntity); - } - - @Override - protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { - return letsItemsIn(side, aCoverID, convert(aCoverVariable), aSlot, aTileEntity); - } - - @Override - protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, int aSlot, ICoverable aTileEntity) { - return letsItemsOut(side, aCoverID, convert(aCoverVariable), aSlot, aTileEntity); - } - - @Override - protected boolean isGUIClickableImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return isGUIClickable(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return manipulatesSidedRedstoneOutput(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected boolean alwaysLookConnectedImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return alwaysLookConnected(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected byte getRedstoneInputImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return getRedstoneInput(side, aInputRedstone, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected int getTickRateImpl(ForgeDirection side, int aCoverID, ISerializableObject.LegacyCoverData aCoverVariable, - ICoverable aTileEntity) { - return getTickRate(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected byte getLensColorImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return getLensColor(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - @Override - protected ItemStack getDropImpl(ForgeDirection side, int aCoverID, - ISerializableObject.LegacyCoverData aCoverVariable, ICoverable aTileEntity) { - return getDrop(side, aCoverID, convert(aCoverVariable), aTileEntity); - } - - // endregion - - public boolean isRedstoneSensitive(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - long aTimer) { - return true; - } - - /** - * Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time. - */ - public int doCoverThings(ForgeDirection side, byte aInputRedstone, int aCoverID, int aCoverVariable, - ICoverable aTileEntity, long aTimer) { - return aCoverVariable; - } - - /** - * Called when someone rightclicks this Cover. - *

- * return true, if something actually happens. - */ - public boolean onCoverRightclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer, float aX, float aY, float aZ) { - return false; - } - - /** - * Called when someone rightclicks this Cover with a Screwdriver. Doesn't call @onCoverRightclick in this Case. - *

- * return the new Value of the Cover Variable - */ - public int onCoverScrewdriverclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer, float aX, float aY, float aZ) { - return aCoverVariable; - } - - /** - * Called when someone shift-rightclicks this Cover with no tool. Doesn't call @onCoverRightclick in this Case. - */ - public boolean onCoverShiftRightclick(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer) { - if (hasCoverGUI() && aPlayer instanceof EntityPlayerMP) { - lastPlayer = new WeakReference<>(aPlayer); - mPlayerNotified = false; - GT_UIInfos.openCoverUI(aTileEntity, aPlayer, side); - return true; - } - return false; - } - - /** - * Removes the Cover if this returns true, or if aForced is true. Doesn't get called when the Machine Block is - * getting broken, only if you break the Cover away from the Machine. - */ - public boolean onCoverRemoval(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity, - boolean aForced) { - return true; - } - - public void onCoverUnload(ICoverable aTileEntity) { - - } - - public void onBaseTEDestroyed(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) {} - - /** - * Gives a small Text for the status of the Cover. - */ - public String getDescription(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return E; - } - - /** - * How Blast Proof the Cover is. 30 is normal. - */ - public float getBlastProofLevel(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return 10.0F; - } - - /** - * If it lets RS-Signals into the Block - *

- * This is just Informative so that Machines know if their Redstone Input is blocked or not - */ - public boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * If it lets RS-Signals out of the Block - */ - public boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Energy into the Block - */ - public boolean letsEnergyIn(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Energy out of the Block - */ - public boolean letsEnergyOut(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Liquids into the Block, aFluid can be null meaning if this is generally allowing Fluids or not. - */ - public boolean letsFluidIn(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Liquids out of the Block, aFluid can be null meaning if this is generally allowing Fluids or not. - */ - public boolean letsFluidOut(ForgeDirection side, int aCoverID, int aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Items into the Block, aSlot = -1 means if it is generally accepting Items (return false for no - * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each - * Slot). - */ - public boolean letsItemsIn(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Items out of the Block, aSlot = -1 means if it is generally accepting Items (return false for no - * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each - * Slot). - */ - public boolean letsItemsOut(ForgeDirection side, int aCoverID, int aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets you rightclick the Machine normally - */ - public boolean isGUIClickable(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return true; - } - - /** - * Needs to return true for Covers, which have a Redstone Output on their Facing. - */ - public boolean manipulatesSidedRedstoneOutput(ForgeDirection side, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - /** - * if this Cover should let Pipe Connections look connected even if it is not the case. - */ - public boolean alwaysLookConnected(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * Called to determine the incoming Redstone Signal of a Machine. Returns the original Redstone per default. The - * Cover should @letsRedstoneGoIn or the aInputRedstone Parameter is always 0. - */ - public byte getRedstoneInput(ForgeDirection side, byte aInputRedstone, int aCoverID, int aCoverVariable, - ICoverable aTileEntity) { - return letsRedstoneGoIn(side, aCoverID, aCoverVariable, aTileEntity) ? aInputRedstone : 0; - } - - /** - * Gets the Tick Rate for doCoverThings of the Cover - *

- * 0 = No Ticks! Yes, 0 is Default, you have to override this - */ - public int getTickRate(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return 0; - } - - /** - * The MC Color of this Lens. -1 for no Color (meaning this isn't a Lens then). - */ - public byte getLensColor(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return -1; - } - - /** - * @return the ItemStack dropped by this Cover - */ - public ItemStack getDrop(ForgeDirection side, int aCoverID, int aCoverVariable, ICoverable aTileEntity) { - return GT_OreDictUnificator.get(true, aTileEntity.getCoverItemAtSide(side)); - } -} diff --git a/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java b/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java deleted file mode 100644 index f5bd7a92f4..0000000000 --- a/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java +++ /dev/null @@ -1,839 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.E; - -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.function.Supplier; - -import javax.annotation.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagInt; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.Fluid; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizons.modularui.api.ModularUITextures; -import com.gtnewhorizons.modularui.api.drawable.ItemDrawable; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; -import com.gtnewhorizons.modularui.common.widget.ButtonWidget; -import com.gtnewhorizons.modularui.common.widget.TextWidget; - -import gregtech.api.GregTech_API; -import gregtech.api.gui.GT_GUIColorOverride; -import gregtech.api.gui.modularui.GT_CoverUIBuildContext; -import gregtech.api.gui.modularui.GT_UIInfos; -import gregtech.api.gui.modularui.GUITextureSet; -import gregtech.api.gui.widgets.GT_CoverTickRateButton; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.common.covers.CoverInfo; - -/** - * For Covers with a special behavior. - * - * @author glease - */ -public abstract class GT_CoverBehaviorBase { - - public WeakReference lastPlayer = null; - private final Class typeToken; - private final ITexture coverFGTexture; - - protected GT_CoverBehaviorBase(Class typeToken) { - this(typeToken, null); - } - - protected GT_CoverBehaviorBase(Class typeToken, ITexture coverTexture) { - this.typeToken = typeToken; - this.coverFGTexture = coverTexture; - reloadColorOverride(); - } - - public void reloadColorOverride() { - this.colorOverride = GT_GUIColorOverride.get(guiTexturePath); - } - - public abstract T createDataObject(int aLegacyData); - - public abstract T createDataObject(); - - public final T createDataObject(NBTBase aNBT) { - // Handle legacy data (migrating from GT_CoverBehavior to GT_CoverBehaviorBase) - if (aNBT instanceof NBTTagInt) { - return createDataObject(((NBTTagInt) aNBT).func_150287_d()); - } - - final T ret = createDataObject(); - ret.loadDataFromNBT(aNBT); - return ret; - } - - public final T cast(ISerializableObject aData) { - if (typeToken.isInstance(aData)) return forceCast(aData); - return null; - } - - private T forceCast(ISerializableObject aData) { - try { - return typeToken.cast(aData); - } catch (Exception e) { - throw new RuntimeException("Casting data in " + this.getClass() + ", data " + aData, e); - } - } - - // region facade - - /** - * Get target facade block. Does not affect rendering of **this** block. It is only used as a hint for other block - * in case of CTM - * - * @return null if none, otherwise return facade target block - */ - public final Block getFacadeBlock(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getFacadeBlockImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Get target facade block. Does not affect rendering of **this** block. It is only used as a hint for other block - * in case of CTM - * - * @return 0 if none, otherwise return facade target meta - */ - public final int getFacadeMeta(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getFacadeMetaImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Get the display stack. Default to {@code int2Stack(aCoverID)} - */ - public final ItemStack getDisplayStack(int aCoverID, ISerializableObject aCoverVariable) { - return getDisplayStackImpl(aCoverID, forceCast(aCoverVariable)); - } - - /** - * Get the special foreground cover texture associated with this cover. Return null if one should use the texture - * passed to {@link gregtech.api.GregTech_API#registerCover(ItemStack, ITexture, GT_CoverBehaviorBase)} or its - * overloads. - */ - public final ITexture getSpecialCoverFGTexture(ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return getSpecialCoverFGTextureImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Get the special cover texture associated with this cover. Return null if one should use the texture passed to - * {@link gregtech.api.GregTech_API#registerCover(ItemStack, ITexture, GT_CoverBehaviorBase)} or its overloads. - */ - public final ITexture getSpecialCoverTexture(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getSpecialCoverTextureImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Return whether cover data needs to be synced to client upon tile entity creation or cover placement. - *

- * Note if you want to sync the data afterwards you will have to manually do it by calling - * {@link ICoverable#issueCoverUpdate(ForgeDirection)} This option only affects the initial sync. - */ - public final boolean isDataNeededOnClient(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return isDataNeededOnClientImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Called upon receiving data from network. Use {@link ICoverable#isClientSide()} to determine the side. - */ - public final void onDataChanged(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - onDataChangedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Called before receiving data from network. Use {@link ICoverable#isClientSide()} to determine the side. - */ - public final void preDataChanged(ForgeDirection side, int aCoverID, int aNewCoverId, - ISerializableObject aCoverVariable, ISerializableObject aNewCoverVariable, ICoverable aTileEntity) { - preDataChangedImpl( - side, - aCoverID, - aNewCoverId, - forceCast(aCoverVariable), - forceCast(aNewCoverVariable), - aTileEntity); - } - - /** - * Called upon cover being removed. Called on both server and client. - */ - public final void onDropped(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - onDroppedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - public final boolean isRedstoneSensitive(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity, long aTimer) { - return isRedstoneSensitiveImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aTimer); - } - - /** - * Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time. - */ - public final T doCoverThings(ForgeDirection side, byte aInputRedstone, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity, long aTimer) { - return doCoverThingsImpl(side, aInputRedstone, aCoverID, forceCast(aCoverVariable), aTileEntity, aTimer); - } - - /** - * Called when someone rightclicks this Cover. - *

- * return true, if something actually happens. - */ - public final boolean onCoverRightClick(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { - return onCoverRightClickImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ); - } - - /** - * Called when someone rightclicks this Cover with a Screwdriver. Doesn't call @onCoverRightclick in this Case. - *

- * return the new Value of the Cover Variable - */ - public final T onCoverScrewdriverClick(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) { - return onCoverScrewdriverClickImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aPlayer, aX, aY, aZ); - } - - /** - * Called when someone shift-rightclicks this Cover with no tool. Doesn't call @onCoverRightclick in this Case. - */ - public final boolean onCoverShiftRightClick(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity, EntityPlayer aPlayer) { - return onCoverShiftRightClickImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aPlayer); - } - - /** - * Removes the Cover if this returns true, or if aForced is true. Doesn't get called when the Machine Block is - * getting broken, only if you break the Cover away from the Machine. - */ - public final boolean onCoverRemoval(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity, boolean aForced) { - return onCoverRemovalImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity, aForced); - } - - /** - * Called upon Base TE being destroyed (once getDrops is called), thus getting called only when destroyed in - * survival. - */ - public final void onBaseTEDestroyed(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - onBaseTEDestroyedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Gives a small Text for the status of the Cover. - */ - public final String getDescription(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getDescriptionImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Called when Base TE being unloaded. - */ - public void onCoverUnload(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - onCoverUnloadImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * How Blast Proof the Cover is. 30 is normal. - */ - public final float getBlastProofLevel(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getBlastProofLevelImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * If it lets RS-Signals into the Block - *

- * This is just Informative so that Machines know if their Redstone Input is blocked or not - */ - public final boolean letsRedstoneGoIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return letsRedstoneGoInImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * If it lets RS-Signals out of the Block - */ - public final boolean letsRedstoneGoOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return letsRedstoneGoOutImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * If it lets Energy into the Block - */ - public final boolean letsEnergyIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return letsEnergyInImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * If it lets Energy out of the Block - */ - public final boolean letsEnergyOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return letsEnergyOutImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * If it lets Liquids into the Block, aFluid can be null meaning if this is generally allowing Fluids or not. - */ - public final boolean letsFluidIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - Fluid aFluid, ICoverable aTileEntity) { - return letsFluidInImpl(side, aCoverID, forceCast(aCoverVariable), aFluid, aTileEntity); - } - - /** - * If it lets Liquids out of the Block, aFluid can be null meaning if this is generally allowing Fluids or not. - */ - public final boolean letsFluidOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - Fluid aFluid, ICoverable aTileEntity) { - return letsFluidOutImpl(side, aCoverID, forceCast(aCoverVariable), aFluid, aTileEntity); - } - - /** - * If it lets Items into the Block, aSlot = -1 means if it is generally accepting Items (return false for no - * reaction at all), aSlot = -2 means if it would accept for all Slots Impl(return true to skip the Checks for each - * Slot). - */ - public final boolean letsItemsIn(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return letsItemsInImpl(side, aCoverID, forceCast(aCoverVariable), aSlot, aTileEntity); - } - - /** - * If it lets Items out of the Block, aSlot = -1 means if it is generally accepting Items (return false for no - * reaction at all), aSlot = -2 means if it would accept for all Slots Impl(return true to skip the Checks for each - * Slot). - */ - public final boolean letsItemsOut(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return letsItemsOutImpl(side, aCoverID, forceCast(aCoverVariable), aSlot, aTileEntity); - } - - /** - * If it lets you rightclick the Machine normally - */ - public final boolean isGUIClickable(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return isGUIClickableImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Needs to return true for Covers, which have a Redstone Output on their Facing. - */ - public final boolean manipulatesSidedRedstoneOutput(ForgeDirection side, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return manipulatesSidedRedstoneOutputImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * if this Cover should let Pipe Connections look connected even if it is not the case. - */ - public final boolean alwaysLookConnected(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return alwaysLookConnectedImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Called to determine the incoming Redstone Signal of a Machine. Returns the original Redstone per default. The - * Cover should @letsRedstoneGoIn or the aInputRedstone Parameter is always 0. - */ - public final byte getRedstoneInput(ForgeDirection side, byte aInputRedstone, int aCoverID, - ISerializableObject aCoverVariable, ICoverable aTileEntity) { - return getRedstoneInputImpl(side, aInputRedstone, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Gets the Tick Rate for doCoverThings of the Cover - *

- * 0 = No Ticks! Yes, 0 is Default, you have to override this - */ - public final int getTickRate(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getTickRateImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * The MC Color of this Lens. -1 for no Color (meaning this isn't a Lens then). - */ - public final byte getLensColor(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getLensColorImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * @return the ItemStack dropped by this Cover - */ - public final ItemStack getDrop(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) { - return getDropImpl(side, aCoverID, forceCast(aCoverVariable), aTileEntity); - } - - /** - * Called when the cover is initially attached to a machine. - * - * @param player The attaching player - * @param aCover An {@link ItemStack} containing the cover - * @param aTileEntity The machine receiving the cover - * @param side Which side the cover is attached to - */ - public void onPlayerAttach(EntityPlayer player, ItemStack aCover, ICoverable aTileEntity, ForgeDirection side) { - // Do nothing by default. - } - - // endregion - - // region UI stuff - - protected GT_TooltipDataCache mTooltipCache = new GT_TooltipDataCache(); - protected GT_GUIColorOverride colorOverride; - private static final String guiTexturePath = "gregtech:textures/gui/GuiCover.png"; - - public ModularWindow createWindow(GT_CoverUIBuildContext buildContext) { - return new UIFactory(buildContext).createWindow(); - } - - /** - * Creates {@link ModularWindow} for this cover. This is separated from base class, as attaching the same covers in - * different sides of the same tile needs different UI with different context. - */ - protected class UIFactory { - - private final GT_CoverUIBuildContext uiBuildContext; - - public UIFactory(GT_CoverUIBuildContext buildContext) { - this.uiBuildContext = buildContext; - } - - public ModularWindow createWindow() { - ModularWindow.Builder builder = ModularWindow.builder(getGUIWidth(), getGUIHeight()); - builder.setBackground(ModularUITextures.VANILLA_BACKGROUND); - builder.setGuiTint(getUIBuildContext().getGuiColorization()); - maybeBindPlayerInventory(builder); - addTitleToUI(builder); - addUIWidgets(builder); - if (getUIBuildContext().isAnotherWindow()) { - builder.widget( - ButtonWidget.closeWindowButton(true) - .setPos(getGUIWidth() - 15, 3)); - } - - final CoverInfo coverInfo = uiBuildContext.getTile() - .getCoverInfoAtSide(uiBuildContext.getCoverSide()); - final GT_CoverBehaviorBase behavior = coverInfo.getCoverBehavior(); - if (coverInfo.getMinimumTickRate() > 0 && behavior.allowsTickRateAddition()) { - builder.widget( - new GT_CoverTickRateButton(coverInfo, builder).setPos(getGUIWidth() - 24, getGUIHeight() - 24)); - } - - return builder.build(); - } - - protected void maybeBindPlayerInventory(ModularWindow.Builder builder) { - if (doesBindPlayerInventory() && !getUIBuildContext().isAnotherWindow()) { - builder.bindPlayerInventory(getUIBuildContext().getPlayer(), 7, GUITextureSet.DEFAULT.getItemSlot()); - } - } - - /** - * Override this to add widgets for your UI. - */ - protected void addUIWidgets(ModularWindow.Builder builder) {} - - public GT_CoverUIBuildContext getUIBuildContext() { - return uiBuildContext; - } - - /** - * Can return null when cover data is invalid e.g. tile is broken or cover is removed - */ - @Nullable - public T getCoverData() { - if (isCoverValid()) { - return forceCast( - getUIBuildContext().getTile() - .getComplexCoverDataAtSide(getUIBuildContext().getCoverSide())); - } else { - return null; - } - } - - public boolean setCoverData(T data) { - if (isCoverValid()) { - getUIBuildContext().getTile() - .receiveCoverData( - getUIBuildContext().getCoverSide(), - getUIBuildContext().getCoverID(), - data, - getUIBuildContext().getPlayer() instanceof EntityPlayerMP - ? (EntityPlayerMP) getUIBuildContext().getPlayer() - : null); - return true; - } else { - return false; - } - } - - public boolean isCoverValid() { - return !getUIBuildContext().getTile() - .isDead() - && getUIBuildContext().getTile() - .getCoverBehaviorAtSideNew(getUIBuildContext().getCoverSide()) != GregTech_API.sNoBehavior; - } - - protected void addTitleToUI(ModularWindow.Builder builder) { - ItemStack coverItem = GT_Utility.intToStack(getUIBuildContext().getCoverID()); - if (coverItem != null) { - builder.widget( - new ItemDrawable(coverItem).asWidget() - .setPos(5, 5) - .setSize(16, 16)) - .widget( - new TextWidget(coverItem.getDisplayName()).setDefaultColor(COLOR_TITLE.get()) - .setPos(25, 9)); - } - } - - protected int getGUIWidth() { - return 176; - } - - protected int getGUIHeight() { - return 107; - } - - protected boolean doesBindPlayerInventory() { - return false; - } - - protected int getTextColorOrDefault(String textType, int defaultColor) { - return colorOverride.getTextColorOrDefault(textType, defaultColor); - } - - protected final Supplier COLOR_TITLE = () -> getTextColorOrDefault("title", 0x222222); - protected final Supplier COLOR_TEXT_GRAY = () -> getTextColorOrDefault("text_gray", 0x555555); - protected final Supplier COLOR_TEXT_WARN = () -> getTextColorOrDefault("text_warn", 0xff0000); - } - - // endregion - - // region impl - - protected Block getFacadeBlockImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return null; - } - - protected int getFacadeMetaImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return 0; - } - - protected ItemStack getDisplayStackImpl(int aCoverID, T aCoverVariable) { - return GT_Utility.intToStack(aCoverID); - } - - protected ITexture getSpecialCoverFGTextureImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return coverFGTexture; - } - - protected ITexture getSpecialCoverTextureImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return null; - } - - protected boolean isDataNeededOnClientImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - protected void onDataChangedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {} - - protected void preDataChangedImpl(ForgeDirection side, int aCoverID, int aNewCoverId, T aCoverVariable, - T aNewCoverVariable, ICoverable aTileEntity) {} - - protected void onDroppedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {} - - protected void onBaseTEDestroyedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {} - - protected void onCoverUnloadImpl(ForgeDirection side, int aCoverID, ISerializableObject aCoverVariable, - ICoverable aTileEntity) {} - - protected boolean isRedstoneSensitiveImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity, long aTimer) { - return false; - } - - /** - * Called by updateEntity inside the covered TileEntity. aCoverVariable is the Value you returned last time. - */ - protected T doCoverThingsImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, T aCoverVariable, - ICoverable aTileEntity, long aTimer) { - return aCoverVariable; - } - - /** - * Called when someone rightclicks this Cover. - *

- * return true, if something actually happens. - */ - protected boolean onCoverRightClickImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer, float aX, float aY, float aZ) { - return false; - } - - /** - * Called when someone rightclicks this Cover with a Screwdriver. Doesn't call @onCoverRightclick in this Case. - *

- * return the new Value of the Cover Variable - */ - protected T onCoverScrewdriverClickImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity, - EntityPlayer aPlayer, float aX, float aY, float aZ) { - return aCoverVariable; - } - - /** - * Called when someone shift-rightclicks this Cover with no tool. Doesn't call @onCoverRightclick in this Case. - */ - protected boolean onCoverShiftRightClickImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity, EntityPlayer aPlayer) { - if (hasCoverGUI() && aPlayer instanceof EntityPlayerMP) { - lastPlayer = new WeakReference<>(aPlayer); - GT_UIInfos.openCoverUI(aTileEntity, aPlayer, side); - return true; - } - return false; - } - - /** - * Removes the Cover if this returns true, or if aForced is true. Doesn't get called when the Machine Block is - * getting broken, only if you break the Cover away from the Machine. - */ - protected boolean onCoverRemovalImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity, - boolean aForced) { - return true; - } - - /** - * Gives a small Text for the status of the Cover. - */ - protected String getDescriptionImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return E; - } - - /** - * How Blast Proof the Cover is. 30 is normal. - */ - protected float getBlastProofLevelImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return 10.0F; - } - - /** - * If it lets RS-Signals into the Block - *

- * This is just Informative so that Machines know if their Redstone Input is blocked or not - */ - protected boolean letsRedstoneGoInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets RS-Signals out of the Block - */ - protected boolean letsRedstoneGoOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Energy into the Block - */ - protected boolean letsEnergyInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Energy out of the Block - */ - protected boolean letsEnergyOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Liquids into the Block, aFluid can be null meaning if this is generally allowing Fluids or not. - */ - protected boolean letsFluidInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Liquids out of the Block, aFluid can be null meaning if this is generally allowing Fluids or not. - */ - protected boolean letsFluidOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, Fluid aFluid, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Items into the Block, aSlot = -1 means if it is generally accepting Items (return false for no - * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each - * Slot). - */ - protected boolean letsItemsInImpl(ForgeDirection side, int aCoverID, T aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets Items out of the Block, aSlot = -1 means if it is generally accepting Items (return false for no - * Interaction at all), aSlot = -2 means if it would accept for all Slots (return true to skip the Checks for each - * Slot). - */ - protected boolean letsItemsOutImpl(ForgeDirection side, int aCoverID, T aCoverVariable, int aSlot, - ICoverable aTileEntity) { - return false; - } - - /** - * If it lets you rightclick the Machine normally - */ - protected boolean isGUIClickableImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return true; - } - - /** - * Needs to return true for Covers, which have a Redstone Output on their Facing. - */ - protected boolean manipulatesSidedRedstoneOutputImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - /** - * if this Cover should let Pipe Connections look connected even if it is not the case. - */ - protected boolean alwaysLookConnectedImpl(ForgeDirection side, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return false; - } - - /** - * Called to determine the incoming Redstone Signal of a Machine. Returns the original Redstone per default. The - * Cover should @letsRedstoneGoIn or the aInputRedstone Parameter is always 0. - */ - protected byte getRedstoneInputImpl(ForgeDirection side, byte aInputRedstone, int aCoverID, T aCoverVariable, - ICoverable aTileEntity) { - return letsRedstoneGoIn(side, aCoverID, aCoverVariable, aTileEntity) ? aInputRedstone : 0; - } - - /** - * Gets the Tick Rate for doCoverThings of the Cover - *

- * 0 = No Ticks! Yes, 0 is Default, you have to override this - */ - protected int getTickRateImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return 0; - } - - /** - * The MC Color of this Lens. -1 for no Color (meaning this isn't a Lens then). - */ - protected byte getLensColorImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return -1; - } - - /** - * @return the ItemStack dropped by this Cover - */ - protected ItemStack getDropImpl(ForgeDirection side, int aCoverID, T aCoverVariable, ICoverable aTileEntity) { - return GT_OreDictUnificator.get(true, aTileEntity.getCoverItemAtSide(side)); - } - - // endregion - - // region no data - - /** - * Checks if the Cover can be placed on this. - */ - public boolean isCoverPlaceable(ForgeDirection side, ItemStack aStack, ICoverable aTileEntity) { - return true; - } - - public boolean hasCoverGUI() { - return false; - } - - /** - * Called when someone rightclicks this Cover Client Side - *

- * return true, if something actually happens. - */ - public boolean onCoverRightclickClient(ForgeDirection side, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, - float aY, float aZ) { - return false; - } - - /** - * If this is a simple Cover, which can also be used on Bronze Machines and similar. - */ - public boolean isSimpleCover() { - return false; - } - - /** - * sets the Cover upon placement. - */ - public void placeCover(ForgeDirection side, ItemStack aCover, ICoverable aTileEntity) { - aTileEntity.setCoverIDAtSide(side, GT_Utility.stackToInt(aCover)); - } - - public boolean allowsCopyPasteTool() { - return true; - } - - public boolean allowsTickRateAddition() { - return true; - } - - @NotNull - public final List getAdditionalTooltip(ISerializableObject coverData) { - return getAdditionalTooltipImpl(forceCast(coverData)); - } - - /** - * Override to add to the tooltip generated when a user hovers over the cover on the left side of a machine's UI. - * - * @param coverData The cover data associated with the cover on a particular side. - * @return A list of new tooltip entries. Entries are inserted at the top, just after the name and direction line. - */ - protected List getAdditionalTooltipImpl(T coverData) { - return ImmutableList.of(); - } - // endregion -} diff --git a/src/main/java/gregtech/api/util/GT_CreativeTab.java b/src/main/java/gregtech/api/util/GT_CreativeTab.java deleted file mode 100644 index 1049f40278..0000000000 --- a/src/main/java/gregtech/api/util/GT_CreativeTab.java +++ /dev/null @@ -1,26 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -import gregtech.api.enums.ItemList; - -public class GT_CreativeTab extends CreativeTabs { - - public GT_CreativeTab(String aName, String aLocalName) { - super("GregTech." + aName); - GT_LanguageManager.addStringLocalization("itemGroup.GregTech." + aName, aLocalName); - } - - @Override - public ItemStack getIconItemStack() { - return ItemList.Tool_Cheat.get(1, new ItemStack(Blocks.iron_block, 1)); - } - - @Override - public Item getTabIconItem() { - return ItemList.Circuit_Integrated.getItem(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_ExoticEnergyInputHelper.java b/src/main/java/gregtech/api/util/GT_ExoticEnergyInputHelper.java deleted file mode 100644 index d59796b251..0000000000 --- a/src/main/java/gregtech/api/util/GT_ExoticEnergyInputHelper.java +++ /dev/null @@ -1,114 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.util.GT_Utility.filterValidMTEs; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch; - -public class GT_ExoticEnergyInputHelper { - - /** - * The Valid Types of TecTech Hatch List. - */ - private static final List> sExoticEnergyHatchType = new ArrayList<>(); - - static { - tryRegister("com.github.technus.tectech.thing.metaTileEntity.hatch.GT_MetaTileEntity_Hatch_EnergyMulti"); - tryRegister("com.github.technus.tectech.thing.metaTileEntity.hatch.GT_MetaTileEntity_Hatch_EnergyTunnel"); - } - - public static void register(Class clazz) { - if (!GT_MetaTileEntity_Hatch.class.isAssignableFrom(clazz)) throw new IllegalArgumentException( - clazz.getName() + " is not a subclass of " + GT_MetaTileEntity_Hatch.class.getName()); - sExoticEnergyHatchType.add(clazz); - } - - @SuppressWarnings("unchecked") - public static void tryRegister(String className) { - Class clazz; - try { - clazz = Class.forName(className); - } catch (ClassNotFoundException e) { - return; - } - if (!GT_MetaTileEntity_Hatch.class.isAssignableFrom(clazz)) throw new IllegalArgumentException( - clazz.getName() + " is not a subclass of " + GT_MetaTileEntity_Hatch.class.getName()); - sExoticEnergyHatchType.add((Class) clazz); - } - - public static boolean drainEnergy(long aEU, Collection hatches) { - for (GT_MetaTileEntity_Hatch tHatch : hatches) { - long tDrain = Math.min( - tHatch.getBaseMetaTileEntity() - .getStoredEU(), - aEU); - tHatch.getBaseMetaTileEntity() - .decreaseStoredEnergyUnits(tDrain, false); - aEU -= tDrain; - } - return aEU <= 0; - } - - public static boolean isExoticEnergyInput(IMetaTileEntity aHatch) { - for (Class clazz : sExoticEnergyHatchType) { - if (clazz.isInstance(aHatch)) return true; - } - return false; - } - - public static long getTotalEuMulti(Collection hatches) { - long rEU = 0L; - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(hatches)) { - rEU += tHatch.getBaseMetaTileEntity() - .getInputVoltage() * tHatch.maxWorkingAmperesIn(); - } - return rEU; - } - - public static long getMaxInputVoltageMulti(Collection hatches) { - long rVoltage = 0; - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(hatches)) { - rVoltage += tHatch.getBaseMetaTileEntity() - .getInputVoltage(); - } - return rVoltage; - } - - public static long getAverageInputVoltageMulti(Collection hatches) { - long rVoltage = 0; - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(hatches)) { - rVoltage += tHatch.getBaseMetaTileEntity() - .getInputVoltage(); - } - if (hatches.isEmpty()) { - return 0; - } - return rVoltage / hatches.size(); - } - - public static long getMaxInputAmpsMulti(Collection hatches) { - long rAmp = 0; - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(hatches)) { - rAmp += tHatch.getBaseMetaTileEntity() - .getInputAmperage(); - } - return rAmp; - } - - public static long getMaxWorkingInputAmpsMulti(Collection hatches) { - long rAmp = 0; - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(hatches)) { - rAmp += tHatch.maxWorkingAmperesIn(); - } - return rAmp; - } - - public static List> getAllClasses() { - return Collections.unmodifiableList(sExoticEnergyHatchType); - } -} diff --git a/src/main/java/gregtech/api/util/GT_FoodStat.java b/src/main/java/gregtech/api/util/GT_FoodStat.java deleted file mode 100644 index 5eda76f9d0..0000000000 --- a/src/main/java/gregtech/api/util/GT_FoodStat.java +++ /dev/null @@ -1,122 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.EnumAction; -import net.minecraft.item.ItemStack; -import net.minecraft.potion.PotionEffect; - -import gregtech.api.damagesources.GT_DamageSources; -import gregtech.api.enums.SoundResource; -import gregtech.api.interfaces.IFoodStat; -import gregtech.api.items.GT_MetaBase_Item; - -public class GT_FoodStat implements IFoodStat { - - private final int mFoodLevel; - private final int[] mPotionEffects; - private final float mSaturation; - private final EnumAction mAction; - private final ItemStack mEmptyContainer; - private final boolean mAlwaysEdible, mInvisibleParticles, mIsRotten; - private boolean mExplosive = false, mMilk = false; - - /** - * @param aFoodLevel Amount of Food in Half Bacon [0 - 20] - * @param aSaturation Amount of Saturation [0.0F - 1.0F] - * @param aAction The Action to be used. If this is null, it uses the Eating Action - * @param aEmptyContainer An empty Container (Optional) - * @param aAlwaysEdible If this Item is always edible, like Golden Apples or Potions - * @param aInvisibleParticles If the Particles of the Potion Effects are invisible - * @param aPotionEffects An Array of Potion Effects with %4==0 Elements as follows ID of a Potion Effect. 0 for - * none Duration of the Potion in Ticks Level of the Effect. [0, 1, 2] are for [I, II, - * III] The likelihood that this Potion Effect takes place upon being eaten [1 - 100] - */ - public GT_FoodStat(int aFoodLevel, float aSaturation, EnumAction aAction, ItemStack aEmptyContainer, - boolean aAlwaysEdible, boolean aInvisibleParticles, boolean aIsRotten, int... aPotionEffects) { - mFoodLevel = aFoodLevel; - mSaturation = aSaturation; - mAction = aAction == null ? EnumAction.eat : aAction; - mPotionEffects = aPotionEffects; - mEmptyContainer = GT_Utility.copyOrNull(aEmptyContainer); - mInvisibleParticles = aInvisibleParticles; - mAlwaysEdible = aAlwaysEdible; - mIsRotten = aIsRotten; - } - - public GT_FoodStat setExplosive() { - mExplosive = true; - return this; - } - - public GT_FoodStat setMilk() { - mMilk = true; - return this; - } - - @Override - public int getFoodLevel(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer) { - return mFoodLevel; - } - - @Override - public float getSaturation(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer) { - return mSaturation; - } - - @Override - public void onEaten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer) { - aStack.stackSize--; - ItemStack tStack = GT_OreDictUnificator.get(GT_Utility.copyOrNull(mEmptyContainer)); - if (tStack != null && !aPlayer.inventory.addItemStackToInventory(tStack)) - aPlayer.dropPlayerItemWithRandomChoice(tStack, true); - - new WorldSpawnedEventBuilder.SoundAtEntityEventBuilder().setIdentifier(SoundResource.RANDOM_BURP) - .setVolume(0.5F) - .setPitch(aPlayer.worldObj.rand.nextFloat() * 0.1F + 0.9F) - .setEntity(aPlayer) - .setWorld(aPlayer.worldObj) - .run(); - - if (!aPlayer.worldObj.isRemote) { - if (mMilk) { - aPlayer.curePotionEffects(new ItemStack(Items.milk_bucket, 1, 0)); - } - for (int i = 3; i < mPotionEffects.length; i += 4) { - if (aPlayer.worldObj.rand.nextInt(100) < mPotionEffects[i]) { - aPlayer.addPotionEffect( - new PotionEffect( - mPotionEffects[i - 3], - mPotionEffects[i - 2], - mPotionEffects[i - 1], - mInvisibleParticles)); - } - } - if (mExplosive) { - new WorldSpawnedEventBuilder.ExplosionEffectEventBuilder().setSmoking(true) - .setFlaming(true) - .setStrength(4f) - .setPosition(aPlayer.posX, aPlayer.posY, aPlayer.posZ) - .setEntity(aPlayer) - .setWorld(aPlayer.worldObj) - .run(); - aPlayer.attackEntityFrom(GT_DamageSources.getExplodingDamage(), Float.MAX_VALUE); - } - } - } - - @Override - public EnumAction getFoodAction(GT_MetaBase_Item aItem, ItemStack aStack) { - return mAction; - } - - @Override - public boolean alwaysEdible(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer) { - return mAlwaysEdible; - } - - @Override - public boolean isRotten(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer) { - return mIsRotten; - } -} diff --git a/src/main/java/gregtech/api/util/GT_Forestry_Compat.java b/src/main/java/gregtech/api/util/GT_Forestry_Compat.java deleted file mode 100644 index 554964a4ed..0000000000 --- a/src/main/java/gregtech/api/util/GT_Forestry_Compat.java +++ /dev/null @@ -1,193 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.recipe.RecipeMaps.centrifugeNonCellRecipes; -import static gregtech.api.recipe.RecipeMaps.centrifugeRecipes; -import static gregtech.api.recipe.RecipeMaps.scannerFakeRecipes; -import static gregtech.api.util.GT_RecipeBuilder.SECONDS; -import static gregtech.api.util.GT_RecipeBuilder.TICKS; - -import java.util.Map; - -import net.minecraft.item.ItemStack; - -import forestry.api.recipes.ICentrifugeRecipe; -import forestry.api.recipes.ISqueezerRecipe; -import forestry.api.recipes.RecipeManagers; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.recipe.RecipeMaps; - -public class GT_Forestry_Compat { - - public static void populateFakeNeiRecipes() { - if (ItemList.FR_Bee_Drone.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Bee_Drone.getWildcard(1L)) - .itemOutputs(ItemList.FR_Bee_Drone.getWithName(1L, "Scanned Drone")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Bee_Princess.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Bee_Princess.getWildcard(1L)) - .itemOutputs(ItemList.FR_Bee_Princess.getWithName(1L, "Scanned Princess")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Bee_Queen.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Bee_Queen.getWildcard(1L)) - .itemOutputs(ItemList.FR_Bee_Queen.getWithName(1L, "Scanned Queen")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Tree_Sapling.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Tree_Sapling.getWildcard(1L)) - .itemOutputs(ItemList.FR_Tree_Sapling.getWithName(1L, "Scanned Sapling")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Butterfly.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Butterfly.getWildcard(1L)) - .itemOutputs(ItemList.FR_Butterfly.getWithName(1L, "Scanned Butterfly")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Larvae.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Larvae.getWildcard(1L)) - .itemOutputs(ItemList.FR_Larvae.getWithName(1L, "Scanned Larvae")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Serum.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Serum.getWildcard(1L)) - .itemOutputs(ItemList.FR_Serum.getWithName(1L, "Scanned Serum")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_Caterpillar.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_Caterpillar.getWildcard(1L)) - .itemOutputs(ItemList.FR_Caterpillar.getWithName(1L, "Scanned Caterpillar")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - if (ItemList.FR_PollenFertile.get(1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(ItemList.FR_PollenFertile.getWildcard(1L)) - .itemOutputs(ItemList.FR_PollenFertile.getWithName(1L, "Scanned Pollen")) - .fluidInputs(Materials.Honey.getFluid(100L)) - .duration(25 * SECONDS) - .eut(2) - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes); - } - } - - public static void transferCentrifugeRecipes() { - try { - for (ICentrifugeRecipe tRecipe : RecipeManagers.centrifugeManager.recipes()) { - Map outputs = tRecipe.getAllProducts(); - ItemStack[] tOutputs = new ItemStack[outputs.size()]; - int[] tChances = new int[outputs.size()]; - int i = 0; - for (Map.Entry entry : outputs.entrySet()) { - tChances[i] = (int) (entry.getValue() * 10000); - tOutputs[i] = entry.getKey() - .copy(); - i++; - } - GT_Values.RA.stdBuilder() - .itemInputs(tRecipe.getInput()) - .itemOutputs(tOutputs) - .outputChances(tChances) - .duration(6 * SECONDS + 8 * TICKS) - .eut(5) - .addTo(centrifugeRecipes); - - GT_Values.RA.stdBuilder() - .itemInputs(tRecipe.getInput()) - .itemOutputs(tOutputs) - .outputChances(tChances) - .duration(6 * SECONDS + 8 * TICKS) - .eut(5) - .addTo(centrifugeNonCellRecipes); - } - } catch (Throwable e) { - if (GT_Values.D1) { - e.printStackTrace(GT_Log.err); - } - } - } - - public static void transferSqueezerRecipes() { - try { - for (ISqueezerRecipe tRecipe : RecipeManagers.squeezerManager.recipes()) { - if ((tRecipe.getResources().length == 1) && (tRecipe.getFluidOutput() != null) - && (tRecipe.getResources()[0] != null)) { - GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder(); - recipeBuilder.itemInputs(tRecipe.getResources()[0]); - if (tRecipe.getRemnants() != null) { - recipeBuilder.itemOutputs(tRecipe.getRemnants()) - .outputChances((int) (tRecipe.getRemnantsChance() * 10000)); - } - recipeBuilder.fluidOutputs(tRecipe.getFluidOutput()) - .duration(1 * SECONDS + 12 * TICKS) - .eut(8) - .addTo(RecipeMaps.fluidExtractionRecipes); - } - } - } catch (Throwable e) { - if (GT_Values.D1) { - e.printStackTrace(GT_Log.err); - } - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_GC_Compat.java b/src/main/java/gregtech/api/util/GT_GC_Compat.java deleted file mode 100644 index 24710ab0ac..0000000000 --- a/src/main/java/gregtech/api/util/GT_GC_Compat.java +++ /dev/null @@ -1,52 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.Mods.GalacticraftCore; - -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.common.util.ForgeDirection; - -import micdoodle8.mods.galacticraft.api.power.EnergySource; -import micdoodle8.mods.galacticraft.api.power.EnergySource.EnergySourceAdjacent; -import micdoodle8.mods.galacticraft.api.power.IEnergyHandlerGC; -import micdoodle8.mods.galacticraft.api.transmission.NetworkType; -import micdoodle8.mods.galacticraft.api.transmission.tile.IConnector; -import micdoodle8.mods.galacticraft.core.energy.EnergyConfigHandler; - -public class GT_GC_Compat { - - public static long insertEnergyInto(TileEntity tTileEntity, long aVoltage, ForgeDirection tDirection) { - // GC Compat - if (GalacticraftCore.isModLoaded() && tTileEntity instanceof IEnergyHandlerGC) { - if (!(tTileEntity instanceof IConnector) - || ((IConnector) tTileEntity).canConnect(tDirection, NetworkType.POWER)) { - EnergySource eSource = new EnergySourceAdjacent(tDirection); - - float tSizeToReceive = aVoltage * EnergyConfigHandler.IC2_RATIO, - tStored = ((IEnergyHandlerGC) tTileEntity).getEnergyStoredGC(eSource); - if (tSizeToReceive >= tStored - || tSizeToReceive <= ((IEnergyHandlerGC) tTileEntity).getMaxEnergyStoredGC(eSource) - tStored) { - float tReceived = ((IEnergyHandlerGC) tTileEntity).receiveEnergyGC(eSource, tSizeToReceive, false); - if (tReceived > 0) { - tSizeToReceive -= tReceived; - while (tSizeToReceive > 0) { - tReceived = ((IEnergyHandlerGC) tTileEntity) - .receiveEnergyGC(eSource, tSizeToReceive, false); - if (tReceived < 1) break; - tSizeToReceive -= tReceived; - } - return 1; - } - } - } - return 0; - } - return 2; - } - - public static boolean canConnect(TileEntity tTileEntity, ForgeDirection tDirection) { - // GC Compat - return GalacticraftCore.isModLoaded() && tTileEntity instanceof IEnergyHandlerGC - && (!(tTileEntity instanceof IConnector) - || ((IConnector) tTileEntity).canConnect(tDirection, NetworkType.POWER)); - } -} diff --git a/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java b/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java deleted file mode 100644 index 416edc9c11..0000000000 --- a/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java +++ /dev/null @@ -1,547 +0,0 @@ -package gregtech.api.util; - -import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.IChatComponent; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; -import com.gtnewhorizon.structurelib.structure.IItemSource; -import com.gtnewhorizon.structurelib.structure.IStructureElement; -import com.gtnewhorizon.structurelib.structure.IStructureElementChain; -import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; -import com.gtnewhorizon.structurelib.structure.StructureUtility; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; - -import gnu.trove.TIntCollection; -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.set.hash.TIntHashSet; -import gregtech.api.interfaces.IHatchElement; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.common.blocks.GT_Item_Machines; - -public class GT_HatchElementBuilder { - - private interface Builtin { - } - - private IGT_HatchAdder mAdder; - private int mCasingIndex = -1; - private int mDot = -1; - private BiPredicate mShouldSkip; - private BiFunction> mHatchItemFilter; - private Supplier mHatchItemType; - private Predicate mReject; - private boolean mCacheHint; - private boolean mNoStop; - private boolean mExclusive; - private EnumSet mDisallowedDirection = EnumSet.noneOf(ForgeDirection.class); - - private GT_HatchElementBuilder() {} - - public static GT_HatchElementBuilder builder() { - return new GT_HatchElementBuilder<>(); - } - - // region composite - - /** - * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. TODO add doc - */ - @SafeVarargs - public final GT_HatchElementBuilder anyOf(IHatchElement... elements) { - if (elements == null || elements.length == 0) throw new IllegalArgumentException(); - return adder( - Arrays.stream(elements) - .map( - e -> e.adder() - .rebrand()) - .reduce(IGT_HatchAdder::orElse) - .get()).hatchClasses( - Arrays.stream(elements) - .map(IHatchElement::mteClasses) - .flatMap(Collection::stream) - .collect(Collectors.toList())) - .cacheHint( - () -> Arrays.stream(elements) - .map(IHatchElement::name) - .sorted() - .collect(Collectors.joining(" or ", "of type ", ""))); - } - - /** - * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. - *

- * Will rotate through all elements TODO add doc - */ - @SafeVarargs - public final GT_HatchElementBuilder atLeast(IHatchElement... elements) { - if (elements == null || elements.length == 0) throw new IllegalArgumentException(); - return atLeast( - Arrays.stream(elements) - .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))); - } - - /** - * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. - *

- * Will rotate through all elements TODO add doc - */ - public final GT_HatchElementBuilder atLeastList(List> elements) { - if (elements == null || elements.isEmpty()) throw new IllegalArgumentException(); - return atLeast( - elements.stream() - .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))); - } - - /** - * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. TODO add doc - */ - public final GT_HatchElementBuilder atLeast(Map, ? extends Number> elements) { - if (elements == null || elements.isEmpty() || elements.containsKey(null) || elements.containsValue(null)) - throw new IllegalArgumentException(); - List> list = elements.keySet() - .stream() - .map(IHatchElement::mteClasses) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - // map cannot be null or empty, so assert Optional isPresent - return adder( - elements.keySet() - .stream() - .map( - e -> e.adder() - .rebrand()) - .reduce(IGT_HatchAdder::orElse) - .orElseThrow(AssertionError::new)) - .hatchItemFilter( - obj -> GT_StructureUtility.filterByMTEClass( - elements.entrySet() - .stream() - .filter( - entry -> entry.getKey() - .count(obj) - < entry.getValue() - .longValue()) - .flatMap( - entry -> entry.getKey() - .mteClasses() - .stream()) - .collect(Collectors.toList()))) - .shouldReject( - obj -> elements.entrySet() - .stream() - .allMatch( - e -> e.getKey() - .count(obj) - >= e.getValue() - .longValue())) - .shouldSkip( - (BiPredicate & Builtin) (c, - t) -> t != null && list.stream() - .anyMatch(clazz -> clazz.isInstance(t.getMetaTileEntity()))) - .cacheHint( - () -> elements.keySet() - .stream() - .map(IHatchElement::name) - .sorted() - .collect(Collectors.joining(" or ", "of type ", ""))); - } - // endregion - - // region primitives - - /** - * Mark this hatch element as the only candidate of given structure element. (e.g. muffler hatch on top of EBF) - * Currently, this will make the built IStructureElement to ignore gt_no_hatch directive from player - * - * Do note that {@link #buildAndChain(IStructureElement[])} and its overloads will force the resulting structure - * element - * to be non-exclusive. - */ - public GT_HatchElementBuilder exclusive() { - mExclusive = true; - return this; - } - - public GT_HatchElementBuilder adder(IGT_HatchAdder aAdder) { - if (aAdder == null) throw new IllegalArgumentException(); - mAdder = aAdder; - return this; - } - - public GT_HatchElementBuilder casingIndex(int aCasingIndex) { - if (aCasingIndex <= 0) throw new IllegalArgumentException(); - mCasingIndex = aCasingIndex; - return this; - } - - public GT_HatchElementBuilder dot(int aDot) { - if (aDot <= 0) throw new IllegalArgumentException(); - mDot = aDot; - return this; - } - - public GT_HatchElementBuilder shouldSkip(BiPredicate aShouldSkip) { - if (!(aShouldSkip instanceof Builtin) || mShouldSkip != null) { - if (!(mShouldSkip instanceof Builtin) && mShouldSkip != null) throw new IllegalStateException(); - if (aShouldSkip == null) throw new IllegalArgumentException(); - } - mShouldSkip = aShouldSkip; - return this; - } - - public GT_HatchElementBuilder shouldReject(Predicate aShouldReject) { - if (aShouldReject == null) throw new IllegalArgumentException(); - mReject = aShouldReject; - return this; - } - - public GT_HatchElementBuilder hatchItemFilter( - Function> aHatchItemFilter) { - if (aHatchItemFilter == null) throw new IllegalArgumentException(); - mHatchItemFilter = (t, s) -> aHatchItemFilter.apply(t); - return this; - } - - public GT_HatchElementBuilder hatchItemFilterAnd( - Function> aHatchItemFilter) { - if (aHatchItemFilter == null) throw new IllegalArgumentException(); - BiFunction> tOldFilter = mHatchItemFilter; - mHatchItemFilter = (t, s) -> tOldFilter.apply(t, s) - .and(aHatchItemFilter.apply(t)); - return this; - } - - public GT_HatchElementBuilder hatchItemFilter( - BiFunction> aHatchItemFilter) { - if (aHatchItemFilter == null) throw new IllegalArgumentException(); - mHatchItemFilter = aHatchItemFilter; - return this; - } - - public GT_HatchElementBuilder hatchItemFilterAnd( - BiFunction> aHatchItemFilter) { - if (aHatchItemFilter == null) throw new IllegalArgumentException(); - BiFunction> tOldFilter = mHatchItemFilter; - mHatchItemFilter = (t, s) -> tOldFilter.apply(t, s) - .and(aHatchItemFilter.apply(t, s)); - return this; - } - - // region hint - public GT_HatchElementBuilder hint(Supplier aSupplier) { - if (aSupplier == null) throw new IllegalArgumentException(); - mHatchItemType = aSupplier; - mCacheHint = false; - return this; - } - - public GT_HatchElementBuilder cacheHint(Supplier aSupplier) { - if (aSupplier == null) throw new IllegalArgumentException(); - mHatchItemType = aSupplier; - mCacheHint = true; - return this; - } - - public GT_HatchElementBuilder cacheHint() { - if (mHatchItemType == null) throw new IllegalStateException(); - mCacheHint = true; - return this; - } - // endregion - - public GT_HatchElementBuilder continueIfSuccess() { - mNoStop = true; - return this; - } - - public GT_HatchElementBuilder stopIfSuccess() { - mNoStop = false; - return this; - } - - /** - * Help automatic hatch side determination code by ruling out some directions. Note the automatic hatch side - * determination code will choose to use the default facing if the final allowed facing set is empty. - *

- * This will clear the sides set by previous call to this or {@link #allowOnly(ForgeDirection...)} - *

- * Usually mandatory for multis with multiple slices, and otherwise not needed if it contains a single slice only. - * - * @param facings disallowed direction in ABC coordinate system - */ - public GT_HatchElementBuilder disallowOnly(ForgeDirection... facings) { - if (facings == null) throw new IllegalArgumentException(); - mDisallowedDirection = EnumSet.copyOf(Arrays.asList(facings)); - return this; - } - - /** - * Help automatic hatch side determination code by allowing only some directions. Note the automatic hatch side - * determination code will choose to use the default facing if the final allowed facing set is empty. - *

- * This will clear the sides set by previous call to this or {@link #disallowOnly(ForgeDirection...)} - *

- * Usually mandatory for multis with multiple slices, and otherwise not needed if it contains a single slice only. - * - * @param facings allowed direction in ABC coordinate system - */ - public GT_HatchElementBuilder allowOnly(ForgeDirection... facings) { - if (facings == null) throw new IllegalArgumentException(); - mDisallowedDirection = EnumSet.complementOf(EnumSet.copyOf(Arrays.asList(facings))); - mDisallowedDirection.remove(ForgeDirection.UNKNOWN); - return this; - } - // endregion - - // region intermediate - public GT_HatchElementBuilder hatchClass(Class clazz) { - return hatchItemFilter(c -> is -> clazz.isInstance(GT_Item_Machines.getMetaTileEntity(is))) - .cacheHint(() -> "of class " + clazz.getSimpleName()) - .shouldSkip( - (BiPredicate & Builtin) (c, t) -> clazz - .isInstance(t.getMetaTileEntity())); - } - - @SafeVarargs - public final GT_HatchElementBuilder hatchClasses(Class... classes) { - return hatchClasses(Arrays.asList(classes)); - } - - public final GT_HatchElementBuilder hatchClasses(List> classes) { - List> list = new ArrayList<>(classes); - return hatchItemFilter(obj -> GT_StructureUtility.filterByMTEClass(list)).cacheHint( - () -> list.stream() - .map(Class::getSimpleName) - .sorted() - .collect(Collectors.joining(" or ", "of class ", ""))) - .shouldSkip( - (BiPredicate & Builtin) (c, t) -> t != null && list.stream() - .anyMatch(clazz -> clazz.isInstance(t.getMetaTileEntity()))); - } - - public GT_HatchElementBuilder hatchId(int aId) { - return hatchItemFilter( - c -> is -> GT_Utility.isStackValid(is) && is.getItem() instanceof GT_Item_Machines - && is.getItemDamage() == aId).cacheHint(() -> "of id " + aId) - .shouldSkip( - (BiPredicate & Builtin) (c, t) -> t != null - && t.getMetaTileID() == aId); - } - - public GT_HatchElementBuilder hatchIds(int... aIds) { - if (aIds == null || aIds.length == 0) throw new IllegalArgumentException(); - if (aIds.length == 1) return hatchId(aIds[0]); - TIntCollection coll = aIds.length < 16 ? new TIntArrayList(aIds) : new TIntHashSet(aIds); - return hatchItemFilter( - c -> is -> GT_Utility.isStackValid(is) && is.getItem() instanceof GT_Item_Machines - && coll.contains(is.getItemDamage())).cacheHint( - () -> Arrays.stream(coll.toArray()) - .sorted() - .mapToObj(String::valueOf) - .collect(Collectors.joining(" or ", "of id ", ""))) - .shouldSkip( - (BiPredicate & Builtin) (c, t) -> t != null - && coll.contains(t.getMetaTileID())); - } - - // endregion - - @SuppressWarnings("unchecked") - @SafeVarargs - public final IStructureElementChain buildAndChain(IStructureElement... elements) { - // just in case - mExclusive = false; - List> l = new ArrayList<>(); - l.add(build()); - l.addAll(Arrays.asList(elements)); - IStructureElement[] array = l.toArray(new IStructureElement[0]); - return () -> array; - } - - public final IStructureElementChain buildAndChain(Block block, int meta) { - return buildAndChain(ofBlock(block, meta)); - } - - public IStructureElement build() { - if (mAdder == null || mCasingIndex == -1 || mDot == -1) { - throw new IllegalArgumentException(); - } - if (mHatchItemFilter == null) { - // no item filter -> no placement - return new IStructureElementNoPlacement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - return tileEntity instanceof IGregTechTileEntity - && mAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) mCasingIndex); - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), mDot - 1); - return true; - } - }; - } - return new IStructureElement<>() { - - private String mHint = mHatchItemType == null ? "unspecified GT hatch" : mHatchItemType.get(); - - @Override - public boolean check(T t, World world, int x, int y, int z) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - return tileEntity instanceof IGregTechTileEntity - && mAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) mCasingIndex); - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), mDot - 1); - return true; - } - - @Override - public boolean placeBlock(T t, World world, int i, int i1, int i2, ItemStack itemStack) { - // TODO - return false; - } - - private String getHint() { - if (mHint != null) return mHint; - String tHint = mHatchItemType.get(); - if (tHint == null) return "?"; - // TODO move this to some .lang instead of half ass it into the crappy gt lang file - tHint = GT_LanguageManager.addStringLocalization("Hatch_Type_" + tHint.replace(' ', '_'), tHint); - if (mCacheHint) { - mHint = tHint; - if (mHint != null) - // yeet the getter, since its product is retrieved and cached - mHatchItemType = null; - } - return tHint; - } - - @Override - public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - return BlocksToPlace.create(mHatchItemFilter.apply(t, trigger)); - } - - @Deprecated - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - return survivalPlaceBlock( - t, - world, - x, - y, - z, - trigger, - AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - if (mShouldSkip != null) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - if (tileEntity instanceof IGregTechTileEntity - && mShouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return PlaceResult.SKIP; - } - if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) - return PlaceResult.REJECT; - if (mReject != null && mReject.test(t)) return PlaceResult.REJECT; - if (ChannelDataAccessor.hasSubChannel(trigger, "gt_no_hatch") && !mExclusive) { - String type = getHint(); - env.getChatter() - .accept(new ChatComponentTranslation("GT5U.autoplace.error.no_hatch", type)); - return PlaceResult.REJECT; - } - ItemStack taken = env.getSource() - .takeOne(mHatchItemFilter.apply(t, trigger), true); - if (GT_Utility.isStackInvalid(taken)) { - String type = getHint(); - env.getChatter() - .accept(new ChatComponentTranslation("GT5U.autoplace.error.no_hatch", type)); - return PlaceResult.REJECT; - } - if (StructureUtility.survivalPlaceBlock( - taken, - ItemStackPredicate.NBTMode.IGNORE, - null, - true, - world, - x, - y, - z, - env.getSource(), - env.getActor()) != PlaceResult.ACCEPT) { - return PlaceResult.REJECT; - } - // try to infer facing - EnumSet allowed = EnumSet.noneOf(ForgeDirection.class); - // first find which face of block is not contained in structure - if (env.getAPILevel() == AutoPlaceEnvironment.APILevel.Legacy) { - // a legacy decorator isn't passing down necessary information - // in that case, we just assume all facing is allowed - allowed.addAll(Arrays.asList(ForgeDirection.VALID_DIRECTIONS)); - } else { - for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { - // as noted on getWorldDirection Y axis should be flipped before use - if (env.isContainedInPiece(direction.offsetX, -direction.offsetY, direction.offsetZ)) continue; - // explicitly rejected, probably obstructed by another slice - if (mDisallowedDirection.contains(direction)) continue; - ForgeDirection rotated = env.getFacing() - .getWorldDirection( - (direction.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) != 0 - ? direction.getOpposite() - : direction); - allowed.add(rotated); - } - } - if (!allowed.isEmpty()) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - if (tileEntity instanceof IGregTechTileEntity) { - ForgeDirection result = null; - // find the first facing available, but prefer a facing that isn't up/down - for (ForgeDirection facing : allowed) { - result = facing; - if ((facing.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) == 0) break; // Horizontal - } - assert result != null; - ((IGregTechTileEntity) tileEntity).setFrontFacing(result); - } - } - return mNoStop ? PlaceResult.ACCEPT : PlaceResult.ACCEPT_STOP; - } - }; - } -} diff --git a/src/main/java/gregtech/api/util/GT_IBoxableWrapper.java b/src/main/java/gregtech/api/util/GT_IBoxableWrapper.java deleted file mode 100644 index 796699c261..0000000000 --- a/src/main/java/gregtech/api/util/GT_IBoxableWrapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.item.ItemStack; - -import ic2.api.item.IBoxable; - -public class GT_IBoxableWrapper implements IBoxable { - - @Override - public boolean canBeStoredInToolbox(ItemStack itemstack) { - return GT_Utility.isStackInList(itemstack, GT_ModHandler.sBoxableItems); - } -} diff --git a/src/main/java/gregtech/api/util/GT_ItsNotMyFaultException.java b/src/main/java/gregtech/api/util/GT_ItsNotMyFaultException.java deleted file mode 100644 index f47a356d7b..0000000000 --- a/src/main/java/gregtech/api/util/GT_ItsNotMyFaultException.java +++ /dev/null @@ -1,18 +0,0 @@ -package gregtech.api.util; - -public class GT_ItsNotMyFaultException extends RuntimeException { - - private static final long serialVersionUID = -8752778866486460495L; - - private final String mError; - - public GT_ItsNotMyFaultException(String aError) { - mError = aError; - } - - @Override - public String toString() { - return "The GregTech-Addon has a Problem.\nIT'S NOT MY FAULT!!! Below is how to fix it.\n" + mError - + "\nDO NOT COME TO ME WITH THIS CRASH. YOU CAUSED IT YOURSELF, AND I TOLD YOU HOW TO FIX IT!!!"; - } -} diff --git a/src/main/java/gregtech/api/util/GT_JubilanceMegaApiary.java b/src/main/java/gregtech/api/util/GT_JubilanceMegaApiary.java deleted file mode 100644 index f20a58c34a..0000000000 --- a/src/main/java/gregtech/api/util/GT_JubilanceMegaApiary.java +++ /dev/null @@ -1,23 +0,0 @@ -package gregtech.api.util; - -import forestry.api.apiculture.IAlleleBeeSpecies; -import forestry.api.apiculture.IBeeGenome; -import forestry.api.apiculture.IBeeHousing; -import forestry.api.apiculture.IJubilanceProvider; - -public class GT_JubilanceMegaApiary implements IJubilanceProvider { - - public static final GT_JubilanceMegaApiary instance = new GT_JubilanceMegaApiary(); - - protected GT_JubilanceMegaApiary() {} - - @Override - public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { - return false; - } - - @Override - public String getDescription() { - return "Will only be produced in mega Apiary"; - } -} diff --git a/src/main/java/gregtech/api/util/GT_LanguageManager.java b/src/main/java/gregtech/api/util/GT_LanguageManager.java deleted file mode 100644 index 4a9dc878ed..0000000000 --- a/src/main/java/gregtech/api/util/GT_LanguageManager.java +++ /dev/null @@ -1,603 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.E; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.StatCollector; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.common.config.Property; - -import cpw.mods.fml.common.registry.LanguageRegistry; -import cpw.mods.fml.relauncher.ReflectionHelper; -import gregtech.api.GregTech_API; - -public class GT_LanguageManager { - - /** - * Buffer to reduce memory allocation when injecting data to LanguageRegistry. - */ - private static final HashMap TEMPMAP = new HashMap<>(); - /** - * Buffer used when something is trying to add new lang entry while config file is not set up yet. - */ - public static final Map BUFFERMAP = new HashMap<>(); - /** - * Map containing all the translation data coming into this class. - */ - private static final Map LANGMAP = new HashMap<>(); - /** - * Config file handler bound to GregTech.lang or GregTech_(locale_name).lang. Even though it says English file, - * it's not necessarily English, but on system it's always treated as English (as in, "default" language.) - */ - public static Configuration sEnglishFile; - /** - * If the game is running with en_US language. This does not get updated when user changes language in game; - * GT lang system cannot handle that anyway. - */ - public static boolean isEN_US; - /** - * If placeholder like %material should be used for writing lang entries to file. - */ - public static boolean i18nPlaceholder = true; - /** - * If there's any lang entry that is not found on lang file and waiting to be written. - */ - private static boolean hasUnsavedEntry = false; - - // TODO: convert to enum - public static String FACE_ANY = "gt.lang.face.any", FACE_BOTTOM = "gt.lang.face.bottom", - FACE_TOP = "gt.lang.face.top", FACE_LEFT = "gt.lang.face.left", FACE_FRONT = "gt.lang.face.front", - FACE_RIGHT = "gt.lang.face.right", FACE_BACK = "gt.lang.face.back", FACE_NONE = "gt.lang.face.none"; - - public static String[] FACES = { FACE_BOTTOM, FACE_TOP, FACE_LEFT, FACE_FRONT, FACE_RIGHT, FACE_BACK, FACE_NONE }; - - /** - * Map referencing private field of StringTranslate, used by StatCollector. Used to inject lang entries there. - */ - private static final Map stringTranslateLanguageList; - - static { - try { - Field fieldStringTranslateLanguageList = ReflectionHelper - .findField(net.minecraft.util.StringTranslate.class, "languageList", "field_74816_c"); - Field fieldStringTranslateInstance = ReflectionHelper - .findField(net.minecraft.util.StringTranslate.class, "instance", "field_74817_a"); - // noinspection unchecked - stringTranslateLanguageList = (Map) fieldStringTranslateLanguageList - .get(fieldStringTranslateInstance.get(null)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * @deprecated Parameter aWriteIntoLangFile is no longer used, - * use {@link #addStringLocalization(String, String)} or consider migrating to MC lang system instead. - */ - @Deprecated - public static synchronized String addStringLocalization(String aKey, String aEnglish, boolean aWriteIntoLangFile) { - return addStringLocalization(aKey, aEnglish); - } - - /** - * If you newly use this method, please consider using MC lang system instead. - */ - public static synchronized String addStringLocalization(String aKey, String aEnglish) { - String trimmedKey = aKey != null ? aKey.trim() : ""; - if (trimmedKey.isEmpty()) return E; // RIP cascading class loading, don't use GT_Utility here - if (sEnglishFile == null) { - // Lang file is not set up yet - BUFFERMAP.put(trimmedKey, aEnglish); - return aEnglish; - } - if (!BUFFERMAP.isEmpty()) { - // Lang file is now set up, resolve all the buffers - // This won't be visited twice - for (Entry tEntry : BUFFERMAP.entrySet()) { - storeTranslation(tEntry.getKey(), tEntry.getValue()); - } - BUFFERMAP.clear(); - } - - if (!LANGMAP.containsKey(trimmedKey)) { - return storeTranslation(trimmedKey, aEnglish); - } - return LANGMAP.get(trimmedKey); - } - - private static synchronized String storeTranslation(String trimmedKey, String english) { - String translation = writeToLangFile(trimmedKey, english); - LANGMAP.put(trimmedKey, translation); - addToMCLangList(trimmedKey, translation); - TEMPMAP.put(trimmedKey, translation); - LanguageRegistry.instance() - // If we use the actual user configured locale here, switching lang to others while running game - // turns everything into unlocalized string. So we make it "default" and call it a day. - .injectLanguage("en_US", TEMPMAP); - TEMPMAP.clear(); - return translation; - } - - private static synchronized String writeToLangFile(String trimmedKey, String aEnglish) { - Property tProperty = sEnglishFile.get("LanguageFile", trimmedKey, aEnglish); - if (hasUnsavedEntry && GregTech_API.sPostloadFinished) { - sEnglishFile.save(); - hasUnsavedEntry = false; - } - String translation = tProperty.getString(); - if (tProperty.wasRead()) { - if (isEN_US && !aEnglish.equals(translation)) { - tProperty.set(aEnglish); - markFileDirty(); - return aEnglish; - } - } else { - markFileDirty(); - } - return translation; - } - - private static synchronized void markFileDirty() { - if (GregTech_API.sPostloadFinished) { - sEnglishFile.save(); - } else { - hasUnsavedEntry = true; - } - } - - public static String getTranslation(String aKey) { - String tTrimmedKey = aKey != null ? aKey.trim() : ""; - if (tTrimmedKey.isEmpty()) return E; - - if (StatCollector.canTranslate(tTrimmedKey)) { - return StatCollector.translateToLocal(tTrimmedKey); - } - String anotherKeyToTry; - if (tTrimmedKey.endsWith(".name")) { - anotherKeyToTry = tTrimmedKey.substring(0, tTrimmedKey.length() - 5); - } else { - anotherKeyToTry = tTrimmedKey + ".name"; - } - if (StatCollector.canTranslate(anotherKeyToTry)) { - return StatCollector.translateToLocal(anotherKeyToTry); - } - return tTrimmedKey; - } - - public static String getTranslation(String aKey, String aSeperator) { - if (aKey == null) return E; - String rTranslation = E; - StringBuilder rTranslationSB = new StringBuilder(rTranslation); - for (String tString : aKey.split(aSeperator)) { - rTranslationSB.append(getTranslation(tString)); - } - rTranslation = String.valueOf(rTranslationSB); - return rTranslation; - } - - @SuppressWarnings("unused") - public static String getTranslateableItemStackName(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return "null"; - NBTTagCompound tNBT = aStack.getTagCompound(); - if (tNBT != null && tNBT.hasKey("display")) { - String tName = tNBT.getCompoundTag("display") - .getString("Name"); - if (GT_Utility.isStringValid(tName)) { - return tName; - } - } - return aStack.getUnlocalizedName() + ".name"; - } - - public static void writePlaceholderStrings() { - addStringLocalization("Interaction_DESCRIPTION_Index_001", "Puts out into adjacent Slot #"); - addStringLocalization("Interaction_DESCRIPTION_Index_002", "Grabs in for own Slot #"); - addStringLocalization("Interaction_DESCRIPTION_Index_003", "Enable with Signal"); - addStringLocalization("Interaction_DESCRIPTION_Index_004", "Disable with Signal"); - addStringLocalization("Interaction_DESCRIPTION_Index_005", "Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_006", "Export"); - addStringLocalization("Interaction_DESCRIPTION_Index_007", "Import"); - addStringLocalization("Interaction_DESCRIPTION_Index_008", "Export (conditional)"); - addStringLocalization("Interaction_DESCRIPTION_Index_009", "Import (conditional)"); - addStringLocalization("Interaction_DESCRIPTION_Index_010", "Export (invert cond)"); - addStringLocalization("Interaction_DESCRIPTION_Index_011", "Import (invert cond)"); - addStringLocalization("Interaction_DESCRIPTION_Index_012", "Export allow Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_013", "Import allow Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_014", "Export allow Input (conditional)"); - addStringLocalization("Interaction_DESCRIPTION_Index_015", "Import allow Output (conditional)"); - addStringLocalization("Interaction_DESCRIPTION_Index_016", "Export allow Input (invert cond)"); - addStringLocalization("Interaction_DESCRIPTION_Index_017", "Import allow Output (invert cond)"); - addStringLocalization("Interaction_DESCRIPTION_Index_018", "Normal"); - addStringLocalization("Interaction_DESCRIPTION_Index_019", "Inverted"); - addStringLocalization("Interaction_DESCRIPTION_Index_020", "Ready to work"); - addStringLocalization("Interaction_DESCRIPTION_Index_021", "Not ready to work"); - addStringLocalization("Interaction_DESCRIPTION_Index_022", "Import"); - addStringLocalization("Interaction_DESCRIPTION_Index_023", "Import (conditional)"); - addStringLocalization("Interaction_DESCRIPTION_Index_024", "Import (invert cond)"); - addStringLocalization("Interaction_DESCRIPTION_Index_025", "Keep Liquids Away"); - addStringLocalization("Interaction_DESCRIPTION_Index_026", "Keep Liquids Away (conditional)"); - addStringLocalization("Interaction_DESCRIPTION_Index_027", "Keep Liquids Away (invert cond)"); - addStringLocalization("Interaction_DESCRIPTION_Index_031", "Normal Universal Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_032", "Inverted Universal Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_033", "Normal Electricity Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_034", "Inverted Electricity Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_035", "Normal Steam Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_036", "Inverted Steam Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_037", "Normal Average Electric Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_038", "Inverted Average Electric Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_039", "Normal Average Electric Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_040", "Inverted Average Electric Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_041", "Normal Electricity Storage(Including Batteries)"); - addStringLocalization("Interaction_DESCRIPTION_Index_042", "Inverted Electricity Storage(Including Batteries)"); - addStringLocalization("Interaction_DESCRIPTION_Index_043", "Filter input, Deny output"); - addStringLocalization("Interaction_DESCRIPTION_Index_044", "Invert input, Deny output"); - addStringLocalization("Interaction_DESCRIPTION_Index_045", "Filter input, Permit any output"); - addStringLocalization("Interaction_DESCRIPTION_Index_046", "Invert input, Permit any output"); - addStringLocalization("Interaction_DESCRIPTION_Index_047", "Filter Fluid: "); - addStringLocalization("Interaction_DESCRIPTION_Index_048", "Pump speed: "); - addStringLocalization("Interaction_DESCRIPTION_Index_049", "L/tick "); - addStringLocalization("Interaction_DESCRIPTION_Index_050", "L/sec"); - addStringLocalization("Interaction_DESCRIPTION_Index_053", "Slot: "); - addStringLocalization("Interaction_DESCRIPTION_Index_054", "Inverted"); - addStringLocalization("Interaction_DESCRIPTION_Index_055", "Normal"); - addStringLocalization("Interaction_DESCRIPTION_Index_056", "Emit if 1 Maintenance Needed"); - addStringLocalization("Interaction_DESCRIPTION_Index_057", "Emit if 1 Maintenance Needed(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_058", "Emit if 2 Maintenance Needed"); - addStringLocalization("Interaction_DESCRIPTION_Index_059", "Emit if 2 Maintenance Needed(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_060", "Emit if 3 Maintenance Needed"); - addStringLocalization("Interaction_DESCRIPTION_Index_061", "Emit if 3 Maintenance Needed(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_062", "Emit if 4 Maintenance Needed"); - addStringLocalization("Interaction_DESCRIPTION_Index_063", "Emit if 4 Maintenance Needed(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_064", "Emit if 5 Maintenance Needed"); - addStringLocalization("Interaction_DESCRIPTION_Index_065", "Emit if 5 Maintenance Needed(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_066", "Emit if rotor needs maintenance low accuracy mod"); - addStringLocalization( - "Interaction_DESCRIPTION_Index_067", - "Emit if rotor needs maintenance low accuracy mod(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_068", "Emit if rotor needs maintenance high accuracy mod"); - addStringLocalization("Interaction_DESCRIPTION_Index_068.1", "Emit if any Player is close"); - addStringLocalization( - "Interaction_DESCRIPTION_Index_069", - "Emit if rotor needs maintenance high accuracy mod(inverted)"); - addStringLocalization("Interaction_DESCRIPTION_Index_069.1", "Emit if other Player is close"); - addStringLocalization("Interaction_DESCRIPTION_Index_070", "Emit if you are close"); - addStringLocalization("Interaction_DESCRIPTION_Index_071", "Conducts strongest Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_072", "Conducts from bottom Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_073", "Conducts from top Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_074", "Conducts from north Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_075", "Conducts from south Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_076", "Conducts from west Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_077", "Conducts from east Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_078", "Signal = "); - addStringLocalization("Interaction_DESCRIPTION_Index_079", "Conditional Signal = "); - addStringLocalization("Interaction_DESCRIPTION_Index_080", "Inverted Conditional Signal = "); - addStringLocalization("Interaction_DESCRIPTION_Index_081", "Frequency: "); - addStringLocalization("Interaction_DESCRIPTION_Index_082", "Open if work enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_083", "Open if work disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_084", "Only Output allowed"); - addStringLocalization("Interaction_DESCRIPTION_Index_085", "Only Input allowed"); - addStringLocalization("Interaction_DESCRIPTION_Index_086", "Auto-Input: "); - addStringLocalization("Interaction_DESCRIPTION_Index_087", "Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_088", "Enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_089", " Auto-Output: "); - addStringLocalization("Interaction_DESCRIPTION_Index_090", "Machine Processing: "); - addStringLocalization("Interaction_DESCRIPTION_Index_091", "Redstone Output at Side "); - addStringLocalization("Interaction_DESCRIPTION_Index_092", " set to: "); - addStringLocalization("Interaction_DESCRIPTION_Index_093", "Strong"); - addStringLocalization("Interaction_DESCRIPTION_Index_094", "Weak"); - addStringLocalization("Interaction_DESCRIPTION_Index_094.1", "Not enough soldering material!"); - addStringLocalization("Interaction_DESCRIPTION_Index_095", "Input from Output Side allowed"); - addStringLocalization("Interaction_DESCRIPTION_Index_096", "Input from Output Side forbidden"); - addStringLocalization("Interaction_DESCRIPTION_Index_098", "Do not regulate Item Stack Size"); - addStringLocalization("Interaction_DESCRIPTION_Index_099", "Regulate Item Stack Size to: "); - addStringLocalization("Interaction_DESCRIPTION_Index_100", "This is "); - addStringLocalization("Interaction_DESCRIPTION_Index_101", " Ore."); - addStringLocalization("Interaction_DESCRIPTION_Index_102", "There is Lava behind this Rock."); - addStringLocalization("Interaction_DESCRIPTION_Index_103", "There is a Liquid behind this Rock."); - addStringLocalization("Interaction_DESCRIPTION_Index_104", "There is an Air Pocket behind this Rock."); - addStringLocalization("Interaction_DESCRIPTION_Index_105", "Material is changing behind this Rock."); - addStringLocalization("Interaction_DESCRIPTION_Index_106", "Found traces of "); - addStringLocalization("Interaction_DESCRIPTION_Index_107", "No Ores found."); - addStringLocalization("Interaction_DESCRIPTION_Index_108", "Outputs misc. Fluids, Steam and Items"); - addStringLocalization("Interaction_DESCRIPTION_Index_109", "Outputs Steam and Items"); - addStringLocalization("Interaction_DESCRIPTION_Index_110", "Outputs Steam and misc. Fluids"); - addStringLocalization("Interaction_DESCRIPTION_Index_111", "Outputs Steam"); - addStringLocalization("Interaction_DESCRIPTION_Index_112", "Outputs misc. Fluids and Items"); - addStringLocalization("Interaction_DESCRIPTION_Index_113", "Outputs only Items"); - addStringLocalization("Interaction_DESCRIPTION_Index_114", "Outputs only misc. Fluids"); - addStringLocalization("Interaction_DESCRIPTION_Index_115", "Outputs nothing"); - // 116 moved to lang files - // 117 obsolete - // 118 moved to lang files - // 119 obsolete - // 120 moved to lang files - // 121 obsolete - addStringLocalization("Interaction_DESCRIPTION_Index_122", "Emit Redstone if slots contain something"); - addStringLocalization("Interaction_DESCRIPTION_Index_123", "Don't emit Redstone"); - // 124 moved to lang files - addStringLocalization("Interaction_DESCRIPTION_Index_124.1", "Blacklist Mode"); - // 125 obsolete - addStringLocalization("Interaction_DESCRIPTION_Index_125.1", "Whitelist Mode"); - // 126 moved to lang files - // 127 obsolete - addStringLocalization("Interaction_DESCRIPTION_Index_128", "Redstone"); - addStringLocalization("Interaction_DESCRIPTION_Index_128.1", "Redstone "); - addStringLocalization("Interaction_DESCRIPTION_Index_129", "Energy"); - addStringLocalization("Interaction_DESCRIPTION_Index_129.1", "Energy "); - addStringLocalization("Interaction_DESCRIPTION_Index_130", "Fluids"); - addStringLocalization("Interaction_DESCRIPTION_Index_130.1", "Fluids "); - addStringLocalization("Interaction_DESCRIPTION_Index_131", "Items"); - addStringLocalization("Interaction_DESCRIPTION_Index_131.1", "Items "); - addStringLocalization("Interaction_DESCRIPTION_Index_132", "Pipe is loose."); - addStringLocalization("Interaction_DESCRIPTION_Index_133", "Screws are loose."); - addStringLocalization("Interaction_DESCRIPTION_Index_134", "Something is stuck."); - addStringLocalization("Interaction_DESCRIPTION_Index_135", "Platings are dented."); - addStringLocalization("Interaction_DESCRIPTION_Index_136", "Circuitry burned out."); - addStringLocalization("Interaction_DESCRIPTION_Index_137", "That doesn't belong there."); - addStringLocalization("Interaction_DESCRIPTION_Index_138", "Incomplete Structure."); - addStringLocalization("Interaction_DESCRIPTION_Index_139", "Hit with Soft Mallet"); - addStringLocalization("Interaction_DESCRIPTION_Index_140", "to (re-)start the Machine"); - addStringLocalization("Interaction_DESCRIPTION_Index_141", "if it doesn't start."); - addStringLocalization("Interaction_DESCRIPTION_Index_142", "Running perfectly."); - addStringLocalization("Interaction_DESCRIPTION_Index_143", "Missing Mining Pipe"); - addStringLocalization("Interaction_DESCRIPTION_Index_144", "Missing Turbine Rotor"); - addStringLocalization("Interaction_DESCRIPTION_Index_145", "Step Down, In: "); - addStringLocalization("Interaction_DESCRIPTION_Index_146", "Step Up, In: "); - addStringLocalization("Interaction_DESCRIPTION_Index_147", "A, Out: "); - addStringLocalization("Interaction_DESCRIPTION_Index_148", "V "); - addStringLocalization("Interaction_DESCRIPTION_Index_149", "A"); - addStringLocalization("Interaction_DESCRIPTION_Index_150", "Chance: "); - addStringLocalization("Interaction_DESCRIPTION_Index_151", "Does not get consumed in the process"); - addStringLocalization("Interaction_DESCRIPTION_Index_151.1", "Outputs items and 1 specific Fluid"); - addStringLocalization("Interaction_DESCRIPTION_Index_151.2", "Outputs 1 specific Fluid"); - addStringLocalization("Interaction_DESCRIPTION_Index_151.4", "Successfully locked Fluid to %s"); - addStringLocalization("Interaction_DESCRIPTION_Index_152", "Total: "); - addStringLocalization("Interaction_DESCRIPTION_Index_153", "Usage: "); - addStringLocalization("Interaction_DESCRIPTION_Index_154", "Voltage: "); - addStringLocalization("Interaction_DESCRIPTION_Index_155", "Amperage: "); - addStringLocalization("Interaction_DESCRIPTION_Index_156", "Voltage: unspecified"); - addStringLocalization("Interaction_DESCRIPTION_Index_157", "Amperage: unspecified"); - addStringLocalization("Interaction_DESCRIPTION_Index_158", "Time: "); - addStringLocalization("Interaction_DESCRIPTION_Index_159", "Needs Low Gravity"); - addStringLocalization("Interaction_DESCRIPTION_Index_160", "Needs Cleanroom"); - addStringLocalization("Interaction_DESCRIPTION_Index_160.1", "Needs Cleanroom & LowGrav"); - addStringLocalization("Interaction_DESCRIPTION_Index_161", " secs"); - addStringLocalization("Interaction_DESCRIPTION_Index_162", "Name: "); - addStringLocalization("Interaction_DESCRIPTION_Index_163", " MetaData: "); - addStringLocalization("Interaction_DESCRIPTION_Index_164", "Hardness: "); - addStringLocalization("Interaction_DESCRIPTION_Index_165", " Blast Resistance: "); - addStringLocalization("Interaction_DESCRIPTION_Index_166", "Is valid Beacon Pyramid Material"); - addStringLocalization("Interaction_DESCRIPTION_Index_167", "Tank "); - addStringLocalization("Interaction_DESCRIPTION_Index_168", "Heat: "); - addStringLocalization("Interaction_DESCRIPTION_Index_169", "HEM: "); - addStringLocalization("Interaction_DESCRIPTION_Index_170", " Base EU Output: "); - addStringLocalization("Interaction_DESCRIPTION_Index_171", "Facing: "); - addStringLocalization("Interaction_DESCRIPTION_Index_172", " / Chance: "); - addStringLocalization("Interaction_DESCRIPTION_Index_173", "You can remove this with a Wrench"); - addStringLocalization("Interaction_DESCRIPTION_Index_174", "You can NOT remove this with a Wrench"); - addStringLocalization("Interaction_DESCRIPTION_Index_175", "Conduction Loss: "); - addStringLocalization("Interaction_DESCRIPTION_Index_176", "Contained Energy: "); - addStringLocalization("Interaction_DESCRIPTION_Index_177", "Has Muffler Upgrade"); - addStringLocalization("Interaction_DESCRIPTION_Index_178", "Progress/Load: "); - addStringLocalization("Interaction_DESCRIPTION_Index_179", "Max IN: "); - addStringLocalization("Interaction_DESCRIPTION_Index_181", "Max OUT: "); - addStringLocalization("Interaction_DESCRIPTION_Index_182", " EU at "); - addStringLocalization("Interaction_DESCRIPTION_Index_183", " A"); - addStringLocalization("Interaction_DESCRIPTION_Index_184", "Energy: "); - addStringLocalization("Interaction_DESCRIPTION_Index_186", "Owned by: "); - addStringLocalization("Interaction_DESCRIPTION_Index_187", "Type -- Crop-Name: "); - addStringLocalization("Interaction_DESCRIPTION_Index_188", " Growth: "); - addStringLocalization("Interaction_DESCRIPTION_Index_189", " Gain: "); - addStringLocalization("Interaction_DESCRIPTION_Index_190", " Resistance: "); - addStringLocalization("Interaction_DESCRIPTION_Index_191", "Plant -- Fertilizer: "); - addStringLocalization("Interaction_DESCRIPTION_Index_192", " Water: "); - addStringLocalization("Interaction_DESCRIPTION_Index_193", " Weed-Ex: "); - addStringLocalization("Interaction_DESCRIPTION_Index_194", " Scan-Level: "); - addStringLocalization("Interaction_DESCRIPTION_Index_195", "Environment -- Nutrients: "); - addStringLocalization("Interaction_DESCRIPTION_Index_196", " Humidity: "); - addStringLocalization("Interaction_DESCRIPTION_Index_197", " Air-Quality: "); - addStringLocalization("Interaction_DESCRIPTION_Index_198", "Attributes:"); - addStringLocalization("Interaction_DESCRIPTION_Index_199", "Discovered by: "); - addStringLocalization("Interaction_DESCRIPTION_Index_200", "Sort mode: "); - addStringLocalization("Interaction_DESCRIPTION_Index_200.1", "Automatic Item Shuffling: "); - addStringLocalization("Interaction_DESCRIPTION_Index_201", "Nothing"); - addStringLocalization("Interaction_DESCRIPTION_Index_202", "Pollution in Chunk: "); - addStringLocalization("Interaction_DESCRIPTION_Index_203", " gibbl"); - addStringLocalization("Interaction_DESCRIPTION_Index_204", "No Pollution in Chunk! HAYO!"); - addStringLocalization("Interaction_DESCRIPTION_Index_206", "Scan for Assembly Line"); - addStringLocalization( - "Interaction_DESCRIPTION_Index_207", - "Pump speed: %dL every %d ticks, %.2f L/sec on average"); - addStringLocalization("Interaction_DESCRIPTION_Index_208", " L"); - addStringLocalization("Interaction_DESCRIPTION_Index_209", " ticks"); - addStringLocalization("Interaction_DESCRIPTION_Index_209.1", " tick"); - addStringLocalization("Interaction_DESCRIPTION_Index_210", "Average: %.2f L/sec"); - addStringLocalization("Interaction_DESCRIPTION_Index_211", "Items per side: "); - addStringLocalization("Interaction_DESCRIPTION_Index_212", "Input enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_213", "Input disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_214", "Connected"); - addStringLocalization("Interaction_DESCRIPTION_Index_215", "Disconnected"); - addStringLocalization("Interaction_DESCRIPTION_Index_216", "Deprecated Recipe"); - addStringLocalization("Interaction_DESCRIPTION_Index_219", "Extended Facing: "); - addStringLocalization("Interaction_DESCRIPTION_Index_220", "Single recipe locking disabled."); - addStringLocalization("Interaction_DESCRIPTION_Index_221", "Item threshold"); - addStringLocalization("Interaction_DESCRIPTION_Index_222", "Fluid threshold"); - addStringLocalization("Interaction_DESCRIPTION_Index_222.1", "Energy threshold"); - addStringLocalization( - "Interaction_DESCRIPTION_Index_223", - "Single recipe locking enabled. Will lock to next recipe."); - addStringLocalization("Interaction_DESCRIPTION_Index_224", "Always On"); - addStringLocalization("Interaction_DESCRIPTION_Index_225", "Active with Redstone Signal"); - addStringLocalization("Interaction_DESCRIPTION_Index_226", "Inactive with Redstone Signal"); - addStringLocalization("Interaction_DESCRIPTION_Index_227", "Allow Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_228", "Block Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_229", "Export/Import"); - addStringLocalization("Interaction_DESCRIPTION_Index_230", "Conditional"); - addStringLocalization("Interaction_DESCRIPTION_Index_231", "Enable Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_232", "Filter Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_233", "Filter Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_234", "Block Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_235", "Allow Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_236", "Whitelist Fluid"); - addStringLocalization("Interaction_DESCRIPTION_Index_237", "Blacklist Fluid"); - addStringLocalization("Interaction_DESCRIPTION_Index_238", "Filter Direction"); - addStringLocalization("Interaction_DESCRIPTION_Index_239", "Filter Type"); - addStringLocalization("Interaction_DESCRIPTION_Index_240", "Block Flow"); - addStringLocalization("Interaction_DESCRIPTION_Index_241", "Recipe progress"); - addStringLocalization("Interaction_DESCRIPTION_Index_242", "Machine idle"); - addStringLocalization("Interaction_DESCRIPTION_Index_243", "Enable with Redstone"); - addStringLocalization("Interaction_DESCRIPTION_Index_244", "Disable with Redstone"); - addStringLocalization("Interaction_DESCRIPTION_Index_245", "Disable machine"); - addStringLocalization("Interaction_DESCRIPTION_Index_246", "Frequency"); - addStringLocalization("Interaction_DESCRIPTION_Index_247", "1 Issue"); - addStringLocalization("Interaction_DESCRIPTION_Index_248", "2 Issues"); - addStringLocalization("Interaction_DESCRIPTION_Index_249", "3 Issues"); - addStringLocalization("Interaction_DESCRIPTION_Index_250", "4 Issues"); - addStringLocalization("Interaction_DESCRIPTION_Index_251", "5 Issues"); - addStringLocalization("Interaction_DESCRIPTION_Index_252", "Rotor < 20%"); - addStringLocalization("Interaction_DESCRIPTION_Index_253", "Rotor ≈ 0%"); - addStringLocalization("Interaction_DESCRIPTION_Index_254", "Detect slot#"); - addStringLocalization("Interaction_DESCRIPTION_Index_254.0", "Detect Slot"); - addStringLocalization("Interaction_DESCRIPTION_Index_254.1", "Internal slot#"); - addStringLocalization("Interaction_DESCRIPTION_Index_255", "Adjacent slot#"); - addStringLocalization("Interaction_DESCRIPTION_Index_256", "Universal Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_257", "Electricity Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_258", "Steam Storage"); - addStringLocalization("Interaction_DESCRIPTION_Index_259", "Average Electric Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_260", "Average Electric Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_261", "Electricity Storage(Including Batteries)"); - addStringLocalization("Interaction_DESCRIPTION_Index_262", "Fluid Auto Output Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_263", "Fluid Auto Output Enabled"); - addStringLocalization( - "Interaction_DESCRIPTION_Index_264", - "currently none, will be locked to the next that is put in"); - addStringLocalization("Interaction_DESCRIPTION_Index_265", "1 specific Fluid"); - addStringLocalization("Interaction_DESCRIPTION_Index_266", "Lock Fluid Mode Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_267", "Overflow Voiding Mode Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_268", "Overflow Voiding Mode Enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_269", "Void Full Mode Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_270", "Void Full Mode Enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_271", "unspecified"); - addStringLocalization("Interaction_DESCRIPTION_Index_272", "Recipe by: "); - addStringLocalization("Interaction_DESCRIPTION_Index_273", "Original Recipe by: "); - addStringLocalization("Interaction_DESCRIPTION_Index_274", "Modified by: "); - addStringLocalization("Interaction_DESCRIPTION_Index_275", "Original voltage: "); - addStringLocalization("Interaction_DESCRIPTION_Index_299", "Item Filter: "); - addStringLocalization("Interaction_DESCRIPTION_Index_300", "Filter Cleared!"); - addStringLocalization("Interaction_DESCRIPTION_Index_300.1", "Fluid Lock Cleared."); - addStringLocalization("Interaction_DESCRIPTION_Index_301", "Universal"); - addStringLocalization("Interaction_DESCRIPTION_Index_302", "Int. EU"); - addStringLocalization("Interaction_DESCRIPTION_Index_303", "Steam"); - addStringLocalization("Interaction_DESCRIPTION_Index_304", "Avg. Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_305", "Avg. Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_306", "EU stored"); - addStringLocalization("Interaction_DESCRIPTION_Index_307", "Deny input, Filter output"); - addStringLocalization("Interaction_DESCRIPTION_Index_308", "Deny input, Invert output"); - addStringLocalization("Interaction_DESCRIPTION_Index_309", "Permit any input, Filter output"); - addStringLocalization("Interaction_DESCRIPTION_Index_310", "Permit any input, Invert output"); - addStringLocalization("Interaction_DESCRIPTION_Index_311", "Block Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_312", "Allow Output"); - addStringLocalization("Interaction_DESCRIPTION_Index_313", "Block Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_314", "Allow Input"); - addStringLocalization("Interaction_DESCRIPTION_Index_315", "Filter Empty"); - addStringLocalization("Interaction_DESCRIPTION_Index_316", "Pump speed limit reached!"); - addStringLocalization("Interaction_DESCRIPTION_Index_317", "Filter: "); - addStringLocalization("Interaction_DESCRIPTION_Index_318", "Check Mode"); - addStringLocalization("Interaction_DESCRIPTION_Index_319", "Any player"); - addStringLocalization("Interaction_DESCRIPTION_Index_320", "Other players"); - addStringLocalization("Interaction_DESCRIPTION_Index_321", "Only owner"); - addStringLocalization("Interaction_DESCRIPTION_Index_322", "Overflow point: "); - addStringLocalization("Interaction_DESCRIPTION_Index_323", "L"); - addStringLocalization("Interaction_DESCRIPTION_Index_324", "Now"); - addStringLocalization("Interaction_DESCRIPTION_Index_325", "Max"); - addStringLocalization("Interaction_DESCRIPTION_Index_326", "Public"); - addStringLocalization("Interaction_DESCRIPTION_Index_327", "Private"); - addStringLocalization("Interaction_DESCRIPTION_Index_328", "Channel"); - addStringLocalization("Interaction_DESCRIPTION_Index_329", "Public/Private"); - addStringLocalization("Interaction_DESCRIPTION_Index_330", "Sneak Rightclick to switch Mode"); - addStringLocalization("Interaction_DESCRIPTION_Index_331", "AND Gate"); - addStringLocalization("Interaction_DESCRIPTION_Index_332", "NAND Gate"); - addStringLocalization("Interaction_DESCRIPTION_Index_333", "OR Gate"); - addStringLocalization("Interaction_DESCRIPTION_Index_334", "NOR Gate"); - addStringLocalization("Interaction_DESCRIPTION_Index_335", "Gate Mode"); - addStringLocalization("Interaction_DESCRIPTION_Index_336", "PCB Factory Tier: "); - addStringLocalization("Interaction_DESCRIPTION_Index_337", "Upgrade Required: "); - addStringLocalization("Interaction_DESCRIPTION_Index_338", "Bio"); - addStringLocalization("Interaction_DESCRIPTION_Index_339", "Biochamber Upgrade Enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_339.1", "Biochamber Upgrade Disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_340", "Rotated biochamber enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_340.1", "Rotated biochamber disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_341", "Tier 1 cooling enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_341.1", "Tier 1 cooling disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_342", "Tier 2 cooling enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_342.1", "Tier 2 cooling disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_343", "Use Machine Processing State"); - addStringLocalization("Interaction_DESCRIPTION_Index_343.1", "Use Inverted Machine Processing State"); - addStringLocalization("Interaction_DESCRIPTION_Index_344", "Input Blocking"); - addStringLocalization("Interaction_DESCRIPTION_Index_344.1", "Output Blocking"); - addStringLocalization("Interaction_DESCRIPTION_Index_400", "Running mode: "); - addStringLocalization("Interaction_DESCRIPTION_Index_500", "Fitting: Loose - More Flow"); - addStringLocalization("Interaction_DESCRIPTION_Index_501", "Fitting: Tight - More Efficiency"); - addStringLocalization("Interaction_DESCRIPTION_Index_502", "Mining chunk loading enabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_503", "Mining chunk loading disabled"); - addStringLocalization("Interaction_DESCRIPTION_Index_505", "Enable with Signal (Safe)"); - addStringLocalization("Interaction_DESCRIPTION_Index_506", "Disable with Signal (Safe)"); - addStringLocalization("Interaction_DESCRIPTION_Index_507", "Safe Mode"); - addStringLocalization("Interaction_DESCRIPTION_Index_508", "Needs Stabilized Black Hole"); - addStringLocalization("Interaction_DESCRIPTION_Index_509", "Requires HIP Unit"); - addStringLocalization("Interaction_DESCRIPTION_Index_602", "Use Private Frequency"); - addStringLocalization("Interaction_DESCRIPTION_Index_756", "Connectable: "); - addStringLocalization("Interaction_DESCRIPTION_Index_ALL", "All"); - addStringLocalization("Interaction_DESCRIPTION_Index_ANY", "Any"); - addStringLocalization("Interaction_DESCRIPTION_Index_INVERTED", "Inverted"); - addStringLocalization("Interaction_DESCRIPTION_Index_NORMAL", "Normal"); - addStringLocalization("Interaction_DESCRIPTION_Index_SIDE", "Side: "); - - addStringLocalization("Item_DESCRIPTION_Index_000", "Stored Heat: %s"); - addStringLocalization("Item_DESCRIPTION_Index_001", "Durability: %s/%s"); - addStringLocalization("Item_DESCRIPTION_Index_002", "%s lvl %s"); - addStringLocalization("Item_DESCRIPTION_Index_003", "Attack Damage: %s"); - addStringLocalization("Item_DESCRIPTION_Index_004", "Mining Speed: %s"); - addStringLocalization("Item_DESCRIPTION_Index_005", "Turbine Efficiency: %s"); - addStringLocalization("Item_DESCRIPTION_Index_006", "Optimal Steam flow: %s L/t"); - addStringLocalization("Item_DESCRIPTION_Index_007", "Energy from Optimal Gas Flow: %s EU/t"); - addStringLocalization("Item_DESCRIPTION_Index_008", "Energy from Optimal Plasma Flow: %s EU/t"); - addStringLocalization("Item_DESCRIPTION_Index_009", "Contains %s EU Tier: %s"); - addStringLocalization("Item_DESCRIPTION_Index_010", "Empty. You should recycle it properly."); - addStringLocalization("Item_DESCRIPTION_Index_011", "%s / %s EU - Voltage: %s"); - addStringLocalization("Item_DESCRIPTION_Index_012", "No Fluids Contained"); - addStringLocalization("Item_DESCRIPTION_Index_013", "%sL / %sL"); - addStringLocalization("Item_DESCRIPTION_Index_014", "Missing Coodinates!"); - addStringLocalization("Item_DESCRIPTION_Index_015", "Device at:"); - addStringLocalization("Item_DESCRIPTION_Index_018", "State: %s"); - addStringLocalization("Item_DESCRIPTION_Index_019", "Bath with neutron in a hot reactor"); - addStringLocalization("Item_DESCRIPTION_Index_020", "Progress: %s/%s"); - addStringLocalization("Item_DESCRIPTION_Index_021", "Radiation Hazard"); - addStringLocalization("Item_DESCRIPTION_Index_500", "Turbine Efficiency (Loose): %s"); - addStringLocalization("Item_DESCRIPTION_Index_501", "Optimal Steam flow (Loose): %s L/t"); - addStringLocalization("Item_DESCRIPTION_Index_502", "Overflow Efficiency Tier: %s"); - addStringLocalization("Item_DESCRIPTION_Index_900", "Energy from Optimal Steam Flow: %s EU/t"); - addStringLocalization("Item_DESCRIPTION_Index_901", "Energy from Optimal Steam Flow (Loose): %s EU/t"); - - addStringLocalization(FACE_ANY, "Any Side"); - addStringLocalization(FACE_BOTTOM, "Bottom"); - addStringLocalization(FACE_TOP, "Top"); - addStringLocalization(FACE_LEFT, "Left"); - addStringLocalization(FACE_FRONT, "Front"); - addStringLocalization(FACE_RIGHT, "Right"); - addStringLocalization(FACE_BACK, "Back"); - addStringLocalization(FACE_NONE, "None"); - } - - private static void addToMCLangList(String aKey, String translation) { - if (stringTranslateLanguageList != null) { - stringTranslateLanguageList.put(aKey, translation); - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_Log.java b/src/main/java/gregtech/api/util/GT_Log.java deleted file mode 100644 index 2d00c2e061..0000000000 --- a/src/main/java/gregtech/api/util/GT_Log.java +++ /dev/null @@ -1,45 +0,0 @@ -package gregtech.api.util; - -import java.io.File; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * Just a simple Logging Function. If on Server, then this will point to System.out and System.err - */ -public class GT_Log { - - public static PrintStream out = System.out; - public static PrintStream err = System.err; - public static PrintStream ore = new LogBuffer(); - public static PrintStream pal = null; - public static PrintStream exp = new LogBuffer(); - public static File mLogFile; - public static File mOreDictLogFile; - public static File mPlayerActivityLogFile; - public static File mExplosionLog; - - public static class LogBuffer extends PrintStream { - - public final List mBufferedOreDictLog = new ArrayList<>(); - - public LogBuffer() { - super(new OutputStream() { - - @Override - public void write(int arg0) { - /* Do nothing */ - } - }); - } - - @Override - public void println(String aString) { - mBufferedOreDictLog.add(aString); - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_ModHandler.java b/src/main/java/gregtech/api/util/GT_ModHandler.java deleted file mode 100644 index b5c7c6fb6e..0000000000 --- a/src/main/java/gregtech/api/util/GT_ModHandler.java +++ /dev/null @@ -1,2437 +0,0 @@ -package gregtech.api.util; - -import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.B; -import static gregtech.api.enums.GT_Values.D1; -import static gregtech.api.enums.GT_Values.DW; -import static gregtech.api.enums.GT_Values.E; -import static gregtech.api.enums.GT_Values.M; -import static gregtech.api.enums.GT_Values.RA; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.GT_Values.VN; -import static gregtech.api.enums.GT_Values.W; -import static gregtech.api.recipe.RecipeMaps.alloySmelterRecipes; -import static gregtech.api.recipe.RecipeMaps.oreWasherRecipes; -import static gregtech.api.util.GT_RecipeBuilder.SECONDS; -import static gregtech.api.util.GT_RecipeBuilder.TICKS; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.CraftingManager; -import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.ShapedRecipes; -import net.minecraft.item.crafting.ShapelessRecipes; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.world.World; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.oredict.ShapedOreRecipe; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import cpw.mods.fml.common.registry.GameRegistry; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OreDictNames; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.Tier; -import gregtech.api.enums.ToolDictNames; -import gregtech.api.interfaces.IDamagableItem; -import gregtech.api.interfaces.IItemContainer; -import gregtech.api.interfaces.internal.IGT_CraftingRecipe; -import gregtech.api.items.GT_MetaBase_Item; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine_GT_Recipe; -import gregtech.api.objects.GT_HashSet; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.objects.ItemData; -import gregtech.api.recipe.RecipeCategories; -import gregtech.api.recipe.RecipeMap; -import ic2.api.item.IBoxable; -import ic2.api.item.IC2Items; -import ic2.api.item.IElectricItem; -import ic2.api.reactor.IReactorComponent; -import ic2.api.recipe.IRecipeInput; -import ic2.api.recipe.RecipeInputItemStack; -import ic2.api.recipe.RecipeOutput; -import ic2.core.item.ItemToolbox; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the Interface I use for interacting with other Mods. - *

- * Due to the many imports, this File can cause compile Problems if not all the APIs are installed - */ -public class GT_ModHandler { - - public static final List sSingleNonBlockDamagableRecipeList = new ArrayList<>(1000); - private static final Map sIC2ItemMap = new HashMap<>(); - - // public for bartworks - public static final List sAllRecipeList = new ArrayList<>(5000), sBufferRecipeList = new ArrayList<>(1000); - private static final List delayedRemovalByOutput = new ArrayList<>(); - private static final List delayedRemovalByRecipe = new ArrayList<>(); - - public static Collection sNativeRecipeClasses = new HashSet<>(), sSpecialRecipeClasses = new HashSet<>(); - public static GT_HashSet sNonReplaceableItems = new GT_HashSet<>(); - public static Object sBoxableWrapper = new GT_IBoxableWrapper(); - public static Collection sBoxableItems = new ArrayList<>(); - private static final Map emptyRecipeMap = new HashMap<>(); - private static Set recyclerWhitelist; - private static Set recyclerBlacklist; - - private static boolean sBufferCraftingRecipes = true; - public static List sSingleNonBlockDamagableRecipeList_list = new ArrayList<>(100); - private static final boolean sSingleNonBlockDamagableRecipeList_create = true; - private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0); - private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R"; - private static final ItemStack[][] sShapes1 = new ItemStack[][] { - { sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null }, - { sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1 }, - { null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1 }, - { sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null }, - { sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1 }, - { sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1 }, - { null, null, null, sMt1, null, sMt1, sMt1, null, sMt1 }, - { null, sMt1, null, null, sMt1, null, null, sMt2, null }, - { sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null }, - { null, sMt1, null, null, sMt2, null, null, sMt2, null }, - { sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null }, - { null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null }, - { sMt1, sMt1, null, null, sMt2, null, null, sMt2, null }, - { null, sMt1, sMt1, null, sMt2, null, null, sMt2, null }, - { null, sMt1, null, sMt1, null, null, null, sMt1, sMt2 }, - { null, sMt1, null, null, null, sMt1, sMt2, sMt1, null }, - { null, sMt1, null, sMt1, null, sMt1, null, null, sMt2 }, - { null, sMt1, null, sMt1, null, sMt1, sMt2, null, null }, - { null, sMt2, null, null, sMt1, null, null, sMt1, null }, - { null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1 }, - { null, sMt2, null, null, sMt2, null, null, sMt1, null }, - { null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null }, - { null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1 }, - { null, sMt2, null, null, sMt2, null, sMt1, sMt1, null }, - { sMt1, null, null, null, sMt2, null, null, null, sMt2 }, - { null, null, sMt1, null, sMt2, null, sMt2, null, null }, - { sMt1, null, null, null, sMt2, null, null, null, null }, - { null, null, sMt1, null, sMt2, null, null, null, null }, - { sMt1, sMt2, null, null, null, null, null, null, null }, - { sMt2, sMt1, null, null, null, null, null, null, null }, - { sMt1, null, null, sMt2, null, null, null, null, null }, - { sMt2, null, null, sMt1, null, null, null, null, null }, - { sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null }, - { sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null }, - { null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1 }, - { null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1 }, - { sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null }, - { sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null }, - { null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1 }, - { null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1 }, - { sMt1, null, null, null, sMt1, null, null, null, null }, - { null, sMt1, null, sMt1, null, null, null, null, null }, - { sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null }, - { null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2 } }; - public static List sSingleNonBlockDamagableRecipeList_validsShapes1 = new ArrayList<>(44); - public static boolean sSingleNonBlockDamagableRecipeList_validsShapes1_update = false; - public static List sSingleNonBlockDamagableRecipeList_warntOutput = new ArrayList<>(50); - public static List sVanillaRecipeList_warntOutput = new ArrayList<>(50); - public static final List sSingleNonBlockDamagableRecipeList_verified = new ArrayList<>(1000); - public static List sAnySteamFluidIDs = new ArrayList<>(); - public static List sSuperHeatedSteamFluidIDs = new ArrayList<>(); - - static { - sNativeRecipeClasses.add(ShapedRecipes.class.getName()); - sNativeRecipeClasses.add(ShapedOreRecipe.class.getName()); - sNativeRecipeClasses.add(GT_Shaped_Recipe.class.getName()); - sNativeRecipeClasses.add(ShapelessRecipes.class.getName()); - sNativeRecipeClasses.add(ShapelessOreRecipe.class.getName()); - sNativeRecipeClasses.add(GT_Shapeless_Recipe.class.getName()); - sNativeRecipeClasses.add(ic2.core.AdvRecipe.class.getName()); - sNativeRecipeClasses.add(ic2.core.AdvShapelessRecipe.class.getName()); - sNativeRecipeClasses.add("appeng.recipes.game.ShapedRecipe"); - sNativeRecipeClasses.add("appeng.recipes.game.ShapelessRecipe"); - sNativeRecipeClasses.add("forestry.core.utils.ShapedRecipeCustom"); - - // Recipe Classes, which should never be removed. - sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipeFireworks.class.getName()); - sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesArmorDyes.class.getName()); - sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipeBookCloning.class.getName()); - sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesMapCloning.class.getName()); - sSpecialRecipeClasses.add(net.minecraft.item.crafting.RecipesMapExtending.class.getName()); - sSpecialRecipeClasses.add("jds.bibliocraft.BiblioSpecialRecipes"); - sSpecialRecipeClasses.add("dan200.qcraft.shared.EntangledQBlockRecipe"); - sSpecialRecipeClasses.add("dan200.qcraft.shared.EntangledQuantumComputerRecipe"); - sSpecialRecipeClasses.add("dan200.qcraft.shared.QBlockRecipe"); - sSpecialRecipeClasses.add("appeng.recipes.game.FacadeRecipe"); - sSpecialRecipeClasses.add("appeng.recipes.game.DisassembleRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.carts.LocomotivePaintingRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RotorRepairRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RoutingTableCopyRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.RoutingTicketCopyRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.util.crafting.TankCartFilterRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.emblems.LocomotiveEmblemRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.emblems.EmblemPostColorRecipe"); - sSpecialRecipeClasses.add("mods.railcraft.common.emblems.EmblemPostEmblemRecipe"); - sSpecialRecipeClasses.add("mods.immibis.redlogic.interaction.RecipeDyeLumarButton"); - sSpecialRecipeClasses.add("thaumcraft.common.items.armor.RecipesRobeArmorDyes"); - sSpecialRecipeClasses.add("thaumcraft.common.items.armor.RecipesVoidRobeArmorDyes"); - sSpecialRecipeClasses.add("thaumcraft.common.lib.crafting.ShapelessNBTOreRecipe"); - sSpecialRecipeClasses.add("twilightforest.item.TFMapCloningRecipe"); - sSpecialRecipeClasses.add("forestry.lepidopterology.MatingRecipe"); - sSpecialRecipeClasses.add("micdoodle8.mods.galacticraft.planets.asteroids.recipe.CanisterRecipes"); - sSpecialRecipeClasses.add("shedar.mods.ic2.nuclearcontrol.StorageArrayRecipe"); - } - - /** - * Returns if that Liquid is Water or Distilled Water - */ - public static boolean isWater(FluidStack aFluid) { - if (aFluid == null) return false; - return aFluid.isFluidEqual(getWater(1)) || aFluid.isFluidEqual(getDistilledWater(1)); - } - - /** - * Returns a Liquid Stack with given amount of Water. - */ - public static FluidStack getWater(long aAmount) { - return FluidRegistry.getFluidStack("water", (int) aAmount); - } - - /** - * Returns a Liquid Stack with given amount of distilled Water. - */ - public static FluidStack getDistilledWater(long aAmount) { - FluidStack tFluid = FluidRegistry.getFluidStack("ic2distilledwater", (int) aAmount); - if (tFluid == null) tFluid = getWater(aAmount); - return tFluid; - } - - /** - * Returns if that Liquid is Lava - */ - public static boolean isLava(FluidStack aFluid) { - if (aFluid == null) return false; - return aFluid.isFluidEqual(getLava(1)); - } - - /** - * Returns a Liquid Stack with given amount of Lava. - */ - public static FluidStack getLava(long aAmount) { - return FluidRegistry.getFluidStack("lava", (int) aAmount); - } - - /** - * Returns if that Liquid is Steam - */ - public static boolean isSteam(FluidStack aFluid) { - if (aFluid == null) return false; - return aFluid.isFluidEqual(getSteam(1)); - } - - /** - * Returns if that Liquid is Any Steam (including other mods) - */ - public static boolean isAnySteam(FluidStack aFluid) { - return (aFluid != null && (isSteam(aFluid) || sAnySteamFluidIDs.contains(aFluid.getFluidID()))); - } - - /** - * Returns if that Liquid is Super Heated Steam (including other mods) - */ - public static boolean isSuperHeatedSteam(FluidStack aFluid) { - return (aFluid != null && sSuperHeatedSteamFluidIDs.contains(aFluid.getFluidID())); - } - - /** - * Returns a Liquid Stack with given amount of Steam. - */ - public static FluidStack getSteam(long aAmount) { - return FluidRegistry.getFluidStack("steam", (int) aAmount); - } - - /** - * Returns if that Liquid is Milk - */ - public static boolean isMilk(FluidStack aFluid) { - if (aFluid == null) return false; - return aFluid.isFluidEqual(getMilk(1)); - } - - /** - * Returns a Liquid Stack with given amount of Milk. - */ - public static FluidStack getMilk(long aAmount) { - return FluidRegistry.getFluidStack("milk", (int) aAmount); - } - - public static ItemStack getEmptyCell(long aAmount) { - return ItemList.Cell_Empty.get(aAmount); - } - - public static ItemStack getAirCell(long aAmount) { - return ItemList.Cell_Air.get(aAmount); - } - - public static ItemStack getWaterCell(long aAmount) { - return ItemList.Cell_Water.get(aAmount); - } - - public static ItemStack getLavaCell(long aAmount) { - return ItemList.Cell_Lava.get(aAmount); - } - - /** - * @param aValue the Value of this Stack, when burning inside a Furnace (200 = 1 Burn Process = 500 EU, max = 32767 - * (that is 81917.5 EU)), limited to Short because the vanilla Furnace otherwise can't handle it - * properly, stupid Mojang... - */ - public static ItemStack setFuelValue(ItemStack aStack, short aValue) { - aStack.setTagCompound(GT_Utility.getNBTContainingShort(aStack.getTagCompound(), "GT.ItemFuelValue", aValue)); - return aStack; - } - - /** - * @return the Value of this Stack, when burning inside a Furnace (200 = 1 Burn Process = 500 EU, max = 32767 (that - * is 81917.5 EU)), limited to Short because the vanilla Furnace otherwise can't handle it properly, stupid - * Mojang... - */ - public static int getFuelValue(ItemStack aStack) { - return TileEntityFurnace.getItemBurnTime(aStack); - } - - /** - * Gets an Item from IndustrialCraft, and returns a Replacement Item if not possible - */ - public static ItemStack getIC2Item(String aItem, long aAmount, ItemStack aReplacement) { - if (GT_Utility.isStringInvalid(aItem) || !GregTech_API.sPreloadStarted) return null; - // if (D1) GT_Log.out.println("Requested the Item '" + aItem + "' from the IC2-API"); - if (!sIC2ItemMap.containsKey(aItem)) try { - ItemStack tStack = IC2Items.getItem(aItem); - sIC2ItemMap.put(aItem, tStack); - if (tStack == null && D1) GT_Log.err.println(aItem + " is not found in the IC2 Items!"); - } catch (Throwable e) { - /* Do nothing */ - } - return GT_Utility.copyAmount(aAmount, sIC2ItemMap.get(aItem), aReplacement); - } - - /** - * Gets an Item from IndustrialCraft, but the Damage Value can be specified, and returns a Replacement Item with the - * same Damage if not possible - */ - public static ItemStack getIC2Item(String aItem, long aAmount, int aMeta, ItemStack aReplacement) { - ItemStack rStack = getIC2Item(aItem, aAmount, aReplacement); - if (rStack == null) return null; - Items.feather.setDamage(rStack, aMeta); - return rStack; - } - - /** - * Gets an Item from IndustrialCraft, but the Damage Value can be specified - */ - public static ItemStack getIC2Item(String aItem, long aAmount, int aMeta) { - return getIC2Item(aItem, aAmount, aMeta, null); - } - - /** - * Gets an Item from IndustrialCraft - */ - public static ItemStack getIC2Item(String aItem, long aAmount) { - return getIC2Item(aItem, aAmount, null); - } - - /** - * Gets an Item from the specified mod - */ - public static ItemStack getModItem(String aModID, String aItem, long aAmount) { - return getModItem(aModID, aItem, aAmount, null); - } - - /** - * Gets an Item from the specified mod, and returns a Replacement Item if not possible - */ - public static ItemStack getModItem(String aModID, String aItem, long aAmount, ItemStack aReplacement) { - ItemStack result; - if (GT_Utility.isStringInvalid(aItem) || !GregTech_API.sPreloadStarted) { - result = null; - } else { - result = GT_Utility - .copyAmount(aAmount, GameRegistry.findItemStack(aModID, aItem, (int) aAmount), aReplacement); - } - - if (result == null) { - String reason; - if (GT_Utility.isStringInvalid(aItem)) { - reason = "the name of the item is an invalid string"; - } else if (!GregTech_API.sPreloadStarted) { - reason = "the GT5U preloading phase has not yet started"; - } else { - reason = "the item was not found in the game registry"; - } - String log_message = "getModItem call: object \"" + aItem - + "\" with mod id \"" - + aModID - + "\" has returned null because " - + reason; - GT_Log.out.println(log_message); - new Exception().printStackTrace(GT_Log.out); - } - return result; - } - - /** - * Gets an Item from the specified mod, but the Damage Value can be specified - */ - public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta) { - ItemStack rStack = getModItem(aModID, aItem, aAmount); - if (rStack == null) return null; - Items.feather.setDamage(rStack, aMeta); - return rStack; - } - - /** - * Gets an Item from the specified mod, but the Damage Value can be specified, and returns a Replacement Item with - * the same Damage if not possible - */ - public static ItemStack getModItem(String aModID, String aItem, long aAmount, int aMeta, ItemStack aReplacement) { - ItemStack rStack = getModItem(aModID, aItem, aAmount, aReplacement); - if (rStack == null) return null; - Items.feather.setDamage(rStack, aMeta); - return rStack; - } - - /** - * OUT OF ORDER - */ - @Deprecated - public static boolean getModeKeyDown(EntityPlayer aPlayer) { - return false; - } - - /** - * OUT OF ORDER - */ - @Deprecated - public static boolean getBoostKeyDown(EntityPlayer aPlayer) { - return false; - } - - /** - * OUT OF ORDER - */ - @Deprecated - public static boolean getJumpKeyDown(EntityPlayer aPlayer) { - return false; - } - - /** - * Adds a Valuable Ore to the Miner - */ - public static boolean addValuableOre(Block aBlock, int aMeta, int aValue) { - if (aValue <= 0) return false; - try { - Class.forName("ic2.core.IC2") - .getMethod("addValuableOre", IRecipeInput.class, int.class) - .invoke(null, new RecipeInputItemStack(new ItemStack(aBlock, 1, aMeta)), aValue); - } catch (Throwable e) { - /* Do nothing */ - } - return true; - } - - /** - * Adds a Scrapbox Drop. Fails at April first for the "suddenly Hoes"-Feature of IC2 - */ - public static boolean addScrapboxDrop(float aChance, ItemStack aOutput) { - aOutput = GT_OreDictUnificator.get(true, aOutput); - if (aOutput == null || aChance <= 0) return false; - aOutput.stackSize = 1; - if (GT_Config.troll && !GT_Utility.areStacksEqual(aOutput, new ItemStack(Items.wooden_hoe, 1, 0))) return false; - try { - GT_Utility.callMethod( - GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), - "addDrop", - true, - false, - true, - GT_Utility.copyOrNull(aOutput), - aChance); - GT_Utility.callMethod( - GT_Utility.getFieldContent("ic2.api.recipe.Recipes", "scrapboxDrops", true, true), - "addRecipe", - true, - true, - false, - GT_Utility.copyOrNull(aOutput), - aChance); - } catch (Throwable e) { - /* Do nothing */ - } - return true; - } - - /** - * Adds an Item to the Recycler Blacklist - */ - public static boolean addToRecyclerBlackList(ItemStack aRecycledStack) { - if (aRecycledStack == null) return false; - try { - ic2.api.recipe.Recipes.recyclerBlacklist.add(new RecipeInputItemStack(aRecycledStack)); - } catch (Throwable e) { - /* Do nothing */ - } - return true; - } - - /** - * Just simple Furnace smelting. Unbelievable how Minecraft fails at making a simple ItemStack->ItemStack mapping... - */ - public static boolean addSmeltingRecipe(ItemStack aInput, ItemStack aOutput) { - aOutput = GT_OreDictUnificator.get(true, aOutput); - if (aInput == null || aOutput == null) return false; - FurnaceRecipes.smelting() - .func_151394_a(aInput, GT_Utility.copyOrNull(aOutput), 0.0F); - return true; - } - - /** - * Adds to Furnace AND Alloy Smelter - */ - public static boolean addSmeltingAndAlloySmeltingRecipe(ItemStack aInput, ItemStack aOutput, boolean hidden) { - if (aInput == null || aOutput == null) { - return false; - } - boolean temp = aInput.stackSize == 1 && addSmeltingRecipe(aInput, aOutput); - ItemStack input2 = OrePrefixes.ingot.contains(aOutput) ? ItemList.Shape_Mold_Ingot.get(0) - : OrePrefixes.block.contains(aOutput) ? ItemList.Shape_Mold_Block.get(0) - : OrePrefixes.nugget.contains(aOutput) ? ItemList.Shape_Mold_Nugget.get(0) : null; - if (Materials.Graphite.contains(aInput)) { - return false; - } - if ((input2 == null) && ((OrePrefixes.ingot.contains(aInput)) || (OrePrefixes.dust.contains(aInput)) - || (OrePrefixes.gem.contains(aInput)))) { - return false; - } - GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder(); - if (input2 == null) { - recipeBuilder.itemInputs(aInput); - } else { - recipeBuilder.itemInputs(aInput, input2); - } - recipeBuilder.itemOutputs(aOutput) - .duration(6 * SECONDS + 10 * TICKS) - .eut(3) - .recipeCategory(RecipeCategories.alloySmelterRecycling); - if (hidden) { - recipeBuilder.hidden(); - } - recipeBuilder.addTo(alloySmelterRecipes); - return true; - } - - /** - * Removes IC2 recipes. - */ - public static void removeAllIC2Recipes() { - getMaceratorRecipeList().entrySet() - .clear(); - getCompressorRecipeList().entrySet() - .clear(); - getExtractorRecipeList().entrySet() - .clear(); - getOreWashingRecipeList().entrySet() - .clear(); - getThermalCentrifugeRecipeList().entrySet() - .clear(); - } - - /** - * Adds GT versions of the IC2 recipes from the supplied IC2RecipeList. Deprecated because all IC2 recipes - * have been manually added to GT. - */ - @Deprecated - public static void addIC2RecipesToGT(Map aIC2RecipeList, RecipeMap aGTRecipeMap, - boolean aAddGTRecipe, boolean aRemoveIC2Recipe, boolean aExcludeGTIC2Items) { - Map aRecipesToRemove = new HashMap<>(); - for (Entry iRecipeInputRecipeOutputEntry : aIC2RecipeList.entrySet()) { - if (iRecipeInputRecipeOutputEntry.getValue().items.isEmpty()) { - continue; - } - - for (ItemStack tStack : (iRecipeInputRecipeOutputEntry.getKey()).getInputs()) { - if (!GT_Utility.isStackValid(tStack)) { - continue; - } - - if (aAddGTRecipe) { - try { - if (aExcludeGTIC2Items && ((tStack.getUnlocalizedName() - .contains("gt.metaitem.01") - || tStack.getUnlocalizedName() - .contains("gt.blockores") - || tStack.getUnlocalizedName() - .contains("ic2.itemCrushed") - || tStack.getUnlocalizedName() - .contains("ic2.itemPurifiedCrushed")))) - continue; - switch (aGTRecipeMap.unlocalizedName) { - case "gt.recipe.macerator", "gt.recipe.extractor", "gt.recipe.compressor" -> GT_Values.RA - .stdBuilder() - .itemInputs( - GT_Utility.copyAmount( - iRecipeInputRecipeOutputEntry.getKey() - .getAmount(), - tStack)) - .itemOutputs(iRecipeInputRecipeOutputEntry.getValue().items.toArray(new ItemStack[0])) - .duration(15 * SECONDS) - .eut(2) - .addTo(aGTRecipeMap); - case "gt.recipe.thermalcentrifuge" -> GT_Values.RA.stdBuilder() - .itemInputs( - GT_Utility.copyAmount( - iRecipeInputRecipeOutputEntry.getKey() - .getAmount(), - tStack)) - .itemOutputs(iRecipeInputRecipeOutputEntry.getValue().items.toArray(new ItemStack[0])) - .duration(25 * SECONDS) - .eut(48) - .addTo(aGTRecipeMap); - } - } catch (Exception e) { - e.printStackTrace(GT_Log.err); - } - } - if (aRemoveIC2Recipe) { - aRecipesToRemove.put(tStack, iRecipeInputRecipeOutputEntry.getValue().items.get(0)); - } - - } - - } - GT_Utility.bulkRemoveSimpleIC2MachineRecipe(aRecipesToRemove, aIC2RecipeList); - } - - public static Map getExtractorRecipeList() { - try { - return ic2.api.recipe.Recipes.extractor.getRecipes(); - } catch (Throwable e) { - /* Do nothing */ - } - return emptyRecipeMap; - } - - public static Map getCompressorRecipeList() { - try { - return ic2.api.recipe.Recipes.compressor.getRecipes(); - } catch (Throwable e) { - /* Do nothing */ - } - return emptyRecipeMap; - } - - public static Map getMaceratorRecipeList() { - try { - return ic2.api.recipe.Recipes.macerator.getRecipes(); - } catch (Throwable e) { - /* Do nothing */ - } - return emptyRecipeMap; - } - - public static Map getThermalCentrifugeRecipeList() { - try { - return ic2.api.recipe.Recipes.centrifuge.getRecipes(); - } catch (Throwable e) { - /* Do nothing */ - } - return emptyRecipeMap; - } - - public static Map getOreWashingRecipeList() { - try { - return ic2.api.recipe.Recipes.oreWashing.getRecipes(); - } catch (Throwable e) { - /* Do nothing */ - } - return emptyRecipeMap; - } - - /** - * IC2-OreWasher Recipe. Overloads old Recipes automatically - */ - @Deprecated - public static boolean addOreWasherRecipe(ItemStack aInput, int[] aChances, int aWaterAmount, Object... aOutput) { - if (aInput == null || aOutput == null || aOutput.length == 0 || aOutput[0] == null) return false; - RA.stdBuilder() - .itemInputs(aInput) - .itemOutputs((ItemStack) aOutput[0], (ItemStack) aOutput[1], (ItemStack) aOutput[2]) - .outputChances(aChances) - .fluidInputs(GT_ModHandler.getWater(aWaterAmount)) - .duration(25 * SECONDS) - .eut(16) - .addTo(oreWasherRecipes); - - RA.stdBuilder() - .itemInputs(aInput) - .itemOutputs((ItemStack) aOutput[0], (ItemStack) aOutput[1], (ItemStack) aOutput[2]) - .outputChances(aChances) - .fluidInputs(GT_ModHandler.getDistilledWater(aWaterAmount / 5)) - .duration(15 * SECONDS) - .eut(16) - .addTo(oreWasherRecipes); - return true; - } - - public static void stopBufferingCraftingRecipes() { - sBufferCraftingRecipes = false; - - bulkRemoveRecipeByOutput(delayedRemovalByOutput); - bulkRemoveByRecipe(delayedRemovalByRecipe); - sBufferRecipeList.forEach(GameRegistry::addRecipe); - - delayedRemovalByOutput.clear(); - delayedRemovalByRecipe.clear(); - sBufferRecipeList.clear(); - } - - /** - * Shapeless Crafting Recipes. Deletes conflicting Recipes too. - */ - public static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, - int[] aEnchantmentLevelsAdded, Object[] aRecipe) { - return addCraftingRecipe( - aResult, - aEnchantmentsAdded, - aEnchantmentLevelsAdded, - false, - true, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true, - aRecipe); - } - - /** - * Regular Crafting Recipes. Deletes conflicting Recipes too. - *

- * You can insert instances of IItemContainer into the Recipe Input Array directly without having to call "get(1)" - * on them. - *

- * Enums are automatically getting their "name()"-Method called in order to deliver an OreDict String. - *

- * Lowercase Letters are reserved for Tools. They are as follows: - *

- * 'b' ToolDictNames.craftingToolBlade 'c' ToolDictNames.craftingToolCrowbar, 'd' - * ToolDictNames.craftingToolScrewdriver, 'f' ToolDictNames.craftingToolFile, 'h' - * ToolDictNames.craftingToolHardHammer, 'i' ToolDictNames.craftingToolSolderingIron, 'j' - * ToolDictNames.craftingToolSolderingMetal, 'k' ToolDictNames.craftingToolKnive 'm' - * ToolDictNames.craftingToolMortar, 'p' ToolDictNames.craftingToolDrawplate, 'r' - * ToolDictNames.craftingToolSoftHammer, 's' ToolDictNames.craftingToolSaw, 'w' ToolDictNames.craftingToolWrench, - * 'x' ToolDictNames.craftingToolWireCutter, - */ - public static boolean addCraftingRecipe(ItemStack aResult, Object[] aRecipe) { - return addCraftingRecipe(aResult, 0, aRecipe); - } - - /** - * Regular Crafting Recipes. Deletes conflicting Recipes too. - *

- * You can insert instances of IItemContainer into the Recipe Input Array directly without having to call "get(1)" - * on them. - *

- * Enums are automatically getting their "name()"-Method called in order to deliver an OreDict String. - *

- * Lowercase Letters are reserved for Tools. They are as follows: - *

- * 'b' ToolDictNames.craftingToolBlade 'c' ToolDictNames.craftingToolCrowbar, 'd' - * ToolDictNames.craftingToolScrewdriver, 'f' ToolDictNames.craftingToolFile, 'h' - * ToolDictNames.craftingToolHardHammer, 'i' ToolDictNames.craftingToolSolderingIron, 'j' - * ToolDictNames.craftingToolSolderingMetal, 'k' ToolDictNames.craftingToolKnive 'm' - * ToolDictNames.craftingToolMortar, 'p' ToolDictNames.craftingToolDrawplate, 'r' - * ToolDictNames.craftingToolSoftHammer, 's' ToolDictNames.craftingToolSaw, 'w' ToolDictNames.craftingToolWrench, - * 'x' ToolDictNames.craftingToolWireCutter, - */ - public static boolean addCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) { - return addCraftingRecipe( - aResult, - new Enchantment[0], - new int[0], - (aBitMask & RecipeBits.MIRRORED) != 0, - (aBitMask & RecipeBits.BUFFERED) != 0, - (aBitMask & RecipeBits.KEEPNBT) != 0, - (aBitMask & RecipeBits.DISMANTLEABLE) != 0, - (aBitMask & RecipeBits.NOT_REMOVABLE) == 0, - (aBitMask & RecipeBits.REVERSIBLE) != 0, - (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES) != 0, - (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT) != 0, - (aBitMask & RecipeBits.DELETE_ALL_OTHER_SHAPED_RECIPES) != 0, - (aBitMask & RecipeBits.DELETE_ALL_OTHER_NATIVE_RECIPES) != 0, - (aBitMask & RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS) == 0, - (aBitMask & RecipeBits.ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT) != 0, - (aBitMask & RecipeBits.ONLY_ADD_IF_RESULT_IS_NOT_NULL) != 0, - aRecipe); - } - - public static boolean addMachineCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe, - int machineTier) { - if (aRecipe != null) { - for (int i = 3; i < aRecipe.length; i++) { - if (!(aRecipe[i] instanceof GT_MetaTileEntity_BasicMachine_GT_Recipe.X)) continue; - - // spotless:off - aRecipe[i] = switch ((GT_MetaTileEntity_BasicMachine_GT_Recipe.X) aRecipe[i]) { - case CIRCUIT -> Tier.ELECTRIC[machineTier].mManagingObject; - case BETTER_CIRCUIT -> Tier.ELECTRIC[machineTier].mBetterManagingObject; - case HULL -> Tier.ELECTRIC[machineTier].mHullObject; - case WIRE -> Tier.ELECTRIC[machineTier].mConductingObject; - case WIRE4 -> Tier.ELECTRIC[machineTier].mLargerConductingObject; - case STICK_DISTILLATION -> OrePrefixes.stick.get(Materials.Blaze); - - case GLASS -> switch (machineTier) { - case 0, 1, 2, 3 -> new ItemStack(Blocks.glass, 1, W); - case 4, 5, 6, 7, 8 -> "blockGlass" + VN[machineTier]; - default -> "blockGlass" + VN[8]; - }; - - case PLATE -> switch (machineTier) { - case 0, 1 -> OrePrefixes.plate.get(Materials.Steel); - case 2 -> OrePrefixes.plate.get(Materials.Aluminium); - case 3 -> OrePrefixes.plate.get(Materials.StainlessSteel); - case 4 -> OrePrefixes.plate.get(Materials.Titanium); - case 5 -> OrePrefixes.plate.get(Materials.TungstenSteel); - case 6 -> OrePrefixes.plate.get(Materials.HSSG); - case 7 -> OrePrefixes.plate.get(Materials.HSSE); - default -> OrePrefixes.plate.get(Materials.Neutronium); - }; - - case PIPE -> switch (machineTier) { - case 0, 1 -> OrePrefixes.pipeMedium.get(Materials.Bronze); - case 2 -> OrePrefixes.pipeMedium.get(Materials.Steel); - case 3 -> OrePrefixes.pipeMedium.get(Materials.StainlessSteel); - case 4 -> OrePrefixes.pipeMedium.get(Materials.Titanium); - case 5 -> OrePrefixes.pipeMedium.get(Materials.TungstenSteel); - case 6 -> OrePrefixes.pipeSmall.get(Materials.Ultimate); - case 7 -> OrePrefixes.pipeMedium.get(Materials.Ultimate); - case 8 -> OrePrefixes.pipeLarge.get(Materials.Ultimate); - default -> OrePrefixes.pipeHuge.get(Materials.Ultimate); - }; - - case COIL_HEATING -> switch (machineTier) { - case 0, 1 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); - case 2 -> OrePrefixes.wireGt02.get(Materials.Cupronickel); - case 3 -> OrePrefixes.wireGt02.get(Materials.Kanthal); - case 4 -> OrePrefixes.wireGt02.get(Materials.Nichrome); - case 5 -> OrePrefixes.wireGt02.get(Materials.TPV); - case 6 -> OrePrefixes.wireGt02.get(Materials.HSSG); - case 7 -> OrePrefixes.wireGt02.get(Materials.Naquadah); - case 8 -> OrePrefixes.wireGt02.get(Materials.NaquadahAlloy); - case 9 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); - default -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); - }; - - case COIL_HEATING_DOUBLE -> switch (machineTier) { - case 0, 1 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); - case 2 -> OrePrefixes.wireGt04.get(Materials.Cupronickel); - case 3 -> OrePrefixes.wireGt04.get(Materials.Kanthal); - case 4 -> OrePrefixes.wireGt04.get(Materials.Nichrome); - case 5 -> OrePrefixes.wireGt04.get(Materials.TPV); - case 6 -> OrePrefixes.wireGt04.get(Materials.HSSG); - case 7 -> OrePrefixes.wireGt04.get(Materials.Naquadah); - case 8 -> OrePrefixes.wireGt04.get(Materials.NaquadahAlloy); - case 9 -> OrePrefixes.wireGt08.get(Materials.NaquadahAlloy); - default -> OrePrefixes.wireGt16.get(Materials.NaquadahAlloy); - }; - - case STICK_MAGNETIC -> switch (machineTier) { - case 0, 1 -> OrePrefixes.stick.get(Materials.IronMagnetic); - case 2, 3 -> OrePrefixes.stick.get(Materials.SteelMagnetic); - case 4, 5 -> OrePrefixes.stick.get(Materials.NeodymiumMagnetic); - case 6, 7, 8, 9 -> OrePrefixes.stick.get(Materials.SamariumMagnetic); - default -> OrePrefixes.stick.get(Materials.TengamAttuned); - }; - - case STICK_ELECTROMAGNETIC -> switch (machineTier) { - case 0, 1 -> OrePrefixes.stick.get(Materials.AnyIron); - case 2, 3 -> OrePrefixes.stick.get(Materials.Steel); - case 4 -> OrePrefixes.stick.get(Materials.Neodymium); - default -> OrePrefixes.stick.get(Materials.VanadiumGallium); - }; - - case COIL_ELECTRIC -> switch (machineTier) { - case 0 -> OrePrefixes.wireGt01.get(Materials.Lead); - case 1 -> OrePrefixes.wireGt02.get(Materials.Tin); - case 2 -> OrePrefixes.wireGt02.get(Materials.AnyCopper); - case 3 -> OrePrefixes.wireGt04.get(Materials.AnyCopper); - case 4 -> OrePrefixes.wireGt08.get(Materials.AnnealedCopper); - case 5 -> OrePrefixes.wireGt16.get(Materials.AnnealedCopper); - case 6 -> OrePrefixes.wireGt04.get(Materials.YttriumBariumCuprate); - case 7 -> OrePrefixes.wireGt08.get(Materials.Iridium); - default -> OrePrefixes.wireGt16.get(Materials.Osmium); - }; - - case ROBOT_ARM -> switch (machineTier) { - case 0, 1 -> ItemList.Robot_Arm_LV; - case 2 -> ItemList.Robot_Arm_MV; - case 3 -> ItemList.Robot_Arm_HV; - case 4 -> ItemList.Robot_Arm_EV; - case 5 -> ItemList.Robot_Arm_IV; - case 6 -> ItemList.Robot_Arm_LuV; - case 7 -> ItemList.Robot_Arm_ZPM; - case 8 -> ItemList.Robot_Arm_UV; - case 9 -> ItemList.Robot_Arm_UHV; - case 10 -> ItemList.Robot_Arm_UEV; - case 11 -> ItemList.Robot_Arm_UIV; - case 12 -> ItemList.Robot_Arm_UMV; - case 13 -> ItemList.Robot_Arm_UXV; - default -> ItemList.Robot_Arm_MAX; - }; - - case PUMP -> switch (machineTier) { - case 0, 1 -> ItemList.Electric_Pump_LV; - case 2 -> ItemList.Electric_Pump_MV; - case 3 -> ItemList.Electric_Pump_HV; - case 4 -> ItemList.Electric_Pump_EV; - case 5 -> ItemList.Electric_Pump_IV; - case 6 -> ItemList.Electric_Pump_LuV; - case 7 -> ItemList.Electric_Pump_ZPM; - case 8 -> ItemList.Electric_Pump_UV; - case 9 -> ItemList.Electric_Pump_UHV; - case 10 -> ItemList.Electric_Pump_UEV; - case 11 -> ItemList.Electric_Pump_UIV; - case 12 -> ItemList.Electric_Pump_UMV; - case 13 -> ItemList.Electric_Pump_UXV; - default -> ItemList.Electric_Pump_MAX; - }; - - case MOTOR -> switch (machineTier) { - case 0, 1 -> ItemList.Electric_Motor_LV; - case 2 -> ItemList.Electric_Motor_MV; - case 3 -> ItemList.Electric_Motor_HV; - case 4 -> ItemList.Electric_Motor_EV; - case 5 -> ItemList.Electric_Motor_IV; - case 6 -> ItemList.Electric_Motor_LuV; - case 7 -> ItemList.Electric_Motor_ZPM; - case 8 -> ItemList.Electric_Motor_UV; - case 9 -> ItemList.Electric_Motor_UHV; - case 10 -> ItemList.Electric_Motor_UEV; - case 11 -> ItemList.Electric_Motor_UIV; - case 12 -> ItemList.Electric_Motor_UMV; - case 13 -> ItemList.Electric_Motor_UXV; - default -> ItemList.Electric_Motor_MAX; - }; - - case PISTON -> switch (machineTier) { - case 0, 1 -> ItemList.Electric_Piston_LV; - case 2 -> ItemList.Electric_Piston_MV; - case 3 -> ItemList.Electric_Piston_HV; - case 4 -> ItemList.Electric_Piston_EV; - case 5 -> ItemList.Electric_Piston_IV; - case 6 -> ItemList.Electric_Piston_LuV; - case 7 -> ItemList.Electric_Piston_ZPM; - case 8 -> ItemList.Electric_Piston_UV; - case 9 -> ItemList.Electric_Piston_UHV; - case 10 -> ItemList.Electric_Piston_UEV; - case 11 -> ItemList.Electric_Piston_UIV; - case 12 -> ItemList.Electric_Piston_UMV; - case 13 -> ItemList.Electric_Piston_UXV; - default -> ItemList.Electric_Piston_MAX; - }; - - case CONVEYOR -> switch (machineTier) { - case 0, 1 -> ItemList.Conveyor_Module_LV; - case 2 -> ItemList.Conveyor_Module_MV; - case 3 -> ItemList.Conveyor_Module_HV; - case 4 -> ItemList.Conveyor_Module_EV; - case 5 -> ItemList.Conveyor_Module_IV; - case 6 -> ItemList.Conveyor_Module_LuV; - case 7 -> ItemList.Conveyor_Module_ZPM; - case 8 -> ItemList.Conveyor_Module_UV; - case 9 -> ItemList.Conveyor_Module_UHV; - case 10 -> ItemList.Conveyor_Module_UEV; - case 11 -> ItemList.Conveyor_Module_UIV; - case 12 -> ItemList.Conveyor_Module_UMV; - case 13 -> ItemList.Conveyor_Module_UXV; - default -> ItemList.Conveyor_Module_MAX; - }; - - case EMITTER -> switch (machineTier) { - case 0, 1 -> ItemList.Emitter_LV; - case 2 -> ItemList.Emitter_MV; - case 3 -> ItemList.Emitter_HV; - case 4 -> ItemList.Emitter_EV; - case 5 -> ItemList.Emitter_IV; - case 6 -> ItemList.Emitter_LuV; - case 7 -> ItemList.Emitter_ZPM; - case 8 -> ItemList.Emitter_UV; - case 9 -> ItemList.Emitter_UHV; - case 10 -> ItemList.Emitter_UEV; - case 11 -> ItemList.Emitter_UIV; - case 12 -> ItemList.Emitter_UMV; - case 13 -> ItemList.Emitter_UXV; - default -> ItemList.Emitter_MAX; - }; - - case SENSOR -> switch (machineTier) { - case 0, 1 -> ItemList.Sensor_LV; - case 2 -> ItemList.Sensor_MV; - case 3 -> ItemList.Sensor_HV; - case 4 -> ItemList.Sensor_EV; - case 5 -> ItemList.Sensor_IV; - case 6 -> ItemList.Sensor_LuV; - case 7 -> ItemList.Sensor_ZPM; - case 8 -> ItemList.Sensor_UV; - case 9 -> ItemList.Sensor_UHV; - case 10 -> ItemList.Sensor_UEV; - case 11 -> ItemList.Sensor_UIV; - case 12 -> ItemList.Sensor_UMV; - case 13 -> ItemList.Sensor_UXV; - default -> ItemList.Sensor_MAX; - }; - - case FIELD_GENERATOR -> switch (machineTier) { - case 0, 1 -> ItemList.Field_Generator_LV; - case 2 -> ItemList.Field_Generator_MV; - case 3 -> ItemList.Field_Generator_HV; - case 4 -> ItemList.Field_Generator_EV; - case 5 -> ItemList.Field_Generator_IV; - case 6 -> ItemList.Field_Generator_LuV; - case 7 -> ItemList.Field_Generator_ZPM; - case 8 -> ItemList.Field_Generator_UV; - case 9 -> ItemList.Field_Generator_UHV; - case 10 -> ItemList.Field_Generator_UEV; - case 11 -> ItemList.Field_Generator_UIV; - case 12 -> ItemList.Field_Generator_UMV; - case 13 -> ItemList.Field_Generator_UXV; - default -> ItemList.Field_Generator_MAX; - }; - - case ROTOR -> switch (machineTier) { - case 0, 1 -> OrePrefixes.rotor.get(Materials.Tin); - case 2 -> OrePrefixes.rotor.get(Materials.Bronze); - case 3 -> OrePrefixes.rotor.get(Materials.Steel); - case 4 -> OrePrefixes.rotor.get(Materials.StainlessSteel); - case 5 -> OrePrefixes.rotor.get(Materials.TungstenSteel); - case 6 -> OrePrefixes.rotor.get(ExternalMaterials.getRhodiumPlatedPalladium()); - case 7 -> OrePrefixes.rotor.get(Materials.Iridium); - default -> OrePrefixes.rotor.get(Materials.Osmium); - }; - - default -> throw new IllegalArgumentException("MISSING TIER MAPPING FOR: " + aRecipe[i] + " AT TIER " + machineTier); - }; - // spotless:on - } - - if (!GT_ModHandler.addCraftingRecipe( - aResult, - GT_ModHandler.RecipeBits.DISMANTLEABLE | GT_ModHandler.RecipeBits.BUFFERED - | GT_ModHandler.RecipeBits.NOT_REMOVABLE - | GT_ModHandler.RecipeBits.REVERSIBLE, - aRecipe)) { - throw new IllegalArgumentException("INVALID CRAFTING RECIPE FOR: " + aResult.getDisplayName()); - } - } - return true; - } - - /** - * Internal realisation of the Crafting Recipe adding Process. - */ - private static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, - int[] aEnchantmentLevelsAdded, boolean aMirrored, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable, - boolean aRemovable, boolean aReversible, boolean aRemoveAllOthersWithSameOutput, - boolean aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, boolean aRemoveAllOtherShapedsWithSameOutput, - boolean aRemoveAllOtherNativeRecipes, boolean aCheckForCollisions, - boolean aOnlyAddIfThereIsAnyRecipeOutputtingThis, boolean aOnlyAddIfResultIsNotNull, Object[] aRecipe) { - - aResult = GT_OreDictUnificator.get(true, aResult); - if (aOnlyAddIfResultIsNotNull && aResult == null) return false; - if (aResult != null && Items.feather.getDamage(aResult) == W) Items.feather.setDamage(aResult, 0); - if (aRecipe == null || aRecipe.length == 0) return false; - - // The renamed variable clarifies what's happening - // noinspection UnnecessaryLocalVariable - boolean tDoWeCareIfThereWasARecipe = aOnlyAddIfThereIsAnyRecipeOutputtingThis; - boolean tThereWasARecipe = false; - - for (byte i = 0; i < aRecipe.length; i++) { - if (aRecipe[i] instanceof IItemContainer) aRecipe[i] = ((IItemContainer) aRecipe[i]).get(1); - else if (aRecipe[i] instanceof Enum) aRecipe[i] = ((Enum) aRecipe[i]).name(); - else if (!(aRecipe[i] == null || aRecipe[i] instanceof ItemStack - || aRecipe[i] instanceof ItemData - || aRecipe[i] instanceof String - || aRecipe[i] instanceof Character)) aRecipe[i] = aRecipe[i].toString(); - } - - try { - StringBuilder shape = new StringBuilder(E); - int idx = 0; - if (aRecipe[idx] instanceof Boolean) { - throw new IllegalArgumentException(); - } - - ArrayList tRecipeList = new ArrayList<>(Arrays.asList(aRecipe)); - - while (aRecipe[idx] instanceof String) { - StringBuilder s = new StringBuilder((String) aRecipe[idx++]); - shape.append(s); - while (s.length() < 3) s.append(" "); - if (s.length() > 3) throw new IllegalArgumentException(); - - for (char c : s.toString() - .toCharArray()) { - switch (c) { - case 'b' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolBlade.name()); - } - case 'c' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolCrowbar.name()); - } - case 'd' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolScrewdriver.name()); - } - case 'f' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolFile.name()); - } - case 'h' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolHardHammer.name()); - } - case 'i' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolSolderingIron.name()); - } - case 'j' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolSolderingMetal.name()); - } - case 'k' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolKnife.name()); - } - case 'm' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolMortar.name()); - } - case 'p' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolDrawplate.name()); - } - case 'r' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolSoftHammer.name()); - } - case 's' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolSaw.name()); - } - case 'w' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolWrench.name()); - } - case 'x' -> { - tRecipeList.add(c); - tRecipeList.add(ToolDictNames.craftingToolWireCutter.name()); - } - } - } - } - - aRecipe = tRecipeList.toArray(); - - if (aRecipe[idx] instanceof Boolean) { - idx++; - } - Map tItemStackMap = new HashMap<>(); - Map tItemDataMap = new HashMap<>(); - tItemStackMap.put(' ', null); - - boolean tRemoveRecipe = true; - - for (; idx < aRecipe.length; idx += 2) { - if (aRecipe[idx] == null || aRecipe[idx + 1] == null) { - if (D1) { - GT_Log.err.println( - "WARNING: Missing Item for shaped Recipe: " - + (aResult == null ? "null" : aResult.getDisplayName())); - for (Object tContent : aRecipe) GT_Log.err.println(tContent); - } - return false; - } - Character chr = (Character) aRecipe[idx]; - Object in = aRecipe[idx + 1]; - if (in instanceof ItemStack is) { - tItemStackMap.put(chr, GT_Utility.copyOrNull(is)); - tItemDataMap.put(chr, GT_OreDictUnificator.getItemData(is)); - } else if (in instanceof ItemData) { - String tString = in.toString(); - switch (tString) { - case "plankWood" -> tItemDataMap.put(chr, new ItemData(Materials.Wood, M)); - case "stoneNetherrack" -> tItemDataMap.put(chr, new ItemData(Materials.Netherrack, M)); - case "stoneObsidian" -> tItemDataMap.put(chr, new ItemData(Materials.Obsidian, M)); - case "stoneEndstone" -> tItemDataMap.put(chr, new ItemData(Materials.Endstone, M)); - default -> tItemDataMap.put(chr, (ItemData) in); - } - ItemStack tStack = GT_OreDictUnificator.getFirstOre(in, 1); - if (tStack == null) tRemoveRecipe = false; - else tItemStackMap.put(chr, tStack); - in = aRecipe[idx + 1] = in.toString(); - } else if (in instanceof String) { - if (in.equals(OreDictNames.craftingChest.toString())) - tItemDataMap.put(chr, new ItemData(Materials.Wood, M * 8)); - else if (in.equals(OreDictNames.craftingBook.toString())) - tItemDataMap.put(chr, new ItemData(Materials.Paper, M * 3)); - else if (in.equals(OreDictNames.craftingPiston.toString())) - tItemDataMap.put(chr, new ItemData(Materials.Stone, M * 4, Materials.Wood, M * 3)); - else if (in.equals(OreDictNames.craftingFurnace.toString())) - tItemDataMap.put(chr, new ItemData(Materials.Stone, M * 8)); - else if (in.equals(OreDictNames.craftingIndustrialDiamond.toString())) - tItemDataMap.put(chr, new ItemData(Materials.Diamond, M)); - else if (in.equals(OreDictNames.craftingAnvil.toString())) - tItemDataMap.put(chr, new ItemData(Materials.Iron, M * 10)); - ItemStack tStack = GT_OreDictUnificator.getFirstOre(in, 1); - if (tStack == null) tRemoveRecipe = false; - else tItemStackMap.put(chr, tStack); - } else { - throw new IllegalArgumentException(); - } - } - - if (aReversible && aResult != null) { - ItemData[] tData = new ItemData[9]; - int x = -1; - for (char chr : shape.toString() - .toCharArray()) tData[++x] = tItemDataMap.get(chr); - if (GT_Utility.arrayContainsNonNull(tData)) - GT_OreDictUnificator.addItemData(aResult, new ItemData(tData)); - } - - if (aCheckForCollisions && tRemoveRecipe) { - ItemStack[] tRecipe = new ItemStack[9]; - int x = -1; - for (char chr : shape.toString() - .toCharArray()) { - tRecipe[++x] = tItemStackMap.get(chr); - if (tRecipe[x] != null && Items.feather.getDamage(tRecipe[x]) == W) - Items.feather.setDamage(tRecipe[x], 0); - } - if (tDoWeCareIfThereWasARecipe || !aBuffered) tThereWasARecipe = removeRecipe(tRecipe) != null; - else removeRecipeDelayed(tRecipe); - } - } catch (Throwable e) { - e.printStackTrace(GT_Log.err); - } - - if (aResult == null || aResult.stackSize <= 0) return false; - - if (aRemoveAllOthersWithSameOutput || aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT - || aRemoveAllOtherShapedsWithSameOutput - || aRemoveAllOtherNativeRecipes) { - if (tDoWeCareIfThereWasARecipe || !aBuffered) tThereWasARecipe = removeRecipeByOutput( - aResult, - !aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, - aRemoveAllOtherShapedsWithSameOutput, - aRemoveAllOtherNativeRecipes) || tThereWasARecipe; - else removeRecipeByOutputDelayed(aResult); - } - - if (aOnlyAddIfThereIsAnyRecipeOutputtingThis && !tDoWeCareIfThereWasARecipe && !tThereWasARecipe) { - ArrayList tList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - int tList_sS = tList.size(); - for (int i = 0; i < tList_sS && !tThereWasARecipe; i++) { - IRecipe tRecipe = tList.get(i); - if (sSpecialRecipeClasses.contains( - tRecipe.getClass() - .getName())) - continue; - if (GT_Utility.areStacksEqual(GT_OreDictUnificator.get(tRecipe.getRecipeOutput()), aResult, true)) { - tList.remove(i--); - tList_sS = tList.size(); - tThereWasARecipe = true; - } - } - } - - if (Items.feather.getDamage(aResult) == W || Items.feather.getDamage(aResult) < 0) - Items.feather.setDamage(aResult, 0); - - GT_Utility.updateItemStack(aResult); - - if (tThereWasARecipe || !aOnlyAddIfThereIsAnyRecipeOutputtingThis) { - if (sBufferCraftingRecipes && aBuffered) sBufferRecipeList.add( - new GT_Shaped_Recipe( - GT_Utility.copyOrNull(aResult), - aDismantleable, - aRemovable, - aKeepNBT, - aEnchantmentsAdded, - aEnchantmentLevelsAdded, - aRecipe).setMirrored(aMirrored)); - else GameRegistry.addRecipe( - new GT_Shaped_Recipe( - GT_Utility.copyOrNull(aResult), - aDismantleable, - aRemovable, - aKeepNBT, - aEnchantmentsAdded, - aEnchantmentLevelsAdded, - aRecipe).setMirrored(aMirrored)); - } - return true; - } - - /** - * Shapeless Crafting Recipes. Deletes conflicting Recipes too. - */ - public static boolean addShapelessEnchantingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, - int[] aEnchantmentLevelsAdded, Object[] aRecipe) { - return addShapelessCraftingRecipe( - aResult, - aEnchantmentsAdded, - aEnchantmentLevelsAdded, - true, - false, - false, - false, - aRecipe); - } - - /** - * Shapeless Crafting Recipes. Deletes conflicting Recipes too. - */ - public static boolean addShapelessCraftingRecipe(ItemStack aResult, Object[] aRecipe) { - return addShapelessCraftingRecipe( - aResult, - RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS | RecipeBits.BUFFERED, - aRecipe); - } - - /** - * Shapeless Crafting Recipes. Deletes conflicting Recipes too. - */ - public static boolean addShapelessCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) { - return addShapelessCraftingRecipe( - aResult, - new Enchantment[0], - new int[0], - (aBitMask & RecipeBits.BUFFERED) != 0, - (aBitMask & RecipeBits.KEEPNBT) != 0, - (aBitMask & RecipeBits.DISMANTLEABLE) != 0, - (aBitMask & RecipeBits.NOT_REMOVABLE) == 0, - aRecipe); - } - - /** - * Shapeless Crafting Recipes. Deletes conflicting Recipes too. - */ - private static boolean addShapelessCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, - int[] aEnchantmentLevelsAdded, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable, boolean aRemovable, - Object[] aRecipe) { - aResult = GT_OreDictUnificator.get(true, aResult); - if (aRecipe == null || aRecipe.length == 0) return false; - for (byte i = 0; i < aRecipe.length; i++) { - if (aRecipe[i] instanceof IItemContainer) aRecipe[i] = ((IItemContainer) aRecipe[i]).get(1); - else if (aRecipe[i] instanceof Enum) aRecipe[i] = ((Enum) aRecipe[i]).name(); - else if (!(aRecipe[i] == null || aRecipe[i] instanceof ItemStack - || aRecipe[i] instanceof String - || aRecipe[i] instanceof Character)) aRecipe[i] = aRecipe[i].toString(); - } - try { - ItemStack[] tRecipe = new ItemStack[9]; - int i = 0; - for (Object tObject : aRecipe) { - if (tObject == null) { - if (D1) GT_Log.err.println( - "WARNING: Missing Item for shapeless Recipe: " - + (aResult == null ? "null" : aResult.getDisplayName())); - for (Object tContent : aRecipe) GT_Log.err.println(tContent); - return false; - } - if (tObject instanceof ItemStack) { - tRecipe[i] = (ItemStack) tObject; - } else if (tObject instanceof String) { - tRecipe[i] = GT_OreDictUnificator.getFirstOre(tObject, 1); - if (tRecipe[i] == null) break; - } - i++; - } - if (sBufferCraftingRecipes && aBuffered) removeRecipeDelayed(tRecipe); - else removeRecipe(tRecipe); - } catch (Throwable e) { - e.printStackTrace(GT_Log.err); - } - - if (aResult == null || aResult.stackSize <= 0) return false; - - if (Items.feather.getDamage(aResult) == W || Items.feather.getDamage(aResult) < 0) - Items.feather.setDamage(aResult, 0); - - GT_Utility.updateItemStack(aResult); - - if (sBufferCraftingRecipes && aBuffered) sBufferRecipeList.add( - new GT_Shapeless_Recipe( - GT_Utility.copyOrNull(aResult), - aDismantleable, - aRemovable, - aKeepNBT, - aEnchantmentsAdded, - aEnchantmentLevelsAdded, - aRecipe)); - else GameRegistry.addRecipe( - new GT_Shapeless_Recipe( - GT_Utility.copyOrNull(aResult), - aDismantleable, - aRemovable, - aKeepNBT, - aEnchantmentsAdded, - aEnchantmentLevelsAdded, - aRecipe)); - return true; - } - - /** - * Removes a Smelting Recipe - */ - public static boolean removeFurnaceSmelting(ItemStack aInput) { - if (aInput != null) { - for (ItemStack tInput : FurnaceRecipes.smelting() - .getSmeltingList() - .keySet()) { - if (GT_Utility.isStackValid(tInput) && GT_Utility.areStacksEqual(aInput, tInput, true)) { - FurnaceRecipes.smelting() - .getSmeltingList() - .remove(tInput); - return true; - } - } - } - return false; - } - - /** - * Removes all matching Smelting Recipes by output - */ - public static boolean removeFurnaceSmeltingByOutput(ItemStack aOutput) { - if (aOutput != null) { - return FurnaceRecipes.smelting() - .getSmeltingList() - .values() - .removeIf( - tOutput -> GT_Utility.isStackValid(tOutput) && GT_Utility.areStacksEqual(aOutput, tOutput, true)); - } - return false; - } - - /** - * Removes a Crafting Recipe and gives you the former output of it. - * - * @param aRecipe The content of the Crafting Grid as ItemStackArray with length 9 - * @return the output of the old Recipe or null if there was nothing. - */ - public static ItemStack removeRecipe(ItemStack... aRecipe) { - if (aRecipe == null) return null; - if (Arrays.stream(aRecipe) - .noneMatch(Objects::nonNull)) return null; - - ItemStack rReturn = null; - InventoryCrafting aCrafting = new InventoryCrafting(new Container() { - - @Override - public boolean canInteractWith(EntityPlayer player) { - return false; - } - }, 3, 3); - for (int i = 0; i < aRecipe.length && i < 9; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); - ArrayList tList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - int tList_sS = tList.size(); - try { - for (int i = 0; i < tList_sS; i++) { - for (; i < tList_sS; i++) { - if ((!(tList.get(i) instanceof IGT_CraftingRecipe) - || ((IGT_CraftingRecipe) tList.get(i)).isRemovable()) && tList.get(i) - .matches(aCrafting, DW)) { - rReturn = tList.get(i) - .getCraftingResult(aCrafting); - if (rReturn != null) tList.remove(i--); - tList_sS = tList.size(); - } - } - } - } catch (Throwable e) { - e.printStackTrace(GT_Log.err); - } - return rReturn; - } - - public static void removeRecipeDelayed(ItemStack... aRecipe) { - if (!sBufferCraftingRecipes) { - removeRecipe(aRecipe); - return; - } - - if (aRecipe == null) return; - if (Arrays.stream(aRecipe) - .noneMatch(Objects::nonNull)) return; - - InventoryCrafting aCrafting = new InventoryCrafting(new Container() { - - @Override - public boolean canInteractWith(EntityPlayer player) { - return false; - } - }, 3, 3); - for (int i = 0; i < aRecipe.length && i < 9; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); - delayedRemovalByRecipe.add(aCrafting); - } - - public static void bulkRemoveByRecipe(List toRemove) { - ArrayList tList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - GT_FML_LOGGER.info("BulkRemoveByRecipe: tList: " + tList.size() + " toRemove: " + toRemove.size()); - - Set tListToRemove = tList.parallelStream() - .filter(tRecipe -> { - if ((tRecipe instanceof IGT_CraftingRecipe) && !((IGT_CraftingRecipe) tRecipe).isRemovable()) - return false; - return toRemove.stream() - .anyMatch(aCrafting -> tRecipe.matches(aCrafting, DW)); - }) - .collect(Collectors.toSet()); - - tList.removeIf(tListToRemove::contains); - } - - public static boolean removeRecipeByOutputDelayed(ItemStack aOutput) { - if (sBufferCraftingRecipes) return delayedRemovalByOutput.add(aOutput); - else return removeRecipeByOutput(aOutput); - } - - public static boolean removeRecipeByOutputDelayed(ItemStack aOutput, boolean aIgnoreNBT, - boolean aNotRemoveShapelessRecipes, boolean aOnlyRemoveNativeHandlers) { - if (sBufferCraftingRecipes && (aIgnoreNBT && !aNotRemoveShapelessRecipes && !aOnlyRemoveNativeHandlers)) - // Too lazy to handle deferred versions of the parameters that aren't used very often - return delayedRemovalByOutput.add(aOutput); - else return removeRecipeByOutput(aOutput, aIgnoreNBT, aNotRemoveShapelessRecipes, aOnlyRemoveNativeHandlers); - } - - public static boolean removeRecipeByOutput(ItemStack aOutput) { - return removeRecipeByOutput(aOutput, true, false, false); - } - - /** - * Removes a Crafting Recipe. - * - * @param aOutput The output of the Recipe. - * @return if it has removed at least one Recipe. - */ - public static boolean removeRecipeByOutput(ItemStack aOutput, boolean aIgnoreNBT, - boolean aNotRemoveShapelessRecipes, boolean aOnlyRemoveNativeHandlers) { - if (aOutput == null) return false; - boolean rReturn = false; - final ArrayList tList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - aOutput = GT_OreDictUnificator.get(aOutput); - int tList_sS = tList.size(); - for (int i = 0; i < tList_sS; i++) { - final IRecipe tRecipe = tList.get(i); - if (aNotRemoveShapelessRecipes - && (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe)) continue; - if (aOnlyRemoveNativeHandlers) { - if (!sNativeRecipeClasses.contains( - tRecipe.getClass() - .getName())) - continue; - } else { - if (sSpecialRecipeClasses.contains( - tRecipe.getClass() - .getName())) - continue; - } - ItemStack tStack = tRecipe.getRecipeOutput(); - if ((!(tRecipe instanceof IGT_CraftingRecipe) || ((IGT_CraftingRecipe) tRecipe).isRemovable()) - && GT_Utility.areStacksEqual(GT_OreDictUnificator.get(tStack), aOutput, aIgnoreNBT)) { - tList.remove(i--); - tList_sS = tList.size(); - rReturn = true; - } - } - return rReturn; - } - - public static boolean bulkRemoveRecipeByOutput(List toRemove) { - ArrayList tList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - - Set setToRemove = toRemove.parallelStream() - .map(GT_OreDictUnificator::get_nocopy) - .collect(Collectors.toSet()); - - GT_FML_LOGGER.info("BulkRemoveRecipeByOutput: tList: " + tList.size() + " setToRemove: " + setToRemove.size()); - - Set tListToRemove = tList.parallelStream() - .filter(tRecipe -> { - if ((tRecipe instanceof IGT_CraftingRecipe) && !((IGT_CraftingRecipe) tRecipe).isRemovable()) - return false; - if (sSpecialRecipeClasses.contains( - tRecipe.getClass() - .getName())) - return false; - final ItemStack tStack = GT_OreDictUnificator.get_nocopy(tRecipe.getRecipeOutput()); - return setToRemove.stream() - .anyMatch(aOutput -> GT_Utility.areStacksEqual(tStack, aOutput, true)); - }) - .collect(Collectors.toSet()); - - tList.removeIf(tListToRemove::contains); - return true; - } - - /** - * Checks all Crafting Handlers for Recipe Output Used for the Autocrafting Table - */ - public static ItemStack getAllRecipeOutput(World aWorld, ItemStack... aRecipe) { - if (aRecipe == null || aRecipe.length == 0) return null; - - if (aWorld == null) aWorld = DW; - - boolean temp = false; - for (ItemStack itemStack : aRecipe) { - if (itemStack != null) { - temp = true; - break; - } - } - if (!temp) return null; - InventoryCrafting aCrafting = new InventoryCrafting(new Container() { - - @Override - public boolean canInteractWith(EntityPlayer player) { - return false; - } - }, 3, 3); - for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); - List tList = CraftingManager.getInstance() - .getRecipeList(); - synchronized (sAllRecipeList) { - if (sAllRecipeList.size() != tList.size()) { - sAllRecipeList.clear(); - sAllRecipeList.addAll(tList); - } - for (int i = 0, j = sAllRecipeList.size(); i < j; i++) { - IRecipe tRecipe = sAllRecipeList.get(i); - if (tRecipe.matches(aCrafting, aWorld)) { - if (i > 10) { - sAllRecipeList.remove(i); - sAllRecipeList.add(i - 10, tRecipe); - } - return tRecipe.getCraftingResult(aCrafting); - } - } - } - - int tIndex = 0; - ItemStack tStack1 = null, tStack2 = null; - for (int i = 0, j = aCrafting.getSizeInventory(); i < j; i++) { - ItemStack tStack = aCrafting.getStackInSlot(i); - if (tStack != null) { - if (tIndex == 0) tStack1 = tStack; - if (tIndex == 1) tStack2 = tStack; - tIndex++; - } - } - - if (tIndex == 2 && tStack2 != null) { - if (tStack1.getItem() == tStack2.getItem() && tStack1.stackSize == 1 - && tStack2.stackSize == 1 - && tStack1.getItem() - .isRepairable()) { - int tNewDamage = tStack1.getMaxDamage() + tStack1.getItemDamage() - - tStack2.getItemDamage() - + tStack1.getMaxDamage() / 20; - return new ItemStack(tStack1.getItem(), 1, Math.max(tNewDamage, 0)); - } - } - - return null; - } - - /** - * Gives you a copy of the Output from a Crafting Recipe Used for Recipe Detection. - */ - public static ItemStack getRecipeOutput(ItemStack... aRecipe) { - return getRecipeOutput(false, true, aRecipe); - } - - public static ItemStack getRecipeOutputNoOreDict(ItemStack... aRecipe) { - return getRecipeOutput(false, false, aRecipe); - } - - public static ItemStack getRecipeOutput(boolean aUncopiedStack, ItemStack... aRecipe) { - return getRecipeOutput(aUncopiedStack, true, aRecipe); - } - - /** - * Gives you a copy of the Output from a Crafting Recipe Used for Recipe Detection. - */ - public static ItemStack getRecipeOutput(boolean aUncopiedStack, boolean allowOreDict, ItemStack... aRecipe) { - if (aRecipe == null || Arrays.stream(aRecipe) - .noneMatch(Objects::nonNull)) return null; - - InventoryCrafting aCrafting = new InventoryCrafting(new Container() { - - @Override - public boolean canInteractWith(EntityPlayer player) { - return false; - } - }, 3, 3); - for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); - ArrayList tList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - boolean found = false; - - for (IRecipe iRecipe : tList) { - found = false; - if (!allowOreDict && iRecipe instanceof ShapedOreRecipe) continue; - - try { - found = iRecipe.matches(aCrafting, DW); - } catch (Throwable e) { - e.printStackTrace(GT_Log.err); - } - if (found) { - ItemStack tOutput = aUncopiedStack ? iRecipe.getRecipeOutput() : iRecipe.getCraftingResult(aCrafting); - if (tOutput == null || tOutput.stackSize <= 0) { - // Seriously, who would ever do that shit? - if (!GregTech_API.sPostloadFinished) throw new GT_ItsNotMyFaultException( - "Seems another Mod added a Crafting Recipe with null Output. Tell the Developer of said Mod to fix that."); - } else { - if (aUncopiedStack) return tOutput; - return GT_Utility.copyOrNull(tOutput); - } - } - } - return null; - } - - /** - * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for - * example This also removes old Recipes from the List. - */ - public static List getVanillyToolRecipeOutputs(ItemStack... aRecipe) { - if (!GregTech_API.sPostloadStarted || GregTech_API.sPostloadFinished) - sSingleNonBlockDamagableRecipeList.clear(); - if (sSingleNonBlockDamagableRecipeList.isEmpty()) { - for (IRecipe tRecipe : CraftingManager.getInstance() - .getRecipeList()) { - ItemStack tStack = tRecipe.getRecipeOutput(); - if (GT_Utility.isStackValid(tStack) && tStack.getMaxStackSize() == 1 - && tStack.getMaxDamage() > 0 - && !(tStack.getItem() instanceof ItemBlock) - && !(tStack.getItem() instanceof IReactorComponent) - && !isElectricItem(tStack) - && !GT_Utility.isStackInList(tStack, sNonReplaceableItems)) { - if (!(tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe)) { - if (tRecipe instanceof ShapedOreRecipe) { - boolean temp = true; - for (Object tObject : ((ShapedOreRecipe) tRecipe).getInput()) if (tObject != null) { - if (tObject instanceof ItemStack && (((ItemStack) tObject).getItem() == null - || ((ItemStack) tObject).getMaxStackSize() < 2 - || ((ItemStack) tObject).getMaxDamage() > 0 - || ((ItemStack) tObject).getItem() instanceof ItemBlock)) { - temp = false; - break; - } - if (tObject instanceof List && ((List) tObject).isEmpty()) { - temp = false; - break; - } - } - if (temp) sSingleNonBlockDamagableRecipeList.add(tRecipe); - } else if (tRecipe instanceof ShapedRecipes) { - boolean temp = true; - for (ItemStack tObject : ((ShapedRecipes) tRecipe).recipeItems) { - if (tObject != null && (tObject.getItem() == null || tObject.getMaxStackSize() < 2 - || tObject.getMaxDamage() > 0 - || tObject.getItem() instanceof ItemBlock)) { - temp = false; - break; - } - } - if (temp) sSingleNonBlockDamagableRecipeList.add(tRecipe); - } else { - sSingleNonBlockDamagableRecipeList.add(tRecipe); - } - } - } - } - GT_Log.out.println( - "GT_Mod: Created a List of Tool Recipes containing " + sSingleNonBlockDamagableRecipeList.size() - + " Recipes for recycling." - + (sSingleNonBlockDamagableRecipeList.size() > 1024 - ? " Scanning all these Recipes is the reason for the startup Lag you receive right now." - : E)); - } - List rList = getRecipeOutputs(sSingleNonBlockDamagableRecipeList, true, aRecipe); - if (!GregTech_API.sPostloadStarted || GregTech_API.sPostloadFinished) - sSingleNonBlockDamagableRecipeList.clear(); - return rList; - } - - /** - * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for - * example - */ - public static List getRecipeOutputs(ItemStack... aRecipe) { - return getRecipeOutputs( - CraftingManager.getInstance() - .getRecipeList(), - false, - aRecipe); - } - - private static List bufferedRecipes = null; - - /** - * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for - * example Buffers a List which only has armor-alike crafting in it - */ - public static List getRecipeOutputsBuffered(ItemStack... aRecipe) { - - if (bufferedRecipes == null) bufferedRecipes = CraftingManager.getInstance() - .getRecipeList() - .stream() - .filter( - tRecipe -> !(tRecipe instanceof ShapelessRecipes) && !(tRecipe instanceof ShapelessOreRecipe) - && !(tRecipe instanceof IGT_CraftingRecipe)) - .filter(tRecipe -> { - try { - ItemStack tOutput = tRecipe.getRecipeOutput(); - if (tOutput.stackSize == 1 && tOutput.getMaxDamage() > 0 && tOutput.getMaxStackSize() == 1) { - return true; - } - } catch (Exception ignored) {} - return false; - }) - .collect(Collectors.toList()); - return getRecipeOutputs(bufferedRecipes, false, aRecipe); - } - - /** - * Gives you a list of the Outputs from a Crafting Recipe If you have multiple Mods, which add Bronze Armor for - * example - */ - public static List getRecipeOutputs(List aList, boolean aDeleteFromList, ItemStack... aRecipe) { - List rList = new ArrayList<>(); - if (aRecipe == null || Arrays.stream(aRecipe) - .noneMatch(Objects::nonNull)) return rList; - InventoryCrafting aCrafting = new InventoryCrafting(new Container() { - - @Override - public boolean canInteractWith(EntityPlayer player) { - return false; - } - }, 3, 3); - for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); - if (!aDeleteFromList) { - HashSet stacks = new HashSet<>(); - aList.stream() - .filter(tRecipe -> { - if (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe - || tRecipe instanceof IGT_CraftingRecipe) return false; - try { - return tRecipe.matches(aCrafting, DW); - } catch (Throwable e) { - e.printStackTrace(GT_Log.err); - return false; - } - }) - .forEach(tRecipe -> stacks.add(tRecipe.getCraftingResult(aCrafting))); - rList = stacks.stream() - .filter( - tOutput -> tOutput.stackSize == 1 && tOutput.getMaxDamage() > 0 && tOutput.getMaxStackSize() == 1) - .collect(Collectors.toList()); - } else for (Iterator iterator = aList.iterator(); iterator.hasNext();) { - IRecipe tRecipe = iterator.next(); - boolean matched = false; - - try { - matched = tRecipe.matches(aCrafting, DW); - } catch (Throwable e) { - e.printStackTrace(GT_Log.err); - } - if (matched) { - ItemStack tOutput = tRecipe.getCraftingResult(aCrafting); - - if (tOutput == null || tOutput.stackSize <= 0) { - // Seriously, who would ever do that shit? - if (!GregTech_API.sPostloadFinished) throw new GT_ItsNotMyFaultException( - "Seems another Mod added a Crafting Recipe with null Output. Tell the Developer of said Mod to fix that."); - continue; - } - if (tOutput.stackSize != 1) continue; - if (tOutput.getMaxDamage() <= 0) continue; - if (tOutput.getMaxStackSize() != 1) continue; - if (tRecipe instanceof ShapelessRecipes) continue; - if (tRecipe instanceof ShapelessOreRecipe) continue; - if (tRecipe instanceof IGT_CraftingRecipe) continue; - rList.add(GT_Utility.copyOrNull(tOutput)); - iterator.remove(); - } - } - return rList; - } - - /** - * Used in my own Furnace. - */ - public static ItemStack getSmeltingOutput(ItemStack aInput, boolean aRemoveInput, ItemStack aOutputSlot) { - if (aInput == null || aInput.stackSize < 1) return null; - ItemStack rStack = GT_OreDictUnificator.get( - FurnaceRecipes.smelting() - .getSmeltingResult(aInput)); - - if (rStack != null && (aOutputSlot == null || (GT_Utility.areStacksEqual(rStack, aOutputSlot) - && rStack.stackSize + aOutputSlot.stackSize <= aOutputSlot.getMaxStackSize()))) { - if (aRemoveInput) aInput.stackSize--; - return rStack; - } - return null; - } - - /** - * Used in my own Machines. Decreases StackSize of the Input if wanted. - *

- * Checks also if there is enough Space in the Output Slots. - */ - public static ItemStack[] getMachineOutput(ItemStack aInput, Map aRecipeList, - boolean aRemoveInput, NBTTagCompound rRecipeMetaData, ItemStack... aOutputSlots) { - if (aOutputSlots == null || aOutputSlots.length == 0) return new ItemStack[0]; - if (aInput == null) return new ItemStack[aOutputSlots.length]; - try { - for (Entry tEntry : aRecipeList.entrySet()) { - if (tEntry.getKey() - .matches(aInput)) { - if (tEntry.getKey() - .getAmount() <= aInput.stackSize) { - ItemStack[] tList = tEntry.getValue().items.toArray(new ItemStack[0]); - if (tList.length == 0) break; - ItemStack[] rList = new ItemStack[aOutputSlots.length]; - rRecipeMetaData.setTag("return", tEntry.getValue().metadata); - for (byte i = 0; i < aOutputSlots.length && i < tList.length; i++) { - if (tList[i] != null) { - if (aOutputSlots[i] == null || (GT_Utility.areStacksEqual(tList[i], aOutputSlots[i]) - && tList[i].stackSize + aOutputSlots[i].stackSize - <= aOutputSlots[i].getMaxStackSize())) { - rList[i] = GT_Utility.copyOrNull(tList[i]); - } else { - return new ItemStack[aOutputSlots.length]; - } - } - } - - if (aRemoveInput) aInput.stackSize -= tEntry.getKey() - .getAmount(); - return rList; - } - break; - } - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return new ItemStack[aOutputSlots.length]; - } - - /** - * Used in my own Recycler. - *

- * Only produces Scrap if aScrapChance == 0. aScrapChance is usually the random Number I give to the Function If you - * directly insert 0 as aScrapChance then you can check if its Recycler-Blacklisted or similar - */ - @Nullable - public static ItemStack getRecyclerOutput(ItemStack aInput, int aScrapChance) { - if (aInput == null || aScrapChance != 0) return null; - if (recyclerWhitelist == null) { - generateRecyclerCache(); - } - - if (recyclerWhitelist.isEmpty()) { - if (searchRecyclerCache(aInput, recyclerBlacklist)) { - return null; - } else { - return ItemList.IC2_Scrap.get(1); - } - } else { - if (searchRecyclerCache(aInput, recyclerWhitelist)) { - return ItemList.IC2_Scrap.get(1); - } else { - return null; - } - } - } - - private static void generateRecyclerCache() { - recyclerWhitelist = new HashSet<>(); - for (IRecipeInput input : ic2.api.recipe.Recipes.recyclerWhitelist) { - for (ItemStack stack : input.getInputs()) { - recyclerWhitelist.add(GT_Utility.ItemId.create(stack.getItem(), stack.getItemDamage(), null)); - } - } - recyclerBlacklist = new HashSet<>(); - for (IRecipeInput input : ic2.api.recipe.Recipes.recyclerBlacklist) { - for (ItemStack stack : input.getInputs()) { - recyclerBlacklist.add(GT_Utility.ItemId.create(stack.getItem(), stack.getItemDamage(), null)); - } - } - } - - private static boolean searchRecyclerCache(ItemStack stack, Set set) { - if (set.contains(GT_Utility.ItemId.createWithoutNBT(stack))) { - return true; - } - // ic2.api.recipe.RecipeInputItemStack#matches expects item with wildcard meta to accept arbitrary meta - return set.contains(GT_Utility.ItemId.createAsWildcard(stack)); - } - - /** - * For the Scrapboxinator - */ - public static ItemStack getRandomScrapboxDrop() { - return ic2.api.recipe.Recipes.scrapboxDrops.getDrop(ItemList.IC2_Scrapbox.get(1), false); - } - - /** - * Charges an Electric Item. Only if it's a valid Electric Item of course. This forces the Usage of proper Voltages - * (so not the transfer limits defined by the Items) unless you ignore the Transfer Limit. If aTier is - * Integer.MAX_VALUE it will ignore Tier based Limitations. - * - * @return the actually used Energy. - */ - public static int chargeElectricItem(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreLimit, - boolean aSimulate) { - try { - if (isElectricItem(aStack)) { - int tTier = ((ic2.api.item.IElectricItem) aStack.getItem()).getTier(aStack); - if (tTier < 0 || tTier == aTier || aTier == Integer.MAX_VALUE) { - if (!aIgnoreLimit && tTier >= 0) - aCharge = (int) Math.min(aCharge, V[Math.max(0, Math.min(V.length - 1, tTier))]); - if (aCharge > 0) { - int rCharge = (int) Math.max( - 0.0, - ic2.api.item.ElectricItem.manager.charge(aStack, aCharge, tTier, true, aSimulate)); - return rCharge + (rCharge * 4 > aTier ? aTier : 0); - } - } - } - } catch (Throwable e) { - /* Do nothing */ - } - return 0; - } - - /** - * Discharges an Electric Item. Only if it's a valid Electric Item for that of course. This forces the Usage of - * proper Voltages (so not the transfer limits defined by the Items) unless you ignore the Transfer Limit. If aTier - * is Integer.MAX_VALUE it will ignore Tier based Limitations. - * - * @return the Energy got from the Item. - */ - public static int dischargeElectricItem(ItemStack aStack, int aCharge, int aTier, boolean aIgnoreLimit, - boolean aSimulate, boolean aIgnoreDischargability) { - try { - // if (isElectricItem(aStack) && (aIgnoreDischargability || - // ((ic2.api.item.IElectricItem)aStack.getItem()).canProvideEnergy(aStack))) { - if (isElectricItem(aStack)) { - int tTier = ((ic2.api.item.IElectricItem) aStack.getItem()).getTier(aStack); - if (tTier < 0 || tTier == aTier || aTier == Integer.MAX_VALUE) { - if (!aIgnoreLimit && tTier >= 0) aCharge = (int) Math.min( - aCharge, - V[Math.max(0, Math.min(V.length - 1, tTier))] + B[Math.max(0, Math.min(V.length - 1, tTier))]); - if (aCharge > 0) { - int rCharge = (int) Math.max( - 0, - ic2.api.item.ElectricItem.manager.discharge( - aStack, - aCharge + (aCharge * 4 > aTier ? aTier : 0), - tTier, - true, - !aIgnoreDischargability, - aSimulate)); - return rCharge - (rCharge * 4 > aTier ? aTier : 0); - } - } - } - } catch (Throwable e) { - /* Do nothing */ - } - return 0; - } - - /** - * Uses an Electric Item. Only if it's a valid Electric Item for that of course. - * - * @return if the action was successful - */ - public static boolean canUseElectricItem(ItemStack aStack, int aCharge) { - try { - if (isElectricItem(aStack)) { - return ic2.api.item.ElectricItem.manager.canUse(aStack, aCharge); - } - } catch (Throwable e) { - /* Do nothing */ - } - return false; - } - - /** - * Uses an Electric Item. Only if it's a valid Electric Item for that of course. - * - * @return if the action was successful - */ - public static boolean useElectricItem(ItemStack aStack, int aCharge, EntityPlayer aPlayer) { - try { - if (isElectricItem(aStack)) { - ic2.api.item.ElectricItem.manager.use(aStack, 0, aPlayer); - if (ic2.api.item.ElectricItem.manager.canUse(aStack, aCharge)) { - return ic2.api.item.ElectricItem.manager.use(aStack, aCharge, aPlayer); - } - } - } catch (Throwable e) { - /* Do nothing */ - } - return false; - } - - /** - * Uses an Item. Tries to discharge in case of Electric Items - */ - public static boolean damageOrDechargeItem(ItemStack aStack, int aDamage, int aDecharge, EntityLivingBase aPlayer) { - if (GT_Utility.isStackInvalid(aStack) || (aStack.getMaxStackSize() <= 1 && aStack.stackSize > 1)) return false; - if (aPlayer instanceof EntityPlayer && ((EntityPlayer) aPlayer).capabilities.isCreativeMode) return true; - if (aStack.getItem() instanceof IDamagableItem) { - return ((IDamagableItem) aStack.getItem()).doDamageToItem(aStack, aDamage); - } else if (GT_ModHandler.isElectricItem(aStack)) { - if (canUseElectricItem(aStack, aDecharge)) { - if (aPlayer instanceof EntityPlayer) { - return GT_ModHandler.useElectricItem(aStack, aDecharge, (EntityPlayer) aPlayer); - } - return GT_ModHandler.dischargeElectricItem(aStack, aDecharge, Integer.MAX_VALUE, true, false, true) - >= aDecharge; - } - } else if (aStack.getItem() - .isDamageable()) { - if (aPlayer == null) { - aStack.setItemDamage(aStack.getItemDamage() + aDamage); - } else { - aStack.damageItem(aDamage, aPlayer); - } - if (aStack.getItemDamage() >= aStack.getMaxDamage()) { - aStack.setItemDamage(aStack.getMaxDamage() + 1); - ItemStack tStack = GT_Utility.getContainerItem(aStack, true); - if (tStack != null) { - aStack.func_150996_a(tStack.getItem()); - aStack.setItemDamage(tStack.getItemDamage()); - aStack.stackSize = tStack.stackSize; - aStack.setTagCompound(tStack.getTagCompound()); - } else if (aStack.stackSize > 0) { - aStack.stackSize--; - } - } - return true; - } - return false; - } - - /** - * Uses a Soldering Iron from player or external inventory - */ - public static boolean useSolderingIron(ItemStack aStack, EntityLivingBase aPlayer, IInventory aExternalInventory) { - if (aPlayer == null || aStack == null) return false; - if (GT_Utility.isStackInList(aStack, GregTech_API.sSolderingToolList)) { - if (aPlayer instanceof EntityPlayer tPlayer) { - if (tPlayer.capabilities.isCreativeMode) return true; - if (isElectricItem(aStack) && ic2.api.item.ElectricItem.manager.getCharge(aStack) > 1000.0d) { - if (consumeSolderingMaterial(tPlayer) - || (aExternalInventory != null && consumeSolderingMaterial(aExternalInventory))) { - if (canUseElectricItem(aStack, 10000)) { - return GT_ModHandler.useElectricItem(aStack, 10000, (EntityPlayer) aPlayer); - } - GT_ModHandler.useElectricItem( - aStack, - (int) ic2.api.item.ElectricItem.manager.getCharge(aStack), - (EntityPlayer) aPlayer); - return false; - } else { - GT_Utility.sendChatToPlayer( - (EntityPlayer) aPlayer, - GT_Utility.trans("094.1", "Not enough soldering material!")); - } - } - } else { - damageOrDechargeItem(aStack, 1, 1000, aPlayer); - return true; - } - } - return false; - } - - public static boolean useSolderingIron(ItemStack aStack, EntityLivingBase aPlayer) { - return useSolderingIron(aStack, aPlayer, null); - } - - public static boolean consumeSolderingMaterial(EntityPlayer aPlayer) { - if (aPlayer.capabilities.isCreativeMode) return true; - IInventory tInventory = aPlayer.inventory; - if (consumeSolderingMaterial(tInventory)) { - if (aPlayer.inventoryContainer != null) { - aPlayer.inventoryContainer.detectAndSendChanges(); - } - return true; - } - for (int i = 0; i < tInventory.getSizeInventory(); i++) { - ItemStack tStack = tInventory.getStackInSlot(i); - if (tStack != null && tStack.getItem() instanceof ItemToolbox) { - IInventory tToolboxInventory = ((ItemToolbox) tStack.getItem()).getInventory(aPlayer, tStack); - if (consumeSolderingMaterial(tToolboxInventory)) { - tInventory.markDirty(); - if (aPlayer.inventoryContainer != null) { - aPlayer.inventoryContainer.detectAndSendChanges(); - } - return true; - } - } - } - return false; - } - - /** - * Consumes soldering material from given inventory - */ - public static boolean consumeSolderingMaterial(IInventory aInventory) { - for (int i = 0; i < aInventory.getSizeInventory(); i++) { - ItemStack tStack = aInventory.getStackInSlot(i); - if (GT_Utility.isStackInList(tStack, GregTech_API.sSolderingMetalList)) { - if (tStack.stackSize < 1) return false; - if (tStack.stackSize == 1) { - tStack = null; - } else { - tStack.stackSize--; - } - aInventory.setInventorySlotContents(i, tStack); - aInventory.markDirty(); - return true; - } - } - return false; - } - - /** - * Is this an electric Item, which can charge other Items? - */ - public static boolean isChargerItem(ItemStack aStack) { - try { - if (isElectricItem(aStack)) { - return ((ic2.api.item.IElectricItem) aStack.getItem()).canProvideEnergy(aStack); - } - } catch (Throwable e) { - /* Do nothing */ - } - return false; - } - - /** - * Is this an electric Item? - */ - public static boolean isElectricItem(ItemStack aStack) { - try { - return aStack != null && aStack.getItem() instanceof ic2.api.item.IElectricItem - && ((IElectricItem) aStack.getItem()).getTier(aStack) < Integer.MAX_VALUE; - } catch (Throwable e) { - /* Do nothing */ - } - return false; - } - - public static boolean isElectricItem(ItemStack aStack, byte aTier) { - try { - return aStack != null && aStack.getItem() instanceof ic2.api.item.IElectricItem - && ((IElectricItem) aStack.getItem()).getTier(aStack) == aTier; - } catch (Throwable e) { - /* Do nothing */ - } - return false; - } - - /** - * Returns the current charge and maximum charge of an ItemStack. - * - * @param aStack Any ItemStack. - * @return Optional.empty() if the stack is null or not an electric item, or an Optional containing a payload of an - * array containing [ current_charge, maximum_charge ] on success. - */ - public static Optional getElectricItemCharge(ItemStack aStack) { - if (aStack == null || !isElectricItem(aStack)) { - return Optional.empty(); - } - - final Item item = aStack.getItem(); - - if (item instanceof final GT_MetaBase_Item metaBaseItem) { - final Long[] stats = metaBaseItem.getElectricStats(aStack); - if (stats != null && stats.length > 0) { - return Optional.of(new Long[] { metaBaseItem.getRealCharge(aStack), stats[0] }); - } - - } else if (item instanceof final IElectricItem ic2ElectricItem) { - return Optional.of( - new Long[] { (long) ic2.api.item.ElectricItem.manager.getCharge(aStack), - (long) ic2ElectricItem.getMaxCharge(aStack) }); - } - - return Optional.empty(); - } - - /** - * Allow item to be inserted into ic2 toolbox - */ - public static void registerBoxableItemToToolBox(ItemStack aStack) { - if (aStack != null) { - try { - ic2.api.item.ItemWrapper.registerBoxable(aStack.getItem(), (IBoxable) sBoxableWrapper); - } catch (Throwable ignored) { - /* Do nothing */ - } - sBoxableItems.add(new GT_ItemStack(aStack)); - } - } - - public static int getCapsuleCellContainerCountMultipliedWithStackSize(ItemStack... aStacks) { - int rAmount = 0; - for (ItemStack tStack : aStacks) - if (tStack != null) rAmount += getCapsuleCellContainerCount(tStack) * tStack.stackSize; - return rAmount; - } - - public static int getCapsuleCellContainerCount(ItemStack aStack) { - if (aStack == null) return 0; - - if (GT_Utility.areStacksEqual(GT_Utility.getContainerForFilledItem(aStack, true), ItemList.Cell_Empty.get(1))) { - return 1; - } - - if (GT_Utility.areStacksEqual(aStack, getIC2Item("waterCell", 1, W))) { - return 1; - } - - for (OrePrefixes cellType : OrePrefixes.CELL_TYPES) { - if (cellType.contains(aStack)) { - return 1; - } - } - - return 0; - } - - public static class RecipeBits { - - /** - * Mirrors the Recipe - */ - public static long MIRRORED = B[0]; - /** - * Buffers the Recipe for later addition. This makes things more efficient. - */ - public static long BUFFERED = B[1]; - /** - * This is a special Tag I used for crafting Coins up and down. - */ - public static long KEEPNBT = B[2]; - /** - * Makes the Recipe Reverse Craftable in the Disassembler. - */ - public static long DISMANTLEABLE = B[3]; - /** - * Prevents the Recipe from accidentally getting removed by my own Handlers. - */ - public static long NOT_REMOVABLE = B[4]; - /** - * Reverses the Output of the Recipe for smelting and pulverising. - */ - public static long REVERSIBLE = B[5]; - /** - * Removes all Recipes with the same Output Item regardless of NBT, unless another Recipe Deletion Bit is added - * too. - */ - public static long DELETE_ALL_OTHER_RECIPES = B[6]; - /** - * Removes all Recipes with the same Output Item limited to the same NBT. - */ - public static long DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT = B[7]; - /** - * Removes all Recipes with the same Output Item limited to Shaped Recipes. - */ - public static long DELETE_ALL_OTHER_SHAPED_RECIPES = B[8]; - /** - * Removes all Recipes with the same Output Item limited to native Recipe Handlers. - */ - public static long DELETE_ALL_OTHER_NATIVE_RECIPES = B[9]; - /** - * Disables the check for colliding Recipes. - */ - public static long DO_NOT_CHECK_FOR_COLLISIONS = B[10]; - /** - * Only adds the Recipe if there is another Recipe having that Output - */ - public static long ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT = B[11]; - /** - * Only adds the Recipe if it has an Output - */ - public static long ONLY_ADD_IF_RESULT_IS_NOT_NULL = B[12]; - /** - * Don't remove shapeless recipes with this output - */ - public static long DONT_REMOVE_SHAPELESS = B[13]; - } -} diff --git a/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java b/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java deleted file mode 100644 index 2d6712788a..0000000000 --- a/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java +++ /dev/null @@ -1,735 +0,0 @@ -package gregtech.api.util; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; - -import com.google.common.collect.Multimaps; -import com.google.common.collect.SetMultimap; -import com.gtnewhorizon.structurelib.StructureLibAPI; - -/** - * This makes it easier to build multi tooltips, with a standardized format.
- * Info section order should be:
- * addMachineType
- * addInfo, for what it does, special notes, etc.
- * addSeparator, if you need it
- * addPollutionAmount
- *
- * Structure order should be:
- * beginStructureBlock
- * addController
- * addCasingInfo
- * addOtherStructurePart, for secondary structure block info (pipes, coils, etc)
- * addEnergyHatch/addDynamoHatch
- * addMaintenanceHatch
- * addMufflerHatch
- * addInputBus/addInputHatch/addOutputBus/addOutputHatch, in that order
- * Use addStructureInfo for any comments on nonstandard structure info wherever needed
- * toolTipFinisher goes at the very end
- *
- * Originally created by kekzdealer - */ -public class GT_Multiblock_Tooltip_Builder { - - private static final String TAB = " "; - private static final String COLON = ": "; - private static final String SEPARATOR = ", "; - - private final List iLines; - private final List sLines; - private final List hLines; - private final SetMultimap hBlocks; - - private String[] iArray; - private String[] sArray; - private String[] hArray; - - // Localized tooltips - private static final String TT_machineType = StatCollector.translateToLocal("GT5U.MBTT.MachineType"); - private static final String TT_dimensions = StatCollector.translateToLocal("GT5U.MBTT.Dimensions"); - private static final String TT_hollow = StatCollector.translateToLocal("GT5U.MBTT.Hollow"); - private static final String TT_structure = StatCollector.translateToLocal("GT5U.MBTT.Structure"); - private static final String TT_controller = StatCollector.translateToLocal("GT5U.MBTT.Controller"); - private static final String TT_minimum = StatCollector.translateToLocal("GT5U.MBTT.Minimum"); - private static final String TT_tiered = StatCollector.translateToLocal("GT5U.MBTT.Tiered"); - private static final String TT_maintenancehatch = StatCollector.translateToLocal("GT5U.MBTT.MaintenanceHatch"); - private static final String TT_energyhatch = StatCollector.translateToLocal("GT5U.MBTT.EnergyHatch"); - private static final String TT_dynamohatch = StatCollector.translateToLocal("GT5U.MBTT.DynamoHatch"); - private static final String TT_mufflerhatch = StatCollector.translateToLocal("GT5U.MBTT.MufflerHatch"); - private static final String TT_inputbus = StatCollector.translateToLocal("GT5U.MBTT.InputBus"); - private static final String TT_inputhatch = StatCollector.translateToLocal("GT5U.MBTT.InputHatch"); - private static final String TT_outputbus = StatCollector.translateToLocal("GT5U.MBTT.OutputBus"); - private static final String TT_outputhatch = StatCollector.translateToLocal("GT5U.MBTT.OutputHatch"); - private static final String TT_causes = StatCollector.translateToLocal("GT5U.MBTT.Causes"); - private static final String TT_pps = StatCollector.translateToLocal("GT5U.MBTT.PPS"); - private static final String TT_hold = StatCollector.translateToLocal("GT5U.MBTT.Hold"); - private static final String TT_todisplay = StatCollector.translateToLocal("GT5U.MBTT.Display"); - private static final String TT_structurehint = StatCollector.translateToLocal("GT5U.MBTT.StructureHint"); - private static final String TT_mod = StatCollector.translateToLocal("GT5U.MBTT.Mod"); - private static final String TT_air = StatCollector.translateToLocal("GT5U.MBTT.Air"); - private static final String[] TT_dots = IntStream.range(0, 16) - .mapToObj(i -> StatCollector.translateToLocal("structurelib.blockhint." + i + ".name")) - .toArray(String[]::new); - - public GT_Multiblock_Tooltip_Builder() { - iLines = new LinkedList<>(); - sLines = new LinkedList<>(); - hLines = new LinkedList<>(); - hBlocks = Multimaps.newSetMultimap(new HashMap<>(), HashSet::new); - hBlocks.put(StructureLibAPI.HINT_BLOCK_META_AIR, TT_air); - } - - /** - * Add a line telling you what the machine type is. Usually, this will be the name of a SB version.
- * Machine Type: machine - * - * @param machine Name of the machine type - * - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addMachineType(String machine) { - iLines.add(TT_machineType + COLON + EnumChatFormatting.YELLOW + machine + EnumChatFormatting.RESET); - return this; - } - - /** - * Add a basic line of information about this structure - * - * @param info The line to be added. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addInfo(String info) { - iLines.add(info); - return this; - } - - /** - * Add a number of basic lines of information about this structure - * - * @param infoStrings The lines to be added. - * @return Instance this method was called on. - */ - - public GT_Multiblock_Tooltip_Builder addInfoAll(String... infoStrings) { - for (String str : infoStrings) { - iLines.add(str); - } - return this; - } - - /** - * Add a separator line like this:
- * ----------------------------------------- - * - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addSeparator() { - iLines.add("-----------------------------------------"); - return this; - } - - /** - * Add a line telling how much this machine pollutes. - * - * @param pollution Amount of pollution per second when active - * - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addPollutionAmount(int pollution) { - iLines.add( - TT_causes + COLON + EnumChatFormatting.DARK_PURPLE + pollution + " " + EnumChatFormatting.GRAY + TT_pps); - return this; - } - - /** - * Begin adding structural information by adding a line about the structure's dimensions and then inserting a - * "Structure:" line. - * - * @param w Structure width. - * @param h Structure height. - * @param l Structure depth/length. - * @param hollow T/F, adds a (hollow) comment if true - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder beginStructureBlock(int w, int h, int l, boolean hollow) { - sLines.add( - EnumChatFormatting.WHITE + TT_dimensions - + COLON - + EnumChatFormatting.GOLD - + w - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + h - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + l - + EnumChatFormatting.GRAY - + " (" - + EnumChatFormatting.GOLD - + "W" - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + "H" - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + "L" - + EnumChatFormatting.GRAY - + ") " - + EnumChatFormatting.RED - + (hollow ? EnumChatFormatting.RED + TT_hollow : "")); - sLines.add(EnumChatFormatting.WHITE + TT_structure + COLON); - return this; - } - - /** - * Begin adding structural information by adding a line about the structure's dimensions
- * and then inserting a "Structure:" line. Variable version displays min and max - * - * @param wmin Structure min width. - * @param wmax Structure max width. - * @param hmin Structure min height. - * @param hmax Structure max height. - * @param lmin Structure min depth/length. - * @param lmax Structure max depth/length. - * @param hollow T/F, adds a (hollow) comment if true - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder beginVariableStructureBlock(int wmin, int wmax, int hmin, int hmax, int lmin, - int lmax, boolean hollow) { - sLines.add( - EnumChatFormatting.WHITE + TT_dimensions - + COLON - + EnumChatFormatting.GOLD - + wmin - + (wmin != wmax ? "-" + wmax : "") - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + hmin - + (hmin != hmax ? "-" + hmax : "") - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + lmin - + (lmin != lmax ? "-" + lmax : "") - + EnumChatFormatting.GRAY - + " (" - + EnumChatFormatting.GOLD - + "W" - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + "H" - + EnumChatFormatting.GRAY - + "x" - + EnumChatFormatting.GOLD - + "L" - + EnumChatFormatting.GRAY - + ") " - + (hollow ? EnumChatFormatting.RED + TT_hollow : "")); - sLines.add(EnumChatFormatting.WHITE + TT_structure + COLON); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Controller: info - * - * @param info Positional information. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addController(String info) { - sLines.add(TAB + EnumChatFormatting.WHITE + TT_controller + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)minCountx casingName (minimum) (tiered) - * - * @param casingName Name of the Casing. - * @param minCount Minimum needed for valid structure check. - * @return Instance this method was called on. - * - * @deprecated Replaced by {@link #addCasingInfoMin(String, int, boolean)} - * - */ - @Deprecated - public GT_Multiblock_Tooltip_Builder addCasingInfo(String casingName, int minCount) { - return addCasingInfoMin(casingName, minCount, false); - } - - /** - * Add a line of information about the structure:
- * (indent)countx casingName (tiered) - * - * @param casingName Name of the Casing. - * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addCasingInfoExactly(String casingName, int count, boolean isTiered) { - return addCasingInfoExactlyColored( - casingName, - EnumChatFormatting.GRAY, - count, - EnumChatFormatting.GOLD, - isTiered); - } - - /** - * Add a line of information about the structure:
- * (indent)countx casingName (tiered) - * - * @param casingName Name of the Casing. - * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) - * @param countColor Color of the casing count text - * @param textColor Color of the casing name text - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addCasingInfoExactlyColored(String casingName, EnumChatFormatting textColor, - int count, EnumChatFormatting countColor, boolean isTiered) { - sLines.add( - countColor + TAB - + count - + "x " - + EnumChatFormatting.RESET - + textColor - + casingName - + (isTiered ? " " + TT_tiered : "")); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)minCountx casingName (minimum) (tiered) - * - * @param casingName Name of the Casing. - * @param minCount Minimum needed for valid structure check. - * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addCasingInfoMin(String casingName, int minCount, boolean isTiered) { - return addCasingInfoMinColored( - casingName, - EnumChatFormatting.GRAY, - minCount, - EnumChatFormatting.GOLD, - isTiered); - } - - /** - * Add a line of information about the structure:
- * (indent)minCountx casingName (minimum) (tiered) - * - * @param casingName Name of the Casing. - * @param minCount Minimum needed for valid structure check. - * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) - * @param countColor Color of the casing count text - * @param textColor Color of the casing name text - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addCasingInfoMinColored(String casingName, EnumChatFormatting textColor, - int minCount, EnumChatFormatting countColor, boolean isTiered) { - sLines.add( - countColor + TAB - + minCount - + "x " - + EnumChatFormatting.RESET - + textColor - + casingName - + " " - + TT_minimum - + (isTiered ? " " + TT_tiered : "")); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)minCountx - maxCountx casingName (minimum) (tiered) - * - * @param casingName Name of the Casing. - * @param minCount Minimum needed for valid structure check. - * @param maxCount Maximum needed for valid structure check. - * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addCasingInfoRange(String casingName, int minCount, int maxCount, - boolean isTiered) { - return addCasingInfoRangeColored( - casingName, - EnumChatFormatting.GRAY, - minCount, - maxCount, - EnumChatFormatting.GOLD, - isTiered); - } - - /** - * Add a line of information about the structure:
- * (indent)minCountx - maxCountx casingName (minimum) (tiered) - * - * @param casingName Name of the Casing. - * @param minCount Minimum needed for valid structure check. - * @param maxCount Maximum needed for valid structure check. - * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) - * @param countColor Color of the casing count text - * @param textColor Color of the casing name text - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addCasingInfoRangeColored(String casingName, EnumChatFormatting textColor, - int minCount, int maxCount, EnumChatFormatting countColor, boolean isTiered) { - sLines.add( - countColor + TAB - + minCount - + "x" - + EnumChatFormatting.GRAY - + " - " - + countColor - + maxCount - + "x " - + EnumChatFormatting.RESET - + textColor - + casingName - + (isTiered ? " " + TT_tiered : "")); - return this; - } - - /** - * Use this method to add a structural part that isn't covered by the other methods.
- * (indent)name: info - * - * @param name Name of the hatch or other component. - * @param info Positional information. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addOtherStructurePart(String name, String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + name + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Maintenance Hatch: info - * - * @param info Positional information. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addMaintenanceHatch(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_maintenancehatch + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Muffler Hatch: info - * - * @param info Location where the hatch goes - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addMufflerHatch(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_mufflerhatch + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Energy Hatch: info - * - * @param info Positional information. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addEnergyHatch(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_energyhatch + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Dynamo Hatch: info - * - * @param info Positional information. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addDynamoHatch(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_dynamohatch + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Input Bus: info - * - * @param info Location where the bus goes - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addInputBus(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputbus + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Input Hatch: info - * - * @param info Location where the hatch goes - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addInputHatch(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputhatch + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Output Bus: info - * - * @param info Location where the bus goes - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addOutputBus(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputbus + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Output Hatch: info - * - * @param info Location where the bus goes - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addOutputHatch(String info) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputhatch + COLON + EnumChatFormatting.GRAY + info); - return this; - } - - /** - * Use this method to add a structural part that isn't covered by the other methods.
- * (indent)name: info - * - * @param name Name of the hatch or other component. - * @param info Positional information. - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addOtherStructurePart(String name, String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + name + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, name); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Maintenance Hatch: info - * - * @param info Positional information. - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addMaintenanceHatch(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_maintenancehatch + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_maintenancehatch); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Muffler Hatch: info - * - * @param info Location where the hatch goes - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addMufflerHatch(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_mufflerhatch + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_mufflerhatch); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Energy Hatch: info - * - * @param info Positional information. - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addEnergyHatch(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_energyhatch + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_energyhatch); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Dynamo Hatch: info - * - * @param info Positional information. - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addDynamoHatch(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_dynamohatch + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_dynamohatch); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Input Bus: info - * - * @param info Location where the bus goes - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addInputBus(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputbus + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_inputbus); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Input Hatch: info - * - * @param info Location where the hatch goes - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addInputHatch(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputhatch + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_inputhatch); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Output Bus: info - * - * @param info Location where the bus goes - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addOutputBus(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputbus + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_outputbus); - return this; - } - - /** - * Add a line of information about the structure:
- * (indent)Output Hatch: info - * - * @param info Location where the bus goes - * @param dots The valid locations for this part when asked to display hints - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addOutputHatch(String info, int... dots) { - sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputhatch + COLON + EnumChatFormatting.GRAY + info); - for (int dot : dots) hBlocks.put(dot, TT_outputhatch); - return this; - } - - /** - * Use this method to add non-standard structural info.
- * (indent)info - * - * @param info The line to be added. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addStructureInfo(String info) { - sLines.add(TAB + info); - return this; - } - - /** - * Use this method to add non-standard structural info.
- * (indent)info - * - * @param channel the name of subchannel - * @param purpose the purpose of subchannel - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addSubChannelUsage(String channel, String purpose) { - sLines.add(TAB + StatCollector.translateToLocalFormatted("GT5U.MBTT.subchannel", channel, purpose)); - return this; - } - - /** - * Use this method to add non-standard structural hint. This info will appear before the standard structural hint. - * - * @param info The line to be added. This should be an entry into minecraft's localization system. - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addStructureHint(String info) { - hLines.add(StatCollector.translateToLocal(info)); - return this; - } - - /** - * Use this method to add an entry to standard structural hint without creating a corresponding line in structure - * information - * - * @param name The name of block This should be an entry into minecraft's localization system. - * @param dots Possible locations of this block - * @return Instance this method was called on. - */ - public GT_Multiblock_Tooltip_Builder addStructureHint(String name, int... dots) { - for (int dot : dots) hBlocks.put(dot, StatCollector.translateToLocal(name)); - return this; - } - - /** - * Call at the very end.
- * Adds a final line with the mod name and information on how to display the structure guidelines.
- * Ends the building process. - * - * @param mod Name of the mod that adds this multiblock machine - */ - public GT_Multiblock_Tooltip_Builder toolTipFinisher(String mod) { - iLines.add( - TT_hold + " " - + EnumChatFormatting.BOLD - + "[LSHIFT]" - + EnumChatFormatting.RESET - + EnumChatFormatting.GRAY - + " " - + TT_todisplay); - iLines.add(TT_mod + COLON + EnumChatFormatting.GREEN + mod + EnumChatFormatting.GRAY); - hLines.add(TT_structurehint); - iArray = iLines.toArray(new String[0]); - sArray = sLines.toArray(new String[0]); - // e.getKey() - 1 because 1 dot is meta 0. - hArray = Stream.concat( - hLines.stream(), - hBlocks.asMap() - .entrySet() - .stream() - .map(e -> TT_dots[e.getKey() - 1] + COLON + String.join(SEPARATOR, e.getValue()))) - .toArray(String[]::new); - return this; - } - - public String[] getInformation() { - return iArray; - } - - public String[] getStructureInformation() { - return sArray; - } - - public String[] getStructureHint() { - return hArray; - } -} diff --git a/src/main/java/gregtech/api/util/GT_MusicSystem.java b/src/main/java/gregtech/api/util/GT_MusicSystem.java deleted file mode 100644 index 7c0ec929e9..0000000000 --- a/src/main/java/gregtech/api/util/GT_MusicSystem.java +++ /dev/null @@ -1,667 +0,0 @@ -package gregtech.api.util; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.TreeMap; -import java.util.UUID; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.SoundEventAccessorComposite; -import net.minecraft.client.audio.SoundRegistry; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemRecord; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.jetbrains.annotations.ApiStatus; -import org.joml.Vector4i; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.jcraft.jorbis.VorbisFile; - -import baubles.api.BaublesApi; -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.network.ByteBufUtils; -import gregtech.GT_Mod; -import gregtech.api.enums.GT_Values; -import gregtech.api.net.GT_Packet_MusicSystemData; -import gregtech.client.ElectricJukeboxSound; -import gregtech.common.items.GT_WirelessHeadphones; -import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_BetterJukebox; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; - -/** - * A system that keeps track of jukebox music tracks playing in different locations. - * Compared to vanilla jukebox handling, this allows music to resume playing after reloading the chunk the jukeboxes are - * in. - * It also allows the headphone item to modify the hearing range of a given disc, including other dimensions. - *

- * Vector4i coordinates point to X,Y,Z,Dimension of the source - * - * @author eigenraven - */ -public final class GT_MusicSystem { - - private GT_MusicSystem() {} - - public static final class MusicSource { - - /** Flag keeping track of when the data of this source needs to be sent to clients again */ - public boolean modified; - public final UUID sourceID; - /** Currently playing track */ - public ResourceLocation currentRecord; - /** Headphone range */ - public GT_MetaTileEntity_BetterJukebox.HeadphoneLimit headphoneLimit; - /** - * {@link System#currentTimeMillis()} at the time this record started playing, in server time - */ - public long startedPlayingAtMs; - /** Time the record was playing for at the time it was serialized. */ - public long playingForMs; - /** The origin of this source used for wireless headphone range calculations */ - public final Vector4i originPosition = new Vector4i(); - /** Number of blocks from {@link MusicSource#originPosition} the headphones can work */ - public int headphoneBlockRange; - /** Densely packed parameters for each "emitter" associated with the source, for fast iteration */ - public int[] emitterParameters; // [{x,y,z,dim,volume}, {x, ...}, {x, ...}, ...] - /** Offsets into the parameters array */ - public static final int EMITTER_X = 0; - /** Offsets into the parameters array */ - public static final int EMITTER_Y = 1; - /** Offsets into the parameters array */ - public static final int EMITTER_Z = 2; - /** Offsets into the parameters array */ - public static final int EMITTER_DIMENSION = 3; - /** 100 times the floating point "volume" used by the sound system for range calculations */ - public static final int EMITTER_VOLUME_X_100 = 4; - /** Iteration stride for packed emitter parameters */ - public static final int EMITTER_STRIDE = EMITTER_VOLUME_X_100 + 1; - - public MusicSource(UUID sourceID) { - this.sourceID = sourceID; - } - - public void resizeEmitterArray(int count) { - int len = count * EMITTER_STRIDE; - if (emitterParameters == null || emitterParameters.length != len) { - if (emitterParameters == null) { - emitterParameters = new int[len]; - } else { - emitterParameters = Arrays.copyOf(emitterParameters, len); - } - modified = true; - } - } - - public void setEmitter(int index, Vector4i position, float volume) { - int arrIndex = index * EMITTER_STRIDE; - if (arrIndex < 0 || arrIndex >= emitterParameters.length) { - throw new IndexOutOfBoundsException( - "Trying to access emitter with index " + index - + " in an array of " - + emitterParameters.length / EMITTER_STRIDE); - } - - if (emitterParameters[arrIndex + EMITTER_X] != position.x) { - modified = true; - emitterParameters[arrIndex + EMITTER_X] = position.x; - } - if (emitterParameters[arrIndex + EMITTER_Y] != position.y) { - modified = true; - emitterParameters[arrIndex + EMITTER_Y] = position.y; - } - if (emitterParameters[arrIndex + EMITTER_Z] != position.z) { - modified = true; - emitterParameters[arrIndex + EMITTER_Z] = position.z; - } - if (emitterParameters[arrIndex + EMITTER_DIMENSION] != position.w) { - modified = true; - emitterParameters[arrIndex + EMITTER_DIMENSION] = position.w; - } - final int intVolume = (int) (volume * 100.0f); - if (emitterParameters[arrIndex + EMITTER_VOLUME_X_100] != intVolume) { - modified = true; - emitterParameters[arrIndex + EMITTER_VOLUME_X_100] = intVolume; - } - } - - /** x squared */ - private static int sq(int x) { - return x * x; - } - - /** @return Index of closest emitter in range, or -1 if none is nearby. */ - public int closestEmitter(int x, int y, int z, int dim) { - int closest = -1; - int closestDistanceSq = Integer.MAX_VALUE; - final int emittersCount = emitterParameters.length / EMITTER_STRIDE; - for (int i = 0; i < emittersCount; i++) { - final int offset = i * EMITTER_STRIDE; - final int eDim = emitterParameters[offset + EMITTER_DIMENSION]; - if (eDim != dim) { - continue; - } - final int eX = emitterParameters[offset + EMITTER_X]; - final int eY = emitterParameters[offset + EMITTER_Y]; - final int eZ = emitterParameters[offset + EMITTER_Z]; - final int distanceSq = sq(x - eX) + sq(y - eY) + sq(z - eZ); - if (distanceSq < closestDistanceSq) { - closestDistanceSq = distanceSq; - closest = i; - } - } - return closest; - } - - public boolean inHeadphoneRange(int x, int y, int z, int dim) { - return switch (headphoneLimit) { - case BETWEEN_DIMENSIONS -> true; - case INSIDE_DIMENSION -> dim == originPosition.w; - case BLOCK_RANGE -> dim == originPosition.w - && originPosition.distanceSquared(x, y, z, dim) <= sq(headphoneBlockRange); - }; - } - - public void encode(final ByteBuf target) { - target.writeLong(sourceID.getMostSignificantBits()); - target.writeLong(sourceID.getLeastSignificantBits()); - if (currentRecord != null) { - final int duration = getMusicRecordDurations().getOrDefault(currentRecord, Integer.MAX_VALUE); - if (playingForMs >= duration) { - // Record already finished playing, let's not send it to the client anymore. - target.writeBoolean(false); - } else { - target.writeBoolean(true); - ByteBufUtils.writeUTF8String(target, currentRecord.getResourceDomain()); - ByteBufUtils.writeUTF8String(target, currentRecord.getResourcePath()); - } - } else { - target.writeBoolean(false); - } - target.writeByte((byte) headphoneLimit.ordinal()); - ByteBufUtils.writeVarInt(target, headphoneBlockRange, 5); - target.writeLong(startedPlayingAtMs); - target.writeLong(playingForMs); - ByteBufUtils.writeVarInt(target, originPosition.x, 5); - ByteBufUtils.writeVarInt(target, originPosition.y, 5); - ByteBufUtils.writeVarInt(target, originPosition.z, 5); - ByteBufUtils.writeVarInt(target, originPosition.w, 5); - ByteBufUtils.writeVarInt(target, emitterParameters.length, 5); - for (int emitterParameter : emitterParameters) { - ByteBufUtils.writeVarInt(target, emitterParameter, 5); - } - } - - public static MusicSource decode(final ByteBuf bytes) { - final long uuidMsb = bytes.readLong(); - final long uuidLsb = bytes.readLong(); - final MusicSource source = new MusicSource(new UUID(uuidMsb, uuidLsb)); - final boolean hasRecord = bytes.readBoolean(); - if (hasRecord) { - final String domain = ByteBufUtils.readUTF8String(bytes); - final String path = ByteBufUtils.readUTF8String(bytes); - source.currentRecord = new ResourceLocation(domain, path); - } - source.headphoneLimit = GT_MetaTileEntity_BetterJukebox.HeadphoneLimit.ENTRIES.get(bytes.readByte()); - source.headphoneBlockRange = ByteBufUtils.readVarInt(bytes, 5); - source.startedPlayingAtMs = bytes.readLong(); - source.playingForMs = bytes.readLong(); - final int originX = ByteBufUtils.readVarInt(bytes, 5); - final int originY = ByteBufUtils.readVarInt(bytes, 5); - final int originZ = ByteBufUtils.readVarInt(bytes, 5); - final int originW = ByteBufUtils.readVarInt(bytes, 5); - source.originPosition.set(originX, originY, originZ, originW); - final int emittersLength = ByteBufUtils.readVarInt(bytes, 5); - source.emitterParameters = new int[emittersLength]; - for (int i = 0; i < emittersLength; i++) { - source.emitterParameters[i] = ByteBufUtils.readVarInt(bytes, 5); - } - - return source; - } - - public void setRecord(final ResourceLocation record) { - setRecord(record, 0); - } - - public void setRecord(final ResourceLocation record, long seekOffset) { - modified = true; - currentRecord = record; - playingForMs = seekOffset; - startedPlayingAtMs = System.currentTimeMillis() - seekOffset; - } - } - - public static final class ServerSystem { - - static final Object2ObjectOpenHashMap musicSources = new Object2ObjectOpenHashMap<>(32); - static boolean musicSourcesDirty = false; - - // Everything is synchronized to allow calling into here from the client when singleplayer synchronization is - // needed. - - public static synchronized MusicSource registerOrGetMusicSource(UUID uuid) { - return musicSources.computeIfAbsent(uuid, (UUID id) -> { - musicSourcesDirty = true; - return new MusicSource(id); - }); - } - - public static synchronized void removeMusicSource(UUID uuid) { - musicSources.remove(uuid); - musicSourcesDirty = true; - } - - public static synchronized void reset() { - musicSources.clear(); - musicSourcesDirty = true; - } - - public static synchronized ByteBuf serialize() { - final ByteBuf out = Unpooled.buffer(); - ByteBufUtils.writeVarInt(out, musicSources.size(), 5); - musicSources.forEach((uuid, source) -> source.encode(out)); - return out; - } - - private static boolean tickAnyDirty; - - public static synchronized void tick() { - final long now = System.currentTimeMillis(); - tickAnyDirty = false; - musicSources.forEach((uuid, source) -> { - source.playingForMs = now - source.startedPlayingAtMs; - tickAnyDirty |= source.modified; - source.modified = false; - }); - if (tickAnyDirty || musicSourcesDirty) { - musicSourcesDirty = false; - GT_Values.NW.sendToAll(new GT_Packet_MusicSystemData(serialize())); - } - } - - static synchronized void onPauseMs(long pauseDurationMs) { - musicSources.forEach((uuid, source) -> { source.startedPlayingAtMs += pauseDurationMs; }); - } - } - - public static final class ClientSystem { - - private static final class ClientSourceData { - - /** Currently playing sound data */ - public ElectricJukeboxSound currentSound = null; - /** Currently playing sound data */ - public ResourceLocation currentSoundResource = null; - /** - * Server's timer value of when the music started, mostly meaningless except for checking for replays of the - * same music file. - */ - public long originalStartTime = 0; - /** - * Computed client value of {@link System#currentTimeMillis()} of the time when the playback would have - * started if it was synchronized with the server. - */ - public long clientReferenceStartTime = 0; - /** Flag for mark and sweep removal of outdated sounds */ - public boolean markFlag = false; - - public void resetMark() { - markFlag = false; - } - - public void mark() { - markFlag = true; - } - - public void clearSound(final Minecraft mc) { - currentSoundResource = null; - if (currentSound != null) { - mc.getSoundHandler() - .stopSound(currentSound); - currentSound = null; - originalStartTime = 0; - } - } - - public boolean equalSound(final MusicSource source) { - if (source == null || source.currentRecord == null) { - return currentSoundResource == null; - } else { - return source.currentRecord.equals(currentSoundResource) - && originalStartTime == source.startedPlayingAtMs; - } - } - - public void resetSound(final Minecraft mc, final MusicSource source, final boolean onHeadphones) { - clearSound(mc); - if (source == null || source.emitterParameters.length == 0) { - return; - } - int closestEmitter = onHeadphones ? 0 - : source.closestEmitter( - (int) Math.floor(mc.thePlayer.posX), - (int) Math.floor(mc.thePlayer.posY), - (int) Math.floor(mc.thePlayer.posZ), - currentDimension); - if (closestEmitter < 0) { - return; - } - this.currentSoundResource = source.currentRecord; - this.originalStartTime = source.startedPlayingAtMs; - this.clientReferenceStartTime = System.currentTimeMillis() - source.playingForMs; - if (currentSoundResource != null) { - this.currentSound = makeRecord(source, closestEmitter); - if (onHeadphones) { - this.currentSound.volume = 1.0e20f; - } - mc.getSoundHandler() - .playSound(this.currentSound); - } - } - - public void updateSound(final Minecraft mc, final MusicSource source, final boolean onHeadphones) { - if (source == null || currentSound == null || source.emitterParameters.length == 0) { - return; - } - int closestEmitter = onHeadphones ? 0 - : source.closestEmitter( - (int) Math.floor(mc.thePlayer.posX), - (int) Math.floor(mc.thePlayer.posY), - (int) Math.floor(mc.thePlayer.posZ), - currentDimension); - if (closestEmitter < 0) { - currentSound.volume = 0.0f; - return; - } - final int offset = closestEmitter * MusicSource.EMITTER_STRIDE; - currentSound.xPosition = source.emitterParameters[offset + MusicSource.EMITTER_X]; - currentSound.yPosition = source.emitterParameters[offset + MusicSource.EMITTER_Y]; - currentSound.zPosition = source.emitterParameters[offset + MusicSource.EMITTER_Z]; - currentSound.volume = onHeadphones ? 1.0e20f - : source.emitterParameters[offset + MusicSource.EMITTER_VOLUME_X_100] / 100.0f; - } - } - - /** Latest music source list as synchronized from the server */ - public static final Object2ObjectOpenHashMap musicSources = new Object2ObjectOpenHashMap<>(); - - private static final Object2ObjectOpenHashMap activelyPlayingMusic = new Object2ObjectOpenHashMap<>( - 16); - - private static final ObjectOpenHashSet wornHeadphones = new ObjectOpenHashSet<>(); - - private static int currentDimension = Integer.MIN_VALUE; - - private static boolean soundsPaused = false; - private static long pauseTimeMs = 0; - private static int tickCounter = 0; - - public static void loadUpdatedSources(ByteBuf bytes) { - final int sourceCount = ByteBufUtils.readVarInt(bytes, 5); - musicSources.clear(); - for (int i = 0; i < sourceCount; i++) { - final MusicSource source = MusicSource.decode(bytes); - musicSources.put(source.sourceID, source); - } - } - - private static ElectricJukeboxSound makeRecord(MusicSource source, int emitter) { - final int x = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + MusicSource.EMITTER_X]; - final int y = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + MusicSource.EMITTER_Y]; - final int z = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE + MusicSource.EMITTER_Z]; - final float volume = source.emitterParameters[emitter * MusicSource.EMITTER_STRIDE - + MusicSource.EMITTER_VOLUME_X_100] / 100.0f; - return new ElectricJukeboxSound(source.currentRecord, volume, source.playingForMs, x, y, z); - } - - public static void dumpAllRecordDurations() { - try { - final Minecraft mc = Minecraft.getMinecraft(); - final SoundRegistry sm = mc.getSoundHandler().sndRegistry; - final SoundDurationsJson json = new SoundDurationsJson(); - @SuppressWarnings("unchecked") - final Map allRecords = ItemRecord.field_150928_b; - // Cursed hack because JOrbis does not support seeking in anything other than filesystem files. - // This is only a dev tool, so it can be a bit slow and use real files here. - final File tempFile = File.createTempFile("mcdecode", ".ogg"); - for (final ItemRecord record : allRecords.values()) { - try { - final ResourceLocation res = record.getRecordResource(record.recordName); - SoundEventAccessorComposite registryEntry = (SoundEventAccessorComposite) sm.getObject(res); - if (registryEntry == null) { - registryEntry = (SoundEventAccessorComposite) sm.getObject( - new ResourceLocation(res.getResourceDomain(), "records." + res.getResourcePath())); - } - final ResourceLocation realPath = registryEntry.func_148720_g() - .getSoundPoolEntryLocation(); - try (final InputStream is = mc.getResourceManager() - .getResource(realPath) - .getInputStream(); final OutputStream os = FileUtils.openOutputStream(tempFile)) { - IOUtils.copy(is, os); - os.close(); - final VorbisFile vf = new VorbisFile(tempFile.getAbsolutePath()); - final float totalSeconds = vf.time_total(-1); - json.soundDurationsMs.put(res.toString(), (int) Math.ceil(totalSeconds * 1000.0f)); - } - } catch (Exception e) { - GT_Mod.GT_FML_LOGGER.warn("Skipping {}", record.recordName, e); - } - } - GT_Mod.GT_FML_LOGGER.info( - "Sound durations json: \n{}", - new GsonBuilder().setPrettyPrinting() - .create() - .toJson(json)); - tempFile.delete(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static void reset() { - musicSources.clear(); - tick(); - } - - public static void tick() { - final Minecraft mc = Minecraft.getMinecraft(); - if (mc == null || mc.renderGlobal == null - || mc.theWorld == null - || mc.thePlayer == null - || mc.theWorld.provider == null) { - return; - } - tickCounter++; - final long now = System.currentTimeMillis(); - currentDimension = mc.theWorld.provider.dimensionId; - - headphoneCheck: if ((tickCounter % 20) == 0) { - wornHeadphones.clear(); - final IInventory baubles = BaublesApi.getBaubles(mc.thePlayer); - if (baubles == null) { - break headphoneCheck; - } - final int baublesSize = baubles.getSizeInventory(); - for (int i = 0; i < baublesSize; i++) { - final ItemStack item = baubles.getStackInSlot(i); - if (item != null && item.getItem() instanceof GT_WirelessHeadphones headphones) { - final UUID id = headphones.getBoundJukeboxUUID(item); - if (id != null) { - wornHeadphones.add(id); - } - } - } - } - - activelyPlayingMusic.forEach((uuid, data) -> data.resetMark()); - - // Update and mark all present music streams - musicSources.forEach((uuid, musicSource) -> { - final ClientSourceData data = activelyPlayingMusic - .computeIfAbsent(uuid, ignored -> new ClientSourceData()); - data.mark(); - if (data.currentSound != null && !mc.getSoundHandler() - .isSoundPlaying(data.currentSound) - && (now - data.clientReferenceStartTime) - < getMusicRecordDurations().getOrDefault(data.currentSoundResource, Integer.MAX_VALUE)) { - data.currentSound = null; - data.currentSoundResource = null; - } - final boolean onHeadphones = wornHeadphones.contains(uuid); - if (!data.equalSound(musicSource)) { - data.resetSound(mc, musicSource, onHeadphones); - } else { - data.updateSound(mc, musicSource, onHeadphones); - } - }); - - // Sweep no longer present music streams - final var entries = activelyPlayingMusic.object2ObjectEntrySet() - .fastIterator(); - while (entries.hasNext()) { - final ClientSourceData entry = entries.next() - .getValue(); - if (!entry.markFlag) { - entry.clearSound(mc); - entries.remove(); - } - } - } - - @ApiStatus.Internal - public static void onSoundBatchStop() { - // All music was forcibly stopped, we can forget about the currently playing music - // and let the update loop re-start them on next tick - long now = System.currentTimeMillis(); - activelyPlayingMusic.forEach((uuid, data) -> { - data.currentSound = null; - data.currentSoundResource = null; - final MusicSource source = musicSources.get(uuid); - if (source == null) { - return; - } - source.playingForMs = now - data.clientReferenceStartTime; - }); - } - - @ApiStatus.Internal - public static void onSoundBatchPause() { - if (soundsPaused) { - return; - } - soundsPaused = true; - pauseTimeMs = System.currentTimeMillis(); - } - - @ApiStatus.Internal - public static void onSoundBatchResume() { - if (!soundsPaused) { - return; - } - final Minecraft mc = Minecraft.getMinecraft(); - if (mc == null || mc.renderGlobal == null - || mc.theWorld == null - || mc.thePlayer == null - || mc.theWorld.provider == null) { - return; - } - soundsPaused = false; - - if (!(mc.isSingleplayer() && !mc.getIntegratedServer() - .getPublic())) { - return; - } - final long now = System.currentTimeMillis(); - final long pauseDurationMs = now - pauseTimeMs; - - // We manipulate server state here, because we've checked this is singleplayer pausing. - GT_MusicSystem.ServerSystem.onPauseMs(pauseDurationMs); - musicSources.forEach((uuid, source) -> { source.startedPlayingAtMs += pauseDurationMs; }); - activelyPlayingMusic.forEach((uuid, data) -> { - data.originalStartTime += pauseDurationMs; - data.clientReferenceStartTime += pauseDurationMs; - }); - - } - } - - private static final Object2IntOpenHashMap musicRecordDurations = new Object2IntOpenHashMap<>(); - private static volatile boolean musicRecordsInitialized; - - /** For GSON consumption */ - public static class SoundDurationsJson { - - public Map soundDurationsMs = new TreeMap<>(); - } - - public static Object2IntOpenHashMap getMusicRecordDurations() { - if (musicRecordsInitialized) { - return musicRecordDurations; - } - // double-checked locking for efficiency - synchronized (musicRecordDurations) { - if (musicRecordsInitialized) { - return musicRecordDurations; - } - - final Gson gson = new Gson(); - - try { - final ArrayList candidates = Collections.list( - GT_MusicSystem.class.getClassLoader() - .getResources("soundmeta/durations.json")); - final Path configPath = Loader.instance() - .getConfigDir() - .toPath() - .resolve("soundmeta") - .resolve("durations.json"); - if (Files.exists(configPath)) { - candidates.add( - configPath.toUri() - .toURL()); - } - for (final URL url : candidates) { - try { - final String objectJson = IOUtils.toString(url); - final SoundDurationsJson object = gson.fromJson(objectJson, SoundDurationsJson.class); - if (object == null || object.soundDurationsMs == null || object.soundDurationsMs.isEmpty()) { - continue; - } - for (final var entry : object.soundDurationsMs.entrySet()) { - musicRecordDurations.put( - new ResourceLocation(entry.getKey()), - entry.getValue() - .intValue()); - } - } catch (Exception e) { - GT_Mod.GT_FML_LOGGER.error("Could not parse sound durations from {}", url, e); - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - - musicRecordsInitialized = true; - return musicRecordDurations; - } - } - -} diff --git a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java deleted file mode 100644 index 82c14f2aeb..0000000000 --- a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java +++ /dev/null @@ -1,578 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.E; -import static gregtech.api.enums.GT_Values.M; -import static gregtech.api.enums.GT_Values.W; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraftforge.oredict.OreDictionary; - -import gregtech.api.GregTech_API; -import gregtech.api.enums.Dyes; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.SubTag; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.objects.ItemData; -import gregtech.api.objects.MaterialStack; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * This is the Core of my OreDict Unification Code - *

- * If you just want to use this to unificate your Items, then use the Function in the GregTech_API File - *

- * P.S. It is intended to be named "Unificator" and not "Unifier", because that sounds more awesome. - */ -public class GT_OreDictUnificator { - - private static final Map sName2StackMap = new HashMap<>(); - private static final Map sItemStack2DataMap = new Object2ObjectOpenCustomHashMap<>( - GT_ItemStack.ITEMSTACK_HASH_STRATEGY2); - private static final Map> sUnificationTable = new Object2ObjectOpenCustomHashMap<>( - GT_ItemStack.ITEMSTACK_HASH_STRATEGY2); - private static final Set sNoUnificationList = new ObjectOpenCustomHashSet<>( - GT_ItemStack.ITEMSTACK_HASH_STRATEGY2); - private static int isRegisteringOre = 0, isAddingOre = 0; - private static boolean mRunThroughTheList = true; - - static { - GregTech_API.sItemStackMappings.add(sItemStack2DataMap); - GregTech_API.sItemStackMappings.add(sUnificationTable); - } - - /** - * The Blacklist just prevents the Item from being unificated into something else. Useful if you have things like - * the Industrial Diamond, which is better than regular Diamond, but also usable in absolutely all Diamond Recipes. - */ - public static void addToBlacklist(ItemStack aStack) { - if (GT_Utility.isStackValid(aStack) && !GT_Utility.isStackInStackSet(aStack, sNoUnificationList)) - sNoUnificationList.add(aStack); - } - - public static boolean isBlacklisted(ItemStack aStack) { - return GT_Utility.isStackInStackSet(aStack, sNoUnificationList); - } - - public static void add(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack) { - set(aPrefix, aMaterial, aStack, false, false); - } - - public static void set(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack) { - set(aPrefix, aMaterial, aStack, true, false); - } - - public static void set(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack, boolean aOverwrite, - boolean aAlreadyRegistered) { - if (aMaterial == null || aPrefix == null - || GT_Utility.isStackInvalid(aStack) - || Items.feather.getDamage(aStack) == W) return; - isAddingOre++; - aStack = GT_Utility.copyAmount(1, aStack); - if (!aAlreadyRegistered) registerOre(aPrefix.get(aMaterial), aStack); - addAssociation(aPrefix, aMaterial, aStack, isBlacklisted(aStack)); - if (aOverwrite || GT_Utility.isStackInvalid( - sName2StackMap.get( - aPrefix.get(aMaterial) - .toString()))) - sName2StackMap.put( - aPrefix.get(aMaterial) - .toString(), - aStack); - isAddingOre--; - } - - public static ItemStack getFirstOre(Object aName, long aAmount) { - if (GT_Utility.isStringInvalid(aName)) return null; - ItemStack tStack = sName2StackMap.get(aName.toString()); - if (GT_Utility.isStackValid(tStack)) return GT_Utility.copyAmount(aAmount, tStack); - return GT_Utility.copyAmount(aAmount, getOresImmutable(aName).toArray()); - } - - public static ItemStack get(Object aName, long aAmount) { - return get(aName, null, aAmount, true, true); - } - - public static ItemStack get(Object aName, ItemStack aReplacement, long aAmount) { - return get(aName, aReplacement, aAmount, true, true); - } - - public static ItemStack get(OrePrefixes aPrefix, Object aMaterial, long aAmount) { - return get(aPrefix, aMaterial, null, aAmount); - } - - public static ItemStack get(OrePrefixes aPrefix, Object aMaterial, ItemStack aReplacement, long aAmount) { - if (OrePrefixes.mPreventableComponents.contains(aPrefix) && aPrefix.mDisabledItems.contains(aMaterial)) - return aReplacement; - return get(aPrefix.get(aMaterial), aReplacement, aAmount, false, true); - } - - public static ItemStack get(OrePrefixes aPrefix, Object aMaterial, long aAmount, boolean aNoInvalidAmounts) { - if (OrePrefixes.mPreventableComponents.contains(aPrefix) && aPrefix.mDisabledItems.contains(aMaterial)) - return null; - return get(aPrefix.get(aMaterial), null, aAmount, false, aNoInvalidAmounts); - } - - public static ItemStack get(Object aName, ItemStack aReplacement, long aAmount, boolean aMentionPossibleTypos, - boolean aNoInvalidAmounts) { - if (aNoInvalidAmounts && aAmount < 1) return null; - final ItemStack stackFromName = sName2StackMap.get(aName.toString()); - if (stackFromName != null) return GT_Utility.copyAmount(aAmount, stackFromName); - if (aMentionPossibleTypos) { - GT_Log.err.println("Unknown Key for Unification, Typo? " + aName); - } - final ItemStack stackFirstOre = getFirstOre(aName, aAmount); - if (stackFirstOre != null) return GT_Utility.copyAmount(aAmount, stackFirstOre); - return GT_Utility.copyAmount(aAmount, aReplacement); - } - - public static ItemStack[] setStackArray(boolean aUseBlackList, ItemStack... aStacks) { - for (int i = 0; i < aStacks.length; i++) aStacks[i] = get(aUseBlackList, GT_Utility.copyOrNull(aStacks[i])); - return aStacks; - } - - public static ItemStack[] getStackArray(boolean aUseBlackList, Object... aStacks) { - ItemStack[] rStacks = new ItemStack[aStacks.length]; - for (int i = 0; i < aStacks.length; i++) { - rStacks[i] = get(aUseBlackList, GT_Utility.copy(aStacks[i]), true); - } - return rStacks; - } - - public static ItemStack setStack(ItemStack aStack) { - return setStack(true, aStack); - } - - public static ItemStack setStack(boolean aUseBlackList, ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return aStack; - ItemStack tStack = get(aUseBlackList, aStack); - if (GT_Utility.areStacksEqual(aStack, tStack)) return aStack; - aStack.func_150996_a(tStack.getItem()); - Items.feather.setDamage(aStack, Items.feather.getDamage(tStack)); - return aStack; - } - - public static ItemStack get(ItemStack aStack) { - return get(true, aStack); - } - - public static ItemStack get(boolean aUseBlackList, ItemStack aStack) { - return get(aUseBlackList, aStack, false); - } - - /** - * @param unsafe If true, it does not limit stack size by 64. - */ - public static ItemStack get(boolean aUseBlackList, ItemStack aStack, boolean unsafe) { - if (GT_Utility.isStackInvalid(aStack)) return null; - ItemData tPrefixMaterial = getAssociation(aStack); - if (tPrefixMaterial == null || !tPrefixMaterial.hasValidPrefixMaterialData() - || (aUseBlackList && tPrefixMaterial.mBlackListed)) return GT_Utility.copyOrNull(aStack); - if (aUseBlackList && !GregTech_API.sUnificationEntriesRegistered && isBlacklisted(aStack)) { - tPrefixMaterial.mBlackListed = true; - return GT_Utility.copyOrNull(aStack); - } - if (tPrefixMaterial.mUnificationTarget == null) - tPrefixMaterial.mUnificationTarget = sName2StackMap.get(tPrefixMaterial.toString()); - ItemStack rStack = tPrefixMaterial.mUnificationTarget; - if (GT_Utility.isStackInvalid(rStack)) return GT_Utility.copyOrNull(aStack); - ItemStack newStack; - if (unsafe) { - newStack = GT_Utility.copyAmountUnsafe(aStack.stackSize, rStack); - } else { - newStack = GT_Utility.copyAmount(aStack.stackSize, rStack); - } - // NBT is assigned by reference here, so mutating it may have unexpected side effects. - newStack.setTagCompound(aStack.getTagCompound()); - return newStack; - } - - /** - * Doesn't copy the returned stack or set quantity. Be careful and do not mutate it; intended only to optimize - * comparisons - */ - public static ItemStack get_nocopy(ItemStack aStack) { - return get_nocopy(true, aStack); - } - - /** - * Doesn't copy the returned stack or set quantity. Be careful and do not mutate it; intended only to optimize - * comparisons - */ - static ItemStack get_nocopy(boolean aUseBlackList, ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return null; - ItemData tPrefixMaterial = getAssociation(aStack); - if (tPrefixMaterial == null || !tPrefixMaterial.hasValidPrefixMaterialData() - || (aUseBlackList && tPrefixMaterial.mBlackListed)) return aStack; - if (aUseBlackList && !GregTech_API.sUnificationEntriesRegistered && isBlacklisted(aStack)) { - tPrefixMaterial.mBlackListed = true; - return aStack; - } - if (tPrefixMaterial.mUnificationTarget == null) - tPrefixMaterial.mUnificationTarget = sName2StackMap.get(tPrefixMaterial.toString()); - ItemStack rStack = tPrefixMaterial.mUnificationTarget; - if (GT_Utility.isStackInvalid(rStack)) return aStack; - - // Yes, == and not .equals(). - // This check is primarily intended to optimize for the case where both rStack and aStack - // do not have NBT, and so we would be comparing null == null. - // - // Even if aStack and rStack may have equal NBT, we prefer to do an inexpensive - // new ItemStack() over the potentially expensive NBTTagCompound.equals(). - if (aStack.getTagCompound() == rStack.getTagCompound()) { - // Warning: rStack's stack size may not be equal to aStack's stack size. - return rStack; - } - - // Okay, okay, I lied, we actually do need to make a copy. - // This is to fix a long-standing bug where we were mutating NBT directly on rStack, - // which had unexpected and unpredictable ripple effects. - // - // We will do some custom copying here, to avoid ItemStack.copy(), - // which calls the potentially expensive NBTTagCompound.copy() - // NBT is assigned by reference here, so mutating it may have unexpected side effects. - ItemStack newStack = new ItemStack(rStack.getItem(), aStack.stackSize, Items.feather.getDamage(rStack)); - newStack.setTagCompound(aStack.getTagCompound()); - return newStack; - } - - /** - * Compares the first argument against an already-unificated second argument as if aUseBlackList was both true and - * false. - */ - public static boolean isInputStackEqual(ItemStack aStack, ItemStack unified_tStack) { - if (GT_Utility.isStackInvalid(aStack)) return false; - return isInputStackEqual(aStack, getAssociation(aStack), unified_tStack); - } - - /** - * Compares the first argument against an already-unificated second argument as if aUseBlackList was both true and - * false. - */ - public static boolean isInputStackEqual(ItemStack aStack, ItemData aStackPrefixData, ItemStack unified_tStack) { - boolean alreadyCompared = false; - if (GT_Utility.isStackInvalid(aStack)) return false; - ItemStack rStack = null; - if (aStackPrefixData == null || !aStackPrefixData.hasValidPrefixMaterialData()) - return GT_Utility.areStacksEqual(aStack, unified_tStack, true); - else if (aStackPrefixData.mBlackListed) { - if (GT_Utility.areStacksEqual(aStack, unified_tStack, true)) return true; - else alreadyCompared = true; - } - if (!alreadyCompared && !GregTech_API.sUnificationEntriesRegistered && isBlacklisted(aStack)) { - aStackPrefixData.mBlackListed = true; - if (GT_Utility.areStacksEqual(aStack, unified_tStack, true)) return true; - else alreadyCompared = true; - } - if (aStackPrefixData.mUnificationTarget == null) - aStackPrefixData.mUnificationTarget = sName2StackMap.get(aStackPrefixData.toString()); - rStack = aStackPrefixData.mUnificationTarget; - if (GT_Utility.isStackInvalid(rStack)) - return !alreadyCompared && GT_Utility.areStacksEqual(aStack, unified_tStack, true); - return GT_Utility.areStacksEqual(rStack, unified_tStack, true); - } - - public static List getNonUnifiedStacks(Object obj) { - if (sUnificationTable.isEmpty() && !sItemStack2DataMap.isEmpty()) { - // use something akin to double check lock. this synchronization overhead is causing lag whenever my - // 5900x tries to do NEI lookup - synchronized (sUnificationTable) { - if (sUnificationTable.isEmpty() && !sItemStack2DataMap.isEmpty()) { - for (ItemStack tGTStack0 : sItemStack2DataMap.keySet()) { - ItemStack tStack0 = GT_ItemStack.internalCopyStack(tGTStack0); - ItemStack tStack1 = get_nocopy(false, tStack0); - if (!GT_Utility.areStacksEqual(tStack0, tStack1)) { - List list = sUnificationTable.computeIfAbsent(tStack1, k -> new ArrayList<>()); - // greg's original code tries to dedupe the list using List#contains, which won't work - // on vanilla ItemStack. I removed it since it never worked and can be slow. - list.add(tStack0); - } - } - } - } - } - ItemStack[] aStacks = {}; - if (obj instanceof ItemStack) aStacks = new ItemStack[] { (ItemStack) obj }; - else if (obj instanceof ItemStack[]) aStacks = (ItemStack[]) obj; - else if (obj instanceof List) aStacks = (ItemStack[]) ((List) obj).toArray(new ItemStack[0]); - List rList = new ArrayList<>(); - for (ItemStack aStack : aStacks) { - if (aStack == null) continue; - rList.add(aStack); - List tList = sUnificationTable.get(aStack); - if (tList != null) { - for (ItemStack tStack : tList) { - ItemStack tStack1 = GT_Utility.copyAmount(aStack.stackSize, tStack); - rList.add(tStack1); - } - } - } - return rList; - } - - public static void addItemData(ItemStack aStack, ItemData aData) { - if (GT_Utility.isStackValid(aStack) && getItemData(aStack) == null && aData != null) setItemData(aStack, aData); - } - - public static void addItemDataFromInputs(ItemStack output, Object... inputs) { - int length = inputs.length; - ItemData[] tData = new ItemData[length]; - for (int i = 0; i < length; i++) { - if (inputs[i] instanceof ItemStack) { - tData[i] = GT_OreDictUnificator.getItemData((ItemStack) inputs[i]); - } else if (inputs[i] instanceof ItemData) { - tData[i] = (ItemData) inputs[i]; - } else { - throw new IllegalArgumentException(); - } - } - if (GT_Utility.arrayContainsNonNull(tData)) { - GT_OreDictUnificator.addItemData(output, new ItemData(tData)); - } - } - - public static void setItemData(ItemStack aStack, ItemData aData) { - if (GT_Utility.isStackInvalid(aStack) || aData == null) return; - ItemData tData = getItemData(aStack); - if (tData == null || !tData.hasValidPrefixMaterialData()) { - if (tData != null) for (Object tObject : tData.mExtraData) - if (!aData.mExtraData.contains(tObject)) aData.mExtraData.add(tObject); - if (aStack.stackSize > 1) { - if (aData.mMaterial != null) aData.mMaterial.mAmount /= aStack.stackSize; - for (MaterialStack tMaterial : aData.mByProducts) tMaterial.mAmount /= aStack.stackSize; - aStack = GT_Utility.copyAmount(1, aStack); - } - sItemStack2DataMap.put(aStack, aData); - if (aData.hasValidMaterialData()) { - long tValidMaterialAmount = aData.mMaterial.mMaterial.contains(SubTag.NO_RECYCLING) ? 0 - : aData.mMaterial.mAmount >= 0 ? aData.mMaterial.mAmount : M; - for (MaterialStack tMaterial : aData.mByProducts) - tValidMaterialAmount += tMaterial.mMaterial.contains(SubTag.NO_RECYCLING) ? 0 - : tMaterial.mAmount >= 0 ? tMaterial.mAmount : M; - if (tValidMaterialAmount < M) GT_ModHandler.addToRecyclerBlackList(aStack); - } - if (mRunThroughTheList) { - if (GregTech_API.sLoadStarted) { - mRunThroughTheList = false; - for (Entry tEntry : sItemStack2DataMap.entrySet()) if (!tEntry.getValue() - .hasValidPrefixData() || tEntry.getValue().mPrefix.mAllowNormalRecycling) - GT_RecipeRegistrator.registerMaterialRecycling( - GT_ItemStack.internalCopyStack(tEntry.getKey()), - tEntry.getValue()); - } - } else { - if (!aData.hasValidPrefixData() || aData.mPrefix.mAllowNormalRecycling) - GT_RecipeRegistrator.registerMaterialRecycling(aStack, aData); - } - } else { - for (Object tObject : aData.mExtraData) - if (!tData.mExtraData.contains(tObject)) tData.mExtraData.add(tObject); - } - } - - public static void removeItemData(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) { - return; - } - sItemStack2DataMap.remove(aStack); - } - - public static void addAssociation(OrePrefixes aPrefix, Materials aMaterial, ItemStack aStack, - boolean aBlackListed) { - if (aPrefix == null || aMaterial == null || GT_Utility.isStackInvalid(aStack)) return; - if (Items.feather.getDamage(aStack) == W) for (byte i = 0; i < 16; i++) - setItemData(GT_Utility.copyAmountAndMetaData(1, i, aStack), new ItemData(aPrefix, aMaterial, aBlackListed)); - setItemData(aStack, new ItemData(aPrefix, aMaterial, aBlackListed)); - } - - @Nullable - public static ItemData getItemData(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return null; - ItemData rData = sItemStack2DataMap.get(aStack); - if (rData == null) { // Try the lookup again but with wildcard damage value - rData = sItemStack2DataMap.get(GT_ItemStack.internalCopyStack(aStack, true)); - } - return rData; - } - - @Nullable - public static ItemData getAssociation(ItemStack aStack) { - ItemData rData = getItemData(aStack); - return rData != null && rData.hasValidPrefixMaterialData() ? rData : null; - } - - public static boolean isItemStackInstanceOf(ItemStack aStack, Object aName) { - if (GT_Utility.isStringInvalid(aName) || GT_Utility.isStackInvalid(aStack)) return false; - for (ItemStack tOreStack : getOresImmutable(aName.toString())) - if (GT_Utility.areStacksEqual(tOreStack, aStack, true)) return true; - return false; - } - - public static boolean isItemStackDye(ItemStack aStack) { - if (GT_Utility.isStackInvalid(aStack)) return false; - - for (Dyes tDye : Dyes.VALUES) if (isItemStackInstanceOf(aStack, tDye.toString())) return true; - - return false; - } - - public static boolean registerOre(OrePrefixes aPrefix, Object aMaterial, ItemStack aStack) { - return registerOre(aPrefix.get(aMaterial), aStack); - } - - public static boolean registerOre(Object aName, ItemStack aStack) { - if (aName == null || GT_Utility.isStackInvalid(aStack)) return false; - - String tName = aName.toString(); - - if (GT_Utility.isStringInvalid(tName)) return false; - - for (ItemStack itemStack : getOresImmutable(tName)) - if (GT_Utility.areStacksEqual(itemStack, aStack, true)) return false; - - isRegisteringOre++; - OreDictionary.registerOre(tName, GT_Utility.copyAmount(1, aStack)); - isRegisteringOre--; - return true; - } - - public static boolean isRegisteringOres() { - return isRegisteringOre > 0; - } - - public static boolean isAddingOres() { - return isAddingOre > 0; - } - - public static void resetUnificationEntries() { - for (ItemData tPrefixMaterial : sItemStack2DataMap.values()) tPrefixMaterial.mUnificationTarget = null; - } - - public static ItemStack getGem(MaterialStack aMaterial) { - return aMaterial == null ? null : getGem(aMaterial.mMaterial, aMaterial.mAmount); - } - - public static ItemStack getGem(Materials aMaterial, OrePrefixes aPrefix) { - return aMaterial == null ? null : getGem(aMaterial, aPrefix.mMaterialAmount); - } - - public static ItemStack getGem(Materials aMaterial, long aMaterialAmount) { - ItemStack rStack = null; - if (((aMaterialAmount >= M))) rStack = get(OrePrefixes.gem, aMaterial, aMaterialAmount / M); - if (rStack == null) { - if ((((aMaterialAmount * 2) % M == 0) || aMaterialAmount >= M * 16)) - rStack = get(OrePrefixes.gemFlawed, aMaterial, (aMaterialAmount * 2) / M); - if ((((aMaterialAmount * 4) >= M))) - rStack = get(OrePrefixes.gemChipped, aMaterial, (aMaterialAmount * 4) / M); - } - return rStack; - } - - public static ItemStack getDust(MaterialStack aMaterial) { - return aMaterial == null ? null : getDust(aMaterial.mMaterial, aMaterial.mAmount); - } - - public static ItemStack getDust(Materials aMaterial, OrePrefixes aPrefix) { - return aMaterial == null ? null : getDust(aMaterial, aPrefix.mMaterialAmount); - } - - public static ItemStack getDust(Materials aMaterial, long aMaterialAmount) { - if (aMaterialAmount <= 0) return null; - ItemStack rStack = null; - if (((aMaterialAmount % M == 0) || aMaterialAmount >= M * 16)) - rStack = get(OrePrefixes.dust, aMaterial, aMaterialAmount / M); - if (rStack == null && (((aMaterialAmount * 4) % M == 0) || aMaterialAmount >= M * 8)) - rStack = get(OrePrefixes.dustSmall, aMaterial, (aMaterialAmount * 4) / M); - if (rStack == null && (((aMaterialAmount * 9) >= M))) - rStack = get(OrePrefixes.dustTiny, aMaterial, (aMaterialAmount * 9) / M); - return rStack; - } - - public static ItemStack getIngot(MaterialStack aMaterial) { - return aMaterial == null ? null : getIngot(aMaterial.mMaterial, aMaterial.mAmount); - } - - public static ItemStack getIngot(Materials aMaterial, OrePrefixes aPrefix) { - return aMaterial == null ? null : getIngot(aMaterial, aPrefix.mMaterialAmount); - } - - public static ItemStack getIngot(Materials aMaterial, long aMaterialAmount) { - if (aMaterialAmount <= 0) return null; - ItemStack rStack = null; - if (((aMaterialAmount % (M * 9) == 0 && aMaterialAmount / (M * 9) > 1) || aMaterialAmount >= M * 72)) - rStack = get(OrePrefixes.block, aMaterial, aMaterialAmount / (M * 9)); - if (rStack == null && ((aMaterialAmount % M == 0) || aMaterialAmount >= M * 8)) - rStack = get(OrePrefixes.ingot, aMaterial, aMaterialAmount / M); - if (rStack == null && (((aMaterialAmount * 9) >= M))) - rStack = get(OrePrefixes.nugget, aMaterial, (aMaterialAmount * 9) / M); - return rStack; - } - - public static ItemStack getIngotOrDust(Materials aMaterial, long aMaterialAmount) { - if (aMaterialAmount <= 0) return null; - ItemStack rStack = getIngot(aMaterial, aMaterialAmount); - if (rStack == null) rStack = getDust(aMaterial, aMaterialAmount); - return rStack; - } - - public static ItemStack getIngotOrDust(MaterialStack aMaterial) { - ItemStack rStack = getIngot(aMaterial); - if (rStack == null) rStack = getDust(aMaterial); - return rStack; - } - - public static ItemStack getDustOrIngot(Materials aMaterial, long aMaterialAmount) { - if (aMaterialAmount <= 0) return null; - ItemStack rStack = getDust(aMaterial, aMaterialAmount); - if (rStack == null) rStack = getIngot(aMaterial, aMaterialAmount); - return rStack; - } - - public static ItemStack getDustOrIngot(MaterialStack aMaterial) { - ItemStack rStack = getDust(aMaterial); - if (rStack == null) rStack = getIngot(aMaterial); - return rStack; - } - - /** - * @return a Copy of the OreDictionary.getOres() List - */ - public static ArrayList getOres(OrePrefixes aPrefix, Object aMaterial) { - return getOres(aPrefix.get(aMaterial)); - } - - /** - * @return a Copy of the OreDictionary.getOres() List - */ - public static ArrayList getOres(Object aOreName) { - String aName = aOreName == null ? E : aOreName.toString(); - ArrayList rList = new ArrayList<>(); - if (GT_Utility.isStringValid(aName)) rList.addAll(OreDictionary.getOres(aName)); - return rList; - } - - /** - * Fast version of {@link #getOres(Object)}, which doesn't call - * {@link System#arraycopy(Object, int, Object, int, int)} in {@link ArrayList#addAll} - */ - public static List getOresImmutable(@Nullable Object aOreName) { - String aName = aOreName == null ? E : aOreName.toString(); - - return GT_Utility.isStringValid(aName) ? Collections.unmodifiableList(OreDictionary.getOres(aName)) - : Collections.emptyList(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java b/src/main/java/gregtech/api/util/GT_OverclockCalculator.java deleted file mode 100644 index 5dda0b5c01..0000000000 --- a/src/main/java/gregtech/api/util/GT_OverclockCalculator.java +++ /dev/null @@ -1,621 +0,0 @@ -package gregtech.api.util; - -import java.util.function.Function; -import java.util.function.Supplier; - -import javax.annotation.Nonnull; - -public class GT_OverclockCalculator { - - // region variables - // region basic properties - /** - * EUt the recipe originally runs at - */ - private long recipeEUt = 0; - /** - * Voltage of the machine - */ - private long machineVoltage = 0; - /** - * Amperage of the machine - */ - private long machineAmperage = 1; - /** - * Duration of the recipe - */ - private int duration = 0; - /** - * A supplier used for machines which have a custom way of calculating base duration, like Neutron Activator - */ - private Supplier durationUnderOneTickSupplier; - /** - * The parallel the machine has when trying to overclock - */ - private int parallel = 1; - // endregion - // region extra factors - /** - * Discount for EUt at the beginning of calculating overclocks, like GT++ machines - */ - private double eutDiscount = 1; - /** - * Speeding/Slowing up/down the duration of a recipe at the beginning of calculating overclocks, like GT++ machines - */ - private double speedBoost = 1; - // endregion - // region overclock parameters - /** - * How much the energy would be multiplied by per overclock available - */ - private double eutIncreasePerOC = 4; - /** - * A supplier used for machines which have a custom way of calculating energy increase multipliers for every - * overclock, like Advanced Assembling Line - */ - private Function eutIncreasePerOCSupplier = getDefaultEutIncreasePerOCSupplier(); - /** - * How much the duration would be divided by per overclock made that isn't an overclock from HEAT - */ - private double durationDecreasePerOC = 2; - /** - * A supplier used for machines which have a custom way of calculating duration decrease multipliers for every - * overclock - */ - private Function durationDecreasePerOCSupplier = getDefaultDurationDecreasePerOCSupplier(); - /** - * Whether at least one of {@link #eutIncreasePerOCSupplier} and {@link #durationDecreasePerOCSupplier} has been set - */ - private boolean hasAtLeastOneSupplierBeenSet; - /** - * Whether to give EUt Discount when the duration goes below one tick - */ - private boolean oneTickDiscount; - /** - * Whether the multi should use amperage to overclock normally. - */ - private boolean amperageOC; - /** - * If the OC calculator should only do a given amount of overclocks. Mainly used in fusion reactors - */ - private boolean limitOverclocks; - /** - * Maximum amount of overclocks to perform, when limitOverclocks = true - */ - private int maxOverclocks; - /** - * How many overclocks have been performed - */ - private int overclockCount; - /** - * Should we actually try to calculate overclocking - */ - private boolean noOverclock; - /** - * The parallel the machine actually used. - */ - private int currentParallel; - // endregion - // region heat overclock - /** - * The min heat required for the recipe - */ - private int recipeHeat = 0; - /** - * The heat the machine has when starting the recipe - */ - private int machineHeat = 0; - /** - * How much the duration should be divided by for each 1800K above recipe heat - */ - private double durationDecreasePerHeatOC = 4; - /** - * Whether to enable overclocking with heat like the EBF every 1800 heat difference - */ - private boolean heatOC; - /** - * Whether to enable heat discounts every 900 heat difference - */ - private boolean heatDiscount; - /** - * The value used for discount final eut per 900 heat - */ - private double heatDiscountExponent = 0.95; - // endregion - // region result - /** - * variable to check whether the overclocks have been calculated - */ - private boolean calculated; - /** - * The calculated duration result. - */ - private int calculatedDuration; - /** - * The calculated energy consumption result. - */ - private long calculatedConsumption; - // endregion - // region constants - private static final int HEAT_DISCOUNT_THRESHOLD = 900; - private static final int HEAT_PERFECT_OVERCLOCK_THRESHOLD = 1800; - private static final double LOG2 = Math.log(2); - // endregion - // endregion - - /** - * Creates calculator that doesn't do OC at all. Will use recipe duration. - */ - public static GT_OverclockCalculator ofNoOverclock(@Nonnull GT_Recipe recipe) { - return ofNoOverclock(recipe.mEUt, recipe.mDuration); - } - - /** - * Creates calculator that doesn't do OC at all, with set duration. - */ - public static GT_OverclockCalculator ofNoOverclock(long eut, int duration) { - return new GT_OverclockCalculator().setRecipeEUt(eut) - .setDuration(duration) - .setEUt(eut) - .setNoOverclock(true); - } - - /** - * An Overclock helper for calculating overclocks in many different situations - */ - public GT_OverclockCalculator() {} - - // region setters - /** - * @param recipeEUt Sets the Recipe's starting voltage - */ - @Nonnull - public GT_OverclockCalculator setRecipeEUt(long recipeEUt) { - this.recipeEUt = recipeEUt; - return this; - } - - /** - * @param machineVoltage Sets the EUt that the machine can use. This is the voltage of the machine - */ - @Nonnull - public GT_OverclockCalculator setEUt(long machineVoltage) { - this.machineVoltage = machineVoltage; - return this; - } - - /** - * @param duration Sets the duration of the recipe - */ - @Nonnull - public GT_OverclockCalculator setDuration(int duration) { - this.duration = duration; - return this; - } - - /** - * @param machineAmperage Sets the Amperage that the machine can support - */ - @Nonnull - public GT_OverclockCalculator setAmperage(long machineAmperage) { - this.machineAmperage = machineAmperage; - return this; - } - - /** - * Enables Perfect OC in calculation - */ - @Nonnull - public GT_OverclockCalculator enablePerfectOC() { - this.durationDecreasePerOC = 4; - return this; - } - - /** - * Set if we should be calculating overclocking using EBF's perfectOC - */ - @Nonnull - public GT_OverclockCalculator setHeatOC(boolean heatOC) { - this.heatOC = heatOC; - return this; - } - - /** - * Sets if we should add a heat discount at the end of calculating an overclock, just like the EBF - */ - @Nonnull - public GT_OverclockCalculator setHeatDiscount(boolean heatDiscount) { - this.heatDiscount = heatDiscount; - return this; - } - - /** - * Sets the starting heat of the recipe - */ - @Nonnull - public GT_OverclockCalculator setRecipeHeat(int recipeHeat) { - this.recipeHeat = recipeHeat; - return this; - } - - /** - * Sets the heat of the coils on the machine - */ - @Nonnull - public GT_OverclockCalculator setMachineHeat(int machineHeat) { - this.machineHeat = machineHeat; - return this; - } - - /** - * Sets an EUtDiscount. 0.9 is 10% less energy. 1.1 is 10% more energy - */ - @Nonnull - public GT_OverclockCalculator setEUtDiscount(float aEUtDiscount) { - this.eutDiscount = aEUtDiscount; - return this; - } - - /** - * Sets a Speed Boost for the multiblock. 0.9 is 10% faster. 1.1 is 10% slower - */ - @Nonnull - public GT_OverclockCalculator setSpeedBoost(float aSpeedBoost) { - this.speedBoost = aSpeedBoost; - return this; - } - - /** - * Sets the parallel that the multiblock uses - */ - @Nonnull - public GT_OverclockCalculator setParallel(int aParallel) { - this.parallel = aParallel; - return this; - } - - /** - * Sets the heat discount during OC calculation if HeatOC is used. Default: 0.95 = 5% discount Used like a EU/t - * Discount - */ - @Nonnull - public GT_OverclockCalculator setHeatDiscountMultiplier(float heatDiscountExponent) { - this.heatDiscountExponent = heatDiscountExponent; - return this; - } - - /** - * Sets the Overclock that should be calculated when a heat OC is applied. - */ - @Nonnull - public GT_OverclockCalculator setHeatPerfectOC(double heatPerfectOC) { - if (heatPerfectOC <= 0) throw new IllegalArgumentException("Heat OC can't be a negative number or zero"); - this.durationDecreasePerHeatOC = heatPerfectOC; - return this; - } - - /** - * Sets the amount that the eut would be multiplied by per overclock. Do not set as 1(ONE) if the duration decrease - * is also 1(ONE)! - */ - @Nonnull - public GT_OverclockCalculator setEUtIncreasePerOC(double eutIncreasePerOC) { - if (eutIncreasePerOC <= 0) - throw new IllegalArgumentException("EUt increase can't be a negative number or zero"); - this.eutIncreasePerOC = eutIncreasePerOC; - return this; - } - - /** - * Sets the amount that the duration would be divided by per overclock. Do not set as 1(ONE) if the eut increase is - * also 1(ONE)! - */ - @Nonnull - public GT_OverclockCalculator setDurationDecreasePerOC(double durationDecreasePerOC) { - if (durationDecreasePerOC <= 0) - throw new IllegalArgumentException("Duration decrease can't be a negative number or zero"); - this.durationDecreasePerOC = durationDecreasePerOC; - return this; - } - - /** - * Set One Tick Discount on EUt based on Duration Decrease Per Overclock. This functions the same as single blocks. - */ - @Nonnull - public GT_OverclockCalculator setOneTickDiscount(boolean oneTickDiscount) { - this.oneTickDiscount = oneTickDiscount; - return this; - } - - /** - * Limit the amount of overclocks that can be performed, regardless of how much power is available. Mainly used for - * fusion reactors. - */ - @Nonnull - public GT_OverclockCalculator limitOverclockCount(int maxOverclocks) { - this.limitOverclocks = true; - this.maxOverclocks = maxOverclocks; - return this; - } - - @Nonnull - public GT_OverclockCalculator setAmperageOC(boolean amperageOC) { - this.amperageOC = amperageOC; - return this; - } - - /** - * Set a supplier for calculating custom duration for when its needed under one tick - */ - @Nonnull - public GT_OverclockCalculator setDurationUnderOneTickSupplier(Supplier supplier) { - this.durationUnderOneTickSupplier = supplier; - return this; - } - - /** - * Sets if we should do overclocking or not - */ - @Nonnull - public GT_OverclockCalculator setNoOverclock(boolean noOverclock) { - this.noOverclock = noOverclock; - return this; - } - - /** - * Set a supplier for calculating custom EUt increase multipliers for every overclock - */ - public GT_OverclockCalculator setEutIncreasePerOCSupplier(Function eutIncreasePerOCSupplier) { - this.eutIncreasePerOCSupplier = eutIncreasePerOCSupplier; - this.hasAtLeastOneSupplierBeenSet = true; - return this; - } - - /** - * Set a supplier for calculating custom duration decrease multipliers for every overclock - */ - public GT_OverclockCalculator setDurationDecreasePerOCSupplier( - Function durationDecreasePerOCSupplier) { - this.durationDecreasePerOCSupplier = durationDecreasePerOCSupplier; - this.hasAtLeastOneSupplierBeenSet = true; - return this; - } - - /** - * Set actually performed parallel - */ - public GT_OverclockCalculator setCurrentParallel(int currentParallel) { - this.currentParallel = currentParallel; - // Sets parallel to the actually performed one if machine's parallel is underused. - this.parallel = Math.min(parallel, currentParallel); - return this; - } - - // endregion - // region calculate - /** - * Call this when all values have been put it. - */ - @Nonnull - public GT_OverclockCalculator calculate() { - if (calculated) { - throw new IllegalStateException("Tried to calculate overclocks twice"); - } - calculateOverclock(); - calculated = true; - return this; - } - - private void calculateOverclock() { - double durationInDouble = durationUnderOneTickSupplier != null ? durationUnderOneTickSupplier.get() - : duration * speedBoost; - calculatedConsumption = recipeEUt; - double heatDiscountMultiplier = calculateHeatDiscountMultiplier(); - // Usually a safeguard when currentParallel is not set: We assume parallel is fully used. - currentParallel = Math.max(currentParallel, parallel); - - if (noOverclock) { - calculatedConsumption = calculateFinalRecipeEUt(heatDiscountMultiplier); - calculatedDuration = (int) Math.ceil(durationInDouble); - return; - } - - // First we need to overclock to reach 1 tick. - // Then we need to overclock under one tick to get more extra parallels. - // We stop overclocking if we've already reached 1 tick and got enough parallels to actually perform. - double requiredUnderOneTickMultiplier = durationInDouble * currentParallel / parallel; - if (hasAtLeastOneSupplierBeenSet) { // custom overclock - double currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); - double currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); - double machinePower = calculateMachinePower(); - double currentConsumption = calculateRecipePower(heatDiscountMultiplier); - double currentUnderOneTickMultiplier = 1; - // Whether we have enough power for the next overclock; - // whether we need more overclock to reach 1 tick and get enough extra parallel; - // whether we have reached the overclock limit - while (machinePower > currentConsumption * currentEutIncrease - && requiredUnderOneTickMultiplier > currentUnderOneTickMultiplier - && (!limitOverclocks || overclockCount < maxOverclocks)) { - currentConsumption *= currentEutIncrease; - durationInDouble /= currentDurationDecrease; - overclockCount++; - currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); - currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); - } - calculatedConsumption = (long) Math.max(currentConsumption, 1); - calculatedDuration = (int) Math.max(durationInDouble, 1); - } else { // general overclock - double recipePowerTier = calculateRecipePowerTier(heatDiscountMultiplier); - double machinePowerTier = calculateMachinePowerTier(); - - int maxOverclockCount = calculateAmountOfOverclocks(machinePowerTier, recipePowerTier); - if (limitOverclocks) maxOverclockCount = Math.min(maxOverclocks, maxOverclockCount); - if (!amperageOC) { - // Limit overclocks by voltage tier. - maxOverclockCount = Math.min(maxOverclockCount, calculateRecipeToMachineVoltageDifference()); - } - overclockCount = calculateAmountOfNeededOverclocks(maxOverclockCount, requiredUnderOneTickMultiplier); - - // If triggered, it indicates that recipe power > machine power. - // Not just a safeguard. This also means that you can run a 1.2A recipe on a single hatch for a regular gt - // multi. - // This is intended, including the fact that you don't get an OC with a one tier upgrade in that case. - overclockCount = Math.max(overclockCount, 0); - - int heatOverclockCount = Math.min(calculateMaxAmountOfHeatOverclocks(), overclockCount); - calculatedConsumption = (long) Math.floor(recipeEUt * Math.pow(eutIncreasePerOC, overclockCount)); - durationInDouble /= Math.pow(durationDecreasePerHeatOC, heatOverclockCount) - * Math.pow(durationDecreasePerOC, overclockCount - heatOverclockCount); - if (oneTickDiscount) { - calculatedConsumption = (long) Math - .floor(calculatedConsumption / Math.pow(durationDecreasePerOC, maxOverclockCount - overclockCount)); - calculatedConsumption = Math.max(calculatedConsumption, 1); - } - calculatedConsumption = calculateFinalRecipeEUt(heatDiscountMultiplier); - calculatedDuration = (int) Math.max(durationInDouble, 1); - } - } - - private double calculateRecipePower(double heatDiscountMultiplier) { - return recipeEUt * parallel * eutDiscount * heatDiscountMultiplier; - } - - private double calculateRecipePowerTier(double heatDiscountMultiplier) { - return calculatePowerTier(calculateRecipePower(heatDiscountMultiplier)); - } - - private double calculateMachinePower() { - return machineVoltage * (amperageOC ? machineAmperage : Math.min(machineAmperage, parallel)); - } - - private double calculateMachinePowerTier() { - return calculatePowerTier(calculateMachinePower()); - } - - private int calculateRecipeToMachineVoltageDifference() { - return (int) (Math.ceil(calculatePowerTier(machineVoltage)) - Math.ceil(calculatePowerTier(recipeEUt))); - } - - private double calculatePowerTier(double voltage) { - return 1 + Math.max(0, (Math.log(voltage) / LOG2) - 5) / 2; - } - - private long calculateFinalRecipeEUt(double heatDiscountMultiplier) { - return (long) Math.ceil(calculatedConsumption * eutDiscount * heatDiscountMultiplier * parallel); - } - - private int calculateMaxAmountOfHeatOverclocks() { - return heatOC ? (machineHeat - recipeHeat) / HEAT_PERFECT_OVERCLOCK_THRESHOLD : 0; - } - - /** - * Calculate maximum possible overclocks ignoring if we are going to go under 1 tick - */ - private int calculateAmountOfOverclocks(double machinePowerTier, double recipePowerTier) { - return (int) (machinePowerTier - recipePowerTier); - } - - private int calculateAmountOfNeededOverclocks(int maxOverclockCount, double requiredUnderOneTickMultiplier) { - int neededHeatOC = (int) Math.min( - calculateMaxAmountOfHeatOverclocks(), - Math.ceil(Math.log(requiredUnderOneTickMultiplier) / Math.log(durationDecreasePerHeatOC))); - neededHeatOC = Math.max(neededHeatOC, 0); - int neededNormalOC = (int) Math.ceil( - (Math.log(requiredUnderOneTickMultiplier) - Math.log(durationDecreasePerHeatOC) * neededHeatOC) - / Math.log(durationDecreasePerOC)); - neededNormalOC = Math.max(neededNormalOC, 0); - return Math.min(maxOverclockCount, neededHeatOC + neededNormalOC); - } - - private double calculateHeatDiscountMultiplier() { - int heatDiscounts = heatDiscount ? (machineHeat - recipeHeat) / HEAT_DISCOUNT_THRESHOLD : 0; - return Math.pow(heatDiscountExponent, heatDiscounts); - } - - // endregion - // region result getters - /** - * @return The consumption after overclock has been calculated - */ - public long getConsumption() { - if (!calculated) { - throw new IllegalStateException("Tried to get consumption before calculating"); - } - return calculatedConsumption; - } - - /** - * @return The duration of the recipe after overclock has been calculated - */ - public int getDuration() { - if (!calculated) { - throw new IllegalStateException("Tried to get duration before calculating"); - } - return calculatedDuration; - } - - /** - * @return Number of performed overclocks - */ - public int getPerformedOverclocks() { - if (!calculated) { - throw new IllegalStateException("Tried to get performed overclocks before calculating"); - } - return overclockCount; - } - - /** - * @return Whether the calculation has happened - */ - public boolean getCalculationStatus() { - return calculated; - } - - // endregion - // region misc - /** - * Returns duration as a double to show how much it is overclocking too much to determine extra parallel. This - * doesn't count as calculating - */ - public double calculateDurationUnderOneTick() { - double durationInDouble = durationUnderOneTickSupplier != null ? durationUnderOneTickSupplier.get() - : duration * speedBoost; - if (noOverclock) return durationInDouble; - double heatDiscountMultiplier = calculateHeatDiscountMultiplier(); - if (hasAtLeastOneSupplierBeenSet) { - int overclockCount = 0; - double currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); - double currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); - double machinePower = calculateMachinePower(); - double recipePower = calculateRecipePower(heatDiscountMultiplier); - while (machinePower > recipePower * currentEutIncrease - && (!limitOverclocks || overclockCount < maxOverclocks)) { - recipePower *= currentEutIncrease; - durationInDouble /= currentDurationDecrease; - overclockCount++; - currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); - currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); - } - } else { - int maxOverclockCount = calculateAmountOfOverclocks( - calculateMachinePowerTier(), - calculateRecipePowerTier(heatDiscountMultiplier)); - if (limitOverclocks) maxOverclockCount = Math.min(maxOverclocks, maxOverclockCount); - int heatOverclocks = Math.min(calculateMaxAmountOfHeatOverclocks(), maxOverclockCount); - durationInDouble /= Math.pow(durationDecreasePerOC, maxOverclockCount - heatOverclocks) - * Math.pow(durationDecreasePerHeatOC, heatOverclocks); - } - return durationInDouble; - } - - private Function getDefaultEutIncreasePerOCSupplier() { - return overclockCount -> eutIncreasePerOC; - } - - private Function getDefaultDurationDecreasePerOCSupplier() { - return overclockCount -> overclockCount <= calculateMaxAmountOfHeatOverclocks() ? durationDecreasePerHeatOC - : durationDecreasePerOC; - } - - // endregion -} diff --git a/src/main/java/gregtech/api/util/GT_PCBFactoryManager.java b/src/main/java/gregtech/api/util/GT_PCBFactoryManager.java deleted file mode 100644 index 990e9bd174..0000000000 --- a/src/main/java/gregtech/api/util/GT_PCBFactoryManager.java +++ /dev/null @@ -1,25 +0,0 @@ -package gregtech.api.util; - -import com.google.common.collect.HashBiMap; - -import gregtech.api.enums.Materials; - -public class GT_PCBFactoryManager { - - private static final HashBiMap mPlasticTiers = HashBiMap.create(); - public static int mTiersOfPlastics = 0; - - public static void addPlasticTier(Materials aMaterial, int aTier) { - mPlasticTiers.put(aMaterial, aTier); - mTiersOfPlastics++; - } - - public static int getPlasticTier(Materials aMaterial) { - return mPlasticTiers.get(aMaterial); - } - - public static Materials getPlasticMaterialFromTier(int aTier) { - return mPlasticTiers.inverse() - .get(aTier); - } -} diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java deleted file mode 100644 index 157488a8ca..0000000000 --- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java +++ /dev/null @@ -1,713 +0,0 @@ -package gregtech.api.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; -import java.util.Random; -import java.util.function.Function; - -import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -import gregtech.api.interfaces.tileentity.IRecipeLockable; -import gregtech.api.interfaces.tileentity.IVoidable; -import gregtech.api.logic.FluidInventoryLogic; -import gregtech.api.logic.ItemInventoryLogic; -import gregtech.api.objects.XSTR; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.recipe.check.CheckRecipeResult; -import gregtech.api.recipe.check.CheckRecipeResultRegistry; -import gregtech.api.recipe.check.SingleRecipeCheck; - -@SuppressWarnings({ "unused", "UnusedReturnValue" }) -public class GT_ParallelHelper { - - private static final double MAX_BATCH_MODE_TICK_TIME = 128; - /** - * Machine used for calculation - */ - private IVoidable machine; - /** - * Machine used for single recipe locking calculation - */ - private IRecipeLockable singleRecipeMachine; - /** - * Is locked to a single recipe? - */ - private boolean isRecipeLocked; - /** - * Recipe used when trying to calculate parallels - */ - private GT_Recipe recipe; - /** - * EUt available to the multiblock (This should be the total eut available) - */ - private long availableEUt; - /** - * The current parallel possible for the multiblock - */ - private int currentParallel = 0; - /** - * The maximum possible parallel possible for the multiblock - */ - private int maxParallel = 1; - /** - * The Batch Modifier applied when batch mode is enabled. 1 does nothing. 2 doubles max possible - * parallel, but also duration - */ - private int batchModifier = 1; - /** - * The inputs of the multiblock for the current recipe check - */ - private ItemStack[] itemInputs; - /** - * The inputs of the machine for current recipe check - */ - private ItemInventoryLogic itemInputInventory; - /** - * The output item inventory of the machine - */ - private ItemInventoryLogic itemOutputInventory; - /** - * The outputs of the recipe with the applied parallel - */ - private ItemStack[] itemOutputs; - /** - * The inputs of the multiblock for the current recipe check - */ - private FluidStack[] fluidInputs; - /** - * The inputs of the machine for the current recipe check - */ - private FluidInventoryLogic fluidInputInventory; - /** - * The output fluid inventory of the machine; - */ - private FluidInventoryLogic fluidOutputInventory; - /** - * The outputs of the recipe with the applied parallel - */ - private FluidStack[] fluidOutputs; - /** - * Does the multi have void protection enabled for items - */ - private boolean protectExcessItem; - /** - * Does the multi have void protection enabled for fluids - */ - private boolean protectExcessFluid; - /** - * Should the Parallel Helper automatically consume for the multi - */ - private boolean consume; - /** - * Is batch mode turned on? - */ - private boolean batchMode; - /** - * Should the Parallel Helper automatically calculate the outputs of the recipe with current parallel? - */ - private boolean calculateOutputs; - /** - * Has the Parallel Helper been built? - */ - private boolean built; - /** - * What is the duration multiplier with batch mode enabled - */ - private double durationMultiplier; - /** - * Modifier which is applied on the recipe eut. Useful for GT++ machines - */ - private float eutModifier = 1; - /** - * Multiplier that is applied on the output chances - */ - private double chanceMultiplier = 1; - /** - * Multiplier by which the output will be multiplied - */ - private int outputMultiplier = 1; - /** - * Method for calculating max parallel from given inputs. - */ - private MaxParallelCalculator maxParallelCalculator = GT_Recipe::maxParallelCalculatedByInputs; - /** - * Method for consuming inputs after determining how many parallels it can execute. - */ - private InputConsumer inputConsumer = GT_Recipe::consumeInput; - - /** - * Calculator to use for overclocking - */ - private GT_OverclockCalculator calculator; - @Nonnull - private CheckRecipeResult result = CheckRecipeResultRegistry.NONE; - - private Function customItemOutputCalculation; - - private Function customFluidOutputCalculation; - - /** - * MuTE Mode this is a mode for changing how the GT_ParallelHelper works as Mutes don't use ItemStack and FluidStack - * arrays for inputs - */ - private boolean muteMode = false; - - public GT_ParallelHelper() {} - - /** - * Sets machine, with current configuration for void protection mode. - */ - @Nonnull - public GT_ParallelHelper setMachine(IVoidable machine) { - return setMachine(machine, machine.protectsExcessItem(), machine.protectsExcessFluid()); - } - - /** - * Sets machine, with void protection mode forcibly. - */ - @Nonnull - public GT_ParallelHelper setMachine(IVoidable machine, boolean protectExcessItem, boolean protectExcessFluid) { - this.protectExcessItem = protectExcessItem; - this.protectExcessFluid = protectExcessFluid; - this.machine = machine; - return this; - } - - /** - * Sets the recipe, which will be used for the parallel calculation - */ - @Nonnull - public GT_ParallelHelper setRecipe(@Nonnull GT_Recipe aRecipe) { - recipe = Objects.requireNonNull(aRecipe); - return this; - } - - @Nonnull - public GT_ParallelHelper setRecipeLocked(IRecipeLockable singleRecipeMachine, boolean isRecipeLocked) { - this.singleRecipeMachine = singleRecipeMachine; - this.isRecipeLocked = isRecipeLocked; - return this; - } - - /** - * Sets the items available for the recipe check - */ - @Nonnull - public GT_ParallelHelper setItemInputs(ItemStack... aItemInputs) { - this.itemInputs = aItemInputs; - return this; - } - - /** - * Sets the fluid inputs available for the recipe check - */ - @Nonnull - public GT_ParallelHelper setFluidInputs(FluidStack... aFluidInputs) { - this.fluidInputs = aFluidInputs; - return this; - } - - /** - * Sets the available eut when trying for more parallels - */ - @Nonnull - public GT_ParallelHelper setAvailableEUt(long aAvailableEUt) { - this.availableEUt = aAvailableEUt; - return this; - } - - /** - * Sets the modifier for recipe eut. 1 does nothing 0.9 is 10% less. 1.1 is 10% more - */ - @Nonnull - public GT_ParallelHelper setEUtModifier(float aEUtModifier) { - this.eutModifier = aEUtModifier; - return this; - } - - /** - * Sets the multiplier that is applied on output chances. 1 does nothing. 0.9 is 10% less. 1.1 is 10% more. - * Only useful for item outputs for sure. - */ - @Nonnull - public GT_ParallelHelper setChanceMultiplier(double chanceMultiplier) { - this.chanceMultiplier = chanceMultiplier; - return this; - } - - /** - * Sets the item/fluid output multiplier. 1 does nothing. 2 doubles the item and fluid outputs. - */ - @Nonnull - public GT_ParallelHelper setOutputMultiplier(int outputMultiplier) { - this.outputMultiplier = outputMultiplier; - return this; - } - - @Nonnull - public GT_ParallelHelper setCalculator(GT_OverclockCalculator calculator) { - this.calculator = calculator; - return this; - } - - /** - * Set if we should consume inputs or not when trying for parallels - * - * @param consume Should we consume inputs - */ - @Nonnull - public GT_ParallelHelper setConsumption(boolean consume) { - this.consume = consume; - return this; - } - - /** - * Sets the MaxParallel a multi can handle - */ - @Nonnull - public GT_ParallelHelper setMaxParallel(int maxParallel) { - this.maxParallel = maxParallel; - return this; - } - - /** - * Enables Batch mode. Can do up to an additional processed recipes of mCurrentParallel * mBatchModifier A batch - * modifier of 1 does nothing - */ - @Nonnull - public GT_ParallelHelper enableBatchMode(int batchModifier) { - this.batchMode = batchModifier > 1; - this.batchModifier = batchModifier; - return this; - } - - /** - * Sets if we should calculate outputs with the parallels we found or not - * - * @param calculateOutputs Should we calculate outputs with the helper or not - */ - @Nonnull - public GT_ParallelHelper setOutputCalculation(boolean calculateOutputs) { - this.calculateOutputs = calculateOutputs; - return this; - } - - /** - * Set a custom way to calculate item outputs. You are given the amount of parallels and must return an ItemStack - * array - */ - @Nonnull - public GT_ParallelHelper setCustomItemOutputCalculation(Function custom) { - customItemOutputCalculation = custom; - return this; - } - - /** - * Set a custom way to calculate item outputs. You are given the amount of parallels and must return a FluidStack - * array - */ - @Nonnull - public GT_ParallelHelper setCustomFluidOutputCalculation(Function custom) { - customFluidOutputCalculation = custom; - return this; - } - - @Nonnull - public GT_ParallelHelper setMuTEMode(boolean muteMode) { - this.muteMode = muteMode; - return this; - } - - @Nonnull - public GT_ParallelHelper setItemInputInventory(ItemInventoryLogic itemInputInventory) { - this.itemInputInventory = itemInputInventory; - return this; - } - - @Nonnull - public GT_ParallelHelper setFluidInputInventory(FluidInventoryLogic fluidInputInventory) { - this.fluidInputInventory = fluidInputInventory; - return this; - } - - /** - * Sets method for calculating max parallel from given inputs. - */ - public GT_ParallelHelper setMaxParallelCalculator(MaxParallelCalculator maxParallelCalculator) { - this.maxParallelCalculator = maxParallelCalculator; - return this; - } - - /** - * Sets method for consuming inputs after determining how many parallels it can execute. - */ - public GT_ParallelHelper setInputConsumer(InputConsumer inputConsumer) { - this.inputConsumer = inputConsumer; - return this; - } - - @Nonnull - public GT_ParallelHelper setItemOutputInventory(ItemInventoryLogic itemOutputInventory) { - this.itemOutputInventory = itemOutputInventory; - return this; - } - - @Nonnull - public GT_ParallelHelper setFluidOutputInventory(FluidInventoryLogic fluidOutputInventory) { - this.fluidOutputInventory = fluidOutputInventory; - return this; - } - - /** - * Finishes the GT_ParallelHelper. Anything changed after this will not effect anything - */ - @Nonnull - public GT_ParallelHelper build() { - if (built) { - throw new IllegalStateException("Tried to build twice"); - } - if (recipe == null) { - throw new IllegalStateException("Recipe is not set"); - } - built = true; - determineParallel(); - return this; - } - - /** - * @return The current parallels possible by the multiblock - */ - public int getCurrentParallel() { - if (!built) { - throw new IllegalStateException("Tried to get parallels before building"); - } - return currentParallel; - } - - /** - * @return The duration multiplier if batch mode was enabled for the multiblock - */ - public double getDurationMultiplierDouble() { - if (!built) { - throw new IllegalStateException("Tried to get duration multiplier before building"); - } - if (batchMode && durationMultiplier > 0) { - return durationMultiplier; - } - return 1; - } - - /** - * @return The ItemOutputs from the recipe - */ - @Nonnull - public ItemStack[] getItemOutputs() { - if (!built || !calculateOutputs) { - throw new IllegalStateException( - "Tried to get item outputs before building or without enabling calculation of outputs"); - } - return itemOutputs; - } - - /** - * @return The FluidOutputs from the recipe - */ - @Nonnull - public FluidStack[] getFluidOutputs() { - if (!built || !calculateOutputs) { - throw new IllegalStateException( - "Tried to get fluid outputs before building or without enabling calculation of outputs"); - } - return fluidOutputs; - } - - /** - * @return The result of why a recipe could've failed or succeeded - */ - @Nonnull - public CheckRecipeResult getResult() { - if (!built) { - throw new IllegalStateException("Tried to get recipe result before building"); - } - return result; - } - - /** - * Called by build(). Determines the parallels and everything else that needs to be done at build time - */ - protected void determineParallel() { - if (maxParallel <= 0) { - return; - } - if (itemInputs == null) { - itemInputs = new ItemStack[0]; - } - if (fluidInputs == null) { - fluidInputs = new FluidStack[0]; - } - - if (!consume) { - copyInputs(); - } - - if (calculator == null) { - calculator = new GT_OverclockCalculator().setEUt(availableEUt) - .setRecipeEUt(recipe.mEUt) - .setDuration(recipe.mDuration) - .setEUtDiscount(eutModifier); - } - - final int tRecipeEUt = (int) Math.ceil(recipe.mEUt * eutModifier); - if (availableEUt < tRecipeEUt) { - result = CheckRecipeResultRegistry.insufficientPower(tRecipeEUt); - return; - } - - // Save the original max parallel before calculating our overclocking under 1 tick - int originalMaxParallel = maxParallel; - calculator.setParallel(originalMaxParallel); - double tickTimeAfterOC = calculator.calculateDurationUnderOneTick(); - if (tickTimeAfterOC < 1) { - maxParallel = GT_Utility.safeInt((long) (maxParallel / tickTimeAfterOC), 0); - } - - int maxParallelBeforeBatchMode = maxParallel; - if (batchMode) { - maxParallel = GT_Utility.safeInt((long) maxParallel * batchModifier, 0); - } - - final ItemStack[] truncatedItemOutputs = recipe.mOutputs != null - ? Arrays.copyOfRange(recipe.mOutputs, 0, Math.min(machine.getItemOutputLimit(), recipe.mOutputs.length)) - : new ItemStack[0]; - final FluidStack[] truncatedFluidOutputs = recipe.mFluidOutputs != null ? Arrays - .copyOfRange(recipe.mFluidOutputs, 0, Math.min(machine.getFluidOutputLimit(), recipe.mFluidOutputs.length)) - : new FluidStack[0]; - - SingleRecipeCheck recipeCheck = null; - SingleRecipeCheck.Builder tSingleRecipeCheckBuilder = null; - if (isRecipeLocked && singleRecipeMachine != null) { - recipeCheck = singleRecipeMachine.getSingleRecipeCheck(); - if (recipeCheck == null) { - // Machine is configured to lock to a single recipe, but haven't built the recipe checker yet. - // Build the checker on next successful recipe. - RecipeMap recipeMap = singleRecipeMachine.getRecipeMap(); - if (recipeMap != null) { - tSingleRecipeCheckBuilder = SingleRecipeCheck.builder(recipeMap) - .setBefore(itemInputs, fluidInputs); - } - } - } - - // Let's look at how many parallels we can get with void protection - if (protectExcessItem || protectExcessFluid) { - if (machine == null && !muteMode) { - throw new IllegalStateException("Tried to calculate void protection, but machine is not set"); - } - VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper(); - voidProtectionHelper.setMachine(machine) - .setItemOutputs(truncatedItemOutputs) - .setFluidOutputs(truncatedFluidOutputs) - .setChangeGetter(recipe::getOutputChance) - .setOutputMultiplier(outputMultiplier) - .setChanceMultiplier(chanceMultiplier) - .setMaxParallel(maxParallel) - .setItemOutputInventory(itemOutputInventory) - .setFluidOutputInventory(fluidOutputInventory) - .setMuTEMode(muteMode) - .build(); - maxParallel = Math.min(voidProtectionHelper.getMaxParallel(), maxParallel); - if (voidProtectionHelper.isItemFull()) { - result = CheckRecipeResultRegistry.ITEM_OUTPUT_FULL; - return; - } - if (voidProtectionHelper.isFluidFull()) { - result = CheckRecipeResultRegistry.FLUID_OUTPUT_FULL; - return; - } - } - - maxParallelBeforeBatchMode = Math.min(maxParallel, maxParallelBeforeBatchMode); - - // determine normal parallel - int actualMaxParallel = tRecipeEUt > 0 ? (int) Math.min(maxParallelBeforeBatchMode, availableEUt / tRecipeEUt) - : maxParallelBeforeBatchMode; - if (recipeCheck != null) { - currentParallel = recipeCheck.checkRecipeInputs(true, actualMaxParallel, itemInputs, fluidInputs); - } else { - currentParallel = (int) maxParallelCalculator.calculate(recipe, actualMaxParallel, fluidInputs, itemInputs); - if (currentParallel > 0) { - if (tSingleRecipeCheckBuilder != null) { - // If recipe checker is not built yet, build and set it - inputConsumer.consume(recipe, 1, fluidInputs, itemInputs); - SingleRecipeCheck builtCheck = tSingleRecipeCheckBuilder.setAfter(itemInputs, fluidInputs) - .setRecipe(recipe) - .build(); - singleRecipeMachine.setSingleRecipeCheck(builtCheck); - inputConsumer.consume(recipe, currentParallel - 1, fluidInputs, itemInputs); - } else { - inputConsumer.consume(recipe, currentParallel, fluidInputs, itemInputs); - } - } - } - - if (currentParallel <= 0) { - result = CheckRecipeResultRegistry.INTERNAL_ERROR; - return; - } - - calculator.setCurrentParallel(currentParallel) - .calculate(); - // If Batch Mode is enabled determine how many extra parallels we can get - if (batchMode && currentParallel > 0 && calculator.getDuration() < MAX_BATCH_MODE_TICK_TIME) { - int tExtraParallels; - double batchMultiplierMax = MAX_BATCH_MODE_TICK_TIME / calculator.getDuration(); - final int maxExtraParallels = (int) Math.floor( - Math.min( - currentParallel * Math.min(batchMultiplierMax - 1, batchModifier - 1), - maxParallel - currentParallel)); - if (recipeCheck != null) { - tExtraParallels = recipeCheck.checkRecipeInputs(true, maxExtraParallels, itemInputs, fluidInputs); - } else { - tExtraParallels = (int) maxParallelCalculator - .calculate(recipe, maxExtraParallels, fluidInputs, itemInputs); - inputConsumer.consume(recipe, tExtraParallels, fluidInputs, itemInputs); - } - durationMultiplier = 1.0f + (float) tExtraParallels / currentParallel; - currentParallel += tExtraParallels; - } - - // If we want to calculate outputs we do it here - if (calculateOutputs && currentParallel > 0) { - calculateItemOutputs(truncatedItemOutputs); - calculateFluidOutputs(truncatedFluidOutputs); - } - result = CheckRecipeResultRegistry.SUCCESSFUL; - } - - protected void copyInputs() { - ItemStack[] itemInputsToUse; - FluidStack[] fluidInputsToUse; - itemInputsToUse = new ItemStack[itemInputs.length]; - for (int i = 0; i < itemInputs.length; i++) { - itemInputsToUse[i] = itemInputs[i].copy(); - } - fluidInputsToUse = new FluidStack[fluidInputs.length]; - for (int i = 0; i < fluidInputs.length; i++) { - fluidInputsToUse[i] = fluidInputs[i].copy(); - } - itemInputs = itemInputsToUse; - fluidInputs = fluidInputsToUse; - } - - private void calculateItemOutputs(ItemStack[] truncatedItemOutputs) { - if (customItemOutputCalculation != null) { - itemOutputs = customItemOutputCalculation.apply(currentParallel); - return; - } - if (truncatedItemOutputs.length == 0) return; - ArrayList itemOutputsList = new ArrayList<>(); - for (int i = 0; i < truncatedItemOutputs.length; i++) { - if (recipe.getOutput(i) == null) continue; - ItemStack origin = recipe.getOutput(i) - .copy(); - final long itemStackSize = origin.stackSize; - double chancedOutputMultiplier = calculateChancedOutputMultiplier( - (int) (recipe.getOutputChance(i) * chanceMultiplier), - currentParallel); - long items = (long) Math.ceil(itemStackSize * chancedOutputMultiplier * outputMultiplier); - addItemsLong(itemOutputsList, origin, items); - } - itemOutputs = itemOutputsList.toArray(new ItemStack[0]); - } - - private void calculateFluidOutputs(FluidStack[] truncatedFluidOutputs) { - if (customFluidOutputCalculation != null) { - fluidOutputs = customFluidOutputCalculation.apply(currentParallel); - return; - } - if (truncatedFluidOutputs.length == 0) return; - ArrayList fluidOutputsList = new ArrayList<>(); - for (int i = 0; i < truncatedFluidOutputs.length; i++) { - if (recipe.getFluidOutput(i) == null) continue; - FluidStack origin = recipe.getFluidOutput(i) - .copy(); - long fluids = (long) this.outputMultiplier * origin.amount * currentParallel; - - addFluidsLong(fluidOutputsList, origin, fluids); - } - fluidOutputs = fluidOutputsList.toArray(new FluidStack[0]); - } - - private static final Random rand = new Random(); - - public static double calculateChancedOutputMultiplier(int chanceInt, int parallel) { - // Multiply the integer part of the chance directly with parallel - double multiplier = Math.floorDiv(chanceInt, 10000) * parallel; - int transformedChanceInt = chanceInt % 10000; - if (transformedChanceInt == 0) return multiplier; - // Calculation of the Decimal Part of chance - double chance = transformedChanceInt / 10000.0; - double mean = parallel * chance; - double stdDev = Math.sqrt(parallel * chance * (1 - chance)); - // Check if everything within 3 standard deviations of mean is within the range - // of possible values (0 ~ currentParallel) - boolean isSuitableForFittingWithNormalDistribution = mean - 3 * stdDev >= 0 && mean + 3 * stdDev <= parallel; - if (isSuitableForFittingWithNormalDistribution) { - // Use Normal Distribution to fit Binomial Distribution - double tMultiplier = stdDev * rand.nextGaussian() + mean; - multiplier += Math.max(Math.min(tMultiplier, parallel), 0); - } else { - // Do Binomial Distribution by loop - for (int roll = 0; roll < parallel; roll++) { - if (transformedChanceInt > XSTR.XSTR_INSTANCE.nextInt(10000)) { - multiplier += 1; - } - } - } - return multiplier; - } - - public static void addItemsLong(ArrayList itemList, ItemStack origin, long amount) { - if (amount > 0) { - while (amount > Integer.MAX_VALUE) { - ItemStack item = origin.copy(); - item.stackSize = Integer.MAX_VALUE; - itemList.add(item); - amount -= Integer.MAX_VALUE; - } - ItemStack item = origin.copy(); - item.stackSize = (int) amount; - itemList.add(item); - } - } - - public static void addFluidsLong(ArrayList fluidList, FluidStack origin, long amount) { - if (amount > 0) { - while (amount > Integer.MAX_VALUE) { - FluidStack fluid = origin.copy(); - fluid.amount = Integer.MAX_VALUE; - fluidList.add(fluid); - amount -= Integer.MAX_VALUE; - } - FluidStack fluid = origin.copy(); - fluid.amount = (int) amount; - fluidList.add(fluid); - } - } - - @FunctionalInterface - public interface MaxParallelCalculator { - - double calculate(GT_Recipe recipe, int maxParallel, FluidStack[] fluids, ItemStack[] items); - } - - @FunctionalInterface - public interface InputConsumer { - - void consume(GT_Recipe recipe, int amountMultiplier, FluidStack[] aFluidInputs, ItemStack[] aInputs); - } -} diff --git a/src/main/java/gregtech/api/util/GT_PlayedSound.java b/src/main/java/gregtech/api/util/GT_PlayedSound.java deleted file mode 100644 index 8604d9b81f..0000000000 --- a/src/main/java/gregtech/api/util/GT_PlayedSound.java +++ /dev/null @@ -1,31 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.util.ResourceLocation; - -public class GT_PlayedSound { - - public final String mSoundName; - public final int mX, mY, mZ; - - public GT_PlayedSound(ResourceLocation aSoundResourceLocation, double aX, double aY, double aZ) { - mSoundName = aSoundResourceLocation.toString(); - mX = (int) aX; - mY = (int) aY; - mZ = (int) aZ; - } - - @Override - public boolean equals(Object aObject) { - if (aObject instanceof GT_PlayedSound) { - return ((GT_PlayedSound) aObject).mX == mX && ((GT_PlayedSound) aObject).mY == mY - && ((GT_PlayedSound) aObject).mZ == mZ - && ((GT_PlayedSound) aObject).mSoundName.equals(mSoundName); - } - return false; - } - - @Override - public int hashCode() { - return mX + mY + mZ + mSoundName.hashCode(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java b/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java deleted file mode 100644 index ead9393d0e..0000000000 --- a/src/main/java/gregtech/api/util/GT_ProcessingArray_Manager.java +++ /dev/null @@ -1,51 +0,0 @@ -package gregtech.api.util; - -import java.util.HashMap; - -import net.minecraft.item.ItemStack; - -import gregtech.api.enums.SoundResource; -import gregtech.api.recipe.RecipeMap; - -@Deprecated -public class GT_ProcessingArray_Manager { - - private static final HashMap> mRecipeSaves = new HashMap<>(); - private static final HashMap machineSounds = new HashMap<>(); - - // Adds recipe Maps to the PA using the machines unlocalized name. - // Example: basicmachine.electrolyzer, with its recipe map will add the electrolyzer's recipe map to the PA - public static void addRecipeMapToPA(String aMachineName, RecipeMap aMap) { - if (aMachineName != null) { - mRecipeSaves.put(aMachineName, aMap); - } - } - - // Allows the PA to extract the recipe map for the machine inside it. - public static RecipeMap giveRecipeMap(String aMachineName) { - if (aMachineName != null) { - return mRecipeSaves.get(aMachineName); - } - return null; - } - - public static void addSoundResourceToPA(String machineName, SoundResource soundResource) { - if (machineName != null) { - machineSounds.put(machineName, soundResource); - } - } - - public static SoundResource getSoundResource(String machineName) { - if (machineName != null) { - return machineSounds.get(machineName); - } - return null; - } - - public static String getMachineName(ItemStack stack) { - int length = stack.getUnlocalizedName() - .length(); - return stack.getUnlocalizedName() - .substring(17, length - 8); // trim "gt.blockmachines." and ".tier.xx" - } -} diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java deleted file mode 100644 index c0812dcaef..0000000000 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ /dev/null @@ -1,1366 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.D2; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidStack; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer; -import gregtech.GT_Mod; -import gregtech.api.GregTech_API; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.logic.FluidInventoryLogic; -import gregtech.api.logic.ItemInventoryLogic; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Input; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_MultiInput; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.objects.ItemData; -import gregtech.api.recipe.RecipeCategory; -import gregtech.api.recipe.RecipeMap; -import gregtech.api.recipe.RecipeMaps; -import gregtech.api.recipe.RecipeMetadataKey; -import gregtech.api.recipe.metadata.EmptyRecipeMetadataStorage; -import gregtech.api.recipe.metadata.IRecipeMetadataStorage; -import gregtech.api.util.extensions.ArrayExt; -import gregtech.api.util.item.ItemHolder; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_InputBus_ME; -import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Input_ME; -import ic2.core.Ic2Items; -import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import it.unimi.dsi.fastutil.objects.Reference2LongArrayMap; -import it.unimi.dsi.fastutil.objects.Reference2LongMap; -import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; - -public class GT_Recipe implements Comparable { - - private static ItemStack dataStick; - private static ItemStack dataOrb; - private static ItemStack ic2FluidCell; - - public static void setItemStacks() { - ic2FluidCell = Ic2Items.FluidCell.copy(); - dataStick = ItemList.Tool_DataStick.get(1L); - dataOrb = ItemList.Tool_DataOrb.get(1L); - } - - /** - * If you want to change the Output, feel free to modify or even replace the whole ItemStack Array, for Inputs, - * please add a new Recipe, because of the HashMaps. - */ - public ItemStack[] mInputs, mOutputs; - /** - * If you want to change the Output, feel free to modify or even replace the whole ItemStack Array, for Inputs, - * please add a new Recipe, because of the HashMaps. - */ - public FluidStack[] mFluidInputs, mFluidOutputs; - /** - * If you changed the amount of Array-Items inside the Output Array then the length of this Array must be larger or - * equal to the Output Array. A chance of 10000 equals 100% - */ - public int[] mChances; - /** - * An Item that needs to be inside the Special Slot, like for example the Copy Slot inside the Printer. This is only - * useful for Fake Recipes in NEI, since findRecipe() and containsInput() don't give a shit about this Field. Lists - * are also possible. - */ - public Object mSpecialItems; - - public int mDuration, mEUt, mSpecialValue; - /** - * Use this to just disable a specific Recipe, but the Configuration enables that already for every single Recipe. - */ - public boolean mEnabled = true; - /** - * If this Recipe is hidden from NEI - */ - public boolean mHidden = false; - /** - * If this Recipe is Fake and therefore doesn't get found by the findRecipe Function (It is still in the HashMaps, - * so that containsInput does return T on those fake Inputs) - */ - public boolean mFakeRecipe = false; - /** - * If this Recipe can be stored inside a Machine in order to make Recipe searching more Efficient by trying the - * previously used Recipe first. In case you have a Recipe Map overriding things and returning one time use Recipes, - * you have to set this to F. - */ - public boolean mCanBeBuffered = true; - /** - * If this Recipe needs the Output Slots to be completely empty. Needed in case you have randomised Outputs - */ - public boolean mNeedsEmptyOutput = false; - /** - * If this is set to true, NBT equality is required for recipe check. - */ - public boolean isNBTSensitive = false; - /** - * Used for describing recipes that do not fit the default recipe pattern (for example Large Boiler Fuels) - */ - private String[] neiDesc = null; - /** - * Holds a set of metadata for this recipe. - */ - @Nonnull - private final IRecipeMetadataStorage metadataStorage; - /** - * Category this recipe belongs to. Recipes belonging to recipemap are forced to have non-null category when added, - * otherwise it can be null. - */ - private RecipeCategory recipeCategory; - /** - * Stores which mod added this recipe - */ - public List owners = new ArrayList<>(); - /** - * Stores stack traces where this recipe was added - */ - // BW wants to overwrite it, so no final - public List> stackTraces = new ArrayList<>(); - - /** Used for simple cache validation */ - private ItemStack[] inputsAtCacheTime = null; - /** Unified and type-merged stacks of mInputs, each item is guaranteed to be unique */ - private RecipeItemInput[] mergedInputCache = null; - private static final RecipeItemInput[] EMPTY_INPUT_CACHE = new RecipeItemInput[0]; - - /** A single recipe input, used for an internal cache to speed up recipe matching */ - public static final class RecipeItemInput { - - /** Item count is ignored on this stack, do not mutate it either */ - public final ItemStack unifiedStack; - /** Number of input items required */ - public long inputAmount; - /** True if the input is NBT-sensitive */ - public final boolean usesNbtMatching; - - public RecipeItemInput(ItemStack stack, boolean recipeIsNBTSensitive) { - Objects.requireNonNull(stack); - this.inputAmount = stack.stackSize; - final boolean stackNeedsNBT = GT_Recipe.shouldCheckNBT(stack); - this.usesNbtMatching = recipeIsNBTSensitive | stackNeedsNBT; - if (stackNeedsNBT) { - this.unifiedStack = stack; - } else { - this.unifiedStack = GT_OreDictUnificator.get_nocopy(true, stack); - if (!this.usesNbtMatching) { - this.unifiedStack.setTagCompound(null); - } - } - } - - /** - * @return True if the passed in stack is of the same item type as this input (respecting - * {@link RecipeItemInput#usesNbtMatching}). - */ - public boolean matchesType(final ItemStack other) { - return GT_Utility.areStacksEqual(this.unifiedStack, other, !usesNbtMatching); - } - - /** - * @return True if the given input+oredict data for that input can be used as a valid recipe ingredient. - */ - public boolean matchesRecipe(final ItemData oredictOther, final ItemStack other) { - if (usesNbtMatching) { - return GT_Utility.areStacksEqual(this.unifiedStack, other, false); - } else { - return GT_OreDictUnificator.isInputStackEqual(other, oredictOther, unifiedStack); - } - } - } - - private GT_Recipe(GT_Recipe aRecipe, boolean shallow) { - mInputs = shallow ? aRecipe.mInputs : GT_Utility.copyItemArray(aRecipe.mInputs); - mOutputs = shallow ? aRecipe.mOutputs : GT_Utility.copyItemArray(aRecipe.mOutputs); - mSpecialItems = aRecipe.mSpecialItems; - mChances = aRecipe.mChances; - mFluidInputs = shallow ? aRecipe.mFluidInputs : GT_Utility.copyFluidArray(aRecipe.mFluidInputs); - mFluidOutputs = shallow ? aRecipe.mFluidOutputs : GT_Utility.copyFluidArray(aRecipe.mFluidOutputs); - mDuration = aRecipe.mDuration; - mSpecialValue = aRecipe.mSpecialValue; - mEUt = aRecipe.mEUt; - mNeedsEmptyOutput = aRecipe.mNeedsEmptyOutput; - isNBTSensitive = aRecipe.isNBTSensitive; - mCanBeBuffered = aRecipe.mCanBeBuffered; - mFakeRecipe = aRecipe.mFakeRecipe; - mEnabled = aRecipe.mEnabled; - mHidden = aRecipe.mHidden; - metadataStorage = EmptyRecipeMetadataStorage.INSTANCE; - owners = new ArrayList<>(aRecipe.owners); - reloadOwner(); - } - - /** - * Only for {@link GT_RecipeBuilder}. - */ - GT_Recipe(ItemStack[] mInputs, ItemStack[] mOutputs, FluidStack[] mFluidInputs, FluidStack[] mFluidOutputs, - int[] mChances, Object mSpecialItems, int mDuration, int mEUt, int mSpecialValue, boolean mEnabled, - boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, boolean mNeedsEmptyOutput, boolean nbtSensitive, - String[] neiDesc, @Nullable IRecipeMetadataStorage metadataStorage, RecipeCategory recipeCategory) { - this.mInputs = mInputs; - this.mOutputs = mOutputs; - this.mFluidInputs = mFluidInputs; - this.mFluidOutputs = mFluidOutputs; - this.mChances = mChances; - this.mSpecialItems = mSpecialItems; - this.mDuration = mDuration; - this.mEUt = mEUt; - this.mSpecialValue = mSpecialValue; - this.mEnabled = mEnabled; - this.mHidden = mHidden; - this.mFakeRecipe = mFakeRecipe; - this.mCanBeBuffered = mCanBeBuffered; - this.mNeedsEmptyOutput = mNeedsEmptyOutput; - this.isNBTSensitive = nbtSensitive; - this.neiDesc = neiDesc; - this.metadataStorage = metadataStorage == null ? EmptyRecipeMetadataStorage.INSTANCE : metadataStorage.copy(); - this.recipeCategory = recipeCategory; - - reloadOwner(); - } - - public GT_Recipe(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, - FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { - if (aInputs == null) aInputs = new ItemStack[0]; - if (aOutputs == null) aOutputs = new ItemStack[0]; - if (aFluidInputs == null) aFluidInputs = new FluidStack[0]; - if (aFluidOutputs == null) aFluidOutputs = new FluidStack[0]; - if (aChances == null) aChances = new int[aOutputs.length]; - if (aChances.length < aOutputs.length) aChances = Arrays.copyOf(aChances, aOutputs.length); - - aInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new); - aOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new); - aFluidInputs = ArrayExt.withoutNulls(aFluidInputs, FluidStack[]::new); - aFluidOutputs = ArrayExt.withoutNulls(aFluidOutputs, FluidStack[]::new); - - GT_OreDictUnificator.setStackArray(true, aInputs); - GT_OreDictUnificator.setStackArray(true, aOutputs); - - for (ItemStack tStack : aOutputs) GT_Utility.updateItemStack(tStack); - - for (int i = 0; i < aChances.length; i++) if (aChances[i] <= 0) aChances[i] = 10000; - for (int i = 0; i < aFluidInputs.length; i++) aFluidInputs[i] = aFluidInputs[i].copy(); - for (int i = 0; i < aFluidOutputs.length; i++) aFluidOutputs[i] = aFluidOutputs[i].copy(); - - if (aOptimize && aDuration >= 32) { - ArrayList tList = new ArrayList<>(); - tList.addAll(Arrays.asList(aInputs)); - tList.addAll(Arrays.asList(aOutputs)); - for (int i = 0; i < tList.size(); i++) if (tList.get(i) == null) tList.remove(i--); - - for (byte i = (byte) Math.min(64, aDuration / 16); i > 1; i--) if (aDuration / i >= 16) { - boolean temp = true; - for (ItemStack stack : tList) if (stack.stackSize % i != 0) { - temp = false; - break; - } - if (temp) for (FluidStack aFluidInput : aFluidInputs) if (aFluidInput.amount % i != 0) { - temp = false; - break; - } - if (temp) for (FluidStack aFluidOutput : aFluidOutputs) if (aFluidOutput.amount % i != 0) { - temp = false; - break; - } - if (temp) { - for (ItemStack itemStack : tList) itemStack.stackSize /= i; - for (FluidStack aFluidInput : aFluidInputs) aFluidInput.amount /= i; - for (FluidStack aFluidOutput : aFluidOutputs) aFluidOutput.amount /= i; - aDuration /= i; - } - } - } - - mInputs = aInputs; - mOutputs = aOutputs; - mSpecialItems = aSpecialItems; - mChances = aChances; - mFluidInputs = aFluidInputs; - mFluidOutputs = aFluidOutputs; - mDuration = aDuration; - mSpecialValue = aSpecialValue; - mEUt = aEUt; - metadataStorage = EmptyRecipeMetadataStorage.INSTANCE; - // checkCellBalance(); - reloadOwner(); - } - - // aSpecialValue = EU per Liter! If there is no Liquid for this Object, then it gets multiplied with 1000! - public GT_Recipe(ItemStack aInput1, ItemStack aOutput1, ItemStack aOutput2, ItemStack aOutput3, ItemStack aOutput4, - int aSpecialValue, int aType) { - this( - true, - new ItemStack[] { aInput1 }, - new ItemStack[] { aOutput1, aOutput2, aOutput3, aOutput4 }, - null, - null, - null, - null, - 0, - 0, - Math.max(1, aSpecialValue)); - - if (mInputs.length > 0 && aSpecialValue > 0) { - switch (aType) { - // Diesel Generator - case 0 -> { - RecipeMaps.dieselFuels.addRecipe(this); - RecipeMaps.largeBoilerFakeFuels.getBackend() - .addDieselRecipe(this); - } - // Gas Turbine - case 1 -> RecipeMaps.gasTurbineFuels.addRecipe(this); - - // Thermal Generator - case 2 -> RecipeMaps.hotFuels.addRecipe(this); - - // Plasma Generator - case 4 -> RecipeMaps.plasmaFuels.addRecipe(this); - - // Magic Generator - case 5 -> RecipeMaps.magicFuels.addRecipe(this); - - // Fluid Generator. Usually 3. Every wrong Type ends up in the Semifluid Generator - default -> { - RecipeMaps.denseLiquidFuels.addRecipe(this); - RecipeMaps.largeBoilerFakeFuels.getBackend() - .addDenseLiquidRecipe(this); - } - } - } - } - - // Dummy GT_Recipe maker... - public GT_Recipe(ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, int[] aChances, - FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, int aSpecialValue) { - this( - true, - aInputs, - aOutputs, - aSpecialItems, - aChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue); - } - - /** - * Re-unificates all the items present in recipes. - */ - public static void reInit() { - GT_Log.out.println("GT_Mod: Re-Unificating Recipes."); - for (RecipeMap map : RecipeMap.ALL_RECIPE_MAPS.values()) { - map.getBackend() - .reInit(); - } - } - - public ItemStack getRepresentativeInput(int aIndex) { - if (aIndex < 0 || aIndex >= mInputs.length) return null; - return GT_Utility.copyOrNull(mInputs[aIndex]); - } - - public ItemStack getOutput(int aIndex) { - if (aIndex < 0 || aIndex >= mOutputs.length) return null; - return GT_Utility.copyOrNull(mOutputs[aIndex]); - } - - /** - * Dictates the ItemStacks displayed in the output slots of any NEI page handled by the default GT NEI handler. - * Override to make shown items differ from a GT_Recipe's item output array - * - * @see gregtech.nei.GT_NEI_DefaultHandler - * @param i Slot index - * @return ItemStack to be displayed in the slot - */ - public ItemStack getRepresentativeOutput(int i) { - return getOutput(i); - } - - public int getOutputChance(int aIndex) { - if (mChances == null) return 10000; - if (aIndex < 0 || aIndex >= mChances.length) return 10000; - return mChances[aIndex]; - } - - public FluidStack getRepresentativeFluidInput(int aIndex) { - if (aIndex < 0 || aIndex >= mFluidInputs.length || mFluidInputs[aIndex] == null) return null; - return mFluidInputs[aIndex].copy(); - } - - public FluidStack getFluidOutput(int aIndex) { - if (aIndex < 0 || aIndex >= mFluidOutputs.length || mFluidOutputs[aIndex] == null) return null; - return mFluidOutputs[aIndex].copy(); - } - - public void checkCellBalance() { - if (!D2 || mInputs.length < 1) return; - - int tInputAmount = GT_ModHandler.getCapsuleCellContainerCountMultipliedWithStackSize(mInputs); - int tOutputAmount = GT_ModHandler.getCapsuleCellContainerCountMultipliedWithStackSize(mOutputs); - - if (tInputAmount < tOutputAmount) { - if (!Materials.Tin.contains(mInputs)) { - GT_Log.err.println("You get more Cells, than you put in? There must be something wrong."); - new Exception().printStackTrace(GT_Log.err); - } - } else if (tInputAmount > tOutputAmount) { - if (!Materials.Tin.contains(mOutputs)) { - GT_Log.err.println("You get less Cells, than you put in? GT Machines usually don't destroy Cells."); - new Exception().printStackTrace(GT_Log.err); - } - } - } - - public GT_Recipe copy() { - return new GT_Recipe(this, false); - } - - public GT_Recipe copyShallow() { - return new GT_Recipe(this, true); - } - - public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, FluidStack[] aFluidInputs, - ItemStack... aInputs) { - return isRecipeInputEqual(aDecreaseStacksizeBySuccess, false, 1, aFluidInputs, aInputs); - } - - // For non-multiplied recipe amount values - public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes, - FluidStack[] aFluidInputs, ItemStack... aInputs) { - return isRecipeInputEqual(aDecreaseStacksizeBySuccess, aDontCheckStackSizes, 1, aFluidInputs, aInputs); - } - - /** - * Okay, did some code archeology to figure out what's going on here. - * - *

- * This variable was added in this - * commit, in order to fix the issues mentioned in the PR. - * - *

- * It looks like it controls checking NBT. At this point, since we are still using universal fluid cells which store - * their fluids in NBT, it probably will not be safe to disable the NBT checks in the near future. Data sticks may - * be another case. Anyway, we probably can't get rid of this without some significant changes to clean up recipe - * inputs. - */ - public static boolean GTppRecipeHelper; - - /** - * @return Computes a (cached) array of all input items, combined by type into stacks. Do not mutate. - */ - private @NotNull RecipeItemInput @NotNull [] getCachedCombinedItemInputs() { - if (mergedInputCache != null) { - if (mInputs != inputsAtCacheTime) { - throw new IllegalStateException( - "Inputs to this recipe have been modified since first recipe match: " + this); - } - return mergedInputCache; - } - - synchronized (this) { - // In case another thread initialized it while this synchronized block was locked: - if (mergedInputCache != null) { - if (mInputs != inputsAtCacheTime) { - throw new IllegalStateException( - "Inputs to this recipe have been modified since first recipe match: " + this); - } - return mergedInputCache; - } - - final ItemStack[] inputs = mInputs; - inputsAtCacheTime = inputs; - if (inputs == null || inputs.length == 0) { - mergedInputCache = EMPTY_INPUT_CACHE; - return mergedInputCache; - } - final ObjectArrayList<@NotNull RecipeItemInput> newCache = ObjectArrayList - .wrap(new RecipeItemInput[inputs.length], 0); - for (final ItemStack itemStack : inputs) { - if (itemStack == null) continue; - final RecipeItemInput existingInput = newCache.stream() - .filter(existing -> existing.matchesType(itemStack)) - .findAny() - .orElse(null); - if (existingInput == null) { - newCache.add(new RecipeItemInput(itemStack, isNBTSensitive)); - } else { - existingInput.inputAmount = Math.addExact(existingInput.inputAmount, itemStack.stackSize); - } - } - final RecipeItemInput[] frozenCache = newCache.toArray(new RecipeItemInput[0]); - if (GregTech_API.sFullLoadFinished) { - mergedInputCache = frozenCache; - } - return frozenCache; - } - } - - /** - * WARNING: Do not call this method with both {@code aDecreaseStacksizeBySuccess} and {@code aDontCheckStackSizes} - * set to {@code true}! You'll get weird behavior. - */ - public boolean isRecipeInputEqual(boolean aDecreaseStacksizeBySuccess, boolean aDontCheckStackSizes, - int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) { - double maxParallel = maxParallelCalculatedByInputs(amountMultiplier, aFluidInputs, aInputs); - if (aDontCheckStackSizes) { - return maxParallel > 0; - } else if (maxParallel >= amountMultiplier) { - if (aDecreaseStacksizeBySuccess) { - consumeInput(amountMultiplier, aFluidInputs, aInputs); - } - return true; - } - return false; - } - - /** - * WARNING: Ensure that item inputs and fluid inputs are enough to be consumed with - * {@link #maxParallelCalculatedByInputs} before calling this method! - */ - public void consumeInput(int amountMultiplier, FluidStack[] aFluidInputs, ItemStack... aInputs) { - if (amountMultiplier <= 0) return; - - if (aFluidInputs != null) { - for (FluidStack recipeFluidCost : mFluidInputs) { - if (recipeFluidCost != null) { - long remainingCost = (long) recipeFluidCost.amount * amountMultiplier; - - for (FluidStack providedFluid : aFluidInputs) { - if (providedFluid != null && providedFluid.isFluidEqual(recipeFluidCost)) { - if (providedFluid.amount >= remainingCost) { - providedFluid.amount -= remainingCost; - break; - } else { - remainingCost -= providedFluid.amount; - providedFluid.amount = 0; - } - } - } - } - } - } - - if (aInputs == null || aInputs.length == 0) { - return; - } - - final ItemData[] unifiedProvidedInputs = new ItemData[aInputs.length]; - for (int i = 0; i < aInputs.length; i++) { - unifiedProvidedInputs[i] = GT_OreDictUnificator.getAssociation(aInputs[i]); - } - final @NotNull RecipeItemInput @NotNull [] combinedInputs = getCachedCombinedItemInputs(); - - for (final RecipeItemInput recipeItemCost : combinedInputs) { - long remainingCost = recipeItemCost.inputAmount * amountMultiplier; - - for (int iProvided = 0; iProvided < aInputs.length && remainingCost > 0; iProvided++) { - final ItemStack providedItem = aInputs[iProvided]; - if (providedItem == null || providedItem.stackSize == 0) { - continue; - } - - final ItemData providedUnifiedItem = unifiedProvidedInputs[iProvided]; - if (!recipeItemCost.matchesRecipe(providedUnifiedItem, providedItem)) { - continue; - } - - if (providedItem.stackSize >= remainingCost) { - providedItem.stackSize -= (int) remainingCost; - break; - } else { - remainingCost -= providedItem.stackSize; - providedItem.stackSize = 0; - } - } - } - } - - /** - * Returns the number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that inputs - * are found but not enough. - */ - public double maxParallelCalculatedByInputs(int maxParallel, FluidStack[] aFluidInputs, ItemStack... aInputs) { - if (mInputs.length > 0 && aInputs == null) return 0; - if (mFluidInputs.length > 0 && aFluidInputs == null) return 0; - - double currentParallel = maxParallel; - - // We need to have any fluids inputs, otherwise the code below does nothing. The second check is always true - // because of early exit condition above. - if (mFluidInputs.length > 0 /* && aFluidInputs != null */) { - // Create map for fluid -> stored amount - Reference2LongMap fluidMap = new Reference2LongArrayMap<>(2); - Reference2LongMap fluidCost = new Reference2LongArrayMap<>(2); - for (FluidStack fluidStack : aFluidInputs) { - if (fluidStack == null) continue; - fluidMap.mergeLong(fluidStack.getFluid(), fluidStack.amount, Long::sum); - } - for (FluidStack fluidStack : mFluidInputs) { - if (fluidStack == null) continue; - fluidCost.mergeLong(fluidStack.getFluid(), fluidStack.amount, Long::sum); - } - - // Check how many parallels can it perform for each fluid - for (Reference2LongMap.Entry costEntry : fluidCost.reference2LongEntrySet()) { - if (costEntry.getLongValue() > 0) { - currentParallel = Math.min( - currentParallel, - (double) fluidMap.getOrDefault(costEntry.getKey(), 0L) / costEntry.getLongValue()); - } - if (currentParallel <= 0) { - return 0; - } - } - } - - if (mInputs.length > 0) { - final @NotNull RecipeItemInput @NotNull [] combinedInputs = getCachedCombinedItemInputs(); - - if (aInputs.length < combinedInputs.length) { - // Fewer item types provided than required by the recipe, making it impossible to satisfy. - return 0; - } - final ItemData[] unifiedProvidedInputs = new ItemData[aInputs.length]; - for (int i = 0; i < aInputs.length; i++) { - unifiedProvidedInputs[i] = GT_OreDictUnificator.getAssociation(aInputs[i]); - } - - recipeItemLoop: for (final RecipeItemInput combinedInput : combinedInputs) { - double remainingCost = combinedInput.inputAmount * currentParallel; - long providedAmount = 0; - - for (int i = 0; i < unifiedProvidedInputs.length; i++) { - final ItemData providedUnifiedItem = unifiedProvidedInputs[i]; - final ItemStack providedItem = aInputs[i]; - if (!combinedInput.matchesRecipe(providedUnifiedItem, providedItem)) { - continue; - } - - providedAmount += providedItem.stackSize; - - if (providedAmount >= remainingCost) { - continue recipeItemLoop; - } - } - if (providedAmount == 0) { - return 0; - } - currentParallel = Math.min(currentParallel, (double) providedAmount / combinedInput.inputAmount); - } - } - return currentParallel; - } - - /** - * Please see JavaDoc on {@link #GTppRecipeHelper} for why this is here. - */ - private static boolean shouldCheckNBT(ItemStack item) { - if (GTppRecipeHelper) { - return GT_Utility.areStacksEqual(item, ic2FluidCell, true) - || GT_Utility.areStacksEqual(item, dataStick, true) - || GT_Utility.areStacksEqual(item, dataOrb, true); - } - return false; - } - - public boolean isRecipePossible(@Nullable ItemInventoryLogic itemInput, @Nullable FluidInventoryLogic fluidInput) { - return getAmountOfRecipesDone(itemInput, fluidInput, 1, true) > 0; - } - - public long getAmountOfRecipesDone(@Nullable ItemInventoryLogic itemInput, @Nullable FluidInventoryLogic fluidInput, - long maxParallel, boolean simulate) { - if (itemInput == null) { - itemInput = new ItemInventoryLogic(0); - } - - if (fluidInput == null) { - fluidInput = new FluidInventoryLogic(0, 0); - } - - itemInput.startRecipeCheck(); - Map recipeItems = getItemInputsAsItemMap(); - for (Entry entry : recipeItems.entrySet()) { - maxParallel = Math - .min(maxParallel, itemInput.calculateAmountOfTimesItemCanBeTaken(entry.getKey(), entry.getValue())); - } - - for (FluidStack fluid : mFluidInputs) { - if (fluid == null) continue; - maxParallel = Math - .min(maxParallel, fluidInput.calculateAmountOfTimesFluidCanBeTaken(fluid.getFluid(), fluid.amount)); - } - - if (simulate) { - itemInput.stopRecipeCheck(); - return maxParallel; - } - - for (Entry entry : recipeItems.entrySet()) { - itemInput.subtractItemAmount(entry.getKey(), entry.getValue() * maxParallel, false); - } - - for (FluidStack fluid : mFluidInputs) { - if (fluid == null) continue; - fluidInput.drain(fluid.getFluid(), fluid.amount * maxParallel, false); - } - itemInput.stopRecipeCheck(); - return maxParallel; - } - - private Map getItemInputsAsItemMap() { - Map items = new HashMap<>(); - for (ItemStack item : mInputs) { - if (item == null) continue; - ItemHolder itemHolder = new ItemHolder(item); - items.put(itemHolder, items.getOrDefault(itemHolder, 0L) + item.stackSize); - } - return items; - } - - @Override - public int compareTo(GT_Recipe recipe) { - // first lowest tier recipes - // then fastest - // then with lowest special value - // then dry recipes - // then with fewer inputs - if (this.mEUt != recipe.mEUt) { - return Integer.compare(this.mEUt, recipe.mEUt); - } else if (this.mDuration != recipe.mDuration) { - return Integer.compare(this.mDuration, recipe.mDuration); - } else if (this.mSpecialValue != recipe.mSpecialValue) { - return Integer.compare(this.mSpecialValue, recipe.mSpecialValue); - } else if (this.mFluidInputs.length != recipe.mFluidInputs.length) { - return Integer.compare(this.mFluidInputs.length, recipe.mFluidInputs.length); - } else if (this.mInputs.length != recipe.mInputs.length) { - return Integer.compare(this.mInputs.length, recipe.mInputs.length); - } - return 0; - } - - public String[] getNeiDesc() { - return neiDesc; - } - - /** - * Sets description shown on NEI.
- * If you have a large number of recipes for the recipemap, this is not efficient memory wise, so use - * {@link gregtech.api.recipe.RecipeMapBuilder#neiSpecialInfoFormatter} instead. - */ - public void setNeiDesc(String... neiDesc) { - this.neiDesc = neiDesc; - } - - // region metadata - - // Don't try implementing setMetadata, as metadataStorage can be EmptyRecipeMetadataStorage - - /** - * Gets metadata associated with this recipe. Can return null. Use - * {@link #getMetadataOrDefault(RecipeMetadataKey, Object)} - * if you want to specify default value. - */ - @Nullable - public T getMetadata(RecipeMetadataKey key) { - return key.cast(metadataStorage.getMetadata(key)); - } - - /** - * Gets metadata associated with this recipe with default value. Does not return null unless default value is null. - */ - @Contract("_, !null -> !null") - @Nullable - public T getMetadataOrDefault(RecipeMetadataKey key, @Nullable T defaultValue) { - return key.cast(metadataStorage.getMetadataOrDefault(key, defaultValue)); - } - - @Nonnull - public IRecipeMetadataStorage getMetadataStorage() { - return metadataStorage; - } - - // endregion - - public RecipeCategory getRecipeCategory() { - return recipeCategory; - } - - /** - * Exists only for recipe copying from external. For ordinal use case, use {@link GT_RecipeBuilder#recipeCategory}. - */ - public void setRecipeCategory(RecipeCategory recipeCategory) { - this.recipeCategory = recipeCategory; - } - - private static final List excludedStacktraces = Arrays.asList( - "java.lang.Thread", - "gregtech.api.interfaces.IRecipeMap", - "gregtech.api.interfaces.IRecipeMap$1", - "gregtech.api.recipe.RecipeMap", - "gregtech.api.recipe.RecipeMapBackend", - "gregtech.api.recipe.RecipeMapBackendPropertiesBuilder", - "gregtech.api.util.GT_Recipe", - "gregtech.api.util.GT_RecipeBuilder", - "gregtech.api.util.GT_RecipeConstants", - "gregtech.api.util.GT_RecipeMapUtil", - "gregtech.common.GT_RecipeAdder"); - - public void reloadOwner() { - setOwner( - Loader.instance() - .activeModContainer()); - - if (GT_Mod.gregtechproxy.mNEIRecipeOwnerStackTrace) { - List toAdd = new ArrayList<>(); - for (StackTraceElement stackTrace : Thread.currentThread() - .getStackTrace()) { - if (excludedStacktraces.stream() - .noneMatch( - c -> stackTrace.getClassName() - .equals(c))) { - toAdd.add(formatStackTrace(stackTrace)); - } - } - stackTraces.add(toAdd); - } - } - - private static String formatStackTrace(StackTraceElement stackTraceElement) { - String raw = stackTraceElement.toString(); - int startParen = raw.lastIndexOf('('); - int colon = raw.lastIndexOf(':'); - if (colon == -1) { - // native or unknown source - return raw; - } - // strip class name and leave line number, as class name is already shown - return raw.substring(0, startParen + 1) + raw.substring(colon); - } - - public void setOwner(ModContainer newOwner) { - ModContainer oldOwner = !owners.isEmpty() ? this.owners.get(owners.size() - 1) : null; - if (newOwner != null && newOwner != oldOwner) { - owners.add(newOwner); - } - } - - /** - * Use in case {@link Loader#activeModContainer()} isn't helpful - */ - public void setOwner(String modId) { - for (ModContainer mod : Loader.instance() - .getModList()) { - if (mod.getModId() - .equals(modId)) { - setOwner(mod); - return; - } - } - } - - public GT_Recipe setInputs(ItemStack... aInputs) { - // TODO determine if we need this without trailing nulls call - this.mInputs = ArrayExt.withoutTrailingNulls(aInputs, ItemStack[]::new); - return this; - } - - public GT_Recipe setOutputs(ItemStack... aOutputs) { - this.mOutputs = ArrayExt.withoutTrailingNulls(aOutputs, ItemStack[]::new); - return this; - } - - public GT_Recipe setFluidInputs(FluidStack... aInputs) { - this.mFluidInputs = ArrayExt.withoutTrailingNulls(aInputs, FluidStack[]::new); - return this; - } - - public GT_Recipe setFluidOutputs(FluidStack... aOutputs) { - this.mFluidOutputs = ArrayExt.withoutTrailingNulls(aOutputs, FluidStack[]::new); - return this; - } - - public GT_Recipe setDuration(int aDuration) { - this.mDuration = aDuration; - return this; - } - - public GT_Recipe setEUt(int aEUt) { - this.mEUt = aEUt; - return this; - } - - public static class GT_Recipe_AssemblyLine { - - public static final ArrayList sAssemblylineRecipes = new ArrayList<>(); - - static { - if (!Boolean.getBoolean("com.gtnh.gt5u.ignore-invalid-assline-recipe")) - GregTech_API.sFirstWorldTick.add(GT_Recipe_AssemblyLine::checkInvalidRecipes); - else GT_Log.out.println("NOT CHECKING INVALID ASSLINE RECIPE."); - } - - private static void checkInvalidRecipes() { - int invalidCount = 0; - GT_Log.out.println("Started assline validation"); - for (GT_Recipe_AssemblyLine recipe : sAssemblylineRecipes) { - if (recipe.getPersistentHash() == 0) { - invalidCount++; - GT_Log.err.printf("Invalid recipe: %s%n", recipe); - } - } - if (invalidCount > 0) throw new RuntimeException( - "There are " + invalidCount + " invalid assembly line recipe(s)! Check GregTech.log for details!"); - } - - public ItemStack mResearchItem; - public int mResearchTime; - public ItemStack[] mInputs; - public FluidStack[] mFluidInputs; - public ItemStack mOutput; - public int mDuration; - public int mEUt; - public ItemStack[][] mOreDictAlt; - private int mPersistentHash; - - /** - * THIS CONSTRUCTOR DOES SET THE PERSISTENT HASH. - *

- * if you set one yourself, it will give you one of the RunetimeExceptions! - */ - public GT_Recipe_AssemblyLine(ItemStack aResearchItem, int aResearchTime, ItemStack[] aInputs, - FluidStack[] aFluidInputs, ItemStack aOutput, int aDuration, int aEUt) { - this( - aResearchItem, - aResearchTime, - aInputs, - aFluidInputs, - aOutput, - aDuration, - aEUt, - new ItemStack[aInputs.length][]); - int tPersistentHash = 1; - for (ItemStack tInput : aInputs) - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(tInput, true, false); - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(aResearchItem, true, false); - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(aOutput, true, false); - for (FluidStack tFluidInput : aFluidInputs) - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(tFluidInput, true, false); - tPersistentHash = tPersistentHash * 31 + aResearchTime; - tPersistentHash = tPersistentHash * 31 + aDuration; - tPersistentHash = tPersistentHash * 31 + aEUt; - setPersistentHash(tPersistentHash); - } - - /** - * THIS CONSTRUCTOR DOES NOT SET THE PERSISTENT HASH. - *

- * if you don't set one yourself, it will break a lot of stuff! - */ - public GT_Recipe_AssemblyLine(ItemStack aResearchItem, int aResearchTime, ItemStack[] aInputs, - FluidStack[] aFluidInputs, ItemStack aOutput, int aDuration, int aEUt, ItemStack[][] aAlt) { - mResearchItem = aResearchItem; - mResearchTime = aResearchTime; - mInputs = aInputs; - mFluidInputs = aFluidInputs; - mOutput = aOutput; - mDuration = aDuration; - mEUt = aEUt; - mOreDictAlt = aAlt; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - GT_ItemStack[] thisInputs = new GT_ItemStack[this.mInputs.length]; - int totalInputStackSize = 0; - for (int i = 0; i < this.mInputs.length; i++) { - thisInputs[i] = new GT_ItemStack(this.mInputs[i]); - totalInputStackSize += thisInputs[i].mStackSize; - } - int inputHash = Arrays.deepHashCode(thisInputs); - int inputFluidHash = Arrays.deepHashCode(this.mFluidInputs); - GT_ItemStack thisOutput = new GT_ItemStack(mOutput); - GT_ItemStack thisResearch = new GT_ItemStack(mResearchItem); - int miscRecipeDataHash = Arrays.deepHashCode( - new Object[] { totalInputStackSize, mDuration, mEUt, thisOutput, thisResearch, mResearchTime }); - result = prime * result + inputFluidHash; - result = prime * result + inputHash; - result = prime * result + miscRecipeDataHash; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof GT_Recipe_AssemblyLine other)) { - return false; - } - if (this.mInputs.length != other.mInputs.length) { - return false; - } - if (this.mFluidInputs.length != other.mFluidInputs.length) { - return false; - } - // Check Outputs Match - GT_ItemStack output1 = new GT_ItemStack(this.mOutput); - GT_ItemStack output2 = new GT_ItemStack(other.mOutput); - if (!output1.equals(output2)) { - return false; - } - // Check Scanned Item Match - GT_ItemStack scan1 = new GT_ItemStack(this.mResearchItem); - GT_ItemStack scan2 = new GT_ItemStack(other.mResearchItem); - if (!scan1.equals(scan2)) { - return false; - } - // Check Items Match - GT_ItemStack[] thisInputs = new GT_ItemStack[this.mInputs.length]; - GT_ItemStack[] otherInputs = new GT_ItemStack[other.mInputs.length]; - for (int i = 0; i < thisInputs.length; i++) { - thisInputs[i] = new GT_ItemStack(this.mInputs[i]); - otherInputs[i] = new GT_ItemStack(other.mInputs[i]); - } - for (int i = 0; i < thisInputs.length; i++) { - if (!thisInputs[i].equals(otherInputs[i]) || thisInputs[i].mStackSize != otherInputs[i].mStackSize) { - return false; - } - } - // Check Fluids Match - for (int i = 0; i < this.mFluidInputs.length; i++) { - if (!this.mFluidInputs[i].isFluidStackIdentical(other.mFluidInputs[i])) { - return false; - } - } - - return this.mDuration == other.mDuration && this.mEUt == other.mEUt - && this.mResearchTime == other.mResearchTime; - } - - public int getPersistentHash() { - if (mPersistentHash == 0) - GT_Log.err.println("Assline recipe persistent hash has not been set! Recipe: " + mOutput); - return mPersistentHash; - } - - @Override - public String toString() { - return "GT_Recipe_AssemblyLine{" + "mResearchItem=" - + mResearchItem - + ", mResearchTime=" - + mResearchTime - + ", mInputs=" - + Arrays.toString(mInputs) - + ", mFluidInputs=" - + Arrays.toString(mFluidInputs) - + ", mOutput=" - + mOutput - + ", mDuration=" - + mDuration - + ", mEUt=" - + mEUt - + ", mOreDictAlt=" - + Arrays.toString(mOreDictAlt) - + '}'; - } - - /** - * @param aPersistentHash the persistent hash. it should reflect the exact input used to generate this recipe If - * 0 is passed in, the actual persistent hash will be automatically remapped to 1 - * instead. - * @throws IllegalStateException if the persistent hash has been set already - */ - public void setPersistentHash(int aPersistentHash) { - if (this.mPersistentHash != 0) throw new IllegalStateException("Cannot set persistent hash twice!"); - if (aPersistentHash == 0) this.mPersistentHash = 1; - else this.mPersistentHash = aPersistentHash; - } - - /** - * @param inputBusses List of input busses to check. - * @return An array containing the amount of item to consume from the first slot of every input bus. - * {@code null} if at least one item fails to match the recipe ingredient. - */ - public static int[] getItemConsumptionAmountArray(ArrayList inputBusses, - GT_Recipe_AssemblyLine recipe) { - int itemCount = recipe.mInputs.length; - if (itemCount == 0) return null; - int[] tStacks = new int[itemCount]; - for (int i = 0; i < itemCount; i++) { - GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); - if (!inputBus.isValid()) return null; - ItemStack slotStack; - if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { - slotStack = meBus.getShadowItemStack(0); - } else { - slotStack = inputBus.getStackInSlot(0); - } - if (slotStack == null) return null; - - int amount = getMatchedIngredientAmount(slotStack, recipe.mInputs[i], recipe.mOreDictAlt[i]); - if (amount < 0) return null; - - tStacks[i] = amount; - } - return tStacks; - } - - public static int getMatchedIngredientAmount(ItemStack aSlotStack, ItemStack aIngredient, ItemStack[] alts) { - if (alts == null || alts.length == 0) { - if (GT_Utility.areStacksEqual(aSlotStack, aIngredient, true)) { - return aIngredient.stackSize; - } - return -1; - } - for (ItemStack tAltStack : alts) { - if (GT_Utility.areStacksEqual(aSlotStack, tAltStack, true)) { - return tAltStack.stackSize; - } - } - return -1; - } - - /** - * @param inputBusses Input bus list to check. Usually the input bus list of multi. - * @param itemConsumptions Should be generated by {@link GT_Recipe_AssemblyLine#getItemConsumptionAmountArray}. - * @Return The number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that - * inputs are found but not enough. - */ - public static double maxParallelCalculatedByInputItems(ArrayList inputBusses, - int maxParallel, int[] itemConsumptions, Map inputsFromME) { - // Recipe item matching is done in the generation of itemConsumptions. - - Map itemConsumptionsFromME = new Object2LongOpenHashMap<>(); - double currentParallel = maxParallel; - - // Calculate the amount of each item to consume from ME - for (int i = 0; i < itemConsumptions.length; i++) { - GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); - if (!inputBus.isValid()) return 0; - if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { - ItemStack item = meBus.getShadowItemStack(0); - if (item == null) return 0; - GT_Utility.ItemId id = GT_Utility.ItemId.createNoCopy(item); - itemConsumptionsFromME.merge(id, (long) itemConsumptions[i], Long::sum); - } - } - // Calculate parallel from ME input busses - for (Entry entry : itemConsumptionsFromME.entrySet()) { - if (!inputsFromME.containsKey(entry.getKey())) return 0; - long consume = entry.getValue(); - // For non-consumed inputs - if (consume == 0) continue; - currentParallel = Math - .min(currentParallel, (double) inputsFromME.get(entry.getKey()).stackSize / consume); - if (currentParallel <= 0) return 0; - } - - // Calculate parallel from regular input busses - for (int i = 0; i < itemConsumptions.length; i++) { - GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); - if (!inputBus.isValid()) return 0; - if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME) continue; - - ItemStack item = inputBus.getStackInSlot(0); - if (item == null) return 0; - // For non-consumed inputs - if (itemConsumptions[i] == 0) continue; - currentParallel = Math.min(currentParallel, (double) item.stackSize / itemConsumptions[i]); - if (currentParallel <= 0) return 0; - } - return currentParallel; - } - - /** - * @param inputHatches Input hatch list to check. Usually the input hatch list of multi. - * @param fluidConsumptions Fluid inputs of the recipe. - * @return The number of parallel recipes, or 0 if recipe is not satisfied at all. 0 < number < 1 means that - * fluids are found but not enough. - */ - public static double maxParallelCalculatedByInputFluids(ArrayList inputHatches, - int maxParallel, FluidStack[] fluidConsumptions, Map fluidsFromME) { - Map fluidConsumptionsFromME = new Reference2LongOpenHashMap<>(); - double currentParallel = maxParallel; - - // Calculate the amount of each fluid to consume from ME - for (int i = 0; i < fluidConsumptions.length; i++) { - GT_MetaTileEntity_Hatch_Input inputHatch = inputHatches.get(i); - if (!inputHatch.isValid()) return 0; - if (inputHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { - FluidStack fluid = meHatch.getShadowFluidStack(0); - if (fluid == null) return 0; - if (!GT_Utility.areFluidsEqual(fluid, fluidConsumptions[i])) return 0; - fluidConsumptionsFromME.merge(fluid.getFluid(), (long) fluidConsumptions[i].amount, Long::sum); - } - } - // Calculate parallel from ME input hatches - for (Entry entry : fluidConsumptionsFromME.entrySet()) { - Fluid fluid = entry.getKey(); - if (!fluidsFromME.containsKey(fluid)) return 0; - long consume = entry.getValue(); - currentParallel = Math.min(currentParallel, (double) fluidsFromME.get(fluid).amount / consume); - if (currentParallel <= 0) return 0; - } - - // Calculate parallel from regular input hatches - for (int i = 0; i < fluidConsumptions.length; i++) { - GT_MetaTileEntity_Hatch_Input inputHatch = inputHatches.get(i); - if (!inputHatch.isValid()) return 0; - if (inputHatch instanceof GT_MetaTileEntity_Hatch_Input_ME) continue; - - FluidStack fluid; - if (inputHatch instanceof GT_MetaTileEntity_Hatch_MultiInput multiInput) { - fluid = multiInput.getFluid(0); - } else { - fluid = inputHatch.getFillableStack(); - } - if (fluid == null) return 0; - if (!GT_Utility.areFluidsEqual(fluid, fluidConsumptions[i])) return 0; - currentParallel = Math.min(currentParallel, (double) fluid.amount / fluidConsumptions[i].amount); - if (currentParallel <= 0) return 0; - } - return currentParallel; - } - - /** - * WARNING: Ensure that item inputs are enough to be consumed with - * {@link GT_Recipe_AssemblyLine#maxParallelCalculatedByInputItems} before calling this method! - * - * @param inputBusses Input bus list to check. Usually the input bus list of multi. - * @param itemConsumptions Should be generated by {@link GT_Recipe_AssemblyLine#getItemConsumptionAmountArray}. - */ - public static void consumeInputItems(ArrayList inputBusses, - int amountMultiplier, int[] itemConsumptions, Map inputsFromME) { - for (int i = 0; i < itemConsumptions.length; i++) { - GT_MetaTileEntity_Hatch_InputBus inputBus = inputBusses.get(i); - if (!inputBus.isValid()) continue; - ItemStack item; - if (inputBus instanceof GT_MetaTileEntity_Hatch_InputBus_ME meBus) { - item = inputsFromME.get(GT_Utility.ItemId.createNoCopy(meBus.getShadowItemStack(0))); - } else { - item = inputBus.getStackInSlot(0); - } - item.stackSize -= itemConsumptions[i] * amountMultiplier; - } - } - - /** - * WARNING: Ensure that fluid inputs are enough to be consumed with - * {@link GT_Recipe_AssemblyLine#maxParallelCalculatedByInputFluids} before calling this method! - * - * @param inputHatches Input hatch list to check. Usually the input hatch list of multi. - * @param fluidConsumptions Fluid inputs of the recipe. - */ - public static void consumeInputFluids(ArrayList inputHatches, - int amountMultiplier, FluidStack[] fluidConsumptions, Map fluidsFromME) { - for (int i = 0; i < fluidConsumptions.length; i++) { - GT_MetaTileEntity_Hatch_Input inputHatch = inputHatches.get(i); - if (!inputHatch.isValid()) continue; - FluidStack fluid; - if (inputHatch instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) { - fluid = fluidsFromME.get( - meHatch.getShadowFluidStack(0) - .getFluid()); - } else if (inputHatch instanceof GT_MetaTileEntity_Hatch_MultiInput multiInput) { - fluid = multiInput.getFluid(0); - } else { - fluid = inputHatch.getFillableStack(); - } - fluid.amount -= fluidConsumptions[i].amount * amountMultiplier; - } - } - } - - public static class GT_Recipe_WithAlt extends GT_Recipe { - - public ItemStack[][] mOreDictAlt; - - /** - * Only for {@link GT_RecipeBuilder}. - */ - GT_Recipe_WithAlt(ItemStack[] mInputs, ItemStack[] mOutputs, FluidStack[] mFluidInputs, - FluidStack[] mFluidOutputs, int[] mChances, Object mSpecialItems, int mDuration, int mEUt, - int mSpecialValue, boolean mEnabled, boolean mHidden, boolean mFakeRecipe, boolean mCanBeBuffered, - boolean mNeedsEmptyOutput, boolean nbtSensitive, String[] neiDesc, - @Nullable IRecipeMetadataStorage metadataStorage, RecipeCategory recipeCategory, - ItemStack[][] mOreDictAlt) { - super( - mInputs, - mOutputs, - mFluidInputs, - mFluidOutputs, - mChances, - mSpecialItems, - mDuration, - mEUt, - mSpecialValue, - mEnabled, - mHidden, - mFakeRecipe, - mCanBeBuffered, - mNeedsEmptyOutput, - nbtSensitive, - neiDesc, - metadataStorage, - recipeCategory); - this.mOreDictAlt = mOreDictAlt; - } - - public GT_Recipe_WithAlt(boolean aOptimize, ItemStack[] aInputs, ItemStack[] aOutputs, Object aSpecialItems, - int[] aChances, FluidStack[] aFluidInputs, FluidStack[] aFluidOutputs, int aDuration, int aEUt, - int aSpecialValue, ItemStack[][] aAlt) { - super( - aOptimize, - aInputs, - aOutputs, - aSpecialItems, - aChances, - aFluidInputs, - aFluidOutputs, - aDuration, - aEUt, - aSpecialValue); - mOreDictAlt = aAlt; - } - - public Object getAltRepresentativeInput(int aIndex) { - if (aIndex < 0) return null; - if (aIndex < mOreDictAlt.length) { - if (mOreDictAlt[aIndex] != null && mOreDictAlt[aIndex].length > 0) { - ItemStack[] rStacks = new ItemStack[mOreDictAlt[aIndex].length]; - for (int i = 0; i < mOreDictAlt[aIndex].length; i++) { - rStacks[i] = GT_Utility.copyOrNull(mOreDictAlt[aIndex][i]); - } - return rStacks; - } - } - if (aIndex >= mInputs.length) return null; - return GT_Utility.copyOrNull(mInputs[aIndex]); - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_RecipeBuilder.java b/src/main/java/gregtech/api/util/GT_RecipeBuilder.java deleted file mode 100644 index 137b7d6c86..0000000000 --- a/src/main/java/gregtech/api/util/GT_RecipeBuilder.java +++ /dev/null @@ -1,946 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.util.GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES; -import static gregtech.api.util.GT_Utility.copyFluidArray; -import static gregtech.api.util.GT_Utility.copyItemArray; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Stream; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.item.ItemStack; -import net.minecraft.launchwrapper.Launch; -import net.minecraftforge.fluids.FluidStack; - -import org.jetbrains.annotations.Contract; - -import gregtech.GT_Mod; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.Mods; -import gregtech.api.interfaces.IRecipeMap; -import gregtech.api.recipe.RecipeCategory; -import gregtech.api.recipe.RecipeMetadataKey; -import gregtech.api.recipe.metadata.IRecipeMetadataStorage; -import gregtech.api.recipe.metadata.RecipeMetadataStorage; -import gregtech.api.util.extensions.ArrayExt; - -@SuppressWarnings({ "unused", "UnusedReturnValue" }) -public class GT_RecipeBuilder { - - // debug mode expose problems. panic mode help you check nothing is wrong-ish without you actively monitoring - private static final boolean DEBUG_MODE_NULL; - // Any stable release should be tested at least once with this: -Dgt.recipebuilder.panic.null=true - private static boolean PANIC_MODE_NULL; - private static final boolean DEBUG_MODE_INVALID; - private static final boolean DEBUG_MODE_FULL_ENERGY; - // Any stable release should be tested at least once with this: -Dgt.recipebuilder.panic.invalid=true - private static final boolean PANIC_MODE_INVALID; - private static final boolean DEBUG_MODE_COLLISION; - - // Any stable release should be tested at least once with this: -Dgt.recipebuilder.panic.collision=true - private static final boolean PANIC_MODE_COLLISION; - - // This should only be enabled in non stable instances only with -Dgt.recipebuilder.recipe_collision_check=true - public static final boolean ENABLE_COLLISION_CHECK; - - public static final int WILDCARD = 32767; - - // time units - public static final int HOURS = 20 * 60 * 60; - public static final int MINUTES = 20 * 60; - public static final int SECONDS = 20; - public static final int TICKS = 1; - - // fluid units - public static final int INGOTS = 144; - public static final int HALF_INGOT = 72; - public static final int QUARTER_INGOT = 36; - public static final int EIGHTH_INGOT = 18; - public static final int NUGGETS = 16; - public static final int BUCKETS = 1000; - - static { - final boolean debugAll; - if (System.getProperties() - .containsKey("gt.recipebuilder.debug")) { - debugAll = Boolean.getBoolean("gt.recipebuilder.debug"); - } else { - // turn on debug by default in dev mode - debugAll = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); - } - DEBUG_MODE_NULL = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.null"); - DEBUG_MODE_INVALID = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.invalid"); - DEBUG_MODE_COLLISION = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.collision"); - DEBUG_MODE_FULL_ENERGY = debugAll || Boolean.getBoolean("gt.recipebuilder.debug.fullenergy"); - - final boolean panicAll = Boolean.getBoolean("gt.recipebuilder.panic"); - PANIC_MODE_NULL = panicAll || Boolean.getBoolean("gt.recipebuilder.panic.null"); - PANIC_MODE_INVALID = panicAll || Boolean.getBoolean("gt.recipebuilder.panic.invalid"); - PANIC_MODE_COLLISION = panicAll || Boolean.getBoolean("gt.recipebuilder.panic.collision"); - ENABLE_COLLISION_CHECK = Boolean.getBoolean("gt.recipebuilder.recipe_collision_check"); - } - - protected ItemStack[] inputsBasic = new ItemStack[0]; - protected Object[] inputsOreDict; - protected ItemStack[] outputs = new ItemStack[0]; - protected ItemStack[][] alts; - protected FluidStack[] fluidInputs = new FluidStack[0]; - protected FluidStack[] fluidOutputs = new FluidStack[0]; - protected int[] chances; - protected Object special; - protected int duration = -1; - protected int eut = -1; - protected int specialValue; - protected boolean enabled = true; - protected boolean hidden = false; - protected boolean fakeRecipe = false; - protected boolean mCanBeBuffered = true; - protected boolean mNeedsEmptyOutput = false; - protected boolean nbtSensitive = false; - protected String[] neiDesc; - protected RecipeCategory recipeCategory; - protected boolean optimize = true; - @Nullable - protected IRecipeMetadataStorage metadataStorage; - protected boolean checkForCollision = true; - /** - * If recipe addition should be skipped. - */ - protected boolean skip = false; - protected boolean valid = true; - - GT_RecipeBuilder() {} - - private GT_RecipeBuilder(ItemStack[] inputsBasic, Object[] inputsOreDict, ItemStack[] outputs, ItemStack[][] alts, - FluidStack[] fluidInputs, FluidStack[] fluidOutputs, int[] chances, Object special, int duration, int eut, - int specialValue, boolean enabled, boolean hidden, boolean fakeRecipe, boolean mCanBeBuffered, - boolean mNeedsEmptyOutput, boolean nbtSensitive, String[] neiDesc, RecipeCategory recipeCategory, - boolean optimize, @Nullable IRecipeMetadataStorage metadataStorage, boolean checkForCollision, boolean skip, - boolean valid) { - this.inputsBasic = inputsBasic; - this.inputsOreDict = inputsOreDict; - this.outputs = outputs; - this.alts = alts; - this.fluidInputs = fluidInputs; - this.fluidOutputs = fluidOutputs; - this.chances = chances; - this.special = special; - this.duration = duration; - this.eut = eut; - this.specialValue = specialValue; - this.enabled = enabled; - this.hidden = hidden; - this.fakeRecipe = fakeRecipe; - this.mCanBeBuffered = mCanBeBuffered; - this.mNeedsEmptyOutput = mNeedsEmptyOutput; - this.nbtSensitive = nbtSensitive; - this.neiDesc = neiDesc; - this.recipeCategory = recipeCategory; - this.optimize = optimize; - this.metadataStorage = metadataStorage; - if (this.metadataStorage != null) { - this.metadataStorage = this.metadataStorage.copy(); - } - this.checkForCollision = checkForCollision; - this.skip = skip; - this.valid = valid; - } - - // region helper methods - - private static FluidStack[] fix(FluidStack[] fluidInputs) { - return Arrays.stream(fluidInputs) - .filter(Objects::nonNull) - .map(FluidStack::copy) - .toArray(FluidStack[]::new); - } - - private static ItemStack[] fix(ItemStack[] inputs) { - return GT_OreDictUnificator.setStackArray(true, ArrayExt.withoutTrailingNulls(inputs, ItemStack[]::new)); - } - - public static GT_RecipeBuilder builder() { - return new GT_RecipeBuilder(); - } - - /** - * Creates empty builder where only duration and EU/t are set to 0. - */ - public static GT_RecipeBuilder empty() { - return new GT_RecipeBuilder().duration(0) - .eut(0); - } - - private static boolean containsNull(Object[] arr) { - return arr == null || Arrays.stream(arr) - .anyMatch(Objects::isNull); - } - - private static void handleNullRecipeComponents(String componentType) { - // place a breakpoint here to catch all these issues - GT_Log.err.print("null detected in "); - GT_Log.err.println(componentType); - new NullPointerException().printStackTrace(GT_Log.err); - if (PANIC_MODE_NULL) { - throw new IllegalArgumentException("null in argument"); - } - } - - private static boolean debugNull() { - return DEBUG_MODE_NULL || PANIC_MODE_NULL; - } - - public static void handleInvalidRecipe() { - if (!DEBUG_MODE_INVALID && !PANIC_MODE_INVALID) { - return; - } - // place a breakpoint here to catch all these issues - GT_Log.err.print("invalid recipe"); - new IllegalArgumentException().printStackTrace(GT_Log.err); - if (PANIC_MODE_INVALID) { - throw new IllegalArgumentException("invalid recipe"); - } - } - - public static void handleRecipeCollision(String details) { - if (!DEBUG_MODE_COLLISION && !PANIC_MODE_COLLISION) { - return; - } - GT_Log.err.print("Recipe collision resulting in recipe loss detected with "); - GT_Log.err.println(details); - if (PANIC_MODE_COLLISION) { - throw new IllegalArgumentException("Recipe Collision"); - } else { - // place a breakpoint here to catch all these issues - new IllegalArgumentException().printStackTrace(GT_Log.err); - } - } - - public static void onConfigLoad() { - PANIC_MODE_NULL |= GT_Mod.gregtechproxy.crashOnNullRecipeInput; - } - - // endregion - - // region setter - - /** - * Non-OreDicted item inputs. Assumes input is unified. - */ - public GT_RecipeBuilder itemInputsUnified(ItemStack... inputs) { - if (skip) return this; - if (debugNull() && containsNull(inputs)) handleNullRecipeComponents("itemInputUnified"); - inputsBasic = ArrayExt.withoutTrailingNulls(inputs, ItemStack[]::new); - inputsOreDict = null; - alts = null; - return this; - } - - /** - * Non-OreDicted item inputs. Assumes input is not unified. - */ - public GT_RecipeBuilder itemInputs(ItemStack... inputs) { - if (skip) return this; - if (debugNull() && containsNull(inputs)) handleNullRecipeComponents("itemInputs"); - inputsBasic = fix(inputs); - inputsOreDict = null; - alts = null; - return this; - } - - /** - * OreDicted item inputs. Currently only used for assline recipes adder. - */ - public GT_RecipeBuilder itemInputs(Object... inputs) { - if (skip) return this; - inputsOreDict = inputs; - alts = new ItemStack[inputs.length][]; - for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) { - Object input = inputs[i]; - if (input instanceof ItemStack) { - alts[i] = new ItemStack[] { (ItemStack) input }; - } else if (input instanceof ItemStack[]) { - alts[i] = ((ItemStack[]) input).clone(); - } else if (input instanceof Object[]arr) { - if (arr.length != 2) continue; - List ores = GT_OreDictUnificator.getOres(arr[0]); - if (ores.isEmpty()) continue; - int size = ((Number) arr[1]).intValue(); - alts[i] = ores.stream() - .map(s -> GT_Utility.copyAmount(size, s)) - .filter(GT_Utility::isStackValid) - .toArray(ItemStack[]::new); - } else if (input == null) { - handleNullRecipeComponents("recipe oredict input"); - alts[i] = new ItemStack[0]; - } else { - throw new IllegalArgumentException("index " + i + ", unexpected type: " + input.getClass()); - } - } - inputsBasic = Arrays.stream(alts) - .map(ss -> ss.length > 0 ? ss[0] : null) - .toArray(ItemStack[]::new); - // optimize cannot handle recipes with alts - return noOptimize(); - } - - public GT_RecipeBuilder itemOutputs(ItemStack... outputs) { - if (skip) return this; - if (debugNull() && containsNull(outputs)) handleNullRecipeComponents("itemOutputs"); - this.outputs = outputs; - if (chances != null && chances.length != outputs.length) { - throw new IllegalArgumentException("Output chances array and items array length differs"); - } - return this; - } - - /** - * Not intended to be used by recipe authors. - * Intended for recipe rewrite middlewares. - */ - public GT_RecipeBuilder itemOutputs(ItemStack[] outputs, int[] chances) { - if (skip) return this; - if (debugNull() && containsNull(outputs)) handleNullRecipeComponents("itemOutputs"); - this.outputs = outputs; - this.chances = chances; - if (chances != null && chances.length != outputs.length) { - throw new IllegalArgumentException("Output chances array and items array length differs"); - } - return this; - } - - public GT_RecipeBuilder fluidInputs(FluidStack... fluidInputs) { - if (skip) return this; - if (debugNull() && containsNull(fluidInputs)) handleNullRecipeComponents("fluidInputs"); - this.fluidInputs = fix(fluidInputs); - return this; - } - - public GT_RecipeBuilder fluidOutputs(FluidStack... fluidOutputs) { - if (skip) return this; - if (debugNull() && containsNull(fluidOutputs)) handleNullRecipeComponents("fluidOutputs"); - this.fluidOutputs = fix(fluidOutputs); - return this; - } - - public GT_RecipeBuilder outputChances(int... chances) { - if (skip) return this; - if (outputs != null && chances.length != outputs.length) { - throw new IllegalArgumentException("Output chances array and items array length differs"); - } - this.chances = chances; - return this; - } - - public GT_RecipeBuilder special(Object special) { - this.special = special; - return this; - } - - public GT_RecipeBuilder duration(int duration) { - this.duration = duration; - return this; - } - - public GT_RecipeBuilder duration(long duration) { - this.duration = (int) duration; - return this; - } - - public GT_RecipeBuilder eut(int eut) { - if (DEBUG_MODE_FULL_ENERGY) { - // Ignores ULV voltage - for (int i = 1; i < GT_Values.VP.length; i++) { - if (eut <= GT_Values.V[i] && eut > GT_Values.VP[i]) { - GT_Log.err.println( - "EUt > Practical Voltage detected. EUt: " + eut + ", Practical Voltage: " + GT_Values.VP[i]); - new IllegalArgumentException().printStackTrace(GT_Log.err); - break; - } - } - } - this.eut = eut; - return this; - } - - public GT_RecipeBuilder eut(long eut) { - return eut((int) eut); - } - - /** - * prefer to use metadata over this. should only use when the target recipe map does not yet support metadata - * system, or it's to bridge legacy code and modern code. - */ - public GT_RecipeBuilder specialValue(int specialValue) { - this.specialValue = specialValue; - return this; - } - - // I don't expect anyone to actually call this... - public GT_RecipeBuilder disabled() { - this.enabled = false; - return this; - } - - public GT_RecipeBuilder hidden() { - this.hidden = true; - return this; - } - - public GT_RecipeBuilder fake() { - this.fakeRecipe = true; - return this; - } - - public GT_RecipeBuilder noBuffer() { - this.mCanBeBuffered = false; - return this; - } - - public GT_RecipeBuilder needsEmptyOutput() { - this.mNeedsEmptyOutput = true; - return this; - } - - public GT_RecipeBuilder nbtSensitive() { - this.nbtSensitive = true; - return this; - } - - public GT_RecipeBuilder setNEIDesc(String... neiDesc) { - this.neiDesc = neiDesc; - return this; - } - - public GT_RecipeBuilder recipeCategory(RecipeCategory recipeCategory) { - this.recipeCategory = recipeCategory; - return this; - } - - /** - * Prevent the resulting recipe from optimizing recipe, which is a process that reduce recipe batch size. - */ - public GT_RecipeBuilder noOptimize() { - this.optimize = false; - return this; - } - - /** - * Prevents checking collision with existing recipes when adding the built recipe. - */ - public GT_RecipeBuilder ignoreCollision() { - this.checkForCollision = false; - return this; - } - - /** - * Sets metadata of the recipe. It can be used for recipe emitter to do special things, or for being stored in the - * built recipe and used for actual recipe processing. - *

- * {@link GT_RecipeConstants} has a series of metadata keys. Or you can create one by yourself. - */ - public GT_RecipeBuilder metadata(RecipeMetadataKey key, T value) { - if (skip) return this; - if (metadataStorage == null) { - metadataStorage = new RecipeMetadataStorage(); - } - metadataStorage.store(key, value); - return this; - } - - /** - * Gets metadata already set for this builder. Can return null. Use - * {@link #getMetadataOrDefault(RecipeMetadataKey, Object)} - * if you want to specify default value. - */ - @Nullable - public T getMetadata(RecipeMetadataKey key) { - if (metadataStorage == null) { - return null; - } - return key.cast(metadataStorage.getMetadata(key)); - } - - /** - * Gets metadata already set for this builder with default value. Does not return null unless default value is null. - */ - @Contract("_, !null -> !null") - @Nullable - public T getMetadataOrDefault(RecipeMetadataKey key, T defaultValue) { - if (metadataStorage == null) { - return defaultValue; - } - return key.cast(metadataStorage.getMetadataOrDefault(key, defaultValue)); - } - - /** - * Specifies mods required to add the recipe. If any of the mods is not loaded, all the operations for this builder - * will be ignored. - * - * @param mods Mod(s) required for the recipe. - */ - public GT_RecipeBuilder requireMods(Mods... mods) { - skip = Stream.of(mods) - .anyMatch(mod -> !mod.isModLoaded()); - return this; - } - - public GT_RecipeBuilder requiresCleanRoom() { - return metadata(GT_RecipeConstants.CLEANROOM, true); - } - - public GT_RecipeBuilder requiresLowGravity() { - return metadata(GT_RecipeConstants.LOW_GRAVITY, true); - } - - // endregion - - private static T[] copy(T[] arr) { - return arr == null ? null : arr.clone(); - } - - private static int[] copy(int[] arr) { - return arr == null ? null : arr.clone(); - } - - /** - * produce a deep copy of current values. anything unset will remain unset. IMPORTANT: If metadata contains mutable - * value, they will not be cloned! - *

- * checkout docs/RecipeBuilder.md for more info on whether to copy or not. - */ - public GT_RecipeBuilder copy() { - return new GT_RecipeBuilder( - copyItemArray(inputsBasic), - copy(inputsOreDict), - copyItemArray(outputs), - copy(alts), - copyFluidArray(fluidInputs), - copyFluidArray(fluidOutputs), - copy(chances), - special, - duration, - eut, - specialValue, - enabled, - hidden, - fakeRecipe, - mCanBeBuffered, - mNeedsEmptyOutput, - nbtSensitive, - copy(neiDesc), - recipeCategory, - optimize, - metadataStorage, - checkForCollision, - skip, - valid); - } - - /** - * produce a deep copy of current values. anything unset will remain unset. discard all existing metadata - */ - public GT_RecipeBuilder copyNoMetadata() { - return new GT_RecipeBuilder( - copyItemArray(inputsBasic), - copy(inputsOreDict), - copyItemArray(outputs), - copy(alts), - copyFluidArray(fluidInputs), - copyFluidArray(fluidOutputs), - copy(chances), - special, - duration, - eut, - specialValue, - enabled, - hidden, - fakeRecipe, - mCanBeBuffered, - mNeedsEmptyOutput, - nbtSensitive, - copy(neiDesc), - recipeCategory, - optimize, - null, - checkForCollision, - skip, - valid); - } - - // region getter - - public ItemStack getItemInputBasic(int index) { - return index < inputsBasic.length ? inputsBasic[index] : null; - } - - public Object getItemInputOreDict(int index) { - return index < inputsOreDict.length ? inputsOreDict[index] : null; - } - - public ItemStack getItemOutput(int index) { - return index < outputs.length ? outputs[index] : null; - } - - public FluidStack getFluidInput(int index) { - return index < fluidInputs.length ? fluidInputs[index] : null; - } - - public FluidStack getFluidOutput(int index) { - return index < fluidOutputs.length ? fluidOutputs[index] : null; - } - - public ItemStack[] getItemInputsBasic() { - return inputsBasic; - } - - public Object[] getItemInputsOreDict() { - return inputsOreDict; - } - - public ItemStack[] getItemOutputs() { - return outputs; - } - - public FluidStack[] getFluidInputs() { - return fluidInputs; - } - - public FluidStack[] getFluidOutputs() { - return fluidOutputs; - } - - public int getDuration() { - return duration; - } - - public int[] getChances() { - return chances; - } - - public int getEUt() { - return eut; - } - - public RecipeCategory getRecipeCategory() { - return recipeCategory; - } - - public boolean isOptimize() { - return optimize; - } - - public boolean isCheckForCollision() { - return checkForCollision; - } - - // endregion - - // region validator - - public GT_RecipeBuilder clearInvalid() { - valid = true; - return this; - } - - public GT_RecipeBuilder invalidate() { - valid = false; - return this; - } - - public boolean isValid() { - return valid; - } - - private static boolean isArrayValid(@Nonnull Object[] arr, int min, int max) { - int count = 0; - for (Object o : arr) { - if (o != null) count += 1; - } - return min <= count && max >= count; - } - - /** - * Validate if input item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateNoInput() { - if (skip) return this; - return GT_Utility.isArrayEmptyOrNull(inputsBasic) ? this : invalidate(); - } - - /** - * Validate if input fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateNoInputFluid() { - if (skip) return this; - return GT_Utility.isArrayEmptyOrNull(fluidInputs) ? this : invalidate(); - } - - /** - * Validate if output item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateNoOutput() { - if (skip) return this; - return GT_Utility.isArrayEmptyOrNull(outputs) ? this : invalidate(); - } - - /** - * Validate if output fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateNoOutputFluid() { - if (skip) return this; - return GT_Utility.isArrayEmptyOrNull(fluidOutputs) ? this : invalidate(); - } - - /** - * Validate if input item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateInputCount(int min, int max) { - if (skip) return this; - if (inputsBasic == null) return min < 0 ? this : invalidate(); - return isArrayValid(inputsBasic, min, max) ? this : invalidate(); - } - - /** - * Validate if input fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateInputFluidCount(int min, int max) { - if (skip) return this; - if (fluidInputs == null) return min < 0 ? this : invalidate(); - return isArrayValid(fluidInputs, min, max) ? this : invalidate(); - } - - /** - * Validate if output item match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateOutputCount(int min, int max) { - if (skip) return this; - if (outputs == null) return min < 0 ? this : invalidate(); - return isArrayValid(outputs, min, max) ? this : invalidate(); - } - - /** - * Validate if output fluid match requirement. Return as invalidated if fails prereq. Specify -1 as min to allow - * unset. Both bound inclusive. Only supposed to be called by IRecipeMap and not client code. - */ - public GT_RecipeBuilder validateOutputFluidCount(int min, int max) { - if (skip) return this; - if (fluidOutputs == null) return min < 0 ? this : invalidate(); - return isArrayValid(fluidOutputs, min, max) ? this : invalidate(); - } - - public GT_RecipeBuilder validateAnyInput() { - if (skip) return this; - if (fluidInputs != null && isArrayValid(fluidInputs, 1, Integer.MAX_VALUE)) { - return this; - } - if (inputsBasic != null && isArrayValid(inputsBasic, 1, Integer.MAX_VALUE)) { - return this; - } - return invalidate(); - } - - public GT_RecipeBuilder validateAnyOutput() { - if (skip) return this; - if (fluidOutputs != null && isArrayValid(fluidOutputs, 1, Integer.MAX_VALUE)) { - return this; - } - if (outputs != null && isArrayValid(outputs, 1, Integer.MAX_VALUE)) { - return this; - } - return invalidate(); - } - - // endregion - - /** - * Builds new recipe, without custom behavior of recipemaps. For adding recipe to recipemap, - * use {@link #addTo} instead. - * - * @return Built recipe. Returns empty if failed to build. - */ - public Optional build() { - if (skip) { - return Optional.empty(); - } - if (!valid) { - handleInvalidRecipe(); - return Optional.empty(); - } - preBuildChecks(); - optimize(); - return Optional.of( - decorate( - new GT_Recipe( - inputsBasic, - outputs, - fluidInputs, - fluidOutputs, - chances, - special, - duration, - eut, - specialValue, - enabled, - hidden, - fakeRecipe, - mCanBeBuffered, - mNeedsEmptyOutput, - nbtSensitive, - neiDesc, - metadataStorage, - recipeCategory))); - } - - public GT_RecipeBuilder forceOreDictInput() { - if (inputsOreDict != null || inputsBasic == null) return this; - return itemInputs((Object[]) inputsBasic); - } - - public Optional buildWithAlt() { - if (skip) { - return Optional.empty(); - } - if (inputsOreDict == null) { - throw new UnsupportedOperationException(); - } - if (!valid) { - handleInvalidRecipe(); - return Optional.empty(); - } - preBuildChecks(); - // no optimize. - return Optional.of( - decorate( - new GT_Recipe.GT_Recipe_WithAlt( - inputsBasic, - outputs, - fluidInputs, - fluidOutputs, - chances, - special, - duration, - eut, - specialValue, - enabled, - hidden, - fakeRecipe, - mCanBeBuffered, - mNeedsEmptyOutput, - nbtSensitive, - neiDesc, - metadataStorage, - recipeCategory, - alts))); - } - - private void preBuildChecks() { - if (duration == -1) throw new IllegalStateException("no duration"); - if (eut == -1) throw new IllegalStateException("no eut"); - } - - private void optimize() { - if (optimize) { - ArrayList l = new ArrayList<>(); - l.addAll(Arrays.asList(inputsBasic)); - l.addAll(Arrays.asList(outputs)); - for (int i = 0; i < l.size(); i++) if (l.get(i) == null) l.remove(i--); - - outer: for (byte i = (byte) Math.min(64, duration / 16); i > 1; i--) { - if (duration / i >= 16) { - for (ItemStack stack : l) { - if (stack.stackSize % i != 0) continue outer; - } - for (FluidStack fluidInput : fluidInputs) { - if (fluidInput.amount % i != 0) continue outer; - } - for (FluidStack fluidOutput : fluidOutputs) { - if (fluidOutput.amount % i != 0) continue outer; - } - for (ItemStack itemStack : l) itemStack.stackSize /= i; - for (FluidStack fluidInput : fluidInputs) fluidInput.amount /= i; - for (FluidStack fluidOutput : fluidOutputs) fluidOutput.amount /= i; - duration /= i; - } - } - optimize = false; - } - } - - private T decorate(T r) { - r.mHidden = hidden; - r.mCanBeBuffered = mCanBeBuffered; - r.mNeedsEmptyOutput = mNeedsEmptyOutput; - r.isNBTSensitive = nbtSensitive; - r.mFakeRecipe = fakeRecipe; - r.mEnabled = enabled; - if (neiDesc != null) r.setNeiDesc(neiDesc); - applyDefaultSpecialValues(r); - return r; - } - - private void applyDefaultSpecialValues(GT_Recipe recipe) { - if (recipe.mSpecialValue != 0) return; - - int specialValue = 0; - if (getMetadataOrDefault(GT_RecipeConstants.LOW_GRAVITY, false)) specialValue -= 100; - if (getMetadataOrDefault(GT_RecipeConstants.CLEANROOM, false)) specialValue -= 200; - for (RecipeMetadataKey ident : SPECIAL_VALUE_ALIASES) { - Integer metadata = getMetadataOrDefault(ident, null); - if (metadata != null) { - specialValue = metadata; - break; - } - } - recipe.mSpecialValue = specialValue; - } - - public Collection addTo(IRecipeMap recipeMap) { - if (skip) { - return Collections.emptyList(); - } - return recipeMap.doAdd(this); - } - - public GT_RecipeBuilder reset() { - metadataStorage = null; - alts = null; - chances = null; - duration = -1; - enabled = true; - eut = -1; - fakeRecipe = false; - fluidInputs = null; - fluidOutputs = null; - hidden = false; - inputsBasic = null; - inputsOreDict = null; - mCanBeBuffered = true; - mNeedsEmptyOutput = false; - nbtSensitive = false; - neiDesc = null; - recipeCategory = null; - optimize = true; - outputs = null; - special = null; - specialValue = 0; - skip = false; - valid = true; - return this; - } -} diff --git a/src/main/java/gregtech/api/util/GT_RecipeConstants.java b/src/main/java/gregtech/api/util/GT_RecipeConstants.java deleted file mode 100644 index c8a002c6c2..0000000000 --- a/src/main/java/gregtech/api/util/GT_RecipeConstants.java +++ /dev/null @@ -1,692 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.recipe.RecipeMaps.scannerFakeRecipes; -import static gregtech.api.util.GT_RecipeMapUtil.convertCellToFluid; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Optional; - -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -import com.elisis.gtnhlanth.common.item.MaskList; -import com.elisis.gtnhlanth.common.item.PhotolithographicMask; -import com.elisis.gtnhlanth.common.register.LanthItemList; - -import cpw.mods.fml.common.registry.GameRegistry; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.TierEU; -import gregtech.api.interfaces.IRecipeMap; -import gregtech.api.objects.ItemData; -import gregtech.api.recipe.RecipeCategories; -import gregtech.api.recipe.RecipeMaps; -import gregtech.api.recipe.RecipeMetadataKey; -import gregtech.api.recipe.metadata.SimpleRecipeMetadataKey; -import gregtech.common.items.GT_MetaGenerated_Item_03; -import gregtech.common.items.ID_MetaItem_03; - -// this class is intended to be import-static-ed on every recipe script -// so take care to not put unrelated stuff here! -public class GT_RecipeConstants { - - /** - * Set to true to signal the recipe require low gravity. do nothing if recipe set specialValue explicitly. Can - * coexist with CLEANROOM just fine - */ - public static final RecipeMetadataKey LOW_GRAVITY = SimpleRecipeMetadataKey - .create(Boolean.class, "low_gravity"); - /** - * Set to true to signal the recipe require cleanroom. do nothing if recipe set specialValue explicitly. Can coexist - * with LOW_GRAVITY just fine - */ - public static final RecipeMetadataKey CLEANROOM = SimpleRecipeMetadataKey - .create(Boolean.class, "cleanroom"); - /** - * Common additive to use in recipe, e.g. for PBF, this is coal amount. - */ - public static final RecipeMetadataKey ADDITIVE_AMOUNT = SimpleRecipeMetadataKey - .create(Integer.class, "additives"); - /** - * Used for fusion reactor. Denotes ignition threshold. - */ - public static final RecipeMetadataKey FUSION_THRESHOLD = SimpleRecipeMetadataKey - .create(Integer.class, "fusion_threshold"); - /** - * Research time in a scanner used in ticks. - */ - public static final RecipeMetadataKey RESEARCH_TIME = SimpleRecipeMetadataKey - .create(Integer.class, "research_time"); - /** - * Fuel type. TODO should we use enum directly? - */ - public static final RecipeMetadataKey FUEL_TYPE = SimpleRecipeMetadataKey - .create(Integer.class, "fuel_type"); - /** - * Fuel value. - */ - public static final RecipeMetadataKey FUEL_VALUE = SimpleRecipeMetadataKey - .create(Integer.class, "fuel_value"); - /** - * Required heat for heating coil (Kelvin). - */ - public static final RecipeMetadataKey COIL_HEAT = SimpleRecipeMetadataKey - .create(Integer.class, "coil_heat"); - /** - * Research item used by assline recipes. - */ - public static final RecipeMetadataKey RESEARCH_ITEM = SimpleRecipeMetadataKey - .create(ItemStack.class, "research_item"); - /** - * For assembler. It accepts a single item as oredict. It looks like no one uses this anyway... - */ - public static final RecipeMetadataKey OREDICT_INPUT = SimpleRecipeMetadataKey - .create(Object.class, "oredict_input"); - /** - * Replicator output material. - */ - public static final RecipeMetadataKey MATERIAL = SimpleRecipeMetadataKey - .create(Materials.class, "material"); - /** - * Marker for {@link #UniversalArcFurnace} to tell that the recipe belongs to recycling category. - */ - public static final RecipeMetadataKey RECYCLE = SimpleRecipeMetadataKey.create(Boolean.class, "recycle"); - /** - * For Microwave. - */ - public static final RecipeMetadataKey EXPLODE = SimpleRecipeMetadataKey.create(Boolean.class, "explode"); - /** - * For Microwave. - */ - public static final RecipeMetadataKey ON_FIRE = SimpleRecipeMetadataKey.create(Boolean.class, "on_fire"); - - /** - * Nano Forge Tier. - */ - public static final RecipeMetadataKey NANO_FORGE_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "nano_forge_tier"); - - /** - * FOG Exotic recipe tier. - */ - public static final RecipeMetadataKey FOG_EXOTIC_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "fog_exotic_tier"); - - /** - * FOG Plasma recipe tier. - */ - public static final RecipeMetadataKey FOG_PLASMA_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "fog_plasma_tier"); - - /** - * DEFC Casing tier. - */ - public static final RecipeMetadataKey DEFC_CASING_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "defc_casing_tier"); - - /** - * Chemplant Casing tier. Beware, codewise index starts at 0, but it is tier 1. - */ - public static final RecipeMetadataKey CHEMPLANT_CASING_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "chemplant_casing_tier"); - - /** - * QFT Focus tier. - */ - public static final RecipeMetadataKey QFT_FOCUS_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "qft_focus_tier"); - - /** - * Tier of advanced compression (HIP/black hole) - */ - public static final RecipeMetadataKey COMPRESSION_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "compression"); - - /** - * Dissolution Tank Ratio. - */ - public static final RecipeMetadataKey DISSOLUTION_TANK_RATIO = SimpleRecipeMetadataKey - .create(Integer.class, "dissolution_tank_ratio"); - - /** - * Duration in days for the RTG. - */ - public static final RecipeMetadataKey RTG_DURATION_IN_DAYS = SimpleRecipeMetadataKey - .create(Integer.class, "rtg_duration_in_days"); - - /** - * Basic output for the Large Naquadah Generator. - */ - public static final RecipeMetadataKey LNG_BASIC_OUTPUT = SimpleRecipeMetadataKey - .create(Integer.class, "lng_basic_output"); - - /** - * Coil tier for the Naquadah Fuel Refinery. - */ - public static final RecipeMetadataKey NFR_COIL_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "nfr_coil_tier"); - - /** - * NKE range for the neutron activator. - */ - public static final RecipeMetadataKey NKE_RANGE = SimpleRecipeMetadataKey - .create(Integer.class, "nke_range"); - /** - * Precise Assembler casing tier. - */ - public static final RecipeMetadataKey PRECISE_ASSEMBLER_CASING_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "precise_assembler_casing_tier"); - /** - * CoAL casing tier. - */ - public static final RecipeMetadataKey COAL_CASING_TIER = SimpleRecipeMetadataKey - .create(Integer.class, "coal_casing_tier"); - - /** - * LFTR output power. - */ - public static final RecipeMetadataKey LFTR_OUTPUT_POWER = SimpleRecipeMetadataKey - .create(Integer.class, "lftr_output_power"); - - /** - * Research Station data. - */ - public static final RecipeMetadataKey RESEARCH_STATION_DATA = SimpleRecipeMetadataKey - .create(Integer.class, "research_station_data"); - - /** - * glass tier required for the biovat recipes. - */ - public static final RecipeMetadataKey SIEVERTS = SimpleRecipeMetadataKey.create(Integer.class, "sieverts"); - - public static final RecipeMetadataKey DECAY_TICKS = SimpleRecipeMetadataKey - .create(Integer.class, "decay_ticks"); - - public static final RecipeMetadataKey NOBLE_GASES = SimpleRecipeMetadataKey - .create(Boolean.class, "noble_gases"); - - public static final RecipeMetadataKey ANAEROBE_GASES = SimpleRecipeMetadataKey - .create(Boolean.class, "anaerobe_gases"); - - public static final RecipeMetadataKey NO_GAS = SimpleRecipeMetadataKey.create(Boolean.class, "no_gas"); - - /** - * Add a arc furnace recipe. Adds to both normal arc furnace and plasma arc furnace. - * Will override the fluid input with oxygen/plasma for the respective recipe maps, so there is no point setting it. - */ - public static final IRecipeMap UniversalArcFurnace = IRecipeMap.newRecipeMap(builder -> { - if (!GT_Utility.isArrayOfLength(builder.getItemInputsBasic(), 1) - || GT_Utility.isArrayEmptyOrNull(builder.getItemOutputs())) return Collections.emptyList(); - int aDuration = builder.getDuration(); - if (aDuration <= 0) { - return Collections.emptyList(); - } - builder.duration(aDuration); - boolean recycle = builder.getMetadataOrDefault(RECYCLE, false); - Collection ret = new ArrayList<>(); - for (Materials mat : new Materials[] { Materials.Argon, Materials.Nitrogen }) { - int tPlasmaAmount = (int) Math.max(1L, aDuration / (mat.getMass() * 16L)); - GT_RecipeBuilder plasmaBuilder = builder.copy() - .fluidInputs(mat.getPlasma(tPlasmaAmount)) - .fluidOutputs(mat.getGas(tPlasmaAmount)); - if (recycle) { - plasmaBuilder.recipeCategory(RecipeCategories.plasmaArcFurnaceRecycling); - } - ret.addAll(RecipeMaps.plasmaArcFurnaceRecipes.doAdd(plasmaBuilder)); - } - GT_RecipeBuilder arcBuilder = builder.copy() - .fluidInputs(Materials.Oxygen.getGas(aDuration)); - if (recycle) { - arcBuilder.recipeCategory(RecipeCategories.arcFurnaceRecycling); - } - ret.addAll(RecipeMaps.arcFurnaceRecipes.doAdd(arcBuilder)); - return ret; - }); - - /** - * Add a chemical reactor recipe to both LCR and singleblocks. - */ - public static final IRecipeMap UniversalChemical = IRecipeMap.newRecipeMap(builder -> { - for (ItemStack input : builder.getItemInputsBasic()) { - // config >= 10 -> this is a special chemical recipe that output fluid/canned fluid variant. - // it doesn't belong to multiblocks - if (GT_Utility.isAnyIntegratedCircuit(input) && input.getItemDamage() >= 10) { - return builder.addTo(RecipeMaps.chemicalReactorRecipes); - } - } - return GT_Utility.concat( - builder.copy() - .addTo(RecipeMaps.chemicalReactorRecipes), - convertCellToFluid(builder, false) - // LCR does not need cleanroom. - .metadata(CLEANROOM, false) - .addTo(RecipeMaps.multiblockChemicalReactorRecipes)); - }); - - /** - * Adds an engraver recipe that might use purified water. Still added to the regular recipemap if it ends up not - * needing it. - */ - public static final IRecipeMap WaferEngravingRecipes = IRecipeMap.newRecipeMap(builder -> { - // spotless:off - enum Wafer{ - Naquadah, - Europium, - Americium, - // Beamline masks - MaskT1, - MaskT2, - MaskT3, - } - // spotless:on - // Find the wafer used - Wafer wafer = null; - PhotolithographicMask t1Item = (PhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK1); - PhotolithographicMask t2Item = (PhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK2); - PhotolithographicMask t3Item = (PhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK3); - for (ItemStack input : builder.getItemInputsBasic()) { - if (input.getItem() instanceof GT_MetaGenerated_Item_03) { - int meta = input.getItemDamage() - 32000; - // Check if this input item is indicating a wafer recipe we want to modify - if (meta == ID_MetaItem_03.Circuit_Silicon_Wafer3.ID) wafer = Wafer.Naquadah; - else if (meta == ID_MetaItem_03.Circuit_Silicon_Wafer4.ID) wafer = Wafer.Europium; - else if (meta == ID_MetaItem_03.Circuit_Silicon_Wafer5.ID) wafer = Wafer.Americium; - } - - // Now look for beamline masks - if (input.getItem() instanceof PhotolithographicMask mask) { - String spectrum = mask.getDescSpectrum(); - if (spectrum.equals(t1Item.getDescSpectrum())) wafer = Wafer.MaskT1; - else if (spectrum.equals(t2Item.getDescSpectrum())) wafer = Wafer.MaskT2; - else if (spectrum.equals(t3Item.getDescSpectrum())) wafer = Wafer.MaskT3; - } - - // Found a wafer, stop checking inputs - if (wafer != null) break; - } - - int recipeTime = builder.duration; - // Bonus for using purified water of a higher tier than necessary - int halfBoostedRecipeTime = (int) (recipeTime * 0.75); - int boostedRecipeTime = (int) (recipeTime * 0.5); - - // If this recipe does not use a wafer, exit without modifying it. - if (wafer == null) return builder.addTo(RecipeMaps.laserEngraverRecipes); - switch (wafer) { - case Naquadah -> { - ArrayList items = new ArrayList<>(Arrays.asList(builder.getItemInputsBasic())); - ItemStack[] itemInputs = items.toArray(new ItemStack[] {}); - // Naquadah wafers can use grade 1-2 purified water for a bonus, otherwise use distilled so we don't - // have to - // deal with circuits - return GT_Utility.concat( - builder.copy() - .itemInputs(itemInputs) - .fluidInputs(GT_ModHandler.getDistilledWater(100L)) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .itemInputs(itemInputs) - .fluidInputs(Materials.Grade1PurifiedWater.getFluid(100L)) - .duration(halfBoostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .itemInputs(itemInputs) - .fluidInputs(Materials.Grade2PurifiedWater.getFluid(100L)) - .duration(boostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes)); - } - case Europium -> { - // Require purified water for europium wafers, at least grade 3 - return GT_Utility.concat( - builder.copy() - .fluidInputs(Materials.Grade3PurifiedWater.getFluid(100L)) - .duration(recipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade4PurifiedWater.getFluid(100L)) - .duration(boostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes)); - } - case Americium -> { - // Require purified water for americium wafers, at least grade 5 - return GT_Utility.concat( - builder.copy() - .fluidInputs(Materials.Grade5PurifiedWater.getFluid(100L)) - .duration(recipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade6PurifiedWater.getFluid(100L)) - .duration(boostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes)); - } - // Masks require much more purified water because they can make many wafers at once - case MaskT1 -> { - // T1 masks require grade 1, 2 or 3 purified water - return GT_Utility.concat( - builder.copy() - .fluidInputs(Materials.Grade1PurifiedWater.getFluid(32000L)) - .duration(recipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade2PurifiedWater.getFluid(32000L)) - .duration(halfBoostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade3PurifiedWater.getFluid(32000L)) - .duration(boostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes)); - } - case MaskT2 -> { - // T2 masks require grade 4 or 5 purified water - return GT_Utility.concat( - builder.copy() - .fluidInputs(Materials.Grade4PurifiedWater.getFluid(32000L)) - .duration(recipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade5PurifiedWater.getFluid(32000L)) - .duration(boostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes)); - } - case MaskT3 -> { - // T3 masks require grade 6, 7 or 8 purified water - return GT_Utility.concat( - builder.copy() - .fluidInputs(Materials.Grade6PurifiedWater.getFluid(32000L)) - .duration(recipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade7PurifiedWater.getFluid(32000L)) - .duration(halfBoostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes), - builder.copy() - .fluidInputs(Materials.Grade8PurifiedWater.getFluid(32000L)) - .duration(boostedRecipeTime) - .addTo(RecipeMaps.laserEngraverRecipes)); - } - } - - throw new RuntimeException("Unreachable code reached in Laser Engraver Recipe Transformer"); - }); - - /** - * The one and only :tm: assline recipe adder. - * Uses {@link #RESEARCH_ITEM} metadata as research item, and {@link #RESEARCH_TIME} metadata as research time, unit - * in ticks. - */ - public static final IRecipeMap AssemblyLine = IRecipeMap.newRecipeMap(builder -> { - Optional rr = builder.forceOreDictInput() - .validateInputCount(4, 16) - .validateOutputCount(1, 1) - .validateOutputFluidCount(-1, 0) - .validateInputFluidCount(1, 4) - .buildWithAlt(); - // noinspection SimplifyOptionalCallChains - if (!rr.isPresent()) return Collections.emptyList(); - GT_Recipe.GT_Recipe_WithAlt r = rr.get(); - ItemStack[][] mOreDictAlt = r.mOreDictAlt; - Object[] inputs = builder.getItemInputsOreDict(); - ItemStack aResearchItem = builder.getMetadata(RESEARCH_ITEM); - if (aResearchItem == null) { - return Collections.emptyList(); - } - ItemStack aOutput = r.mOutputs[0]; - int tPersistentHash = 1; - for (int i = 0, mOreDictAltLength = mOreDictAlt.length; i < mOreDictAltLength; i++) { - ItemStack[] alts = mOreDictAlt[i]; - Object input = inputs[i]; - if (input == null) { - GT_Log.err.println( - "addAssemblingLineRecipe " + aResearchItem.getDisplayName() - + " --> " - + aOutput.getUnlocalizedName() - + " there is some null item in that recipe"); - } - if (input instanceof ItemStack) { - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash((ItemStack) input, true, false); - } else if (input instanceof ItemStack[]) { - for (ItemStack alt : ((ItemStack[]) input)) { - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(alt, true, false); - if (alt == null) { - GT_Log.err.println( - "addAssemblingLineRecipe " + aResearchItem.getDisplayName() - + " --> " - + aOutput.getUnlocalizedName() - + " there is some null alt item in that recipe"); - } - } - tPersistentHash *= 31; - } else if (input instanceof Object[]objs) { - Arrays.sort( - alts, - Comparator - .comparing(s -> GameRegistry.findUniqueIdentifierFor(s.getItem()).modId) - .thenComparing(s -> GameRegistry.findUniqueIdentifierFor(s.getItem()).name) - .thenComparingInt(Items.feather::getDamage) - .thenComparingInt(s -> s.stackSize)); - - tPersistentHash = tPersistentHash * 31 + (objs[0] == null ? "" : objs[0].toString()).hashCode(); - tPersistentHash = tPersistentHash * 31 + ((Number) objs[1]).intValue(); - } - } - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(aResearchItem, true, false); - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(aOutput, true, false); - for (FluidStack fluidInput : r.mFluidInputs) { - if (fluidInput == null) continue; - tPersistentHash = tPersistentHash * 31 + GT_Utility.persistentHash(fluidInput, true, false); - } - int aResearchTime = builder.getMetadataOrDefault(RESEARCH_TIME, 0); - tPersistentHash = tPersistentHash * 31 + aResearchTime; - tPersistentHash = tPersistentHash * 31 + r.mDuration; - tPersistentHash = tPersistentHash * 31 + r.mEUt; - - GT_Recipe.GT_Recipe_AssemblyLine tRecipe = new GT_Recipe.GT_Recipe_AssemblyLine( - aResearchItem, - aResearchTime, - r.mInputs, - r.mFluidInputs, - aOutput, - r.mDuration, - r.mEUt, - r.mOreDictAlt); - tRecipe.setPersistentHash(tPersistentHash); - GT_Recipe.GT_Recipe_AssemblyLine.sAssemblylineRecipes.add(tRecipe); - GT_AssemblyLineUtils.addRecipeToCache(tRecipe); - - ItemStack writesDataStick = ItemList.Tool_DataStick.getWithName(1L, "Writes Research result"); - GT_AssemblyLineUtils.setAssemblyLineRecipeOnDataStick(writesDataStick, tRecipe, false); - Collection ret = new ArrayList<>(3); - ret.addAll( - GT_Values.RA.stdBuilder() - .itemInputs(aResearchItem) - .itemOutputs(aOutput) - .special(writesDataStick) - .duration(aResearchTime) - .eut(TierEU.RECIPE_LV) - .specialValue(-201) // means it's scanned - .noOptimize() - .ignoreCollision() - .fake() - .addTo(scannerFakeRecipes)); - - ItemStack readsDataStick = ItemList.Tool_DataStick.getWithName(1L, "Reads Research result"); - GT_AssemblyLineUtils.setAssemblyLineRecipeOnDataStick(readsDataStick, tRecipe, false); - ret.add( - RecipeMaps.assemblylineVisualRecipes.addFakeRecipe( - false, - r.mInputs, - new ItemStack[] { aOutput }, - new ItemStack[] { readsDataStick }, - r.mFluidInputs, - null, - r.mDuration, - r.mEUt, - 0, - r.mOreDictAlt, - false)); - - return ret; - }); - - /** - * Adds an Electric Blast Furnace recipe that might use gas. - */ - public static final IRecipeMap BlastFurnaceWithGas = IRecipeMap.newRecipeMap(builder -> { - Collection ret = new ArrayList<>(); - int basicGasAmount = builder.getMetadataOrDefault(ADDITIVE_AMOUNT, 1000); - double durationBase = builder.getDuration(); - ArrayList items = new ArrayList<>(Arrays.asList(builder.getItemInputsBasic())); - int circuitConfig = 1; - if (items.size() == 1) {// Set circuit config if it is a dust -> ingot recipe. - ItemData data = GT_OreDictUnificator.getAssociation(items.get(0)); - if (data != null) { - OrePrefixes prefix = data.mPrefix; - if (OrePrefixes.dust.equals(prefix)) { - circuitConfig = 1; - } else if (OrePrefixes.dustSmall.equals(prefix)) { - circuitConfig = 4; - } else if (OrePrefixes.dustTiny.equals(prefix)) { - circuitConfig = 9; - } - } - } else { // Set circuit config if there is an integrated circuit - for (int i = 0; i < items.size(); i++) { - if (GT_Utility.isAnyIntegratedCircuit(items.get(i))) { - circuitConfig = items.get(i) - .getItemDamage(); - items.remove(i--); - } - } - } - - if (builder.getMetadataOrDefault(NO_GAS, false)) { - items.add(GT_Utility.getIntegratedCircuit(circuitConfig)); - ret.addAll( - builder.copy() - .itemInputs(items.toArray(new ItemStack[0])) - .fluidInputs() - .duration((int) Math.max(durationBase * 1.1, 1)) - .addTo(RecipeMaps.blastFurnaceRecipes)); - items.remove(items.size() - 1); - circuitConfig += 10; - } - - items.add(GT_Utility.getIntegratedCircuit(circuitConfig)); - boolean nobleGases = builder.getMetadataOrDefault(NOBLE_GASES, false); - boolean anaerobeGases = builder.getMetadataOrDefault(ANAEROBE_GASES, false); - Collection gases = new ArrayList<>(); - - if (nobleGases && anaerobeGases) { - gases = BlastFurnaceGasStat.getNobleAndAnaerobeGases(); - } else if (nobleGases) { - gases = BlastFurnaceGasStat.getNobleGases(); - } else if (anaerobeGases) { - gases = BlastFurnaceGasStat.getAnaerobeGases(); - } - for (BlastFurnaceGasStat gas : gases) { - int gasAmount = (int) (gas.recipeConsumedAmountMultiplier * basicGasAmount); - int duration = (int) Math.max(gas.recipeTimeMultiplier * durationBase, 1); - ret.addAll( - builder.copy() - .itemInputs(items.toArray(new ItemStack[0])) - .fluidInputs(GT_Utility.copyAmount(gasAmount, gas.gas)) - .duration(duration) - .addTo(RecipeMaps.blastFurnaceRecipes)); - } - return ret; - }); - - /** - * Just like any normal assembler recipe, however it accepts one input item to be oredicted. Pass in the item to - * oredict via {@link #OREDICT_INPUT}. It will be used along all other item inputs as input of this recipe. - */ - public static IRecipeMap AssemblerOD = IRecipeMap.newRecipeMap(builder -> { - Collection ret = new ArrayList<>(); - for (ItemStack input : GT_OreDictUnificator.getOresImmutable(builder.getMetadata(OREDICT_INPUT))) { - ret.addAll( - builder.copy() - .itemInputs(GT_RecipeMapUtil.appendArray(builder.getItemInputsBasic(), input)) - .addTo(RecipeMaps.assemblerRecipes)); - } - return ret; - }); - - /** - * A universal fuel adder. It's actually just a dispatcher towards all actual fuel recipe maps. - * Dispatch based on {@link #FUEL_TYPE}. Uses {@link #FUEL_VALUE} as fuel value. - * Can use {@link FuelType#ordinal()} as a human-readable form of what FUEL_TYPE should be. - * You can bypass this and add to relevant fuel maps directly if you wish. - */ - public static IRecipeMap Fuel = IRecipeMap.newRecipeMap(builder -> { - builder.validateInputCount(1, 1) - .validateNoInputFluid() - .validateOutputCount(-1, 1) - .validateNoOutputFluid(); - if (!builder.isValid()) return Collections.emptyList(); - Integer fuelType = builder.getMetadata(FUEL_TYPE); - if (fuelType == null) return Collections.emptyList(); - builder.metadata(FUEL_VALUE, builder.getMetadataOrDefault(FUEL_VALUE, 0)); - return FuelType.get(fuelType) - .getTarget() - .doAdd(builder); - }); - - public enum FuelType { - - // ORDER MATTERS. DO NOT INSERT ELEMENT BETWEEN EXISTING ONES - DieselFuel(RecipeMaps.dieselFuels), - GasTurbine(RecipeMaps.gasTurbineFuels), - // appears unused - HotFuel(RecipeMaps.hotFuels), - SemiFluid(RecipeMaps.denseLiquidFuels), - PlasmaTurbine(RecipeMaps.plasmaFuels), - Magic(RecipeMaps.magicFuels),; - - private static final FuelType[] VALUES = values(); - private final IRecipeMap target; - - FuelType(IRecipeMap target) { - this.target = target; - } - - public static FuelType get(int fuelType) { - if (fuelType < 0 || fuelType >= VALUES.length) return SemiFluid; - return VALUES[fuelType]; - } - - public IRecipeMap getTarget() { - return target; - } - } - - static { - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COIL_HEAT); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FUSION_THRESHOLD); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FUEL_VALUE); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NANO_FORGE_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FOG_EXOTIC_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FOG_PLASMA_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DEFC_CASING_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(CHEMPLANT_CASING_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(QFT_FOCUS_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DISSOLUTION_TANK_RATIO); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(RTG_DURATION_IN_DAYS); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(LNG_BASIC_OUTPUT); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NFR_COIL_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NKE_RANGE); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(PRECISE_ASSEMBLER_CASING_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COAL_CASING_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COMPRESSION_TIER); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(RESEARCH_STATION_DATA); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(SIEVERTS); - GT_RecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DECAY_TICKS); - - } -} diff --git a/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java b/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java deleted file mode 100644 index 67d50188fe..0000000000 --- a/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java +++ /dev/null @@ -1,198 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.Mods.GregTech; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Function; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; - -import cpw.mods.fml.common.Loader; -import gnu.trove.list.TIntList; -import gnu.trove.list.array.TIntArrayList; -import gregtech.api.interfaces.IRecipeMap; -import gregtech.api.recipe.RecipeMetadataKey; - -/** - * Define helpers useful in the creation of recipe maps. - */ -public class GT_RecipeMapUtil { - - public static final Function ALL_FAKE_RECIPE = r -> { - r.mFakeRecipe = true; - return r; - }; - - private static final Map addonRecipeMaps = new HashMap<>(); - private static final Multimap> delayedActions = ArrayListMultimap.create(); - - /** - * Set of metadata that work as alias for special values. - */ - public static final Set> SPECIAL_VALUE_ALIASES = new HashSet<>(); - - public static T[] appendArray(T[] arr, T val) { - T[] newArr = Arrays.copyOf(arr, arr.length + 1); - newArr[arr.length] = val; - return newArr; - } - - public static GT_RecipeTemplate asTemplate(GT_Recipe r) { - return asTemplate(r, false); - } - - public static GT_RecipeTemplate asTemplate(GT_Recipe r, boolean includeTemplate) { - return new GT_RecipeTemplate(r, includeTemplate); - } - - public static List buildRecipeForMultiblock(GT_RecipeBuilder b) { - return buildOrEmpty(convertCellToFluid(b, true)); - - } - - public static List buildRecipeForMultiblockNoCircuit(GT_RecipeBuilder b) { - return buildOrEmpty(convertCellToFluid(b, false)); - } - - public static GT_RecipeBuilder convertCellToFluid(GT_RecipeBuilder b, boolean removeIntegratedCircuit) { - List itemInputs = new ArrayList<>(Arrays.asList(b.getItemInputsBasic())); - List itemOutputs = new ArrayList<>(Arrays.asList(b.getItemOutputs())); - List fluidInputs = new ArrayList<>(Arrays.asList(b.getFluidInputs())); - List fluidOutputs = new ArrayList<>(Arrays.asList(b.getFluidOutputs())); - TIntList chances = b.getChances() != null ? new TIntArrayList(b.getChances()) : null; - cellToFluid(itemInputs, fluidInputs, removeIntegratedCircuit, null); - cellToFluid(itemOutputs, fluidOutputs, removeIntegratedCircuit, chances); - itemInputs.removeIf(Objects::isNull); - if (chances == null) { - itemOutputs.removeIf(Objects::isNull); - } - fluidInputs.removeIf(Objects::isNull); - fluidOutputs.removeIf(Objects::isNull); - b.itemInputs(itemInputs.toArray(new ItemStack[0])); - b.itemOutputs(itemOutputs.toArray(new ItemStack[0]), chances != null ? chances.toArray() : null); - b.fluidInputs(fluidInputs.toArray(new FluidStack[0])); - b.fluidOutputs(fluidOutputs.toArray(new FluidStack[0])); - return b; - } - - private static void cellToFluid(List items, List fluids, boolean removeIntegratedCircuit, - TIntList chances) { - for (int i = items.size() - 1; i >= 0; i--) { - ItemStack item = items.get(i); - if (GT_Utility.getFluidForFilledItem(item, true) != null || GT_Utility.isCellEmpty(item) - || (removeIntegratedCircuit && GT_Utility.isAnyIntegratedCircuit(item))) { - fluids.add(GT_Utility.convertCellToFluid(item)); - items.remove(i); - if (chances != null) chances.removeAt(i); - } - } - } - - public static List buildOrEmpty(GT_RecipeBuilder builder) { - return builder.build() - .map(Collections::singletonList) - .orElse(Collections.emptyList()); - } - - /** - * Register a recipe map as part of your mod's public API under your modID and your given identifier. - * - * @param identifier map name - * @param recipeMap the map to register - * @param dependencies fully qualified identifier of dependent recipe maps. scheduler will only add recipes to one - * of the dependent recipe maps and this recipe map concurrently, guaranteeing thread safety. - * Currently unused, but you are advised to fill them, so that when The Day (tm) comes we don't - * end up with a bunch of weird concurrency bugs. - */ - public static void registerRecipeMap(String identifier, IRecipeMap recipeMap, RecipeMapDependency... dependencies) { - String modId = Loader.instance() - .activeModContainer() - .getModId(); - if (GregTech.ID.equals(modId)) throw new IllegalStateException( - "do not register recipe map under the name of gregtech! do it in your own preinit!"); - String id = modId + "@" + identifier; - addonRecipeMaps.put(id, recipeMap); - for (Consumer action : delayedActions.get(id)) { - action.accept(recipeMap); - } - } - - /** - * Use this to register recipes for a recipe map in addon not present at compile time. - *

- * Do not use this for recipes maps already in {@link GT_RecipeConstants}. None of them will be available via this - * interface! - * - * @param identifier recipe map id - * @param registerAction DO NOT ADD RECIPES TO MAPS OTHER THAN THE ONE PASSED TO YOU. DO NOT DO ANYTHING OTHER THAN - * ADDING RECIPES TO THIS R - */ - public static void registerRecipesFor(String modid, String identifier, Consumer registerAction) { - String id = modid + "@" + identifier; - IRecipeMap map = addonRecipeMaps.get(id); - if (map == null) delayedActions.put(id, registerAction); - else registerAction.accept(map); - } - - public static final class GT_RecipeTemplate { - - private final GT_Recipe template; - private final List derivatives = new ArrayList<>(); - - private GT_RecipeTemplate(GT_Recipe template, boolean includeTemplate) { - this.template = template; - if (includeTemplate) derivatives.add(template); - } - - public GT_Recipe derive() { - GT_Recipe derived = template.copyShallow(); - derivatives.add(derived); - return derived; - } - - public List getAll() { - // fix shallow references - Set references = Collections.newSetFromMap(new IdentityHashMap<>()); - for (GT_Recipe r : derivatives) { - if (!references.add(r.mInputs)) r.mInputs = r.mInputs.clone(); - if (!references.add(r.mOutputs)) r.mOutputs = r.mOutputs.clone(); - if (!references.add(r.mFluidInputs)) r.mFluidInputs = r.mFluidInputs.clone(); - if (!references.add(r.mFluidOutputs)) r.mFluidOutputs = r.mFluidOutputs.clone(); - } - return derivatives; - } - } - - public static final class RecipeMapDependency { - - private final IRecipeMap obj; - private final String id; - - public RecipeMapDependency(IRecipeMap obj, String id) { - this.obj = obj; - this.id = id; - } - - public static RecipeMapDependency create(String id) { - return new RecipeMapDependency(null, id); - } - - public static RecipeMapDependency create(IRecipeMap obj) { - return new RecipeMapDependency(obj, null); - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java deleted file mode 100644 index 5acb15b242..0000000000 --- a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java +++ /dev/null @@ -1,872 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.enums.GT_Values.L; -import static gregtech.api.enums.GT_Values.M; -import static gregtech.api.enums.GT_Values.RA; -import static gregtech.api.enums.GT_Values.VP; -import static gregtech.api.enums.Materials.Bronze; -import static gregtech.api.enums.Materials.Cobalt; -import static gregtech.api.enums.Materials.DarkSteel; -import static gregtech.api.enums.Materials.Diamond; -import static gregtech.api.enums.Materials.FierySteel; -import static gregtech.api.enums.Materials.Gold; -import static gregtech.api.enums.Materials.Iron; -import static gregtech.api.enums.Materials.IronWood; -import static gregtech.api.enums.Materials.Knightmetal; -import static gregtech.api.enums.Materials.Lead; -import static gregtech.api.enums.Materials.Ruby; -import static gregtech.api.enums.Materials.Sapphire; -import static gregtech.api.enums.Materials.Steel; -import static gregtech.api.enums.Materials.Steeleaf; -import static gregtech.api.enums.Materials.Thaumium; -import static gregtech.api.enums.Materials.Void; -import static gregtech.api.recipe.RecipeMaps.fluidExtractionRecipes; -import static gregtech.api.recipe.RecipeMaps.hammerRecipes; -import static gregtech.api.recipe.RecipeMaps.maceratorRecipes; -import static gregtech.api.recipe.RecipeMaps.wiremillRecipes; -import static gregtech.api.util.GT_RecipeBuilder.SECONDS; -import static gregtech.api.util.GT_RecipeBuilder.TICKS; -import static gregtech.api.util.GT_RecipeConstants.RECYCLE; -import static gregtech.api.util.GT_RecipeConstants.UniversalArcFurnace; -import static gregtech.api.util.GT_Utility.calculateRecipeEU; -import static gregtech.api.util.GT_Utility.getTier; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; - -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.CraftingManager; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.ShapedRecipes; -import net.minecraft.item.crafting.ShapelessRecipes; -import net.minecraftforge.oredict.ShapedOreRecipe; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.SetMultimap; - -import cpw.mods.fml.relauncher.ReflectionHelper; -import gregtech.api.GregTech_API; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.SubTag; -import gregtech.api.enums.TierEU; -import gregtech.api.objects.ItemData; -import gregtech.api.objects.MaterialStack; -import gregtech.api.recipe.RecipeCategories; -import ic2.api.reactor.IReactorComponent; - -/** - * Class for Automatic Recipe registering. - */ -public class GT_RecipeRegistrator { - - /** - * List of Materials, which are used in the Creation of Sticks. All Rod Materials are automatically added to this - * List. - */ - public static final List sRodMaterialList = new ArrayList<>(); - - private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0); - private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R"; - private static final RecipeShape[] sShapes = new RecipeShape[] { - new RecipeShape(sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1, null), - new RecipeShape(sMt1, null, sMt1, sMt1, null, sMt1, sMt1, sMt1, sMt1), - new RecipeShape(null, sMt1, null, sMt1, sMt1, sMt1, sMt1, null, sMt1), - new RecipeShape(sMt1, sMt1, sMt1, sMt1, null, sMt1, null, null, null), - new RecipeShape(sMt1, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1), - new RecipeShape(sMt1, sMt1, sMt1, sMt1, null, sMt1, sMt1, null, sMt1), - new RecipeShape(null, null, null, sMt1, null, sMt1, sMt1, null, sMt1), - new RecipeShape(null, sMt1, null, null, sMt1, null, null, sMt2, null), - new RecipeShape(sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2, null), - new RecipeShape(null, sMt1, null, null, sMt2, null, null, sMt2, null), - new RecipeShape(sMt1, sMt1, null, sMt1, sMt2, null, null, sMt2, null), - new RecipeShape(null, sMt1, sMt1, null, sMt2, sMt1, null, sMt2, null), - new RecipeShape(sMt1, sMt1, null, null, sMt2, null, null, sMt2, null), - new RecipeShape(null, sMt1, sMt1, null, sMt2, null, null, sMt2, null), - new RecipeShape(null, sMt1, null, sMt1, null, null, null, sMt1, sMt2), - new RecipeShape(null, sMt1, null, null, null, sMt1, sMt2, sMt1, null), - new RecipeShape(null, sMt1, null, sMt1, null, sMt1, null, null, sMt2), - new RecipeShape(null, sMt1, null, sMt1, null, sMt1, sMt2, null, null), - new RecipeShape(null, sMt2, null, null, sMt1, null, null, sMt1, null), - new RecipeShape(null, sMt2, null, null, sMt2, null, sMt1, sMt1, sMt1), - new RecipeShape(null, sMt2, null, null, sMt2, null, null, sMt1, null), - new RecipeShape(null, sMt2, null, sMt1, sMt2, null, sMt1, sMt1, null), - new RecipeShape(null, sMt2, null, null, sMt2, sMt1, null, sMt1, sMt1), - new RecipeShape(null, sMt2, null, null, sMt2, null, sMt1, sMt1, null), - new RecipeShape(sMt1, null, null, null, sMt2, null, null, null, sMt2), - new RecipeShape(null, null, sMt1, null, sMt2, null, sMt2, null, null), - new RecipeShape(sMt1, null, null, null, sMt2, null, null, null, null), - new RecipeShape(null, null, sMt1, null, sMt2, null, null, null, null), - new RecipeShape(sMt1, sMt2, null, null, null, null, null, null, null), - new RecipeShape(sMt2, sMt1, null, null, null, null, null, null, null), - new RecipeShape(sMt1, null, null, sMt2, null, null, null, null, null), - new RecipeShape(sMt2, null, null, sMt1, null, null, null, null, null), - new RecipeShape(sMt1, sMt1, sMt1, sMt1, sMt1, sMt1, null, sMt2, null), - new RecipeShape(sMt1, sMt1, null, sMt1, sMt1, sMt2, sMt1, sMt1, null), - new RecipeShape(null, sMt1, sMt1, sMt2, sMt1, sMt1, null, sMt1, sMt1), - new RecipeShape(null, sMt2, null, sMt1, sMt1, sMt1, sMt1, sMt1, sMt1), - new RecipeShape(sMt1, sMt1, sMt1, sMt1, sMt2, sMt1, null, sMt2, null), - new RecipeShape(sMt1, sMt1, null, sMt1, sMt2, sMt2, sMt1, sMt1, null), - new RecipeShape(null, sMt1, sMt1, sMt2, sMt2, sMt1, null, sMt1, sMt1), - new RecipeShape(null, sMt2, null, sMt1, sMt2, sMt1, sMt1, sMt1, sMt1), - new RecipeShape(sMt1, null, null, null, sMt1, null, null, null, null), - new RecipeShape(null, sMt1, null, sMt1, null, null, null, null, null), - new RecipeShape(sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null), - new RecipeShape(null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2) }; - public static final Field SHAPED_ORE_RECIPE_WIDTH = ReflectionHelper.findField(ShapedOreRecipe.class, "width"); - public static final Field SHAPED_ORE_RECIPE_HEIGHT = ReflectionHelper.findField(ShapedOreRecipe.class, "height"); - private static volatile Map> indexedRecipeListCache; - private static final String[][] sShapesA = new String[][] { null, null, null, - { "Helmet", s_P + s_P + s_P, s_P + s_H + s_P }, - { "ChestPlate", s_P + s_H + s_P, s_P + s_P + s_P, s_P + s_P + s_P }, - { "Pants", s_P + s_P + s_P, s_P + s_H + s_P, s_P + " " + s_P }, { "Boots", s_P + " " + s_P, s_P + s_H + s_P }, - { "Sword", " " + s_P + " ", s_F + s_P + s_H, " " + s_R + " " }, - { "Pickaxe", s_P + s_I + s_I, s_F + s_R + s_H, " " + s_R + " " }, - { "Shovel", s_F + s_P + s_H, " " + s_R + " ", " " + s_R + " " }, - { "Axe", s_P + s_I + s_H, s_P + s_R + " ", s_F + s_R + " " }, - { "Axe", s_P + s_I + s_H, s_P + s_R + " ", s_F + s_R + " " }, - { "Hoe", s_P + s_I + s_H, s_F + s_R + " ", " " + s_R + " " }, - { "Hoe", s_P + s_I + s_H, s_F + s_R + " ", " " + s_R + " " }, - { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, - { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, - { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, - { "Sickle", " " + s_P + " ", s_P + s_F + " ", s_H + s_P + s_R }, - { "Sword", " " + s_R + " ", s_F + s_P + s_H, " " + s_P + " " }, - { "Pickaxe", " " + s_R + " ", s_F + s_R + s_H, s_P + s_I + s_I }, - { "Shovel", " " + s_R + " ", " " + s_R + " ", s_F + s_P + s_H }, - { "Axe", s_F + s_R + " ", s_P + s_R + " ", s_P + s_I + s_H }, - { "Axe", s_F + s_R + " ", s_P + s_R + " ", s_P + s_I + s_H }, - { "Hoe", " " + s_R + " ", s_F + s_R + " ", s_P + s_I + s_H }, - { "Hoe", " " + s_R + " ", s_F + s_R + " ", s_P + s_I + s_H }, - { "Spear", s_P + s_H + " ", s_F + s_R + " ", " " + " " + s_R }, - { "Spear", s_P + s_H + " ", s_F + s_R + " ", " " + " " + s_R }, { "Knive", s_H + s_P, s_R + s_F }, - { "Knive", s_F + s_H, s_P + s_R }, { "Knive", s_F + s_H, s_P + s_R }, { "Knive", s_P + s_F, s_R + s_H }, - { "Knive", s_P + s_F, s_R + s_H }, null, null, null, null, - { "WarAxe", s_P + s_P + s_P, s_P + s_R + s_P, s_F + s_R + s_H }, null, null, null, - { "Shears", s_H + s_P, s_P + s_F }, { "Shears", s_H + s_P, s_P + s_F }, - { "Scythe", s_I + s_P + s_H, s_R + s_F + s_P, s_R + " " + " " }, - { "Scythe", s_H + s_P + s_I, s_P + s_F + s_R, " " + " " + s_R } }; - - static { - // flush the cache on post load finish - GregTech_API.sAfterGTPostload.add(() -> indexedRecipeListCache = null); - } - - public static void registerMaterialRecycling(ItemStack aStack, Materials aMaterial, long aMaterialAmount, - MaterialStack aByproduct) { - if (GT_Utility.isStackInvalid(aStack)) return; - if (aByproduct != null) { - aByproduct = aByproduct.clone(); - aByproduct.mAmount /= aStack.stackSize; - } - GT_OreDictUnificator.addItemData( - GT_Utility.copyAmount(1, aStack), - new ItemData(aMaterial, aMaterialAmount / aStack.stackSize, aByproduct)); - } - - public static void registerMaterialRecycling(ItemStack aStack, ItemData aData) { - if (GT_Utility.isStackInvalid(aStack) || GT_Utility.areStacksEqual(new ItemStack(Items.blaze_rod), aStack) - || aData == null - || !aData.hasValidMaterialData() - || !aData.mMaterial.mMaterial.mAutoGenerateRecycleRecipes - || aData.mMaterial.mAmount <= 0 - || GT_Utility.getFluidForFilledItem(aStack, false) != null - || aData.mMaterial.mMaterial.mSubTags.contains(SubTag.NO_RECIPES)) return; - registerReverseMacerating(GT_Utility.copyAmount(1, aStack), aData, aData.mPrefix == null); - if (!GT_Utility.areStacksEqual(GT_ModHandler.getIC2Item("iridiumOre", 1L), aStack)) { - registerReverseSmelting( - GT_Utility.copyAmount(1, aStack), - aData.mMaterial.mMaterial, - aData.mMaterial.mAmount, - true); - registerReverseFluidSmelting( - GT_Utility.copyAmount(1, aStack), - aData.mMaterial.mMaterial, - aData.mMaterial.mAmount, - aData.getByProduct(0)); - registerReverseArcSmelting(GT_Utility.copyAmount(1, aStack), aData); - } - } - - /** - * @param aStack the stack to be recycled. - * @param aMaterial the Material. - * @param aMaterialAmount the amount of it in Material Units. - */ - public static void registerReverseFluidSmelting(ItemStack aStack, Materials aMaterial, long aMaterialAmount, - MaterialStack aByproduct) { - if (aStack == null || aMaterial == null - || aMaterial.mSmeltInto.mStandardMoltenFluid == null - || !aMaterial.contains(SubTag.SMELTING_TO_FLUID) - || (L * aMaterialAmount) / (M * aStack.stackSize) <= 0) return; - - ItemStack recipeOutput = aByproduct == null ? null - : aByproduct.mMaterial.contains(SubTag.NO_SMELTING) || !aByproduct.mMaterial.contains(SubTag.METAL) - ? aByproduct.mMaterial.contains(SubTag.FLAMMABLE) - ? GT_OreDictUnificator.getDust(Materials.Ash, aByproduct.mAmount / 2) - : aByproduct.mMaterial.contains(SubTag.UNBURNABLE) - ? GT_OreDictUnificator.getDustOrIngot(aByproduct.mMaterial.mSmeltInto, aByproduct.mAmount) - : null - : GT_OreDictUnificator.getIngotOrDust(aByproduct.mMaterial.mSmeltInto, aByproduct.mAmount); - - GT_RecipeBuilder builder = RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, aStack)); - if (recipeOutput != null) { - builder.itemOutputs(recipeOutput); - } - long powerUsage = Math.max(8, (long) Math.sqrt(2 * aMaterial.mSmeltInto.mStandardMoltenFluid.getTemperature())); - // avoid full amp recipes - int powerTier = getTier(powerUsage); - if (powerTier > 0 && powerTier < VP.length && powerUsage > VP[powerTier]) { - powerUsage = VP[powerTier]; - } - builder.fluidOutputs(aMaterial.mSmeltInto.getMolten((L * aMaterialAmount) / (M * aStack.stackSize))) - .duration((int) Math.max(1, (24 * aMaterialAmount) / M)) - .eut(powerUsage) - .recipeCategory(RecipeCategories.fluidExtractorRecycling) - .addTo(fluidExtractionRecipes); - } - - /** - * @param aStack the stack to be recycled. - * @param aMaterial the Material. - * @param aMaterialAmount the amount of it in Material Units. - * @param aAllowAlloySmelter if it is allowed to be recycled inside the Alloy Smelter. - */ - public static void registerReverseSmelting(ItemStack aStack, Materials aMaterial, long aMaterialAmount, - boolean aAllowAlloySmelter) { - if (aStack == null || aMaterial == null - || aMaterialAmount <= 0 - || aMaterial.contains(SubTag.NO_SMELTING) - || (aMaterialAmount > M && aMaterial.contains(SubTag.METAL)) - || (aMaterial.getProcessingMaterialTierEU() > TierEU.IV)) return; - if (aMaterial == Materials.Naquadah || aMaterial == Materials.NaquadahEnriched) return; - - aMaterialAmount /= aStack.stackSize; - - if (aAllowAlloySmelter) GT_ModHandler.addSmeltingAndAlloySmeltingRecipe( - GT_Utility.copyAmount(1, aStack), - GT_OreDictUnificator.getIngot(aMaterial.mSmeltInto, aMaterialAmount), - false); - else GT_ModHandler.addSmeltingRecipe( - GT_Utility.copyAmount(1, aStack), - GT_OreDictUnificator.getIngot(aMaterial.mSmeltInto, aMaterialAmount)); - } - - public static void registerReverseArcSmelting(ItemStack aStack, Materials aMaterial, long aMaterialAmount, - MaterialStack aByProduct01, MaterialStack aByProduct02, MaterialStack aByProduct03) { - registerReverseArcSmelting( - aStack, - new ItemData( - aMaterial == null ? null : new MaterialStack(aMaterial, aMaterialAmount), - aByProduct01, - aByProduct02, - aByProduct03)); - } - - public static void registerReverseArcSmelting(ItemStack aStack, ItemData aData) { - if (aStack == null || aData == null) return; - aData = new ItemData(aData); - - if (!aData.hasValidMaterialData()) return; - boolean isRecycle = true; - - for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { - if (tMaterial.mMaterial == Materials.Iron || tMaterial.mMaterial == Materials.Copper - || tMaterial.mMaterial == Materials.WroughtIron - || tMaterial.mMaterial == Materials.AnnealedCopper) { - ItemData stackData = GT_OreDictUnificator.getItemData(aStack); - if (stackData != null - && (stackData.mPrefix == OrePrefixes.ingot || stackData.mPrefix == OrePrefixes.dust)) { - // iron ingot/dust -> wrought iron, copper ingot/dust -> annealed copper - isRecycle = false; - } - } - - if (tMaterial.mMaterial.contains(SubTag.UNBURNABLE)) { - tMaterial.mMaterial = tMaterial.mMaterial.mSmeltInto.mArcSmeltInto; - continue; - } - if (tMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) { - tMaterial.mMaterial = Materials.Ash; - tMaterial.mAmount /= 16; - continue; - } - if (tMaterial.mMaterial.contains(SubTag.FLAMMABLE)) { - tMaterial.mMaterial = Materials.Ash; - tMaterial.mAmount /= 8; - continue; - } - if (tMaterial.mMaterial.contains(SubTag.NO_SMELTING)) { - tMaterial.mAmount = 0; - continue; - } - if (tMaterial.mMaterial.contains(SubTag.METAL)) { - - tMaterial.mMaterial = tMaterial.mMaterial.mSmeltInto.mArcSmeltInto; - continue; - } - tMaterial.mAmount = 0; - } - - aData = new ItemData(aData); - if (aData.mByProducts.length > 3) for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { - if (tMaterial.mMaterial == Materials.Ash) tMaterial.mAmount = 0; - } - - aData = new ItemData(aData); - - if (!aData.hasValidMaterialData()) return; - - long tAmount = 0; - for (MaterialStack tMaterial : aData.getAllMaterialStacks()) - tAmount += tMaterial.mAmount * tMaterial.mMaterial.getMass(); - - ArrayList outputs = new ArrayList<>(); - if (GT_OreDictUnificator.getIngotOrDust(aData.mMaterial) != null) { - outputs.add(GT_OreDictUnificator.getIngotOrDust(aData.mMaterial)); - } - for (int i = 0; i < 8; i++) { - if (GT_OreDictUnificator.getIngotOrDust(aData.getByProduct(i)) != null) { - outputs.add(GT_OreDictUnificator.getIngotOrDust(aData.getByProduct(i))); - } - } - if (!outputs.isEmpty()) { - GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder(); - recipeBuilder.itemInputs(aStack) - .itemOutputs(outputs.toArray(new ItemStack[0])) - .fluidInputs(Materials.Oxygen.getGas((int) Math.max(16, tAmount / M))) - .duration(((int) Math.max(16, tAmount / M)) * TICKS) - .eut(90) - .metadata(RECYCLE, isRecycle) - .addTo(UniversalArcFurnace); - } - - } - - public static void registerReverseMacerating(ItemStack aStack, Materials aMaterial, long aMaterialAmount, - MaterialStack aByProduct01, MaterialStack aByProduct02, MaterialStack aByProduct03, boolean aAllowHammer) { - registerReverseMacerating( - aStack, - new ItemData( - aMaterial == null ? null : new MaterialStack(aMaterial, aMaterialAmount), - aByProduct01, - aByProduct02, - aByProduct03), - aAllowHammer); - } - - public static void registerReverseMacerating(ItemStack aStack, ItemData aData, boolean aAllowHammer) { - if (aStack == null || aData == null) return; - aData = new ItemData(aData); - - if (!aData.hasValidMaterialData()) return; - - for (MaterialStack tMaterial : aData.getAllMaterialStacks()) - tMaterial.mMaterial = tMaterial.mMaterial.mMacerateInto; - - aData = new ItemData(aData); - - if (!aData.hasValidMaterialData()) return; - - long tAmount = 0; - for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { - tAmount += tMaterial.mAmount * tMaterial.mMaterial.getMass(); - } - - { - ArrayList outputs = new ArrayList<>(); - if (GT_OreDictUnificator.getDust(aData.mMaterial) != null) { - outputs.add(GT_OreDictUnificator.getDust(aData.mMaterial)); - } - for (int i = 0; i < 3; i++) { - if (GT_OreDictUnificator.getDust(aData.getByProduct(i)) != null) { - outputs.add(GT_OreDictUnificator.getDust(aData.getByProduct(i))); - } - } - if (!outputs.isEmpty()) { - ItemStack[] outputsArray = outputs.toArray(new ItemStack[0]); - GT_RecipeBuilder recipeBuilder = GT_Values.RA.stdBuilder(); - recipeBuilder.itemInputs(aStack) - .itemOutputs(outputsArray) - .duration( - (aData.mMaterial.mMaterial == Materials.Marble ? 1 : (int) Math.max(16, tAmount / M)) * TICKS) - .eut(4) - .recipeCategory(RecipeCategories.maceratorRecycling) - .addTo(maceratorRecipes); - } - } - - if (!aAllowHammer) { - return; - } - - for (MaterialStack tMaterial : aData.getAllMaterialStacks()) { - if (tMaterial.mMaterial.contains(SubTag.CRYSTAL) && !tMaterial.mMaterial.contains(SubTag.METAL) - && tMaterial.mMaterial != Materials.Glass - && GT_OreDictUnificator.getDust(aData.mMaterial) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(GT_Utility.copyAmount(1, aStack)) - .itemOutputs(GT_OreDictUnificator.getDust(aData.mMaterial)) - .duration(10 * SECONDS) - .eut(TierEU.RECIPE_LV) - .recipeCategory(RecipeCategories.forgeHammerRecycling) - .addTo(hammerRecipes); - break; - } - } - - } - - /** - * Place Materials which you want to replace in Non-GT-Recipes here (warning HUGHE impact on loading times!) - */ - private static final Materials[] VANILLA_MATS = { Cobalt, Gold, Iron, Lead, FierySteel, Void, Bronze, Diamond, Ruby, - Sapphire, Steel, IronWood, Steeleaf, Knightmetal, Thaumium, DarkSteel, }; - - /** - * You give this Function a Material and it will scan almost everything for adding recycling Recipes and replacing - * Ingots, Gems etc. - * - * @param aMats Materials, for example an Ingot or a Gem. - * @param aPlate the Plate referenced to aMat - * @param aRecipeReplacing allows to replace the Recipe with a Plate variant - */ - public static synchronized void registerUsagesForMaterials(String aPlate, boolean aRecipeReplacing, - ItemStack... aMats) { - for (ItemStack aMat : aMats) { - aMat = GT_Utility.copyOrNull(aMat); - - if (aMat == null) continue; - - ItemData aItemData = GT_OreDictUnificator.getItemData(aMat); - if (aItemData == null || aItemData.mPrefix != OrePrefixes.ingot) aPlate = null; - if (aPlate != null && GT_OreDictUnificator.getFirstOre(aPlate, 1) == null) aPlate = null; - - sMt1.func_150996_a(aMat.getItem()); - sMt1.stackSize = 1; - Items.feather.setDamage(sMt1, Items.feather.getDamage(aMat)); - - sMt2.func_150996_a(new ItemStack(Blocks.dirt).getItem()); - sMt2.stackSize = 1; - Items.feather.setDamage(sMt2, 0); - - if (aItemData != null && aItemData.hasValidPrefixMaterialData()) { - for (RecipeShape tRecipe : sShapes) { - for (ItemStack tCrafted : GT_ModHandler.getRecipeOutputsBuffered(tRecipe.shape)) { - GT_OreDictUnificator.addItemData( - tCrafted, - new ItemData(aItemData.mMaterial.mMaterial, aItemData.mMaterial.mAmount * tRecipe.amount1)); - // - // GT_Log.out.println("###################################################################################"); - // GT_Log.out.println("registerUsagesForMaterials used aPlate: "+aPlate); - // GT_Log.out.println("registerUsagesForMaterials used aPlate: - // "+aMat.getUnlocalizedName()); - // GT_Log.out.println("registerUsagesForMaterials used aPlate: - // "+aMat.getDisplayName()); - // - // GT_Log.out.println("###################################################################################"); - } - } - } - registerStickStuff(aPlate, aItemData, aRecipeReplacing); - } - } - - private static List getRecipeList(RecipeShape shape) { - boolean force = !GregTech_API.sPostloadStarted || GregTech_API.sPostloadFinished; - if (force || indexedRecipeListCache == null) { - synchronized (GT_RecipeRegistrator.class) { - if (indexedRecipeListCache == null || force) { - indexedRecipeListCache = createIndexedRecipeListCache(); - } - } - } - return indexedRecipeListCache.get(shape); - } - - private static Map> createIndexedRecipeListCache() { - Map> result = new IdentityHashMap<>(); - ArrayList allRecipeList = (ArrayList) CraftingManager.getInstance() - .getRecipeList(); - // filter using the empty slots in the shape. - // if the empty slots doesn't match, the recipe will definitely fail - SetMultimap, RecipeShape> filter = HashMultimap.create(); - for (RecipeShape shape : sShapes) { - for (List list : shape.getEmptySlotsAllVariants()) { - filter.put(list, shape); - } - } - List buffer = new ArrayList<>(9); - for (IRecipe tRecipe : allRecipeList) { - if (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe) { - // we don't target shapeless recipes - continue; - } - buffer.clear(); - ItemStack tStack = tRecipe.getRecipeOutput(); - if (GT_Utility.isStackValid(tStack) && tStack.getMaxStackSize() == 1 - && tStack.getMaxDamage() > 0 - && !(tStack.getItem() instanceof ItemBlock) - && !(tStack.getItem() instanceof IReactorComponent) - && !GT_ModHandler.isElectricItem(tStack) - && !GT_Utility.isStackInList(tStack, GT_ModHandler.sNonReplaceableItems)) { - if (tRecipe instanceof ShapedOreRecipe tShapedRecipe) { - if (checkRecipeShape( - buffer, - tShapedRecipe.getInput(), - getRecipeWidth(tShapedRecipe), - getRecipeHeight(tShapedRecipe))) { - for (RecipeShape s : filter.get(buffer)) { - result.computeIfAbsent(s, k -> new ArrayList<>()) - .add(tRecipe); - } - } - } else if (tRecipe instanceof ShapedRecipes tShapedRecipe) { - if (checkRecipeShape( - buffer, - tShapedRecipe.recipeItems, - getRecipeWidth(tShapedRecipe), - getRecipeHeight(tShapedRecipe))) { - for (RecipeShape s : filter.get(buffer)) { - result.computeIfAbsent(s, k -> new ArrayList<>()) - .add(tRecipe); - } - } - } else { - for (RecipeShape s : sShapes) { - // unknown recipe type. cannot determine empty slots. we choose to add to the recipe list for - // all shapes - result.computeIfAbsent(s, k -> new ArrayList<>()) - .add(tRecipe); - } - } - } - } - return result; - } - - private static boolean checkRecipeShape(List emptySlotIndexesBuffer, Object[] input, int tRecipeWidth, - int tRecipeHeight) { - for (int y = 0; y < 3; y++) { - for (int x = 0; x < 3; x++) { - if (x >= tRecipeWidth || y >= tRecipeHeight) { - emptySlotIndexesBuffer.add(x + y * 3); - continue; - } - Object tObject = input[x + y * tRecipeWidth]; - if (tObject == null) { - emptySlotIndexesBuffer.add(x + y * 3); - continue; - } - if (tObject instanceof ItemStack - && (((ItemStack) tObject).getItem() == null || ((ItemStack) tObject).getMaxStackSize() < 2 - || ((ItemStack) tObject).getMaxDamage() > 0 - || ((ItemStack) tObject).getItem() instanceof ItemBlock)) { - return false; - } - if (tObject instanceof List && ((List) tObject).isEmpty()) { - return false; - } - } - } - return true; - } - - private static synchronized void registerStickStuff(String aPlate, ItemData aItemData, boolean aRecipeReplacing) { - ItemStack tStack; - for (Materials tMaterial : sRodMaterialList) { - ItemStack tMt2 = GT_OreDictUnificator.get(OrePrefixes.stick, tMaterial, 1); - if (tMt2 != null) { - sMt2.func_150996_a(tMt2.getItem()); - sMt2.stackSize = 1; - Items.feather.setDamage(sMt2, Items.feather.getDamage(tMt2)); - - for (int i = 0; i < sShapes.length; i++) { - RecipeShape tRecipe = sShapes[i]; - - for (ItemStack tCrafted : GT_ModHandler - .getRecipeOutputs(getRecipeList(tRecipe), true, tRecipe.shape)) { - if (aItemData != null && aItemData.hasValidPrefixMaterialData()) - GT_OreDictUnificator.addItemData( - tCrafted, - new ItemData( - aItemData.mMaterial.mMaterial, - aItemData.mMaterial.mAmount * tRecipe.amount1, - new MaterialStack(tMaterial, OrePrefixes.stick.mMaterialAmount * tRecipe.amount2))); - - if (aRecipeReplacing && aPlate != null && sShapesA[i] != null && sShapesA[i].length > 1) { - assert aItemData != null; - - if (null != (tStack = GT_ModHandler.removeRecipe(tRecipe.shape))) { - switch (sShapesA[i].length) { - case 2 -> GT_ModHandler.addCraftingRecipe( - tStack, - GT_ModHandler.RecipeBits.BUFFERED, - new Object[] { sShapesA[i][1], s_P.charAt(0), aPlate, s_R.charAt(0), - OrePrefixes.stick.get(tMaterial), s_I.charAt(0), aItemData }); - case 3 -> GT_ModHandler.addCraftingRecipe( - tStack, - GT_ModHandler.RecipeBits.BUFFERED, - new Object[] { sShapesA[i][1], sShapesA[i][2], s_P.charAt(0), aPlate, - s_R.charAt(0), OrePrefixes.stick.get(tMaterial), s_I.charAt(0), - aItemData }); - default -> GT_ModHandler.addCraftingRecipe( - tStack, - GT_ModHandler.RecipeBits.BUFFERED, - new Object[] { sShapesA[i][1], sShapesA[i][2], sShapesA[i][3], s_P.charAt(0), - aPlate, s_R.charAt(0), OrePrefixes.stick.get(tMaterial), s_I.charAt(0), - aItemData }); - } - } - } - } - } - } - } - } - - /** - * Registers wiremill recipes for given material using integrated circuits. - * - * @param aMaterial material to register - * @param baseDuration base duration ticks for ingot -> 1x wire recipe - * @param aEUt EU/t for recipe If you provide a proper EU tier for recipe processing then aEUt will be - * overriden with it. - */ - public static void registerWiremillRecipes(Materials aMaterial, int baseDuration, int aEUt) { - registerWiremillRecipes( - aMaterial, - baseDuration, - calculateRecipeEU(aMaterial, aEUt), - OrePrefixes.ingot, - OrePrefixes.stick, - 2); - } - - /** - * Registers wiremill recipes for given material using integrated circuits. - * - * @param aMaterial material to register - * @param baseDuration base duration ticks for ingot -> 1x wire recipe - * @param aEUt EU/t for recipe - * @param prefix1 prefix corresponds to ingot - * @param prefix2 prefix corresponds to stick - * @param multiplier amount of wires created from 1 ingot - */ - public static void registerWiremillRecipes(Materials aMaterial, int baseDuration, int aEUt, OrePrefixes prefix1, - OrePrefixes prefix2, int multiplier) { - if (GT_OreDictUnificator.get(prefix1, aMaterial, 1L) != null - && GT_OreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(GT_OreDictUnificator.get(prefix1, aMaterial, 1L), GT_Utility.getIntegratedCircuit(1)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, multiplier)) - .duration(baseDuration * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix1, aMaterial, 2L / multiplier), - GT_Utility.getIntegratedCircuit(2)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt02, aMaterial, 1L)) - .duration(((int) (baseDuration * 1.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix1, aMaterial, 4L / multiplier), - GT_Utility.getIntegratedCircuit(4)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt04, aMaterial, 1L)) - .duration(baseDuration * 2 * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix1, aMaterial, 8L / multiplier), - GT_Utility.getIntegratedCircuit(8)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt08, aMaterial, 1L)) - .duration(((int) (baseDuration * 2.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix1, aMaterial, 12L / multiplier), - GT_Utility.getIntegratedCircuit(12)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt12, aMaterial, 1L)) - .duration(baseDuration * 3 * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix1, aMaterial, 16L / multiplier), - GT_Utility.getIntegratedCircuit(16)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt16, aMaterial, 1L)) - .duration(((int) (baseDuration * 3.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - } - - if (GT_OreDictUnificator.get(prefix2, aMaterial, 1L) != null - && GT_OreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(GT_OreDictUnificator.get(prefix2, aMaterial, 1L), GT_Utility.getIntegratedCircuit(1)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt01, aMaterial, 2L / multiplier)) - .duration(((int) (baseDuration * 0.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix2, aMaterial, 4L / multiplier), - GT_Utility.getIntegratedCircuit(2)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt02, aMaterial, 1L)) - .duration(baseDuration * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix2, aMaterial, 8L / multiplier), - GT_Utility.getIntegratedCircuit(4)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt04, aMaterial, 1L)) - .duration(((int) (baseDuration * 1.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix2, aMaterial, 16L / multiplier), - GT_Utility.getIntegratedCircuit(8)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt08, aMaterial, 1L)) - .duration(baseDuration * 2 * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix2, aMaterial, 24L / multiplier), - GT_Utility.getIntegratedCircuit(12)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt12, aMaterial, 1L)) - .duration(((int) (baseDuration * 2.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - GT_Values.RA.stdBuilder() - .itemInputs( - GT_OreDictUnificator.get(prefix2, aMaterial, 32L / multiplier), - GT_Utility.getIntegratedCircuit(16)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireGt16, aMaterial, 1L)) - .duration(baseDuration * 3 * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - } - if (GT_OreDictUnificator.get(prefix1, aMaterial, 1L) != null - && GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(GT_OreDictUnificator.get(prefix1, aMaterial, 1L), GT_Utility.getIntegratedCircuit(3)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 4L * multiplier)) - .duration(baseDuration * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - } - if (GT_OreDictUnificator.get(prefix2, aMaterial, 1L) != null - && GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 1L) != null) { - GT_Values.RA.stdBuilder() - .itemInputs(GT_OreDictUnificator.get(prefix2, aMaterial, 1L), GT_Utility.getIntegratedCircuit(3)) - .itemOutputs(GT_OreDictUnificator.get(OrePrefixes.wireFine, aMaterial, 2L * multiplier)) - .duration(((int) (baseDuration * 0.5f)) * TICKS) - .eut(aEUt) - .addTo(wiremillRecipes); - } - } - - public static boolean hasVanillaRecipes(Materials materials) { - return Arrays.stream(VANILLA_MATS) - .anyMatch(mat -> mat == materials); - } - - private static int getRecipeWidth(ShapedOreRecipe r) { - try { - return (int) SHAPED_ORE_RECIPE_WIDTH.get(r); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - private static int getRecipeHeight(ShapedOreRecipe r) { - try { - return (int) SHAPED_ORE_RECIPE_HEIGHT.get(r); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - private static int getRecipeHeight(ShapedRecipes r) { - return r.recipeHeight; - } - - private static int getRecipeWidth(ShapedRecipes r) { - return r.recipeWidth; - } - - private static class RecipeShape { - - private final ItemStack[] shape; - private int amount1; - private int amount2; - - public RecipeShape(ItemStack... shape) { - this.shape = shape; - - for (ItemStack stack : shape) { - if (stack == sMt1) this.amount1++; - if (stack == sMt2) this.amount2++; - } - } - - public List> getEmptySlotsAllVariants() { - // "shake" the grid in 8 direction and see if the recipe shape is still valid - // also include the "no movement" case - ImmutableList.Builder> b = ImmutableList.builder(); - for (int i = -1; i < 2; i++) { - if (i != 0 && !isColClear(i + 1)) continue; - for (int j = -1; j < 2; j++) { - if (j != 0 && !isRowClear(j + 1)) continue; - b.add(getEmptySlots(i, j)); - } - } - return b.build(); - } - - private boolean isRowClear(int row) { - for (int i = 0; i < 3; i++) { - if (shape[i + row * 3] != null) return false; - } - return true; - } - - private boolean isColClear(int col) { - for (int i = 0; i < 3; i++) { - if (shape[col + i * 3] != null) return false; - } - return true; - } - - private List getEmptySlots(int offsetX, int offsetY) { - ImmutableList.Builder b = ImmutableList.builder(); - for (int i = 0; i < shape.length; i++) { - int mappedIndex = i - offsetX - offsetY * 3; - // empty slot if it either - // 1) map to a slot outside the original shape - // 2) map to an empty slot in original shape - if (mappedIndex < 0 || mappedIndex > 8 || shape[mappedIndex] == null) b.add(i); - } - return b.build(); - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_RenderingWorld.java b/src/main/java/gregtech/api/util/GT_RenderingWorld.java deleted file mode 100644 index 7220b921a5..0000000000 --- a/src/main/java/gregtech/api/util/GT_RenderingWorld.java +++ /dev/null @@ -1,195 +0,0 @@ -package gregtech.api.util; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.ChunkPosition; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.event.world.ChunkEvent; -import net.minecraftforge.event.world.WorldEvent; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.EventPriority; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; - -/** - * Provide a fake IBlockAccess to support CTM. Facade are supposed to set these when they are placed/received by client. - */ -public class GT_RenderingWorld implements IBlockAccess { - - private static final GT_RenderingWorld INSTANCE = new GT_RenderingWorld(); - /* - * I do not think this map would ever grow too huge, so I won't go too overcomplicated on this one - */ - private final Map infos = new HashMap<>(); - private final Map> index = new HashMap<>(); - private IBlockAccess mWorld = Minecraft.getMinecraft().theWorld; - - private GT_RenderingWorld() { - new FMLEventHandler(); - new ForgeEventHandler(); - } - - public static GT_RenderingWorld getInstance() { - return INSTANCE; - } - - public static GT_RenderingWorld getInstance(IBlockAccess aWorld) { - if (aWorld == INSTANCE) return INSTANCE; - if (aWorld == null) INSTANCE.mWorld = Minecraft.getMinecraft().theWorld; - else INSTANCE.mWorld = aWorld; - return INSTANCE; - } - - private void setWorld(IBlockAccess aWorld) { - if (aWorld == null) mWorld = Minecraft.getMinecraft().theWorld; - else mWorld = aWorld; - } - - public void register(int x, int y, int z, Block block, int meta) { - ChunkPosition key = new ChunkPosition(x, y, z); - infos.put(key, new BlockInfo(block, meta)); - index.computeIfAbsent(new ChunkCoordIntPair(x >> 4, z >> 4), p -> new HashSet<>()) - .add(key); - } - - public void unregister(int x, int y, int z, Block block, int meta) { - ChunkPosition key = new ChunkPosition(x, y, z); - if (infos.remove(key, new BlockInfo(block, meta))) { - ChunkCoordIntPair chunkKey = new ChunkCoordIntPair(x >> 4, z >> 4); - Set set = index.get(chunkKey); - set.remove(key); - if (set.isEmpty()) index.remove(chunkKey); - } - } - - @Override - public Block getBlock(int p_147439_1_, int p_147439_2_, int p_147439_3_) { - BlockInfo blockInfo = infos.get(new ChunkPosition(p_147439_1_, p_147439_2_, p_147439_3_)); - return blockInfo != null ? blockInfo.block : mWorld.getBlock(p_147439_1_, p_147439_2_, p_147439_3_); - } - - @Override - public TileEntity getTileEntity(int p_147438_1_, int p_147438_2_, int p_147438_3_) { - return mWorld.getTileEntity(p_147438_1_, p_147438_2_, p_147438_3_); - } - - @Override - public int getLightBrightnessForSkyBlocks(int p_72802_1_, int p_72802_2_, int p_72802_3_, int p_72802_4_) { - return mWorld.getLightBrightnessForSkyBlocks(p_72802_1_, p_72802_2_, p_72802_3_, p_72802_4_); - } - - @Override - public int getBlockMetadata(int p_72805_1_, int p_72805_2_, int p_72805_3_) { - BlockInfo blockInfo = infos.get(new ChunkPosition(p_72805_1_, p_72805_2_, p_72805_3_)); - return blockInfo != null ? blockInfo.meta : mWorld.getBlockMetadata(p_72805_1_, p_72805_2_, p_72805_3_); - } - - @Override - public int isBlockProvidingPowerTo(int p_72879_1_, int p_72879_2_, int p_72879_3_, int p_72879_4_) { - return mWorld.isBlockProvidingPowerTo(p_72879_1_, p_72879_2_, p_72879_3_, p_72879_4_); - } - - @Override - public boolean isAirBlock(int p_147437_1_, int p_147437_2_, int p_147437_3_) { - return getBlock(p_147437_1_, p_147437_2_, p_147437_3_).isAir(mWorld, p_147437_1_, p_147437_2_, p_147437_3_); - } - - @Override - public BiomeGenBase getBiomeGenForCoords(int p_72807_1_, int p_72807_2_) { - return mWorld.getBiomeGenForCoords(p_72807_1_, p_72807_2_); - } - - @Override - public int getHeight() { - return mWorld.getHeight(); - } - - @Override - public boolean extendedLevelsInChunkCache() { - return mWorld.extendedLevelsInChunkCache(); - } - - @Override - public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) { - return getBlock(x, y, z).isSideSolid(this, x, y, z, side); - } - - public class FMLEventHandler { - - public FMLEventHandler() { - FMLCommonHandler.instance() - .bus() - .register(this); - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onRenderTickStart(TickEvent.RenderTickEvent e) { - if (e.phase == TickEvent.Phase.START) mWorld = Minecraft.getMinecraft().theWorld; - } - } - - public class ForgeEventHandler { - - private ForgeEventHandler() { - MinecraftForge.EVENT_BUS.register(this); - } - - @SubscribeEvent - public void onChunkUnloaded(ChunkEvent.Unload e) { - if (!e.world.isRemote) return; - Set set = index.remove( - e.getChunk() - .getChunkCoordIntPair()); - if (set != null) infos.keySet() - .removeAll(set); - } - - @SubscribeEvent - public void onWorldUnloaded(WorldEvent.Unload e) { - if (!e.world.isRemote) return; - infos.clear(); - index.clear(); - } - } - - private static class BlockInfo { - - private final Block block; - private final int meta; - - public BlockInfo(Block block, int meta) { - this.block = block; - this.meta = meta; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BlockInfo blockInfo = (BlockInfo) o; - - if (meta != blockInfo.meta) return false; - return Objects.equals(block, blockInfo.block); - } - - @Override - public int hashCode() { - int result = block != null ? block.hashCode() : 0; - result = 31 * result + meta; - return result; - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java b/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java deleted file mode 100644 index 95a1a0bb66..0000000000 --- a/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java +++ /dev/null @@ -1,100 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraftforge.oredict.ShapedOreRecipe; - -import gregtech.api.interfaces.internal.IGT_CraftingRecipe; - -public class GT_Shaped_Recipe extends ShapedOreRecipe implements IGT_CraftingRecipe { - - public final boolean mRemovableByGT, mKeepingNBT; - private final Enchantment[] mEnchantmentsAdded; - private final int[] mEnchantmentLevelsAdded; - - public GT_Shaped_Recipe(ItemStack aResult, boolean aDismantleAble, boolean aRemovableByGT, boolean aKeepingNBT, - Enchantment[] aEnchantmentsAdded, int[] aEnchantmentLevelsAdded, Object... aRecipe) { - super(aResult, aRecipe); - mEnchantmentsAdded = aEnchantmentsAdded; - mEnchantmentLevelsAdded = aEnchantmentLevelsAdded; - mRemovableByGT = aRemovableByGT; - mKeepingNBT = aKeepingNBT; - } - - @Override - public boolean matches(InventoryCrafting aGrid, World aWorld) { - if (mKeepingNBT) { - ItemStack tStack = null; - for (int i = 0; i < aGrid.getSizeInventory(); i++) { - if (aGrid.getStackInSlot(i) != null) { - if (tStack != null) { - if ((tStack.hasTagCompound() != aGrid.getStackInSlot(i) - .hasTagCompound()) || (tStack.hasTagCompound() - && !tStack.getTagCompound() - .equals( - aGrid.getStackInSlot(i) - .getTagCompound()))) - return false; - } - tStack = aGrid.getStackInSlot(i); - } - } - } - return super.matches(aGrid, aWorld); - } - - @Override - public ItemStack getCraftingResult(InventoryCrafting aGrid) { - ItemStack rStack = super.getCraftingResult(aGrid); - if (rStack != null) { - // Update the Stack - GT_Utility.updateItemStack(rStack); - - // Keeping NBT - if (mKeepingNBT) for (int i = 0; i < aGrid.getSizeInventory(); i++) { - if (aGrid.getStackInSlot(i) != null && aGrid.getStackInSlot(i) - .hasTagCompound()) { - rStack.setTagCompound( - (NBTTagCompound) aGrid.getStackInSlot(i) - .getTagCompound() - .copy()); - break; - } - } - - // Charge Values - if (GT_ModHandler.isElectricItem(rStack)) { - GT_ModHandler.dischargeElectricItem(rStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); - int tCharge = 0; - for (int i = 0; i < aGrid.getSizeInventory(); i++) tCharge += GT_ModHandler.dischargeElectricItem( - aGrid.getStackInSlot(i), - Integer.MAX_VALUE, - Integer.MAX_VALUE, - true, - true, - true); - if (tCharge > 0) GT_ModHandler.chargeElectricItem(rStack, tCharge, Integer.MAX_VALUE, true, false); - } - - // Add Enchantments - for (int i = 0; i < mEnchantmentsAdded.length; i++) GT_Utility.ItemNBT.addEnchantment( - rStack, - mEnchantmentsAdded[i], - EnchantmentHelper.getEnchantmentLevel(mEnchantmentsAdded[i].effectId, rStack) - + mEnchantmentLevelsAdded[i]); - - // Update the Stack again - GT_Utility.updateItemStack(rStack); - } - return rStack; - } - - @Override - public boolean isRemovable() { - return mRemovableByGT; - } -} diff --git a/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java b/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java deleted file mode 100644 index 582dd7cc10..0000000000 --- a/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java +++ /dev/null @@ -1,100 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import gregtech.api.interfaces.internal.IGT_CraftingRecipe; - -public class GT_Shapeless_Recipe extends ShapelessOreRecipe implements IGT_CraftingRecipe { - - public final boolean mRemovableByGT, mKeepingNBT; - private final Enchantment[] mEnchantmentsAdded; - private final int[] mEnchantmentLevelsAdded; - - public GT_Shapeless_Recipe(ItemStack aResult, boolean aDismantleAble, boolean aRemovableByGT, boolean aKeepingNBT, - Enchantment[] aEnchantmentsAdded, int[] aEnchantmentLevelsAdded, Object... aRecipe) { - super(aResult, aRecipe); - mEnchantmentsAdded = aEnchantmentsAdded; - mEnchantmentLevelsAdded = aEnchantmentLevelsAdded; - mRemovableByGT = aRemovableByGT; - mKeepingNBT = aKeepingNBT; - } - - @Override - public boolean matches(InventoryCrafting aGrid, World aWorld) { - if (mKeepingNBT) { - ItemStack tStack = null; - for (int i = 0; i < aGrid.getSizeInventory(); i++) { - if (aGrid.getStackInSlot(i) != null) { - if (tStack != null) { - if ((tStack.hasTagCompound() != aGrid.getStackInSlot(i) - .hasTagCompound()) || (tStack.hasTagCompound() - && !tStack.getTagCompound() - .equals( - aGrid.getStackInSlot(i) - .getTagCompound()))) - return false; - } - tStack = aGrid.getStackInSlot(i); - } - } - } - return super.matches(aGrid, aWorld); - } - - @Override - public ItemStack getCraftingResult(InventoryCrafting aGrid) { - ItemStack rStack = super.getCraftingResult(aGrid); - if (rStack != null) { - // Update the Stack - GT_Utility.updateItemStack(rStack); - - // Keeping NBT - if (mKeepingNBT) for (int i = 0; i < aGrid.getSizeInventory(); i++) { - if (aGrid.getStackInSlot(i) != null && aGrid.getStackInSlot(i) - .hasTagCompound()) { - rStack.setTagCompound( - (NBTTagCompound) aGrid.getStackInSlot(i) - .getTagCompound() - .copy()); - break; - } - } - - // Charge Values - if (GT_ModHandler.isElectricItem(rStack)) { - GT_ModHandler.dischargeElectricItem(rStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); - int tCharge = 0; - for (int i = 0; i < aGrid.getSizeInventory(); i++) tCharge += GT_ModHandler.dischargeElectricItem( - aGrid.getStackInSlot(i), - Integer.MAX_VALUE, - Integer.MAX_VALUE, - true, - true, - true); - if (tCharge > 0) GT_ModHandler.chargeElectricItem(rStack, tCharge, Integer.MAX_VALUE, true, false); - } - - // Add Enchantments - for (int i = 0; i < mEnchantmentsAdded.length; i++) GT_Utility.ItemNBT.addEnchantment( - rStack, - mEnchantmentsAdded[i], - EnchantmentHelper.getEnchantmentLevel(mEnchantmentsAdded[i].effectId, rStack) - + mEnchantmentLevelsAdded[i]); - - // Update the Stack again - GT_Utility.updateItemStack(rStack); - } - return rStack; - } - - @Override - public boolean isRemovable() { - return mRemovableByGT; - } -} diff --git a/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java b/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java deleted file mode 100644 index ebdba1144b..0000000000 --- a/src/main/java/gregtech/api/util/GT_SpawnEventHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package gregtech.api.util; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.entity.monster.EntitySlime; -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.living.LivingSpawnEvent.CheckSpawn; - -import cpw.mods.fml.common.eventhandler.Event; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import gregtech.api.enums.GT_Values; -import gregtech.api.metatileentity.BaseMetaTileEntity; -import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_MonsterRepellent; - -public class GT_SpawnEventHandler { - - public static volatile List mobReps = new CopyOnWriteArrayList<>(); - // Future Optimiztation ideas, if this isn't sufficient - // 1: Keep a weakref list of mob repellents so we already have the tile - // 2: Have the tick method update a HashMap of (int[], range) so we don't have to load the tile at all - - public GT_SpawnEventHandler() { - MinecraftForge.EVENT_BUS.register(this); - } - - // Range of a powered repellent - public static int getPoweredRepellentRange(int aTier) { - return 16 + (48 * aTier); - } - - // Range of an unpowered repellent - public static int getUnpoweredRepellentRange(int aTier) { - return 4 + (12 * aTier); - } - - @SubscribeEvent - public void denyMobSpawn(CheckSpawn event) { - if (event.getResult() == Event.Result.DENY) return; - - if (event.entityLiving instanceof EntitySlime slime && !slime.hasCustomNameTag() - && event.getResult() == Event.Result.ALLOW) { - event.setResult(Event.Result.DEFAULT); - } - - if (event.getResult() == Event.Result.ALLOW) { - return; - } - - if (event.entityLiving.isCreatureType(EnumCreatureType.monster, false)) { - final double maxRangeCheck = Math.pow(getPoweredRepellentRange(GT_Values.V.length - 1), 2); - for (int[] rep : mobReps) { - if (rep[3] == event.entity.worldObj.provider.dimensionId) { - // If the chunk isn't loaded, we ignore this Repellent - if (!event.entity.worldObj.blockExists(rep[0], rep[1], rep[2])) continue; - final double dx = rep[0] + 0.5F - event.entity.posX; - final double dy = rep[1] + 0.5F - event.entity.posY; - final double dz = rep[2] + 0.5F - event.entity.posZ; - - final double check = (dx * dx + dz * dz + dy * dy); - // Fail early if outside of max range - if (check > maxRangeCheck) continue; - - final TileEntity tTile = event.entity.worldObj.getTileEntity(rep[0], rep[1], rep[2]); - if (tTile instanceof BaseMetaTileEntity metaTile - && metaTile.getMetaTileEntity() instanceof GT_MetaTileEntity_MonsterRepellent repellent - && check <= Math.pow(repellent.mRange, 2)) { - if (event.entityLiving instanceof EntitySlime slime) { - slime.setCustomNameTag("DoNotSpawnSlimes"); - } - event.setResult(Event.Result.DENY); - // We're already DENYing it. No reason to keep checking - return; - } - } - } - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_StreamUtil.java b/src/main/java/gregtech/api/util/GT_StreamUtil.java deleted file mode 100644 index c29e611c4e..0000000000 --- a/src/main/java/gregtech/api/util/GT_StreamUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -package gregtech.api.util; - -import java.util.Arrays; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -public final class GT_StreamUtil { - - /** - * Backport of {@link Stream#ofNullable}. - */ - public static Stream ofNullable(@Nullable T value) { - return value == null ? Stream.empty() : Stream.of(value); - } - - /** - * Returns a sequential ordered {@code Stream} whose elements are the specified values, - * if {@code condition} is true, otherwise returns an empty {@code Stream}. - * - * @param the type of stream elements - * @param values the elements of the new stream - * @return the new stream - */ - public static Stream ofConditional(boolean condition, T[] values) { - return condition ? Arrays.stream(values) : Stream.empty(); - } - - /** - * Returns a sequential {@code Stream} containing a single element, which will be lazily evaluated from supplier. - * - * @param the type of stream elements - * @param supplier the supplier for single stream element - * @return the new stream - */ - public static Stream ofSupplier(Supplier supplier) { - return Stream.generate(supplier) - .limit(1); - } -} diff --git a/src/main/java/gregtech/api/util/GT_StructureUtility.java b/src/main/java/gregtech/api/util/GT_StructureUtility.java deleted file mode 100644 index 6bbb3e1223..0000000000 --- a/src/main/java/gregtech/api/util/GT_StructureUtility.java +++ /dev/null @@ -1,618 +0,0 @@ -package gregtech.api.util; - -import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.ACCEPT; -import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.ACCEPT_STOP; -import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.REJECT; -import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.SKIP; -import static com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode.EXACT; - -import java.util.Arrays; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.BiPredicate; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.ToIntFunction; - -import javax.annotation.Nonnull; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; - -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; -import com.gtnewhorizon.structurelib.structure.IItemSource; -import com.gtnewhorizon.structurelib.structure.IStructureElement; -import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; -import com.gtnewhorizon.structurelib.structure.StructureUtility; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; - -import gregtech.api.GregTech_API; -import gregtech.api.enums.HeatingCoilLevel; -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.interfaces.IHeatingCoil; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_TieredMachineBlock; -import gregtech.common.blocks.GT_Block_Casings5; -import gregtech.common.blocks.GT_Block_FrameBox; -import gregtech.common.blocks.GT_Cyclotron_Coils; -import gregtech.common.blocks.GT_Item_Machines; - -public class GT_StructureUtility { - - // private static final Map, String> customNames = new HashMap<>(); - private GT_StructureUtility() { - throw new AssertionError("Not instantiable"); - } - - public static boolean hasMTE(IGregTechTileEntity aTile, Class clazz) { - return aTile != null && clazz.isInstance(aTile.getMetaTileEntity()); - } - - public static IStructureElementNoPlacement ofHatchAdder(IGT_HatchAdder aHatchAdder, int aTextureIndex, - int aDots) { - return ofHatchAdder(aHatchAdder, aTextureIndex, StructureLibAPI.getBlockHint(), aDots - 1); - } - - public static IStructureElement ofFrame(Materials aFrameMaterial) { - if (aFrameMaterial == null) throw new IllegalArgumentException(); - return new IStructureElement<>() { - - private IIcon[] mIcons; - - @Override - public boolean check(T t, World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - if (block instanceof GT_Block_FrameBox frameBox) { - int meta = world.getBlockMetadata(x, y, z); - Materials material = frameBox.getMaterial(meta); - return aFrameMaterial == material; - } - return false; - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - if (mIcons == null) { - mIcons = new IIcon[6]; - Arrays.fill(mIcons, aFrameMaterial.mIconSet.mTextures[OrePrefixes.frameGt.mTextureIndex].getIcon()); - } - StructureLibAPI.hintParticleTinted(world, x, y, z, mIcons, aFrameMaterial.mRGBa); - return true; - } - - @Override - public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { - ItemStack tFrameStack = getFrameStack(); - if (!GT_Utility.isStackValid(tFrameStack) - || !(tFrameStack.getItem() instanceof ItemBlock tFrameStackItem)) return false; - return tFrameStackItem - .placeBlockAt(tFrameStack, null, world, x, y, z, 6, 0, 0, 0, Items.feather.getDamage(tFrameStack)); - } - - private ItemStack getFrameStack() { - return GT_OreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1); - } - - @Override - public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - ItemStack tFrameStack = getFrameStack(); - if (!GT_Utility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock)) - return BlocksToPlace.errored; - return BlocksToPlace.create(tFrameStack); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - return survivalPlaceBlock( - t, - world, - x, - y, - z, - trigger, - AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - if (check(t, world, x, y, z)) return SKIP; - ItemStack tFrameStack = getFrameStack(); - if (!GT_Utility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock)) - return REJECT; // honestly, this is more like a programming error or pack issue - return StructureUtility.survivalPlaceBlock( - tFrameStack, - ItemStackPredicate.NBTMode.IGNORE_KNOWN_INSIGNIFICANT_TAGS, - null, - false, - world, - x, - y, - z, - env.getSource(), - env.getActor(), - env.getChatter()); - } - }; - } - - public static GT_HatchElementBuilder buildHatchAdder() { - return GT_HatchElementBuilder.builder(); - } - - /** - * Completely equivalent to {@link #buildHatchAdder()}, except it plays nicer with type inference when statically - * imported - */ - public static GT_HatchElementBuilder buildHatchAdder(Class typeToken) { - return GT_HatchElementBuilder.builder(); - } - - public static IStructureElementNoPlacement ofHatchAdder(IGT_HatchAdder aHatchAdder, int aTextureIndex, - Block aHintBlock, int aHintMeta) { - if (aHatchAdder == null || aHintBlock == null) { - throw new IllegalArgumentException(); - } - return new IStructureElementNoPlacement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - return tileEntity instanceof IGregTechTileEntity - && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); - return true; - } - }; - } - - public static IStructureElement ofHatchAdder(IGT_HatchAdder aHatchAdder, int aTextureIndex, - Block aHintBlock, int aHintMeta, BiPredicate shouldSkip, - Function> aMetaId, final IStructureElement.PlaceResult acceptType) { - if (aHatchAdder == null) { - throw new IllegalArgumentException(); - } - return new IStructureElement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - return tileEntity instanceof IGregTechTileEntity - && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); - return true; - } - - @Override - public boolean placeBlock(T t, World world, int i, int i1, int i2, ItemStack itemStack) { - // TODO - return false; - } - - @Override - public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - Class clazz = aMetaId.apply(t); - if (clazz == null) return BlocksToPlace.createEmpty(); - return BlocksToPlace.create(is -> clazz.isInstance(GT_Item_Machines.getMetaTileEntity(is))); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - return survivalPlaceBlock( - t, - world, - x, - y, - z, - trigger, - AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - if (shouldSkip != null) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - if (tileEntity instanceof IGregTechTileEntity - && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return SKIP; - } - if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return REJECT; - Class clazz = aMetaId.apply(t); - if (clazz == null) return REJECT; - ItemStack taken = env.getSource() - .takeOne(is -> clazz.isInstance(GT_Item_Machines.getMetaTileEntity(is)), true); - if (GT_Utility.isStackInvalid(taken)) { - env.getChatter() - .accept( - new ChatComponentTranslation( - "GT5U.autoplace.error.no_mte.class_name", - clazz.getSimpleName())); - return REJECT; - } - if (StructureUtility - .survivalPlaceBlock(taken, EXACT, null, true, world, x, y, z, env.getSource(), env.getActor()) - == ACCEPT) return acceptType; - return REJECT; - } - }; - } - - public static IStructureElement ofHatchAdder(IGT_HatchAdder aHatchAdder, int aTextureIndex, - Block aHintBlock, int aHintMeta, BiPredicate shouldSkip, ToIntFunction aMetaId) { - if (aHatchAdder == null) { - throw new IllegalArgumentException(); - } - return new IStructureElement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - return tileEntity instanceof IGregTechTileEntity - && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); - return true; - } - - @Override - public boolean placeBlock(T t, World world, int i, int i1, int i2, ItemStack itemStack) { - // TODO - return false; - } - - @Override - public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - GT_Item_Machines item = (GT_Item_Machines) Item.getItemFromBlock(GregTech_API.sBlockMachines); - int meta = aMetaId.applyAsInt(t); - if (meta < 0) return BlocksToPlace.createEmpty(); - return BlocksToPlace.create( - ItemStackPredicate.from(item) - .setMeta(meta)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - return survivalPlaceBlock( - t, - world, - x, - y, - z, - trigger, - AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - if (shouldSkip != null) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - if (tileEntity instanceof IGregTechTileEntity - && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return SKIP; - } - if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return REJECT; - GT_Item_Machines item = (GT_Item_Machines) Item.getItemFromBlock(GregTech_API.sBlockMachines); - int meta = aMetaId.applyAsInt(t); - if (meta < 0) return REJECT; - ItemStack taken = env.getSource() - .takeOne( - ItemStackPredicate.from(item) - .setMeta(meta), - true); - if (GT_Utility.isStackInvalid(taken)) { - env.getChatter() - .accept(new ChatComponentTranslation("GT5U.autoplace.error.no_mte.id", meta)); - return REJECT; - } - return StructureUtility - .survivalPlaceBlock(taken, EXACT, null, true, world, x, y, z, env.getSource(), env.getActor()) - == ACCEPT ? ACCEPT_STOP : REJECT; - } - }; - } - - public static IStructureElement ofHatchAdderOptional(IGT_HatchAdder aHatchAdder, int textureIndex, - int dots, Block placeCasing, int placeCasingMeta) { - return ofHatchAdderOptional( - aHatchAdder, - textureIndex, - StructureLibAPI.getBlockHint(), - dots - 1, - placeCasing, - placeCasingMeta); - } - - public static IStructureElement ofHatchAdderOptional(IGT_HatchAdder aHatchAdder, int aTextureIndex, - Block aHintBlock, int hintMeta, Block placeCasing, int placeCasingMeta) { - if (aHatchAdder == null || aHintBlock == null) { - throw new IllegalArgumentException(); - } - return new IStructureElement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - Block worldBlock = world.getBlock(x, y, z); - return (tileEntity instanceof IGregTechTileEntity - && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex)) - || (worldBlock == placeCasing && worldBlock.getDamageValue(world, x, y, z) == placeCasingMeta); - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, hintMeta); - return true; - } - - @Override - public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { - world.setBlock(x, y, z, placeCasing, placeCasingMeta, 2); - return true; - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - if (check(t, world, x, y, z)) return SKIP; - return StructureUtility - .survivalPlaceBlock(placeCasing, placeCasingMeta, world, x, y, z, s, actor, chatter); - } - }; - } - - /** - * Assume all coils accepted. - * - * @see #ofCoil(BiPredicate, Function) - */ - public static IStructureElement ofCoil(BiConsumer aHeatingCoilSetter, - Function aHeatingCoilGetter) { - return ofCoil((t, l) -> { - aHeatingCoilSetter.accept(t, l); - return true; - }, aHeatingCoilGetter); - } - - /** - * Heating coil structure element. - * - * @param aHeatingCoilSetter Notify the controller of this new coil. Got called exactly once per coil. Might be - * called less times if structure test fails. If the setter returns false then it assumes - * the coil is rejected. - * @param aHeatingCoilGetter Get the current heating level. Null means no coil recorded yet. - */ - public static IStructureElement ofCoil(BiPredicate aHeatingCoilSetter, - Function aHeatingCoilGetter) { - if (aHeatingCoilSetter == null || aHeatingCoilGetter == null) { - throw new IllegalArgumentException(); - } - return new IStructureElement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - if (!(block instanceof IHeatingCoil)) return false; - HeatingCoilLevel existingLevel = aHeatingCoilGetter.apply(t), - newLevel = ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z)); - if (existingLevel == null || existingLevel == HeatingCoilLevel.None) { - return aHeatingCoilSetter.test(t, newLevel); - } else { - return newLevel == existingLevel; - } - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI.hintParticle(world, x, y, z, GregTech_API.sBlockCasings5, getMetaFromHint(trigger)); - return true; - } - - private int getMetaFromHint(ItemStack trigger) { - return GT_Block_Casings5.getMetaFromCoilHeat(getHeatFromHint(trigger)); - } - - private HeatingCoilLevel getHeatFromHint(ItemStack trigger) { - return HeatingCoilLevel - .getFromTier((byte) Math.min(HeatingCoilLevel.getMaxTier(), Math.max(0, trigger.stackSize - 1))); - } - - @Override - public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { - return world.setBlock(x, y, z, GregTech_API.sBlockCasings5, getMetaFromHint(trigger), 3); - } - - @Override - public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - return BlocksToPlace.create(GregTech_API.sBlockCasings5, getMetaFromHint(trigger)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - return survivalPlaceBlock( - t, - world, - x, - y, - z, - trigger, - AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - Block block = world.getBlock(x, y, z); - boolean isCoil = block instanceof IHeatingCoil - && ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z)) == getHeatFromHint(trigger); - if (isCoil) return SKIP; - return StructureUtility.survivalPlaceBlock( - GregTech_API.sBlockCasings5, - getMetaFromHint(trigger), - world, - x, - y, - z, - env.getSource(), - env.getActor(), - env.getChatter()); - } - }; - } - - /** - * Assumes all solenoids are accepted. - * - * @see #ofSolenoidCoil(BiPredicate, Function) - */ - public static IStructureElement ofSolenoidCoil(BiConsumer aSolenoidTierSetter, - Function aSolenoidTierGetter) { - return ofSolenoidCoil((t, l) -> { - aSolenoidTierSetter.accept(t, l); - return true; - }, aSolenoidTierGetter); - } - - /** - * Solenoid coil structure element. - * - * @param aSolenoidTierSetter Notify the controller of this new solenoid. Got called exactly once per solenoid. - * Might be - * called less times if structure test fails. If the setter returns false then it assumes - * the solenoid is rejected. - * @param aSolenoidTierGetter Get the solenoid voltage tier. Null means no tier recorded yet. - */ - public static IStructureElement ofSolenoidCoil(BiPredicate aSolenoidTierSetter, - Function aSolenoidTierGetter) { - if (aSolenoidTierSetter == null || aSolenoidTierGetter == null) { - throw new IllegalArgumentException(); - } - return new IStructureElement<>() { - - @Override - public boolean check(T t, World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - - if (block != GregTech_API.sSolenoidCoilCasings) return false; - - var coils = ((GT_Cyclotron_Coils) GregTech_API.sSolenoidCoilCasings); - - Byte existingLevel = aSolenoidTierGetter.apply(t); - byte newLevel = (byte) (coils.getVoltageTier(world.getBlockMetadata(x, y, z))); - - if (existingLevel == null) { - return aSolenoidTierSetter.test(t, newLevel); - } else { - return newLevel == existingLevel; - } - } - - @Override - public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { - StructureLibAPI - .hintParticle(world, x, y, z, GregTech_API.sSolenoidCoilCasings, getMetaFromHint(trigger)); - return true; - } - - private int getMetaFromHint(ItemStack trigger) { - return Math.min(Math.max(trigger.stackSize - 1, 0), 10); - } - - @Override - public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { - return world.setBlock(x, y, z, GregTech_API.sSolenoidCoilCasings, getMetaFromHint(trigger), 3); - } - - @Override - public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - return BlocksToPlace.create(GregTech_API.sSolenoidCoilCasings, getMetaFromHint(trigger)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - IItemSource s, EntityPlayerMP actor, Consumer chatter) { - return survivalPlaceBlock( - t, - world, - x, - y, - z, - trigger, - AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); - } - - @Override - public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, - AutoPlaceEnvironment env) { - Block block = world.getBlock(x, y, z); - - boolean isCoil = block == GregTech_API.sSolenoidCoilCasings - && world.getBlockMetadata(x, y, z) == getMetaFromHint(trigger); - - if (isCoil) return SKIP; - - return StructureUtility.survivalPlaceBlock( - GregTech_API.sSolenoidCoilCasings, - getMetaFromHint(trigger), - world, - x, - y, - z, - env.getSource(), - env.getActor(), - env.getChatter()); - } - }; - } - - @Nonnull - public static Predicate filterByMTEClass(List> list) { - return is -> { - IMetaTileEntity tile = GT_Item_Machines.getMetaTileEntity(is); - return tile != null && list.stream() - .anyMatch(c -> c.isInstance(tile)); - }; - } - - @Nonnull - public static Predicate filterByMTETier(int aMinTier, int aMaxTier) { - return is -> { - IMetaTileEntity tile = GT_Item_Machines.getMetaTileEntity(is); - return tile instanceof GT_MetaTileEntity_TieredMachineBlock - && ((GT_MetaTileEntity_TieredMachineBlock) tile).mTier <= aMaxTier - && ((GT_MetaTileEntity_TieredMachineBlock) tile).mTier >= aMinTier; - }; - } -} diff --git a/src/main/java/gregtech/api/util/GT_StructureUtilityMuTE.java b/src/main/java/gregtech/api/util/GT_StructureUtilityMuTE.java index a4c4630209..3efbebdcbf 100644 --- a/src/main/java/gregtech/api/util/GT_StructureUtilityMuTE.java +++ b/src/main/java/gregtech/api/util/GT_StructureUtilityMuTE.java @@ -1,6 +1,6 @@ package gregtech.api.util; -import static gregtech.GT_Mod.GT_FML_LOGGER; +import static gregtech.GTMod.GT_FML_LOGGER; import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.*; import static gregtech.api.multitileentity.enums.GT_MultiTileUpgradeCasing.*; import static gregtech.loaders.preload.GT_Loader_MultiTileEntities.*; @@ -16,7 +16,7 @@ import net.minecraft.world.World; import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.structure.IStructureElement; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.TextureSet; import gregtech.api.multitileentity.MultiTileEntityBlock; @@ -220,7 +220,7 @@ public class GT_StructureUtilityMuTE { public static class MuTEStructureCasing { private String registryName; - private int registryId = GT_Values.W; + private int registryId = GTValues.W; private final int defaultMeta; private final Integer[] validIds; @@ -253,7 +253,7 @@ public class GT_StructureUtilityMuTE { public int getRegistryId() { // TODO: MuTE registry seems to somehow shift, probably due to NBT shenanigans. Lazy init circumvents this // but it should be properly fixed in the future - if (registryId == GT_Values.W) { + if (registryId == GTValues.W) { MultiTileEntityRegistry registry = MultiTileEntityRegistry.getRegistry(registryName); registryId = Block.getIdFromBlock(registry.getBlock()); } diff --git a/src/main/java/gregtech/api/util/GT_ToolHarvestHelper.java b/src/main/java/gregtech/api/util/GT_ToolHarvestHelper.java deleted file mode 100644 index 4263b77be6..0000000000 --- a/src/main/java/gregtech/api/util/GT_ToolHarvestHelper.java +++ /dev/null @@ -1,71 +0,0 @@ -package gregtech.api.util; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; - -import ic2.core.block.BlockMultiID; -import ic2.core.block.BlockScaffold; -import ic2.core.block.machine.BlockMiningPipe; -import ic2.core.block.machine.BlockMiningTip; -import ic2.core.block.wiring.BlockCable; -import ic2.core.crop.BlockCrop; - -public class GT_ToolHarvestHelper { - - public static boolean isAppropriateTool(Block aBlock, byte aMetaData, String... tTools) { - - if (aBlock == null || tTools == null) { - return false; - } - String targetTool = aBlock.getHarvestTool(aMetaData); - return !isStringEmpty(targetTool) && isArrayContains(targetTool, tTools); - } - - public static boolean isAppropriateMaterial(Block aBlock, Material... tMats) { - if (aBlock == null || tMats == null) { - return false; - } - return isArrayContains(aBlock.getMaterial(), tMats); - } - - public static boolean isSpecialBlock(Block aBlock, Block... tBlocks) { - if (aBlock == null || tBlocks == null) { - return false; - } - return isArrayContains(aBlock, tBlocks); - } - - public static boolean isArrayContains(T obj, T[] list) { - - if (obj == null || list == null) { - return false; - } - - for (T iObj : list) { - if (obj == iObj || obj.equals(iObj)) { - return true; - } - } - return false; - } - - public static boolean isStringEmpty(String s) { - return s == null || s.isEmpty(); - } - - public static boolean isIC2Wrenchable(Block block) { - return (block instanceof BlockMultiID && !(block instanceof BlockCable) && !(block instanceof BlockCrop)) - || block instanceof BlockScaffold - || block instanceof BlockMiningPipe - || block instanceof BlockMiningTip; - } - - public static boolean hasNull(Object... obj) { - for (Object iObj : obj) { - if (iObj == null) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/gregtech/api/util/GT_TooltipDataCache.java b/src/main/java/gregtech/api/util/GT_TooltipDataCache.java index 431ef34fa4..6b42a8e7fa 100644 --- a/src/main/java/gregtech/api/util/GT_TooltipDataCache.java +++ b/src/main/java/gregtech/api/util/GT_TooltipDataCache.java @@ -7,7 +7,7 @@ import java.util.Map; import net.minecraft.util.StatCollector; -import gregtech.GT_Mod; +import gregtech.GTMod; public class GT_TooltipDataCache { @@ -50,7 +50,7 @@ public class GT_TooltipDataCache { public TooltipData getUncachedTooltipData(String key, Object... args) { List lines = getAllLines(key, args); int normalLines = lines.size(); - if (Math.max(GT_Mod.gregtechproxy.mTooltipVerbosity, GT_Mod.gregtechproxy.mTooltipShiftVerbosity) >= 3) { + if (Math.max(GTMod.gregtechproxy.mTooltipVerbosity, GTMod.gregtechproxy.mTooltipShiftVerbosity) >= 3) { lines.addAll(getAllLines(key + ".extended", args)); // Are extended lines enabled? If so add them to the // lines } @@ -58,9 +58,8 @@ public class GT_TooltipDataCache { lines.add(key); // Fallback in case no lines could be found at all } return new TooltipData( - lines.subList(0, getVerbosityIndex(GT_Mod.gregtechproxy.mTooltipVerbosity, normalLines, lines.size())), - lines - .subList(0, getVerbosityIndex(GT_Mod.gregtechproxy.mTooltipShiftVerbosity, normalLines, lines.size()))); + lines.subList(0, getVerbosityIndex(GTMod.gregtechproxy.mTooltipVerbosity, normalLines, lines.size())), + lines.subList(0, getVerbosityIndex(GTMod.gregtechproxy.mTooltipShiftVerbosity, normalLines, lines.size()))); } /** diff --git a/src/main/java/gregtech/api/util/GT_Util.java b/src/main/java/gregtech/api/util/GT_Util.java deleted file mode 100644 index cdca6a1b9e..0000000000 --- a/src/main/java/gregtech/api/util/GT_Util.java +++ /dev/null @@ -1,347 +0,0 @@ -package gregtech.api.util; - -import static gregtech.api.util.GT_Utility.filterValidMTEs; - -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.Tuple; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import net.minecraftforge.common.util.Constants; - -import gregtech.api.enums.ItemList; -import gregtech.api.interfaces.IDataCopyable; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase; -import gregtech.api.multitileentity.interfaces.IMultiTileEntity; -import gregtech.common.items.behaviors.Behaviour_DataOrb; - -public class GT_Util { - - // Last broken tile entity - public static final ThreadLocal LAST_BROKEN_TILEENTITY = new ThreadLocal<>(); - - public static Tuple tuple(String key, Object value) { - return new Tuple(key, value); - } - - public static NBTTagCompound fuseNBT(NBTTagCompound nbt1, NBTTagCompound nbt2) { - if (nbt1 == null) return nbt2 == null ? new NBTTagCompound() : (NBTTagCompound) nbt2.copy(); - final NBTTagCompound rNBT = (NBTTagCompound) nbt1.copy(); - if (nbt2 == null) return rNBT; - for (Object tKey : nbt2.func_150296_c /* getKeySet */()) - if (!rNBT.hasKey(tKey.toString())) rNBT.setTag(tKey.toString(), nbt2.getTag(tKey.toString())); - return rNBT; - } - - /** - * Construct a NBTTagCompound from a series of key, value pairs. Inspired from GT6. - */ - public static NBTTagCompound makeNBT(Tuple... tags) { - final NBTTagCompound nbt = new NBTTagCompound(); - for (Tuple t : tags) { - if (t.getSecond() == null) continue; - - if (t.getSecond() instanceof Boolean) nbt.setBoolean( - t.getFirst() - .toString(), - (Boolean) t.getSecond()); - else if (t.getSecond() instanceof Byte) nbt.setByte( - t.getFirst() - .toString(), - (Byte) t.getSecond()); - else if (t.getSecond() instanceof Short) nbt.setShort( - t.getFirst() - .toString(), - (Short) t.getSecond()); - else if (t.getSecond() instanceof Integer) nbt.setInteger( - t.getFirst() - .toString(), - (Integer) t.getSecond()); - else if (t.getSecond() instanceof Long) nbt.setLong( - t.getFirst() - .toString(), - (Long) t.getSecond()); - else if (t.getSecond() instanceof Float) nbt.setFloat( - t.getFirst() - .toString(), - (Float) t.getSecond()); - else if (t.getSecond() instanceof Double) nbt.setDouble( - t.getFirst() - .toString(), - (Double) t.getSecond()); - else if (t.getSecond() instanceof String) nbt.setString( - t.getFirst() - .toString(), - (String) t.getSecond()); - else if (t.getSecond() instanceof NBTBase) nbt.setTag( - t.getFirst() - .toString(), - (NBTBase) t.getSecond()); - else nbt.setString( - t.getFirst() - .toString(), - t.getSecond() - .toString()); - } - - return nbt; - } - - /** - * Get a TileEntity - */ - public static TileEntity getTileEntity(World world, int x, int y, int z, boolean aLoadUnloadedChunks) { - if (aLoadUnloadedChunks || world.blockExists(x, y, z)) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - if (tileEntity instanceof IMultiTileEntity && ((IMultiTileEntity) tileEntity).isDead()) return null; - if (tileEntity != null) return tileEntity; - tileEntity = LAST_BROKEN_TILEENTITY.get(); - if (tileEntity != null && tileEntity.xCoord == x && tileEntity.yCoord == y && tileEntity.zCoord == z) - return tileEntity; - } - return null; - } - - /** - * Sets the TileEntity at the passed position, with the option of turning adjacent TileEntity updates off. - */ - public static TileEntity setTileEntity(World world, int x, int y, int z, TileEntity aTileEntity, - boolean aCauseTileEntityUpdates) { - if (aCauseTileEntityUpdates) world.setTileEntity(x, y, z, aTileEntity); - else { - final Chunk tChunk = world.getChunkFromChunkCoords(x >> 4, z >> 4); - if (tChunk != null) { - world.addTileEntity(aTileEntity); - tChunk.func_150812_a /* setBlockTileEntityInChunk */(x & 15, y, z & 15, aTileEntity); - tChunk.setChunkModified(); - } - } - return aTileEntity; - } - - public static boolean setBlock(World world, int x, int y, int z, Block block, short aMeta, long aFlags, - boolean aRemoveGrassBelow) { - if (aRemoveGrassBelow) { - final Block blockBelow = world.getBlock(x, y - 1, z); - if (blockBelow == Blocks.grass || blockBelow == Blocks.mycelium) - world.setBlock(x, y - 1, z, Blocks.dirt, 0, (byte) aFlags); - } - return world.setBlock(x, y, z, block, aMeta, (byte) aFlags); - } - - public static TileEntity getTileEntity(World world, ChunkCoordinates coords, boolean loadUnloadedChunks) { - return getTileEntity(world, coords.posX, coords.posY, coords.posZ, loadUnloadedChunks); - } - - /** - * Marks a Chunk dirty so it is saved - */ - public static boolean markChunkDirty(World world, int x, int z) { - if (world == null || world.isRemote) return false; - Chunk aChunk = world.getChunkFromBlockCoords(x, z); - if (aChunk == null) { - world.getBlockMetadata(x, 0, z); - aChunk = world.getChunkFromBlockCoords(x, z); - if (aChunk == null) { - GT_Log.err.println( - "Some important Chunk does not exist for some reason at Coordinates X: " + x + " and Z: " + z); - return false; - } - } - aChunk.setChunkModified(); - return true; - } - - /** - * Marks a Chunk dirty so it is saved - */ - public static boolean markChunkDirty(Object maybeTile) { - return maybeTile instanceof TileEntity tileEntity - && markChunkDirty(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.zCoord); - } - - public static int mixRGBInt(int aRGB1, int aRGB2) { - return getRGBInt( - new short[] { (short) ((getR(aRGB1) + getR(aRGB2)) >> 1), (short) ((getG(aRGB1) + getG(aRGB2)) >> 1), - (short) ((getB(aRGB1) + getB(aRGB2)) >> 1) }); - } - - public static int getRGBInt(short[] aColors) { - return aColors == null ? 16777215 : (aColors[0] << 16) | (aColors[1] << 8) | aColors[2]; - } - - public static int getRGBaInt(short[] aColors) { - return aColors == null ? 16777215 : (aColors[0]) << 16 | (aColors[1] << 8) | aColors[2] | (aColors[3] << 24); - } - - public static String toHexString(short[] aColors) { - return aColors == null ? "FFFFFF" : Integer.toHexString((aColors[0] << 16) | (aColors[1] << 8) | aColors[2]); - } - - public static int getRGBInt(short aR, short aG, short aB) { - return (aR << 16) | (aG << 8) | aB; - } - - public static int getRGBaInt(short aR, short aG, short aB, short aA) { - return (aR << 16) | (aG << 8) | aB | (aA << 24); - } - - public static short[] getRGBaArray(int aColors) { - return new short[] { (short) ((aColors >>> 16) & 255), (short) ((aColors >>> 8) & 255), (short) (aColors & 255), - (short) ((aColors >>> 24) & 255) }; - } - - public static short getR(int aColors) { - return (short) ((aColors >>> 16) & 255); - } - - public static short getG(int aColors) { - return (short) ((aColors >>> 8) & 255); - } - - public static short getB(int aColors) { - return (short) (aColors & 255); - } - - public static short getA(int aColors) { - return (short) ((aColors >>> 24) & 255); - } - - public static boolean saveMultiblockInputConfiguration(GT_MetaTileEntity_MultiBlockBase controller, - EntityPlayer player) { - NBTTagCompound newTag = new NBTTagCompound(); - ItemStack dataOrb = player.getHeldItem(); - if (GT_Utility.isStackInvalid(dataOrb) || !ItemList.Tool_DataOrb.isStackEqual(dataOrb, false, true)) { - return false; - } - if (!controller.saveOtherHatchConfiguration(player)) { - return false; - } - newTag.setString("type", "MultiblockConfiguration"); - int count = 0; - NBTTagList list = saveConfigurationToDataStick(player, controller.mInputBusses); - if (list == null) return false; - newTag.setTag("mInputBusses", list); - count += list.tagCount(); - list = saveConfigurationToDataStick(player, controller.mInputHatches); - if (list == null) return false; - newTag.setTag("mInputHatches", list); - count += list.tagCount(); - list = saveConfigurationToDataStick(player, controller.mOutputBusses); - if (list == null) return false; - newTag.setTag("mOutputBusses", list); - count += list.tagCount(); - // Output hatch config currently cannot be copied, so we omit this part for now - // TODO this doesn't work for now - // newTag.setTag("mDualInputHatches", saveToDataStick(player, controller.mDualInputHatches)); - dataOrb.setTagCompound(newTag); - Behaviour_DataOrb.setDataTitle(dataOrb, "Multiblock Hatch Configuration"); - Behaviour_DataOrb.setDataName(dataOrb, String.format("%s configuration saved", count)); - return true; - } - - public static boolean hasMultiblockInputConfiguration(ItemStack dataOrb) { - return !GT_Utility.isStackInvalid(dataOrb) && ItemList.Tool_DataOrb.isStackEqual(dataOrb, false, true) - && dataOrb.getTagCompound() != null - && "MultiblockConfiguration".equals( - dataOrb.getTagCompound() - .getString("type")); - } - - public static boolean loadMultiblockInputConfiguration(GT_MetaTileEntity_MultiBlockBase controller, - EntityPlayer player) { - ItemStack dataOrb = player.getHeldItem(); - if (!hasMultiblockInputConfiguration(dataOrb)) { - return false; - } - if (!controller.loadOtherHatchConfiguration(player)) { - return false; - } - NBTTagCompound tag = dataOrb.getTagCompound(); - if (!checkCanLoadConfigurationFromDataStick( - tag.getTagList("mInputBusses", Constants.NBT.TAG_COMPOUND), - player, - controller.mInputBusses) - || !checkCanLoadConfigurationFromDataStick( - tag.getTagList("mInputHatches", Constants.NBT.TAG_COMPOUND), - player, - controller.mInputHatches) - || !checkCanLoadConfigurationFromDataStick( - tag.getTagList("mOutputBusses", Constants.NBT.TAG_COMPOUND), - player, - controller.mOutputBusses)) - return false; - - if (!loadConfigurationFromDataStick( - tag.getTagList("mInputBusses", Constants.NBT.TAG_COMPOUND), - player, - controller.mInputBusses)) return false; - if (!loadConfigurationFromDataStick( - tag.getTagList("mInputHatches", Constants.NBT.TAG_COMPOUND), - player, - controller.mInputHatches)) return false; - if (!loadConfigurationFromDataStick( - tag.getTagList("mOutputBusses", Constants.NBT.TAG_COMPOUND), - player, - controller.mOutputBusses)) return false; - return true; - } - - private static NBTTagList saveConfigurationToDataStick(EntityPlayer player, - List hatches) { - NBTTagList list = new NBTTagList(); - for (GT_MetaTileEntity_Hatch tHatch : filterValidMTEs(hatches)) { - if (!(tHatch instanceof IDataCopyable copyable)) { - list.appendTag(new NBTTagCompound()); - continue; - } - NBTTagCompound tag = copyable.getCopiedData(player); - if (tag == null) return null; - list.appendTag(tag); - } - return list; - } - - private static boolean loadConfigurationFromDataStick(NBTTagList list, EntityPlayer player, - List hatches) { - if (list == null || list.tagList.isEmpty()) return false; - List validMTEs = filterValidMTEs(hatches); - int end = Math.min(validMTEs.size(), list.tagCount()); - for (int i = 0; i < end; i++) { - GT_MetaTileEntity_Hatch tHatch = validMTEs.get(i); - NBTTagCompound tag = list.getCompoundTagAt(i); - if (!(tHatch instanceof IDataCopyable copyable)) { - if (tag.hasNoTags()) continue; - return false; - } - if (tag.hasNoTags()) return false; - if (!copyable.pasteCopiedData(player, tag)) return false; - } - return true; - } - - private static boolean checkCanLoadConfigurationFromDataStick(NBTTagList list, EntityPlayer player, - List hatches) { - if (list == null || list.tagList.isEmpty()) return false; - List validMTEs = filterValidMTEs(hatches); - int end = Math.min(validMTEs.size(), list.tagCount()); - for (int i = 0; i < end; i++) { - GT_MetaTileEntity_Hatch tHatch = validMTEs.get(i); - NBTTagCompound tag = list.getCompoundTagAt(i); - if (tag.hasNoTags()) continue; - if (!(tHatch instanceof IDataCopyable copyable) || !copyable.getCopiedDataIdentifier(player) - .equals(tag.getString("type"))) return false; - } - return true; - } -} diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java deleted file mode 100644 index 84e67ab728..0000000000 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ /dev/null @@ -1,4859 +0,0 @@ -package gregtech.api.util; - -import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.COMPASS_DIRECTIONS; -import static gregtech.api.enums.GT_Values.D1; -import static gregtech.api.enums.GT_Values.E; -import static gregtech.api.enums.GT_Values.GT; -import static gregtech.api.enums.GT_Values.L; -import static gregtech.api.enums.GT_Values.M; -import static gregtech.api.enums.GT_Values.NW; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.GT_Values.W; -import static gregtech.api.enums.Materials.FLUID_MAP; -import static gregtech.api.enums.Mods.Translocator; -import static gregtech.common.GT_UndergroundOil.undergroundOilReadInformation; -import static net.minecraftforge.common.util.ForgeDirection.DOWN; -import static net.minecraftforge.common.util.ForgeDirection.EAST; -import static net.minecraftforge.common.util.ForgeDirection.NORTH; -import static net.minecraftforge.common.util.ForgeDirection.SOUTH; -import static net.minecraftforge.common.util.ForgeDirection.UNKNOWN; -import static net.minecraftforge.common.util.ForgeDirection.UP; -import static net.minecraftforge.common.util.ForgeDirection.WEST; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.math.BigInteger; -import java.math.RoundingMode; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.function.Function; -import java.util.function.IntFunction; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.EnumCreatureAttribute; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.ISidedInventory; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTBase.NBTPrimitive; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; -import net.minecraft.network.play.server.S07PacketRespawn; -import net.minecraft.network.play.server.S1DPacketEntityEffect; -import net.minecraft.network.play.server.S1FPacketSetExperience; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.tileentity.TileEntityChest; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.Vec3; -import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import net.minecraft.world.chunk.Chunk; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.util.BlockSnapshot; -import net.minecraftforge.common.util.Constants; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.common.util.FakePlayerFactory; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidContainerItem; -import net.minecraftforge.fluids.IFluidHandler; -import net.minecraftforge.oredict.OreDictionary; - -import com.google.auto.value.AutoValue; -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.collect.SetMultimap; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; -import com.mojang.authlib.GameProfile; - -import buildcraft.api.transport.IPipeTile; -import cofh.api.energy.IEnergyReceiver; -import cofh.api.transport.IItemDuct; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.registry.GameRegistry; -import gregtech.api.GregTech_API; -import gregtech.api.damagesources.GT_DamageSources; -import gregtech.api.damagesources.GT_DamageSources.DamageSourceHotItem; -import gregtech.api.enchants.Enchantment_Hazmat; -import gregtech.api.enchants.Enchantment_Radioactivity; -import gregtech.api.enums.GT_Values; -import gregtech.api.enums.ItemList; -import gregtech.api.enums.Materials; -import gregtech.api.enums.Mods; -import gregtech.api.enums.OrePrefixes; -import gregtech.api.enums.SoundResource; -import gregtech.api.enums.SubTag; -import gregtech.api.enums.Textures; -import gregtech.api.enums.ToolDictNames; -import gregtech.api.events.BlockScanningEvent; -import gregtech.api.interfaces.IBlockContainer; -import gregtech.api.interfaces.IDebugableBlock; -import gregtech.api.interfaces.IHasIndexedTexture; -import gregtech.api.interfaces.IProjectileItem; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.IBasicEnergyContainer; -import gregtech.api.interfaces.tileentity.ICoverable; -import gregtech.api.interfaces.tileentity.IGregTechDeviceInformation; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.interfaces.tileentity.IMachineProgress; -import gregtech.api.interfaces.tileentity.IUpgradableMachine; -import gregtech.api.items.GT_EnergyArmor_Item; -import gregtech.api.items.GT_Generic_Item; -import gregtech.api.items.GT_MetaGenerated_Tool; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.net.GT_Packet_Sound; -import gregtech.api.objects.CollectorUtils; -import gregtech.api.objects.GT_ItemStack; -import gregtech.api.objects.GT_ItemStack2; -import gregtech.api.objects.ItemData; -import gregtech.api.recipe.RecipeMaps; -import gregtech.api.threads.GT_Runnable_Sound; -import gregtech.api.util.extensions.ArrayExt; -import gregtech.common.GT_Pollution; -import gregtech.common.blocks.GT_Block_Ores_Abstract; -import ic2.api.recipe.IRecipeInput; -import ic2.api.recipe.RecipeInputItemStack; -import ic2.api.recipe.RecipeInputOreDict; -import ic2.api.recipe.RecipeOutput; -import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; - -/** - * NEVER INCLUDE THIS FILE IN YOUR MOD!!! - *

- * Just a few Utility Functions I use. - */ -public class GT_Utility { - - /** - * Formats a number with group separator and at most 2 fraction digits. - */ - private static final Map decimalFormatters = new HashMap<>(); - - /** - * Forge screwed the Fluid Registry up again, so I make my own, which is also much more efficient than the stupid - * Stuff over there. - */ - private static final List sFluidContainerList = new ArrayList<>(); - - private static final Map sFilledContainerToData = new /* Concurrent */ HashMap<>(); - private static final Map> sEmptyContainerToFluidToData = new HashMap<>(); - private static final Map> sFluidToContainers = new HashMap<>(); - /** - * Must use {@code Supplier} here because the ore prefixes have not yet been registered at class load time. - */ - private static final Map> sOreToCobble = new HashMap<>(); - - private static final Map sOreTable = new HashMap<>(); - public static boolean TE_CHECK = false, BC_CHECK = false, CHECK_ALL = true, RF_CHECK = false; - public static Map sPlayedSoundMap = new /* Concurrent */ HashMap<>(); - private static int sBookCount = 0; - public static UUID defaultUuid = null; // maybe default non-null? - // UUID.fromString("00000000-0000-0000-0000-000000000000"); - - static { - GregTech_API.sItemStackMappings.add(sFilledContainerToData); - GregTech_API.sItemStackMappings.add(sEmptyContainerToFluidToData); - - // 1 is the magic index to get the cobblestone block. - // See: GT_Block_Stones.java, GT_Block_Granites.java - Function> materialToCobble = m -> Suppliers.memoize( - () -> GT_OreDictUnificator.getOres(OrePrefixes.stone, m) - .get(1))::get; - sOreToCobble.put(OrePrefixes.oreBlackgranite, materialToCobble.apply(Materials.GraniteBlack)); - sOreToCobble.put(OrePrefixes.oreRedgranite, materialToCobble.apply(Materials.GraniteRed)); - sOreToCobble.put(OrePrefixes.oreMarble, materialToCobble.apply(Materials.Marble)); - sOreToCobble.put(OrePrefixes.oreBasalt, materialToCobble.apply(Materials.Basalt)); - sOreToCobble.put(OrePrefixes.oreNetherrack, () -> new ItemStack(Blocks.netherrack)); - sOreToCobble.put(OrePrefixes.oreEndstone, () -> new ItemStack(Blocks.end_stone)); - } - - public static int safeInt(long number, int margin) { - return number > Integer.MAX_VALUE - margin ? Integer.MAX_VALUE - margin : (int) number; - } - - public static int safeInt(long number) { - return number > V[V.length - 1] ? safeInt(V[V.length - 1], 1) - : number < Integer.MIN_VALUE ? Integer.MIN_VALUE : (int) number; - } - - public static Field getPublicField(Object aObject, String aField) { - Field rField = null; - try { - rField = aObject.getClass() - .getDeclaredField(aField); - } catch (Throwable e) { - /* Do nothing */ - } - return rField; - } - - public static Field getField(Object aObject, String aField) { - Field rField = null; - try { - rField = aObject.getClass() - .getDeclaredField(aField); - rField.setAccessible(true); - } catch (Throwable e) { - /* Do nothing */ - } - return rField; - } - - public static Field getField(Class aObject, String aField) { - Field rField = null; - try { - rField = aObject.getDeclaredField(aField); - rField.setAccessible(true); - } catch (Throwable e) { - /* Do nothing */ - } - return rField; - } - - public static Method getMethod(Class aObject, String aMethod, Class... aParameterTypes) { - Method rMethod = null; - try { - rMethod = aObject.getMethod(aMethod, aParameterTypes); - rMethod.setAccessible(true); - } catch (Throwable e) { - /* Do nothing */ - } - return rMethod; - } - - public static Method getMethod(Object aObject, String aMethod, Class... aParameterTypes) { - Method rMethod = null; - try { - rMethod = aObject.getClass() - .getMethod(aMethod, aParameterTypes); - rMethod.setAccessible(true); - } catch (Throwable e) { - /* Do nothing */ - } - return rMethod; - } - - public static Field getField(Object aObject, String aField, boolean aPrivate, boolean aLogErrors) { - try { - Field tField = (aObject instanceof Class) ? ((Class) aObject).getDeclaredField(aField) - : (aObject instanceof String) ? Class.forName((String) aObject) - .getDeclaredField(aField) - : aObject.getClass() - .getDeclaredField(aField); - if (aPrivate) tField.setAccessible(true); - return tField; - } catch (Throwable e) { - if (aLogErrors) e.printStackTrace(GT_Log.err); - } - return null; - } - - public static Object getFieldContent(Object aObject, String aField, boolean aPrivate, boolean aLogErrors) { - try { - Field tField = (aObject instanceof Class) ? ((Class) aObject).getDeclaredField(aField) - : (aObject instanceof String) ? Class.forName((String) aObject) - .getDeclaredField(aField) - : aObject.getClass() - .getDeclaredField(aField); - if (aPrivate) tField.setAccessible(true); - return tField.get(aObject instanceof Class || aObject instanceof String ? null : aObject); - } catch (Throwable e) { - if (aLogErrors) e.printStackTrace(GT_Log.err); - } - return null; - } - - public static Object callPublicMethod(Object aObject, String aMethod, Object... aParameters) { - return callMethod(aObject, aMethod, false, false, true, aParameters); - } - - public static Object callPrivateMethod(Object aObject, String aMethod, Object... aParameters) { - return callMethod(aObject, aMethod, true, false, true, aParameters); - } - - public static Object callMethod(Object aObject, String aMethod, boolean aPrivate, boolean aUseUpperCasedDataTypes, - boolean aLogErrors, Object... aParameters) { - try { - Class[] tParameterTypes = new Class[aParameters.length]; - for (byte i = 0; i < aParameters.length; i++) { - if (aParameters[i] instanceof Class) { - tParameterTypes[i] = (Class) aParameters[i]; - aParameters[i] = null; - } else { - tParameterTypes[i] = aParameters[i].getClass(); - } - if (!aUseUpperCasedDataTypes) { - if (tParameterTypes[i] == Boolean.class) tParameterTypes[i] = boolean.class; - else if (tParameterTypes[i] == Byte.class) tParameterTypes[i] = byte.class; - else if (tParameterTypes[i] == Short.class) tParameterTypes[i] = short.class; - else if (tParameterTypes[i] == Integer.class) tParameterTypes[i] = int.class; - else if (tParameterTypes[i] == Long.class) tParameterTypes[i] = long.class; - else if (tParameterTypes[i] == Float.class) tParameterTypes[i] = float.class; - else if (tParameterTypes[i] == Double.class) tParameterTypes[i] = double.class; - } - } - - Method tMethod = (aObject instanceof Class) ? ((Class) aObject).getMethod(aMethod, tParameterTypes) - : aObject.getClass() - .getMethod(aMethod, tParameterTypes); - if (aPrivate) tMethod.setAccessible(true); - return tMethod.invoke(aObject, aParameters); - } catch (Throwable e) { - if (aLogErrors) e.printStackTrace(GT_Log.err); - } - return null; - } - - public static Object callConstructor(String aClass, int aConstructorIndex, Object aReplacementObject, - boolean aLogErrors, Object... aParameters) { - try { - return callConstructor( - Class.forName(aClass), - aConstructorIndex, - aReplacementObject, - aLogErrors, - aParameters); - } catch (Throwable e) { - if (aLogErrors) e.printStackTrace(GT_Log.err); - } - return aReplacementObject; - } - - public static Object callConstructor(Class aClass, int aConstructorIndex, Object aReplacementObject, - boolean aLogErrors, Object... aParameters) { - if (aConstructorIndex < 0) { - try { - for (Constructor tConstructor : aClass.getConstructors()) { - try { - return tConstructor.newInstance(aParameters); - } catch (Throwable ignored) {} - } - } catch (Throwable e) { - if (aLogErrors) e.printStackTrace(GT_Log.err); - } - } else { - try { - return aClass.getConstructors()[aConstructorIndex].newInstance(aParameters); - } catch (Throwable e) { - if (aLogErrors) e.printStackTrace(GT_Log.err); - } - } - return aReplacementObject; - } - - public static String capitalizeString(String aString) { - if (aString != null && aString.length() > 0) return aString.substring(0, 1) - .toUpperCase() + aString.substring(1); - return E; - } - - public static boolean getPotion(EntityLivingBase aPlayer, int aPotionIndex) { - try { - Field tPotionHashmap = null; - - Field[] fields = EntityLiving.class.getDeclaredFields(); - - for (Field field : fields) { - if (field.getType() == HashMap.class) { - tPotionHashmap = field; - tPotionHashmap.setAccessible(true); - break; - } - } - - if (tPotionHashmap != null) return ((HashMap) tPotionHashmap.get(aPlayer)).get(aPotionIndex) != null; - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return false; - } - - public static String getClassName(Object aObject) { - if (aObject == null) return "null"; - return aObject.getClass() - .getName() - .substring( - aObject.getClass() - .getName() - .lastIndexOf(".") + 1); - } - - public static void removePotion(EntityLivingBase aPlayer, int aPotionIndex) { - try { - Field tPotionHashmap = null; - - Field[] fields = EntityLiving.class.getDeclaredFields(); - - for (Field field : fields) { - if (field.getType() == HashMap.class) { - tPotionHashmap = field; - tPotionHashmap.setAccessible(true); - break; - } - } - - if (tPotionHashmap != null) ((HashMap) tPotionHashmap.get(aPlayer)).remove(aPotionIndex); - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - } - - public static boolean getFullInvisibility(EntityPlayer aPlayer) { - try { - if (aPlayer.isInvisible()) { - for (int i = 0; i < 4; i++) { - if (aPlayer.inventory.armorInventory[i] != null) { - if (aPlayer.inventory.armorInventory[i].getItem() instanceof GT_EnergyArmor_Item) { - if ((((GT_EnergyArmor_Item) aPlayer.inventory.armorInventory[i].getItem()).mSpecials & 512) - != 0) { - if (GT_ModHandler.canUseElectricItem(aPlayer.inventory.armorInventory[i], 10000)) { - return true; - } - } - } - } - } - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - return false; - } - - public static ItemStack suckOneItemStackAt(World aWorld, double aX, double aY, double aZ, double aL, double aH, - double aW) { - for (EntityItem tItem : aWorld.getEntitiesWithinAABB( - EntityItem.class, - AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + aL, aY + aH, aZ + aW))) { - if (!tItem.isDead) { - aWorld.removeEntity(tItem); - tItem.setDead(); - return tItem.getEntityItem(); - } - } - return null; - } - - public static byte getOppositeSide(ForgeDirection side) { - return (byte) side.getOpposite() - .ordinal(); - } - - public static byte getTier(long l) { - byte i = -1; - while (++i < V.length) if (l <= V[i]) return i; - return (byte) (V.length - 1); - } - - public static long getAmperageForTier(long voltage, byte tier) { - return ceilDiv(voltage, GT_Values.V[tier]); - } - - /** - * Rounds up partial voltage that exceeds tiered voltage, e.g. 4,096 -> 8,192(IV) - */ - public static long roundUpVoltage(long voltage) { - if (voltage > V[V.length - 1]) { - return voltage; - } - return V[GT_Utility.getTier(voltage)]; - } - - public static String getColoredTierNameFromVoltage(long voltage) { - return getColoredTierNameFromTier(getTier(voltage)); - } - - public static String getColoredTierNameFromTier(byte tier) { - return GT_Values.TIER_COLORS[tier] + GT_Values.VN[tier] + EnumChatFormatting.RESET; - } - - /** - * @return e.g. {@code " (LV)"} - */ - @Nonnull - public static String getTierNameWithParentheses(long voltage) { - byte tier = getTier(voltage); - if (tier < 0) { - return ""; - } else if (tier == 0) { - return " (" + GT_Values.VN[1] + ")"; - } else if (tier >= GT_Values.VN.length - 1) { - return " (MAX+)"; - } - return " (" + GT_Values.VN[tier] + ")"; - } - - public static void sendChatToPlayer(EntityPlayer aPlayer, String aChatMessage) { - if (aPlayer instanceof EntityPlayerMP && aChatMessage != null) { - aPlayer.addChatComponentMessage(new ChatComponentText(aChatMessage)); - } - } - - public static void checkAvailabilities() { - if (CHECK_ALL) { - try { - Class tClass = IItemDuct.class; - tClass.getCanonicalName(); - TE_CHECK = true; - } catch (Throwable e) { - /**/ - } - try { - Class tClass = buildcraft.api.transport.IPipeTile.class; - tClass.getCanonicalName(); - BC_CHECK = true; - } catch (Throwable e) { - /**/ - } - try { - Class tClass = cofh.api.energy.IEnergyReceiver.class; - tClass.getCanonicalName(); - RF_CHECK = true; - } catch (Throwable e) { - /**/ - } - CHECK_ALL = false; - } - } - - public static boolean isConnectableNonInventoryPipe(TileEntity tileEntity, ForgeDirection side) { - if (tileEntity == null) return false; - checkAvailabilities(); - if (TE_CHECK && tileEntity instanceof IItemDuct) return true; - if (BC_CHECK && tileEntity instanceof buildcraft.api.transport.IPipeTile pipeTile) - return pipeTile.isPipeConnected(side); - return Translocator.isModLoaded() && tileEntity instanceof codechicken.translocator.TileItemTranslocator; - } - - /** - * Moves Stack from Inv-Slot to Inv-Slot, without checking if its even allowed. - * - * @return the Amount of moved Items - */ - public static byte moveStackIntoPipe(IInventory aTileEntity1, Object aTileEntity2, int[] aGrabSlots, - ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, - byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { - return moveStackIntoPipe( - aTileEntity1, - aTileEntity2, - aGrabSlots, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - true); - } - - /** - * Moves Stack from Inv-Slot to Inv-Slot, without checking if it is even allowed. - * - * @return the Amount of moved Items - */ - public static byte moveStackIntoPipe(IInventory fromInventory, Object toObject, int[] fromSlots, - ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, - byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, - boolean dropItem) { - if (fromInventory == null || aMaxTargetStackSize <= 0 - || aMinTargetStackSize <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMaxMoveAtOnce <= 0 - || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; - if (toObject != null) { - checkAvailabilities(); - if (TE_CHECK && toObject instanceof IItemDuct itemDuct) { - for (final int aGrabSlot : fromSlots) { - if (listContainsItem(aFilter, fromInventory.getStackInSlot(aGrabSlot), true, aInvertFilter)) { - if (isAllowedToTakeFromSlot( - fromInventory, - aGrabSlot, - fromSide, - fromInventory.getStackInSlot(aGrabSlot))) { - if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) - <= fromInventory.getStackInSlot(aGrabSlot).stackSize) { - ItemStack tStack = copyAmount( - Math.min( - fromInventory.getStackInSlot(aGrabSlot).stackSize, - Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), - fromInventory.getStackInSlot(aGrabSlot)); - ItemStack rStack = itemDuct.insertItem(putSide, copyOrNull(tStack)); - byte tMovedItemCount = (byte) (tStack.stackSize - - (rStack == null ? 0 : rStack.stackSize)); - if (tMovedItemCount >= 1 /* Math.max(aMinMoveAtOnce, aMinTargetStackSize) */) { - fromInventory.decrStackSize(aGrabSlot, tMovedItemCount); - fromInventory.markDirty(); - return tMovedItemCount; - } - } - } - } - } - return 0; - } - if (BC_CHECK && toObject instanceof buildcraft.api.transport.IPipeTile bcPipe) { - for (int fromSlot : fromSlots) { - if (listContainsItem(aFilter, fromInventory.getStackInSlot(fromSlot), true, aInvertFilter)) { - if (isAllowedToTakeFromSlot( - fromInventory, - fromSlot, - fromSide, - fromInventory.getStackInSlot(fromSlot))) { - if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) - <= fromInventory.getStackInSlot(fromSlot).stackSize) { - ItemStack tStack = copyAmount( - Math.min( - fromInventory.getStackInSlot(fromSlot).stackSize, - Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), - fromInventory.getStackInSlot(fromSlot)); - byte tMovedItemCount = (byte) bcPipe.injectItem(copyOrNull(tStack), false, putSide); - if (tMovedItemCount >= Math.max(aMinMoveAtOnce, aMinTargetStackSize)) { - tMovedItemCount = (byte) (bcPipe - .injectItem(copyAmount(tMovedItemCount, tStack), true, putSide)); - fromInventory.decrStackSize(fromSlot, tMovedItemCount); - fromInventory.markDirty(); - return tMovedItemCount; - } - } - } - } - } - return 0; - } - } - - if (fromInventory instanceof TileEntity fromTileEntity && fromSide != ForgeDirection.UNKNOWN - && fromSide.getOpposite() == ForgeDirection.getOrientation(putSide.ordinal())) { - int tX = fromTileEntity.xCoord + fromSide.offsetX, tY = fromTileEntity.yCoord + fromSide.offsetY, - tZ = fromTileEntity.zCoord + fromSide.offsetZ; - if (!hasBlockHitBox(((TileEntity) fromInventory).getWorldObj(), tX, tY, tZ) && dropItem) { - for (final int fromSlot : fromSlots) { - if (listContainsItem(aFilter, fromInventory.getStackInSlot(fromSlot), true, aInvertFilter)) { - if (isAllowedToTakeFromSlot( - fromInventory, - fromSlot, - fromSide, - fromInventory.getStackInSlot(fromSlot))) { - if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) - <= fromInventory.getStackInSlot(fromSlot).stackSize) { - final ItemStack tStack = copyAmount( - Math.min( - fromInventory.getStackInSlot(fromSlot).stackSize, - Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), - fromInventory.getStackInSlot(fromSlot)); - final EntityItem tEntity = new EntityItem( - ((TileEntity) fromInventory).getWorldObj(), - tX + 0.5, - tY + 0.5, - tZ + 0.5, - tStack); - tEntity.motionX = tEntity.motionY = tEntity.motionZ = 0; - ((TileEntity) fromInventory).getWorldObj() - .spawnEntityInWorld(tEntity); - assert tStack != null; - fromInventory.decrStackSize(fromSlot, tStack.stackSize); - fromInventory.markDirty(); - return (byte) tStack.stackSize; - } - } - } - } - } - } - return 0; - } - - /** - * Moves Stack from Inv-Slot to Inv-Slot, without checking if its even allowed. (useful for internal Inventory - * Operations) - * - * @return the Amount of moved Items - */ - public static byte moveStackFromSlotAToSlotB(IInventory aTileEntity1, IInventory aTileEntity2, int aGrabFrom, - int aPutTo, byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { - if (aTileEntity1 == null || aTileEntity2 == null - || aMinTargetStackSize <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMaxMoveAtOnce <= 0 - || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; - - ItemStack tStack1 = aTileEntity1.getStackInSlot(aGrabFrom), tStack2 = aTileEntity2.getStackInSlot(aPutTo), - tStack3; - if (tStack1 != null) { - if (tStack2 != null && !areStacksEqual(tStack1, tStack2)) return 0; - tStack3 = copyOrNull(tStack1); - aMaxTargetStackSize = (byte) Math.min( - aMaxTargetStackSize, - Math.min( - tStack3.getMaxStackSize(), - Math.min( - tStack2 == null ? Integer.MAX_VALUE : tStack2.getMaxStackSize(), - aTileEntity2.getInventoryStackLimit()))); - tStack3.stackSize = Math - .min(tStack3.stackSize, aMaxTargetStackSize - (tStack2 == null ? 0 : tStack2.stackSize)); - if (tStack3.stackSize > aMaxMoveAtOnce) tStack3.stackSize = aMaxMoveAtOnce; - if (tStack3.stackSize + (tStack2 == null ? 0 : tStack2.stackSize) - >= Math.min(tStack3.getMaxStackSize(), aMinTargetStackSize) && tStack3.stackSize >= aMinMoveAtOnce) { - tStack3 = aTileEntity1.decrStackSize(aGrabFrom, tStack3.stackSize); - aTileEntity1.markDirty(); - if (tStack3 != null) { - if (tStack2 == null) { - aTileEntity2.setInventorySlotContents(aPutTo, copyOrNull(tStack3)); - } else { - tStack2.stackSize += tStack3.stackSize; - } - aTileEntity2.markDirty(); - return (byte) tStack3.stackSize; - } - } - } - return 0; - } - - public static boolean isAllowedToTakeFromSlot(IInventory aTileEntity, int aSlot, ForgeDirection side, - ItemStack aStack) { - if (side == ForgeDirection.UNKNOWN) { - return Arrays.stream(ForgeDirection.VALID_DIRECTIONS) - .anyMatch(d -> isAllowedToTakeFromSlot(aTileEntity, aSlot, d, aStack)); - } - if (aTileEntity instanceof ISidedInventory sided) return sided.canExtractItem(aSlot, aStack, side.ordinal()); - return true; - } - - public static boolean isAllowedToPutIntoSlot(IInventory aTileEntity, int aSlot, ForgeDirection side, - ItemStack aStack, byte aMaxStackSize) { - ItemStack tStack = aTileEntity.getStackInSlot(aSlot); - if (tStack != null && (!areStacksEqual(tStack, aStack) || tStack.stackSize >= tStack.getMaxStackSize())) - return false; - if (side == ForgeDirection.UNKNOWN) { - return Arrays.stream(ForgeDirection.VALID_DIRECTIONS) - .anyMatch(d -> isAllowedToPutIntoSlot(aTileEntity, aSlot, d, aStack, aMaxStackSize)); - } - if (aTileEntity instanceof ISidedInventory - && !((ISidedInventory) aTileEntity).canInsertItem(aSlot, aStack, side.ordinal())) return false; - return aSlot < aTileEntity.getSizeInventory() && aTileEntity.isItemValidForSlot(aSlot, aStack); - } - - /** - * moves multiple stacks from Inv-Side to Inv-Side - * - * @return the Amount of moved Items - */ - public static int moveMultipleItemStacks(Object aTileEntity1, Object aTileEntity2, ForgeDirection fromSide, - ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, - byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, int aStackAmount) { - if (aTileEntity1 instanceof IInventory) return moveMultipleItemStacks( - (IInventory) aTileEntity1, - aTileEntity2, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aStackAmount, - true); - return 0; - } - - public static int moveMultipleItemStacks(IInventory fromInventory, Object toObject, ForgeDirection fromSide, - ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, - byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, int aMaxStackTransfer, - boolean aDoCheckChests) { - if (fromInventory == null || aMaxTargetStackSize <= 0 - || aMinTargetStackSize <= 0 - || aMaxMoveAtOnce <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMinMoveAtOnce > aMaxMoveAtOnce - || aMaxStackTransfer == 0) return 0; - - // find where to take from - final int[] tGrabSlots = new int[fromInventory.getSizeInventory()]; - int tGrabSlotsSize = 0; - if (fromInventory instanceof ISidedInventory) { - for (int i : ((ISidedInventory) fromInventory).getAccessibleSlotsFromSide(fromSide.ordinal())) { - final ItemStack s = fromInventory.getStackInSlot(i); - if (s == null || !isAllowedToTakeFromSlot(fromInventory, i, fromSide, s) - || s.stackSize < aMinMoveAtOnce - || !listContainsItem(aFilter, s, true, aInvertFilter)) continue; - tGrabSlots[tGrabSlotsSize++] = i; - } - } else { - for (int i = 0; i < tGrabSlots.length; i++) { - ItemStack s = fromInventory.getStackInSlot(i); - if (s == null || s.stackSize < aMinMoveAtOnce || !listContainsItem(aFilter, s, true, aInvertFilter)) - continue; - tGrabSlots[tGrabSlotsSize++] = i; - } - } - - // no source, bail out - if (tGrabSlotsSize == 0) { - // maybe source is a double chest. check it - if (aDoCheckChests && fromInventory instanceof TileEntityChest chest) return moveFromAdjacentChests( - chest, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer); - return 0; - } - - // if target is an inventory, e.g. chest, machine, drawers... - if (toObject instanceof IInventory toInventory) { - - // partially filled slot spare space mapping. - // value is the sum of all spare space left not counting completely empty slot - final HashMap tPutItems = new HashMap<>(toInventory.getSizeInventory()); - // partially filled slot contents - final HashMap> tPutItemStacks = new HashMap<>(toInventory.getSizeInventory()); - // completely empty slots - final List tPutFreeSlots = new ArrayList<>(toInventory.getSizeInventory()); - - // find possible target slots - int[] accessibleSlots = null; - if (toObject instanceof ISidedInventory sided) - accessibleSlots = sided.getAccessibleSlotsFromSide(putSide.ordinal()); - for (int i = 0; i < toInventory.getSizeInventory(); i++) { - int slot = i; - if (accessibleSlots != null) { - if (accessibleSlots.length <= i) break; - slot = accessibleSlots[slot]; - } - ItemStack s = toInventory.getStackInSlot(slot); - if (s == null) { - tPutFreeSlots.add(slot); - } else if ((s.stackSize < s.getMaxStackSize() && s.stackSize < toInventory.getInventoryStackLimit()) - && aMinMoveAtOnce <= s.getMaxStackSize() - s.stackSize - && isAllowedToPutIntoSlot(toInventory, slot, putSide, s, (byte) 64)) { - ItemId sID = ItemId.createNoCopy(s); - tPutItems.merge( - sID, - (Math.min(s.getMaxStackSize(), toInventory.getInventoryStackLimit()) - s.stackSize), - Integer::sum); - tPutItemStacks.computeIfAbsent(sID, k -> new ArrayList<>()) - .add(s); - } - } - - // target completely filled, bail out - if (tPutItems.isEmpty() && tPutFreeSlots.isEmpty()) { - // maybe target is a double chest. check it. - if (aDoCheckChests && toObject instanceof TileEntityChest chest) return moveToAdjacentChests( - fromInventory, - chest, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer); - return 0; - } - - // go over source stacks one by one - int tStacksMoved = 0, tTotalItemsMoved = 0; - for (int j = 0; j < tGrabSlotsSize; j++) { - final int grabSlot = tGrabSlots[j]; - int tMovedItems; - int tStackSize; - do { - tMovedItems = 0; - final ItemStack tGrabStack = fromInventory.getStackInSlot(grabSlot); - if (tGrabStack == null) break; - tStackSize = tGrabStack.stackSize; - final ItemId sID = ItemId.createNoCopy(tGrabStack); - - if (tPutItems.containsKey(sID)) { - // there is a partially filled slot, try merging - final int canPut = Math.min(tPutItems.get(sID), aMaxMoveAtOnce); - if (canPut >= aMinMoveAtOnce) { - final List putStack = tPutItemStacks.get(sID); - if (!putStack.isEmpty()) { - // can move, do merge - int toPut = Math.min(canPut, tStackSize); - tMovedItems = toPut; - for (int i = 0; i < putStack.size(); i++) { - final ItemStack s = putStack.get(i); - final int sToPut = Math.min( - Math.min( - Math.min(toPut, s.getMaxStackSize() - s.stackSize), - toInventory.getInventoryStackLimit() - s.stackSize), - aMaxTargetStackSize - s.stackSize); - if (sToPut <= 0) continue; - if (sToPut < aMinMoveAtOnce) continue; - if (s.stackSize + sToPut < aMinTargetStackSize) continue; - toPut -= sToPut; - s.stackSize += sToPut; - if (s.stackSize == s.getMaxStackSize() - || s.stackSize == toInventory.getInventoryStackLimit()) { - // this slot is full. remove this stack from candidate list - putStack.remove(i); - i--; - } - if (toPut == 0) break; - } - tMovedItems -= toPut; - if (tMovedItems > 0) { - tStackSize -= tMovedItems; - tTotalItemsMoved += tMovedItems; - // deduct spare space - tPutItems.merge(sID, tMovedItems, (a, b) -> a.equals(b) ? null : a - b); - - if (tStackSize == 0) fromInventory.setInventorySlotContents(grabSlot, null); - else tGrabStack.stackSize = tStackSize; - - fromInventory.markDirty(); - toInventory.markDirty(); - } - } - } - } - // still stuff to move & have completely empty slots - if (tStackSize > 0 && !tPutFreeSlots.isEmpty()) { - for (int i = 0; i < tPutFreeSlots.size(); i++) { - final int tPutSlot = tPutFreeSlots.get(i); - if (isAllowedToPutIntoSlot(toInventory, tPutSlot, putSide, tGrabStack, (byte) 64)) { - // allowed, now do moving - final int tMoved = moveStackFromSlotAToSlotB( - fromInventory, - toInventory, - grabSlot, - tPutSlot, - aMaxTargetStackSize, - aMinTargetStackSize, - (byte) (aMaxMoveAtOnce - tMovedItems), - aMinMoveAtOnce); - if (tMoved > 0) { - final ItemStack s = toInventory.getStackInSlot(tPutSlot); - if (s != null) { - // s might be null if tPutInventory is very special, e.g. infinity chest - // if s is null, we will not mark this slot as target candidate for anything - final int spare = Math - .min(s.getMaxStackSize(), toInventory.getInventoryStackLimit()) - - s.stackSize; - if (spare > 0) { - final ItemId ssID = ItemId.createNoCopy(s); - // add back to spare space count - tPutItems.merge(ssID, spare, Integer::sum); - // add to partially filled slot list - tPutItemStacks.computeIfAbsent(ssID, k -> new ArrayList<>()) - .add(s); - } - // this is no longer free - tPutFreeSlots.remove(i); - i--; - } - // else -> noop - // this is still a free slot. no need to do anything. - tTotalItemsMoved += tMoved; - tMovedItems += tMoved; - tStackSize -= tMoved; - if (tStackSize == 0) break; - } - } - } - } - - if (tMovedItems > 0) { - // check if we have moved enough stacks - if (++tStacksMoved >= aMaxStackTransfer) return tTotalItemsMoved; - } - } while (tMovedItems > 0 && tStackSize > 0); // support inventories that store more than a stack in a - // slot - } - - // check if source is a double chest, if yes, try move from the adjacent as well - if (aDoCheckChests && fromInventory instanceof TileEntityChest chest) { - final int tAmount = moveFromAdjacentChests( - chest, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer - tStacksMoved); - if (tAmount != 0) return tAmount + tTotalItemsMoved; - } - - // check if target is a double chest, if yes, try move to the adjacent as well - if (aDoCheckChests && toObject instanceof TileEntityChest chest) { - final int tAmount = moveToAdjacentChests( - fromInventory, - chest, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer - tStacksMoved); - if (tAmount != 0) return tAmount + tTotalItemsMoved; - } - - return tTotalItemsMoved; - } - // there should be a function to transfer more than 1 stack in a pipe - // however I do not see any ways to improve it. too much work for what it is worth - int tTotalItemsMoved = 0; - final int tGrabInventorySize = tGrabSlots.length; - for (int i = 0; i < tGrabInventorySize; i++) { - final int tMoved = moveStackIntoPipe( - fromInventory, - toObject, - tGrabSlots, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aDoCheckChests); - if (tMoved == 0) return tTotalItemsMoved; - else tTotalItemsMoved += tMoved; - } - return 0; - } - - private static int moveToAdjacentChests(IInventory aTileEntity1, TileEntityChest aTargetChest, - ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, - byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, - int aMaxStackTransfer) { - if (aTargetChest.adjacentChestChecked) { - if (aTargetChest.adjacentChestXNeg != null) { - return moveMultipleItemStacks( - aTileEntity1, - aTargetChest.adjacentChestXNeg, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } else if (aTargetChest.adjacentChestZNeg != null) { - return moveMultipleItemStacks( - aTileEntity1, - aTargetChest.adjacentChestZNeg, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } else if (aTargetChest.adjacentChestXPos != null) { - return moveMultipleItemStacks( - aTileEntity1, - aTargetChest.adjacentChestXPos, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } else if (aTargetChest.adjacentChestZPos != null) { - return moveMultipleItemStacks( - aTileEntity1, - aTargetChest.adjacentChestZPos, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } - } - return 0; - } - - private static int moveFromAdjacentChests(TileEntityChest fromTileEntityChest, Object toObject, - ForgeDirection fromSide, ForgeDirection putSide, List aFilter, boolean aInvertFilter, - byte aMaxTargetStackSize, byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, - int aMaxStackTransfer) { - if (fromTileEntityChest.adjacentChestXNeg != null) { - return moveMultipleItemStacks( - fromTileEntityChest.adjacentChestXNeg, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } else if (fromTileEntityChest.adjacentChestZNeg != null) { - return moveMultipleItemStacks( - fromTileEntityChest.adjacentChestZNeg, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } else if (fromTileEntityChest.adjacentChestXPos != null) { - return moveMultipleItemStacks( - fromTileEntityChest.adjacentChestXPos, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } else if (fromTileEntityChest.adjacentChestZPos != null) { - return moveMultipleItemStacks( - fromTileEntityChest.adjacentChestZPos, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aMaxStackTransfer, - false); - } - return 0; - } - - /** - * Moves Stack from Inv-Side to Inv-Side. - * - * @return the Amount of moved Items - */ - public static byte moveOneItemStack(Object fromObject, Object toObject, ForgeDirection fromSide, - ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, - byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { - if (fromObject instanceof IInventory inv) return moveOneItemStack( - inv, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - true); - return 0; - } - - /** - * This is only because I needed an additional Parameter for the Double Chest Check. - */ - private static byte moveOneItemStack(IInventory fromInventory, Object toObject, ForgeDirection fromSide, - ForgeDirection putSide, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, - byte aMinTargetStackSize, byte aMaxMoveAtOnce, byte aMinMoveAtOnce, boolean aDoCheckChests) { - if (fromInventory == null || aMaxTargetStackSize <= 0 - || aMinTargetStackSize <= 0 - || aMaxMoveAtOnce <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; - - int[] tGrabSlots = null; - if (fromInventory instanceof ISidedInventory) - tGrabSlots = ((ISidedInventory) fromInventory).getAccessibleSlotsFromSide(fromSide.ordinal()); - if (tGrabSlots == null) { - tGrabSlots = new int[fromInventory.getSizeInventory()]; - for (int i = 0; i < tGrabSlots.length; i++) tGrabSlots[i] = i; - } - - if (toObject instanceof IInventory inv) { - int[] tPutSlots = null; - if (toObject instanceof ISidedInventory sided) - tPutSlots = sided.getAccessibleSlotsFromSide(putSide.ordinal()); - - if (tPutSlots == null) { - tPutSlots = new int[inv.getSizeInventory()]; - for (int i = 0; i < tPutSlots.length; i++) tPutSlots[i] = i; - } - - for (final int tGrabSlot : tGrabSlots) { - byte tMovedItemCount = 0; - final ItemStack tGrabStack = fromInventory.getStackInSlot(tGrabSlot); - if (listContainsItem(aFilter, tGrabStack, true, aInvertFilter) - && (tGrabStack.stackSize >= aMinMoveAtOnce - && isAllowedToTakeFromSlot(fromInventory, tGrabSlot, fromSide, tGrabStack))) { - for (final int tPutSlot : tPutSlots) { - if (isAllowedToPutIntoSlot(inv, tPutSlot, putSide, tGrabStack, aMaxTargetStackSize)) { - tMovedItemCount += moveStackFromSlotAToSlotB( - fromInventory, - inv, - tGrabSlot, - tPutSlot, - aMaxTargetStackSize, - aMinTargetStackSize, - (byte) (aMaxMoveAtOnce - tMovedItemCount), - aMinMoveAtOnce); - if (tMovedItemCount >= aMaxMoveAtOnce || (tMovedItemCount > 0 && aMaxTargetStackSize < 64)) - return tMovedItemCount; - } - } - - } - if (tMovedItemCount > 0) return tMovedItemCount; - } - - if (aDoCheckChests && fromInventory instanceof TileEntityChest fromChest - && (fromChest.adjacentChestChecked)) { - byte tAmount = 0; - if (fromChest.adjacentChestXNeg != null) { - tAmount = moveOneItemStack( - fromChest.adjacentChestXNeg, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (fromChest.adjacentChestZNeg != null) { - tAmount = moveOneItemStack( - fromChest.adjacentChestZNeg, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (fromChest.adjacentChestXPos != null) { - tAmount = moveOneItemStack( - fromChest.adjacentChestXPos, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (fromChest.adjacentChestZPos != null) { - tAmount = moveOneItemStack( - fromChest.adjacentChestZPos, - toObject, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } - if (tAmount != 0) return tAmount; - - } - if (aDoCheckChests && toObject instanceof TileEntityChest toChest && (toChest.adjacentChestChecked)) { - byte tAmount = 0; - if (toChest.adjacentChestXNeg != null) { - tAmount = moveOneItemStack( - fromInventory, - toChest.adjacentChestXNeg, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (toChest.adjacentChestZNeg != null) { - tAmount = moveOneItemStack( - fromInventory, - toChest.adjacentChestZNeg, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (toChest.adjacentChestXPos != null) { - tAmount = moveOneItemStack( - fromInventory, - toChest.adjacentChestXPos, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (toChest.adjacentChestZPos != null) { - tAmount = moveOneItemStack( - fromInventory, - toChest.adjacentChestZPos, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } - if (tAmount != 0) return tAmount; - - } - } - - return moveStackIntoPipe( - fromInventory, - toObject, - tGrabSlots, - fromSide, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aDoCheckChests); - } - - /** - * Moves Stack from Inv-Side to Inv-Slot. - * - * @return the Amount of moved Items - */ - public static byte moveOneItemStackIntoSlot(Object fromTileEntity, Object toTileEntity, ForgeDirection fromSide, - int putSlot, List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, - byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { - if (!(fromTileEntity instanceof IInventory fromInv) || aMaxTargetStackSize <= 0 - || aMinTargetStackSize <= 0 - || aMaxMoveAtOnce <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; - - int[] tGrabSlots = null; - if (fromTileEntity instanceof ISidedInventory sided) - tGrabSlots = sided.getAccessibleSlotsFromSide(fromSide.ordinal()); - if (tGrabSlots == null) { - tGrabSlots = new int[fromInv.getSizeInventory()]; - for (int i = 0; i < tGrabSlots.length; i++) tGrabSlots[i] = i; - } - - if (toTileEntity instanceof IInventory toInv) { - for (final int tGrabSlot : tGrabSlots) { - if (listContainsItem(aFilter, fromInv.getStackInSlot(tGrabSlot), true, aInvertFilter)) { - if (isAllowedToTakeFromSlot(fromInv, tGrabSlot, fromSide, fromInv.getStackInSlot(tGrabSlot))) { - if (isAllowedToPutIntoSlot( - toInv, - putSlot, - ForgeDirection.UNKNOWN, - fromInv.getStackInSlot(tGrabSlot), - aMaxTargetStackSize)) { - byte tMovedItemCount = moveStackFromSlotAToSlotB( - fromInv, - toInv, - tGrabSlot, - putSlot, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce); - if (tMovedItemCount > 0) return tMovedItemCount; - } - } - } - } - } - - final ForgeDirection toSide = fromSide.getOpposite(); - moveStackIntoPipe( - fromInv, - toTileEntity, - tGrabSlots, - fromSide, - ForgeDirection.UNKNOWN, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce); - return 0; - } - - /** - * Moves Stack from Inv-Slot to Inv-Slot. - * - * @return the Amount of moved Items - */ - public static byte moveFromSlotToSlot(IInventory fromInv, IInventory toInv, int aGrabFrom, int aPutTo, - List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, - byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { - if (fromInv == null || toInv == null - || aGrabFrom < 0 - || aPutTo < 0 - || aMinTargetStackSize <= 0 - || aMaxMoveAtOnce <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; - if (listContainsItem(aFilter, fromInv.getStackInSlot(aGrabFrom), true, aInvertFilter)) { - if (isAllowedToTakeFromSlot( - fromInv, - aGrabFrom, - ForgeDirection.UNKNOWN, - fromInv.getStackInSlot(aGrabFrom))) { - if (isAllowedToPutIntoSlot( - toInv, - aPutTo, - ForgeDirection.UNKNOWN, - fromInv.getStackInSlot(aGrabFrom), - aMaxTargetStackSize)) { - byte tMovedItemCount = moveStackFromSlotAToSlotB( - fromInv, - toInv, - aGrabFrom, - aPutTo, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce); - if (tMovedItemCount > 0) return tMovedItemCount; - } - } - } - return 0; - } - - /** - * Moves Stack from Inv-Side to Inv-Slot. - * - * @return the Amount of moved Items - */ - public static byte moveFromSlotToSide(IInventory fromTile, Object toTile, int fromSlot, ForgeDirection putSide, - List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, - byte aMaxMoveAtOnce, byte aMinMoveAtOnce, boolean aDoCheckChests) { - if (fromTile == null || fromSlot < 0 - || aMinTargetStackSize <= 0 - || aMaxMoveAtOnce <= 0 - || aMinTargetStackSize > aMaxTargetStackSize - || aMinMoveAtOnce > aMaxMoveAtOnce) return 0; - - if (!listContainsItem(aFilter, fromTile.getStackInSlot(fromSlot), true, aInvertFilter) - || !isAllowedToTakeFromSlot(fromTile, fromSlot, ForgeDirection.UNKNOWN, fromTile.getStackInSlot(fromSlot))) - return 0; - - if (toTile instanceof IInventory) { - int[] tPutSlots = null; - if (toTile instanceof ISidedInventory sided) - tPutSlots = sided.getAccessibleSlotsFromSide(putSide.ordinal()); - - if (tPutSlots == null) { - tPutSlots = new int[((IInventory) toTile).getSizeInventory()]; - for (int i = 0; i < tPutSlots.length; i++) tPutSlots[i] = i; - } - - byte tMovedItemCount = 0; - for (final int tPutSlot : tPutSlots) { - if (isAllowedToPutIntoSlot( - (IInventory) toTile, - tPutSlot, - putSide, - fromTile.getStackInSlot(fromSlot), - aMaxTargetStackSize)) { - tMovedItemCount += moveStackFromSlotAToSlotB( - fromTile, - (IInventory) toTile, - fromSlot, - tPutSlot, - aMaxTargetStackSize, - aMinTargetStackSize, - (byte) (aMaxMoveAtOnce - tMovedItemCount), - aMinMoveAtOnce); - if (tMovedItemCount >= aMaxMoveAtOnce) { - return tMovedItemCount; - } - } - } - if (tMovedItemCount > 0) return tMovedItemCount; - - if (aDoCheckChests && toTile instanceof TileEntityChest tTileEntity2) { - if (tTileEntity2.adjacentChestChecked) { - if (tTileEntity2.adjacentChestXNeg != null) { - tMovedItemCount = moveFromSlotToSide( - fromTile, - tTileEntity2.adjacentChestXNeg, - fromSlot, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (tTileEntity2.adjacentChestZNeg != null) { - tMovedItemCount = moveFromSlotToSide( - fromTile, - tTileEntity2.adjacentChestZNeg, - fromSlot, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (tTileEntity2.adjacentChestXPos != null) { - tMovedItemCount = moveFromSlotToSide( - fromTile, - tTileEntity2.adjacentChestXPos, - fromSlot, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } else if (tTileEntity2.adjacentChestZPos != null) { - tMovedItemCount = moveFromSlotToSide( - fromTile, - tTileEntity2.adjacentChestZPos, - fromSlot, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - false); - } - if (tMovedItemCount > 0) return tMovedItemCount; - } - } - } - return moveStackIntoPipe( - fromTile, - toTile, - new int[] { fromSlot }, - ForgeDirection.UNKNOWN, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - aDoCheckChests); - } - - public static byte moveFromSlotToSide(IInventory fromTile, Object toTile, int fromSlot, ForgeDirection putSide, - List aFilter, boolean aInvertFilter, byte aMaxTargetStackSize, byte aMinTargetStackSize, - byte aMaxMoveAtOnce, byte aMinMoveAtOnce) { - return moveFromSlotToSide( - fromTile, - toTile, - fromSlot, - putSide, - aFilter, - aInvertFilter, - aMaxTargetStackSize, - aMinTargetStackSize, - aMaxMoveAtOnce, - aMinMoveAtOnce, - true); - } - - /** - * Move up to maxAmount amount of fluid from source to dest, with optional filtering via allowMove. note that this - * filter cannot bypass filtering done by IFluidHandlers themselves. - * - * this overload will assume the fill side is the opposite of drainSide - * - * @param source tank to drain from. method become noop if this is null - * @param dest tank to fill to. method become noop if this is null - * @param drainSide side used during draining operation - * @param maxAmount max amount of fluid to transfer. method become noop if this is not a positive integer - * @param allowMove filter. can be null to signal all fluids are accepted - */ - public static void moveFluid(IFluidHandler source, IFluidHandler dest, ForgeDirection drainSide, int maxAmount, - @Nullable Predicate allowMove) { - moveFluid(source, dest, drainSide, drainSide.getOpposite(), maxAmount, allowMove); - } - - /** - * Move up to maxAmount amount of fluid from source to dest, with optional filtering via allowMove. note that this - * filter cannot bypass filtering done by IFluidHandlers themselves. - * - * @param source tank to drain from. method become noop if this is null - * @param dest tank to fill to. method become noop if this is null - * @param drainSide side used during draining operation - * @param fillSide side used during filling operation - * @param maxAmount max amount of fluid to transfer. method become noop if this is not a positive integer - * @param allowMove filter. can be null to signal all fluids are accepted - */ - public static void moveFluid(IFluidHandler source, IFluidHandler dest, ForgeDirection drainSide, - ForgeDirection fillSide, int maxAmount, @Nullable Predicate allowMove) { - if (source == null || dest == null || maxAmount <= 0) return; - FluidStack liquid = source.drain(drainSide, maxAmount, false); - if (liquid == null) return; - liquid = liquid.copy(); - liquid.amount = dest.fill(fillSide, liquid, false); - if (liquid.amount > 0 && (allowMove == null || allowMove.test(liquid))) { - dest.fill(fillSide, source.drain(drainSide, liquid.amount, true), true); - } - } - - public static boolean listContainsItem(Collection aList, ItemStack aStack, boolean aTIfListEmpty, - boolean aInvertFilter) { - if (aStack == null || aStack.stackSize < 1) return false; - if (aList == null) return aTIfListEmpty; - boolean tEmpty = true; - for (ItemStack tStack : aList) { - if (tStack != null) { - tEmpty = false; - if (areStacksEqual(aStack, tStack)) { - return !aInvertFilter; - } - } - } - return tEmpty ? aTIfListEmpty : aInvertFilter; - } - - public static boolean areStacksOrToolsEqual(ItemStack aStack1, ItemStack aStack2) { - if (aStack1 != null && aStack2 != null && aStack1.getItem() == aStack2.getItem()) { - if (aStack1.getItem() - .isDamageable()) return true; - return ((aStack1.getTagCompound() == null) == (aStack2.getTagCompound() == null)) - && (aStack1.getTagCompound() == null || aStack1.getTagCompound() - .equals(aStack2.getTagCompound())) - && (Items.feather.getDamage(aStack1) == Items.feather.getDamage(aStack2) - || Items.feather.getDamage(aStack1) == W - || Items.feather.getDamage(aStack2) == W); - } - return false; - } - - public static boolean areFluidsEqual(FluidStack aFluid1, FluidStack aFluid2) { - return areFluidsEqual(aFluid1, aFluid2, false); - } - - public static boolean areFluidsEqual(FluidStack aFluid1, FluidStack aFluid2, boolean aIgnoreNBT) { - return aFluid1 != null && aFluid2 != null - && aFluid1.getFluid() == aFluid2.getFluid() - && (aIgnoreNBT || ((aFluid1.tag == null) == (aFluid2.tag == null)) - && (aFluid1.tag == null || aFluid1.tag.equals(aFluid2.tag))); - } - - public static boolean areStacksEqual(ItemStack aStack1, ItemStack aStack2) { - return areStacksEqual(aStack1, aStack2, false); - } - - public static boolean areStacksEqual(ItemStack aStack1, ItemStack aStack2, boolean aIgnoreNBT) { - return aStack1 != null && aStack2 != null - && aStack1.getItem() == aStack2.getItem() - && (Items.feather.getDamage(aStack1) == Items.feather.getDamage(aStack2) - || Items.feather.getDamage(aStack1) == W - || Items.feather.getDamage(aStack2) == W) - && (aIgnoreNBT || (((aStack1.getTagCompound() == null) == (aStack2.getTagCompound() == null)) - && (aStack1.getTagCompound() == null || aStack1.getTagCompound() - .equals(aStack2.getTagCompound())))); - } - - public static boolean areStacksEqualOrNull(ItemStack stack1, ItemStack stack2) { - return (stack1 == null && stack2 == null) || GT_Utility.areStacksEqual(stack1, stack2); - } - - /** - * Treat both null list, or both null item stack at same list position as equal. - *

- * Since ItemStack doesn't override equals and hashCode, you cannot just use Objects.equals - */ - public static boolean areStackListsEqual(List lhs, List rhs, boolean ignoreStackSize, - boolean ignoreNBT) { - if (lhs == null) return rhs == null; - if (rhs == null) return false; - if (lhs.size() != rhs.size()) return false; - for (Iterator it1 = lhs.iterator(), it2 = rhs.iterator(); it1.hasNext() && it2.hasNext();) { - if (!areStacksEqualExtended(it1.next(), it2.next(), ignoreStackSize, ignoreNBT)) return false; - } - return true; - } - - private static boolean areStacksEqualExtended(ItemStack lhs, ItemStack rhs, boolean ignoreStackSize, - boolean ignoreNBT) { - if (lhs == null) return rhs == null; - if (rhs == null) return false; - return lhs.getItem() == rhs.getItem() - && (ignoreNBT || Objects.equals(lhs.stackTagCompound, rhs.stackTagCompound)) - && (ignoreStackSize || lhs.stackSize == rhs.stackSize); - } - - public static boolean areUnificationsEqual(ItemStack aStack1, ItemStack aStack2) { - return areUnificationsEqual(aStack1, aStack2, false); - } - - public static boolean areUnificationsEqual(ItemStack aStack1, ItemStack aStack2, boolean aIgnoreNBT) { - return areStacksEqual( - GT_OreDictUnificator.get_nocopy(aStack1), - GT_OreDictUnificator.get_nocopy(aStack2), - aIgnoreNBT); - } - - public static String getFluidName(Fluid aFluid, boolean aLocalized) { - if (aFluid == null) return E; - String rName = aLocalized ? aFluid.getLocalizedName(new FluidStack(aFluid, 0)) : aFluid.getUnlocalizedName(); - if (rName.contains("fluid.") || rName.contains("tile.")) return capitalizeString( - rName.replaceAll("fluid.", E) - .replaceAll("tile.", E)); - return rName; - } - - public static String getFluidName(FluidStack aFluid, boolean aLocalized) { - if (aFluid == null) return E; - return getFluidName(aFluid.getFluid(), aLocalized); - } - - public static void reInit() { - sFilledContainerToData.clear(); - sEmptyContainerToFluidToData.clear(); - sFluidToContainers.clear(); - for (FluidContainerData tData : sFluidContainerList) { - String fluidName = tData.fluid.getFluid() - .getName(); - sFilledContainerToData.put(new GT_ItemStack(tData.filledContainer), tData); - Map tFluidToContainer = sEmptyContainerToFluidToData - .get(new GT_ItemStack(tData.emptyContainer)); - List tContainers = sFluidToContainers.get(fluidName); - if (tFluidToContainer == null) { - sEmptyContainerToFluidToData - .put(new GT_ItemStack(tData.emptyContainer), tFluidToContainer = new /* Concurrent */ HashMap<>()); - } - tFluidToContainer.put(fluidName, tData); - if (tContainers == null) { - tContainers = new ArrayList<>(); - tContainers.add(tData.filledContainer); - sFluidToContainers.put(fluidName, tContainers); - } else tContainers.add(tData.filledContainer); - } - } - - public static void addFluidContainerData(FluidContainerData aData) { - String fluidName = aData.fluid.getFluid() - .getName(); - sFluidContainerList.add(aData); - sFilledContainerToData.put(new GT_ItemStack(aData.filledContainer), aData); - Map tFluidToContainer = sEmptyContainerToFluidToData - .get(new GT_ItemStack(aData.emptyContainer)); - List tContainers = sFluidToContainers.get(fluidName); - if (tFluidToContainer == null) { - sEmptyContainerToFluidToData - .put(new GT_ItemStack(aData.emptyContainer), tFluidToContainer = new /* Concurrent */ HashMap<>()); - } - tFluidToContainer.put(fluidName, aData); - if (tContainers == null) { - tContainers = new ArrayList<>(); - tContainers.add(aData.filledContainer); - sFluidToContainers.put(fluidName, tContainers); - } else tContainers.add(aData.filledContainer); - } - - public static List getContainersFromFluid(FluidStack tFluidStack) { - if (tFluidStack != null) { - List tContainers = sFluidToContainers.get( - tFluidStack.getFluid() - .getName()); - if (tContainers == null) return new ArrayList<>(); - return tContainers; - } - return new ArrayList<>(); - } - - public static ItemStack fillFluidContainer(FluidStack aFluid, ItemStack aStack, boolean aRemoveFluidDirectly, - boolean aCheckIFluidContainerItems) { - if (isStackInvalid(aStack) || aFluid == null) return null; - if (GT_ModHandler.isWater(aFluid) && ItemList.Bottle_Empty.isStackEqual(aStack)) { - if (aFluid.amount >= 1000) { - return new ItemStack(Items.potionitem, 1, 0); - } - return null; - } - if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem - && ((IFluidContainerItem) aStack.getItem()).getFluid(aStack) == null - && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) <= aFluid.amount) { - if (aRemoveFluidDirectly) aFluid.amount -= ((IFluidContainerItem) aStack.getItem()) - .fill(aStack = copyAmount(1, aStack), aFluid, true); - else((IFluidContainerItem) aStack.getItem()).fill(aStack = copyAmount(1, aStack), aFluid, true); - return aStack; - } - Map tFluidToContainer = sEmptyContainerToFluidToData.get(new GT_ItemStack(aStack)); - if (tFluidToContainer == null) return null; - FluidContainerData tData = tFluidToContainer.get( - aFluid.getFluid() - .getName()); - if (tData == null || tData.fluid.amount > aFluid.amount) return null; - if (aRemoveFluidDirectly) aFluid.amount -= tData.fluid.amount; - return copyAmount(1, tData.filledContainer); - } - - public static int calculateRecipeEU(Materials aMaterial, int defaultRecipeEUPerTick) { - return aMaterial.getProcessingMaterialTierEU() == 0 ? defaultRecipeEUPerTick - : aMaterial.getProcessingMaterialTierEU(); - } - - public static ItemStack getFluidDisplayStack(Fluid aFluid) { - return aFluid == null ? null : getFluidDisplayStack(new FluidStack(aFluid, 0), false); - } - - public static ItemStack getFluidDisplayStack(FluidStack aFluid, boolean aUseStackSize) { - return getFluidDisplayStack(aFluid, aUseStackSize, false); - } - - public static ItemStack getFluidDisplayStack(FluidStack aFluid, boolean aUseStackSize, boolean aHideStackSize) { - if (aFluid == null || aFluid.getFluid() == null) return null; - int tmp = 0; - try { - tmp = aFluid.getFluid() - .getID(); - } catch (Exception e) { - System.err.println(e); - } - ItemStack rStack = ItemList.Display_Fluid.getWithDamage(1, tmp); - NBTTagCompound tNBT = new NBTTagCompound(); - tNBT.setLong("mFluidDisplayAmount", aUseStackSize ? aFluid.amount : 0); - tNBT.setLong( - "mFluidDisplayHeat", - aFluid.getFluid() - .getTemperature(aFluid)); - tNBT.setBoolean( - "mFluidState", - aFluid.getFluid() - .isGaseous(aFluid)); - tNBT.setBoolean("mHideStackSize", aHideStackSize); - try { - tNBT.setString("mFluidMaterialName", FLUID_MAP.get(aFluid.getFluid()).mName); - } catch (Exception ignored) {} - rStack.setTagCompound(tNBT); - return rStack; - } - - public static FluidStack getFluidFromDisplayStack(ItemStack aDisplayStack) { - if (!isStackValid(aDisplayStack) || aDisplayStack.getItem() != ItemList.Display_Fluid.getItem() - || !aDisplayStack.hasTagCompound()) return null; - Fluid tFluid = FluidRegistry.getFluid( - ItemList.Display_Fluid.getItem() - .getDamage(aDisplayStack)); - return new FluidStack( - tFluid, - (int) aDisplayStack.getTagCompound() - .getLong("mFluidDisplayAmount")); - } - - public static boolean containsFluid(ItemStack aStack, FluidStack aFluid, boolean aCheckIFluidContainerItems) { - if (isStackInvalid(aStack) || aFluid == null) return false; - if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem - && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) - return aFluid - .isFluidEqual(((IFluidContainerItem) aStack.getItem()).getFluid(aStack = copyAmount(1, aStack))); - FluidContainerData tData = sFilledContainerToData.get(new GT_ItemStack(aStack)); - return tData != null && tData.fluid.isFluidEqual(aFluid); - } - - public static FluidStack getFluidForFilledItem(ItemStack aStack, boolean aCheckIFluidContainerItems) { - if (isStackInvalid(aStack)) return null; - if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem - && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) - return ((IFluidContainerItem) aStack.getItem()).drain(copyAmount(1, aStack), Integer.MAX_VALUE, true); - FluidContainerData tData = sFilledContainerToData.get(new GT_ItemStack(aStack)); - return tData == null ? null : tData.fluid.copy(); - } - - /** - * Get empty fluid container from filled one. - */ - public static ItemStack getContainerForFilledItem(ItemStack aStack, boolean aCheckIFluidContainerItems) { - if (isStackInvalid(aStack)) return null; - FluidContainerData tData = sFilledContainerToData.get(new GT_ItemStack(aStack)); - if (tData != null) return copyAmount(1, tData.emptyContainer); - if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem - && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) { - ((IFluidContainerItem) aStack.getItem()).drain(aStack = copyAmount(1, aStack), Integer.MAX_VALUE, true); - return aStack; - } - return null; - } - - /** - * This is NOT meant for fluid manipulation! It's for getting item container, which is generally used for - * crafting recipes. While it also works for many of the fluid containers, some don't. - *

- * Use {@link #getContainerForFilledItem} for getting empty fluid container. - */ - public static ItemStack getContainerItem(ItemStack aStack, boolean aCheckIFluidContainerItems) { - if (isStackInvalid(aStack)) return null; - if (aStack.getItem() - .hasContainerItem(aStack)) - return aStack.getItem() - .getContainerItem(aStack); - /* - * These are all special Cases, in which it is intended to have only GT Blocks outputting those Container Items - */ - if (ItemList.Cell_Empty.isStackEqual(aStack, false, true)) return null; - if (aStack.getItem() == Items.potionitem || aStack.getItem() == Items.experience_bottle - || ItemList.TF_Vial_FieryBlood.isStackEqual(aStack) - || ItemList.TF_Vial_FieryTears.isStackEqual(aStack)) return ItemList.Bottle_Empty.get(1); - - if (aCheckIFluidContainerItems && aStack.getItem() instanceof IFluidContainerItem - && ((IFluidContainerItem) aStack.getItem()).getCapacity(aStack) > 0) { - ItemStack tStack = copyAmount(1, aStack); - ((IFluidContainerItem) aStack.getItem()).drain(tStack, Integer.MAX_VALUE, true); - if (!areStacksEqual(aStack, tStack)) return tStack; - return null; - } - - int tCapsuleCount = GT_ModHandler.getCapsuleCellContainerCount(aStack); - if (tCapsuleCount > 0) return ItemList.Cell_Empty.get(tCapsuleCount); - - if (ItemList.IC2_ForgeHammer.isStackEqual(aStack) || ItemList.IC2_WireCutter.isStackEqual(aStack)) - return copyMetaData(Items.feather.getDamage(aStack) + 1, aStack); - return null; - } - - public static FluidStack getFluidFromContainerOrFluidDisplay(ItemStack stack) { - FluidStack fluidStack = GT_Utility.getFluidForFilledItem(stack, true); - if (fluidStack == null) { - fluidStack = GT_Utility.getFluidFromDisplayStack(stack); - } - return fluidStack; - } - - public static synchronized boolean removeIC2BottleRecipe(ItemStack aContainer, ItemStack aInput, - Map aRecipeList, ItemStack aOutput) { - if ((isStackInvalid(aInput) && isStackInvalid(aOutput) && isStackInvalid(aContainer)) || aRecipeList == null) - return false; - boolean rReturn = false; - Iterator> tIterator = aRecipeList - .entrySet() - .iterator(); - aOutput = GT_OreDictUnificator.get(aOutput); - while (tIterator.hasNext()) { - Map.Entry tEntry = tIterator.next(); - if (aInput == null || tEntry.getKey() - .matches(aContainer, aInput)) { - List tList = tEntry.getValue().items; - if (tList != null) for (ItemStack tOutput : tList) - if (aOutput == null || areStacksEqual(GT_OreDictUnificator.get(tOutput), aOutput)) { - tIterator.remove(); - rReturn = true; - break; - } - } - } - return rReturn; - } - - public static synchronized boolean removeSimpleIC2MachineRecipe(ItemStack aInput, - Map aRecipeList, ItemStack aOutput) { - if ((isStackInvalid(aInput) && isStackInvalid(aOutput)) || aRecipeList == null) return false; - boolean rReturn = false; - Iterator> tIterator = aRecipeList.entrySet() - .iterator(); - aOutput = GT_OreDictUnificator.get(aOutput); - while (tIterator.hasNext()) { - Map.Entry tEntry = tIterator.next(); - if (aInput == null || tEntry.getKey() - .matches(aInput)) { - List tList = tEntry.getValue().items; - if (tList != null) for (ItemStack tOutput : tList) - if (aOutput == null || areStacksEqual(GT_OreDictUnificator.get(tOutput), aOutput)) { - tIterator.remove(); - rReturn = true; - break; - } - } - } - return rReturn; - } - - public static synchronized void bulkRemoveSimpleIC2MachineRecipe(Map toRemove, - Map aRecipeList) { - if (aRecipeList == null || aRecipeList.isEmpty()) return; - toRemove.entrySet() - .removeIf(aEntry -> (isStackInvalid(aEntry.getKey()) && isStackInvalid(aEntry.getValue()))); - final Map finalToRemove = Maps - .transformValues(toRemove, GT_OreDictUnificator::get_nocopy); - - aRecipeList.entrySet() - .removeIf( - tEntry -> finalToRemove.entrySet() - .stream() - .anyMatch(aEntry -> { - final ItemStack aInput = aEntry.getKey(), aOutput = aEntry.getValue(); - final List tList = tEntry.getValue().items; - - if (tList == null) return false; - if (aInput != null && !tEntry.getKey() - .matches(aInput)) return false; - - return tList.stream() - .anyMatch( - tOutput -> (aOutput == null - || areStacksEqual(GT_OreDictUnificator.get(tOutput), aOutput))); - })); - } - - public static boolean addSimpleIC2MachineRecipe(ItemStack aInput, Map aRecipeList, - NBTTagCompound aNBT, Object... aOutput) { - if (isStackInvalid(aInput) || aOutput.length == 0 || aRecipeList == null) return false; - ItemData tOreName = GT_OreDictUnificator.getAssociation(aInput); - for (Object o : aOutput) { - if (o == null) { - GT_FML_LOGGER.info("EmptyIC2Output!" + aInput.getUnlocalizedName()); - return false; - } - } - ItemStack[] tStack = GT_OreDictUnificator.getStackArray(true, aOutput); - if (tStack.length > 0 && areStacksEqual(aInput, tStack[0])) return false; - if (tOreName != null) { - if (tOreName.toString() - .equals("dustAsh") - && tStack[0].getUnlocalizedName() - .equals("tile.volcanicAsh")) - return false; - aRecipeList - .put(new RecipeInputOreDict(tOreName.toString(), aInput.stackSize), new RecipeOutput(aNBT, tStack)); - } else { - aRecipeList - .put(new RecipeInputItemStack(copyOrNull(aInput), aInput.stackSize), new RecipeOutput(aNBT, tStack)); - } - return true; - } - - public static ItemStack getWrittenBook(String aMapping, ItemStack aStackToPutNBT) { - if (isStringInvalid(aMapping)) return null; - ItemStack rStack = GregTech_API.sBookList.get(aMapping); - if (rStack == null) return aStackToPutNBT; - if (aStackToPutNBT != null) { - aStackToPutNBT.setTagCompound(rStack.getTagCompound()); - return aStackToPutNBT; - } - return copyAmount(1, rStack); - } - - public static ItemStack getWrittenBook(String aMapping, String aTitle, String aAuthor, String... aPages) { - if (isStringInvalid(aMapping)) return null; - ItemStack rStack = GregTech_API.sBookList.get(aMapping); - if (rStack != null) return copyAmount(1, rStack); - if (isStringInvalid(aTitle) || isStringInvalid(aAuthor) || aPages.length == 0) return null; - sBookCount++; - rStack = new ItemStack(Items.written_book, 1); - NBTTagCompound tNBT = new NBTTagCompound(); - tNBT.setString("title", GT_LanguageManager.addStringLocalization("Book." + aTitle + ".Name", aTitle)); - tNBT.setString("author", aAuthor); - NBTTagList tNBTList = new NBTTagList(); - for (byte i = 0; i < aPages.length; i++) { - aPages[i] = GT_LanguageManager - .addStringLocalization("Book." + aTitle + ".Page" + ((i < 10) ? "0" + i : i), aPages[i]); - if (i < 48) { - if (aPages[i].length() < 256) tNBTList.appendTag(new NBTTagString(aPages[i])); - else GT_Log.err.println("WARNING: String for written Book too long! -> " + aPages[i]); - } else { - GT_Log.err.println("WARNING: Too much Pages for written Book! -> " + aTitle); - break; - } - } - tNBTList.appendTag( - new NBTTagString( - "Credits to " + aAuthor - + " for writing this Book. This was Book Nr. " - + sBookCount - + " at its creation. Gotta get 'em all!")); - tNBT.setTag("pages", tNBTList); - rStack.setTagCompound(tNBT); - GT_Log.out.println( - "GT_Mod: Added Book to Book List - Mapping: '" + aMapping - + "' - Name: '" - + aTitle - + "' - Author: '" - + aAuthor - + "'"); - GregTech_API.sBookList.put(aMapping, rStack); - return copyOrNull(rStack); - } - - public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength) { - if (aSoundName == null) return false; - return doSoundAtClient(aSoundName, aTimeUntilNextSound, aSoundStrength, GT.getThePlayer()); - } - - public static boolean doSoundAtClient(SoundResource sound, int aTimeUntilNextSound, float aSoundStrength) { - return doSoundAtClient(sound.resourceLocation, aTimeUntilNextSound, aSoundStrength, GT.getThePlayer()); - } - - public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, - float aSoundStrength) { - return doSoundAtClient(aSoundResourceLocation, aTimeUntilNextSound, aSoundStrength, GT.getThePlayer()); - } - - public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength, - Entity aEntity) { - if (aEntity == null || aSoundName == null) return false; - return doSoundAtClient( - aSoundName, - aTimeUntilNextSound, - aSoundStrength, - aEntity.posX, - aEntity.posY, - aEntity.posZ); - } - - public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, - float aSoundStrength, Entity aEntity) { - if (aEntity == null) return false; - return doSoundAtClient( - aSoundResourceLocation.toString(), - aTimeUntilNextSound, - aSoundStrength, - aEntity.posX, - aEntity.posY, - aEntity.posZ); - } - - public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, - float aSoundStrength, double aX, double aY, double aZ) { - return doSoundAtClient(aSoundResourceLocation, aTimeUntilNextSound, aSoundStrength, 1.01818028F, aX, aY, aZ); - } - - /** - * @inheritDoc - * @deprecated Use {@link #doSoundAtClient(ResourceLocation, int, float, double, double, double)} - */ - @Deprecated - public static boolean doSoundAtClient(String aSoundName, int aTimeUntilNextSound, float aSoundStrength, double aX, - double aY, double aZ) { - if (aSoundName == null) return false; - return doSoundAtClient( - new ResourceLocation(aSoundName), - aTimeUntilNextSound, - aSoundStrength, - 1.01818028F, - aX, - aY, - aZ); - } - - public static boolean doSoundAtClient(SoundResource aSound, int aTimeUntilNextSound, float aSoundStrength, - double aX, double aY, double aZ) { - return doSoundAtClient(aSound.resourceLocation, aTimeUntilNextSound, aSoundStrength, aX, aY, aZ); - } - - public static boolean doSoundAtClient(SoundResource aSound, int aTimeUntilNextSound, float aSoundStrength, - float aSoundModulation, double aX, double aY, double aZ) { - return doSoundAtClient( - aSound.resourceLocation, - aTimeUntilNextSound, - aSoundStrength, - aSoundModulation, - aX, - aY, - aZ); - } - - public static boolean doSoundAtClient(ResourceLocation aSoundResourceLocation, int aTimeUntilNextSound, - float aSoundStrength, float aSoundModulation, double aX, double aY, double aZ) { - if (!FMLCommonHandler.instance() - .getEffectiveSide() - .isClient() || GT.getThePlayer() == null || !GT.getThePlayer().worldObj.isRemote) return false; - if (GregTech_API.sMultiThreadedSounds) new Thread( - new GT_Runnable_Sound( - GT.getThePlayer().worldObj, - aX, - aY, - aZ, - aTimeUntilNextSound, - aSoundResourceLocation, - aSoundStrength, - aSoundModulation), - "Sound Effect").start(); - else new GT_Runnable_Sound( - GT.getThePlayer().worldObj, - aX, - aY, - aZ, - aTimeUntilNextSound, - aSoundResourceLocation, - aSoundStrength, - aSoundModulation).run(); - return true; - } - - public static boolean sendSoundToPlayers(World aWorld, String aSoundName, float aSoundStrength, - float aSoundModulation, int aX, int aY, int aZ) { - if (isStringInvalid(aSoundName) || aWorld == null || aWorld.isRemote) return false; - NW.sendPacketToAllPlayersInRange( - aWorld, - new GT_Packet_Sound(aSoundName, aSoundStrength, aSoundModulation, aX, (short) aY, aZ), - aX, - aZ); - return true; - } - - public static boolean sendSoundToPlayers(World aWorld, SoundResource sound, float aSoundStrength, - float aSoundModulation, int aX, int aY, int aZ) { - if (aWorld == null || aWorld.isRemote) return false; - NW.sendPacketToAllPlayersInRange( - aWorld, - new GT_Packet_Sound( - sound.resourceLocation.toString(), - aSoundStrength, - aSoundModulation, - aX, - (short) aY, - aZ), - aX, - aZ); - return true; - } - - public static int stackToInt(ItemStack aStack) { - if (isStackInvalid(aStack)) return 0; - return itemToInt(aStack.getItem(), Items.feather.getDamage(aStack)); - } - - public static int itemToInt(Item aItem, int aMeta) { - return Item.getIdFromItem(aItem) | (aMeta << 16); - } - - public static int stackToWildcard(ItemStack aStack) { - if (isStackInvalid(aStack)) return 0; - return Item.getIdFromItem(aStack.getItem()) | (W << 16); - } - - public static ItemStack intToStack(int aStack) { - int tID = aStack & (~0 >>> 16), tMeta = aStack >>> 16; - Item tItem = Item.getItemById(tID); - if (tItem != null) return new ItemStack(tItem, 1, tMeta); - return null; - } - - public static Integer[] stacksToIntegerArray(ItemStack... aStacks) { - Integer[] rArray = new Integer[aStacks.length]; - for (int i = 0; i < rArray.length; i++) { - rArray[i] = stackToInt(aStacks[i]); - } - return rArray; - } - - public static int[] stacksToIntArray(ItemStack... aStacks) { - int[] rArray = new int[aStacks.length]; - for (int i = 0; i < rArray.length; i++) { - rArray[i] = stackToInt(aStacks[i]); - } - return rArray; - } - - public static boolean arrayContains(Object aObject, Object... aObjects) { - return listContains(aObject, Arrays.asList(aObjects)); - } - - public static boolean listContains(Object aObject, Collection aObjects) { - if (aObjects == null) return false; - return aObjects.contains(aObject); - } - - @SafeVarargs - public static boolean arrayContainsNonNull(T... aArray) { - if (aArray != null) for (Object tObject : aArray) if (tObject != null) return true; - return false; - } - - /** - * Note: use {@link ArrayExt#withoutNulls(Object[], IntFunction)} if you want an array as a result. - */ - @SafeVarargs - public static ArrayList getArrayListWithoutNulls(T... aArray) { - if (aArray == null) return new ArrayList<>(); - ArrayList rList = new ArrayList<>(Arrays.asList(aArray)); - for (int i = 0; i < rList.size(); i++) if (rList.get(i) == null) rList.remove(i--); - return rList; - } - - /** - * Note: use {@link ArrayExt#withoutTrailingNulls(Object[], IntFunction)} if you want an array as a result. - */ - @SafeVarargs - public static ArrayList getArrayListWithoutTrailingNulls(T... aArray) { - if (aArray == null) return new ArrayList<>(); - ArrayList rList = new ArrayList<>(Arrays.asList(aArray)); - for (int i = rList.size() - 1; i >= 0 && rList.get(i) == null;) rList.remove(i--); - return rList; - } - - public static Block getBlockFromStack(ItemStack itemStack) { - if (isStackInvalid(itemStack)) return Blocks.air; - return getBlockFromItem(itemStack.getItem()); - } - - public static Block getBlockFromItem(Item item) { - return Block.getBlockFromItem(item); - } - - public static boolean isStringValid(Object aString) { - return aString != null && !aString.toString() - .isEmpty(); - } - - public static boolean isStringInvalid(Object aString) { - return aString == null || aString.toString() - .isEmpty(); - } - - @Deprecated - public static boolean isStackValid(Object aStack) { - return (aStack instanceof ItemStack stack) && isStackValid(stack); - } - - public static boolean isStackValid(ItemStack aStack) { - return (aStack != null) && aStack.getItem() != null && aStack.stackSize >= 0; - } - - @Deprecated - public static boolean isStackInvalid(Object aStack) { - return !(aStack instanceof ItemStack stack) || isStackInvalid(stack); - } - - public static boolean isStackInvalid(ItemStack aStack) { - return aStack == null || aStack.getItem() == null || aStack.stackSize < 0; - } - - public static boolean isDebugItem(ItemStack aStack) { - return /* ItemList.Armor_Cheat.isStackEqual(aStack, T, T) || */ areStacksEqual( - GT_ModHandler.getIC2Item("debug", 1), - aStack, - true); - } - - public static ItemStack updateItemStack(ItemStack aStack) { - if (isStackValid(aStack) && aStack.getItem() instanceof GT_Generic_Item) - ((GT_Generic_Item) aStack.getItem()).isItemStackUsable(aStack); - return aStack; - } - - public static boolean isOpaqueBlock(World aWorld, int aX, int aY, int aZ) { - return aWorld.getBlock(aX, aY, aZ) - .isOpaqueCube(); - } - - public static boolean isBlockAir(World aWorld, int aX, int aY, int aZ) { - return aWorld.getBlock(aX, aY, aZ) - .isAir(aWorld, aX, aY, aZ); - } - - public static boolean hasBlockHitBox(World aWorld, int aX, int aY, int aZ) { - return aWorld.getBlock(aX, aY, aZ) - .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ) != null; - } - - public static void setCoordsOnFire(World aWorld, int aX, int aY, int aZ, boolean aReplaceCenter) { - if (aReplaceCenter) if (aWorld.getBlock(aX, aY, aZ) - .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ) == null) aWorld.setBlock(aX, aY, aZ, Blocks.fire); - if (aWorld.getBlock(aX + 1, aY, aZ) - .getCollisionBoundingBoxFromPool(aWorld, aX + 1, aY, aZ) == null) - aWorld.setBlock(aX + 1, aY, aZ, Blocks.fire); - if (aWorld.getBlock(aX - 1, aY, aZ) - .getCollisionBoundingBoxFromPool(aWorld, aX - 1, aY, aZ) == null) - aWorld.setBlock(aX - 1, aY, aZ, Blocks.fire); - if (aWorld.getBlock(aX, aY + 1, aZ) - .getCollisionBoundingBoxFromPool(aWorld, aX, aY + 1, aZ) == null) - aWorld.setBlock(aX, aY + 1, aZ, Blocks.fire); - if (aWorld.getBlock(aX, aY - 1, aZ) - .getCollisionBoundingBoxFromPool(aWorld, aX, aY - 1, aZ) == null) - aWorld.setBlock(aX, aY - 1, aZ, Blocks.fire); - if (aWorld.getBlock(aX, aY, aZ + 1) - .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ + 1) == null) - aWorld.setBlock(aX, aY, aZ + 1, Blocks.fire); - if (aWorld.getBlock(aX, aY, aZ - 1) - .getCollisionBoundingBoxFromPool(aWorld, aX, aY, aZ - 1) == null) - aWorld.setBlock(aX, aY, aZ - 1, Blocks.fire); - } - - public static ItemStack getProjectile(SubTag aProjectileType, IInventory aInventory) { - if (aInventory != null) for (int i = 0, j = aInventory.getSizeInventory(); i < j; i++) { - ItemStack rStack = aInventory.getStackInSlot(i); - if (isStackValid(rStack) && rStack.getItem() instanceof IProjectileItem - && ((IProjectileItem) rStack.getItem()).hasProjectile(aProjectileType, rStack)) - return updateItemStack(rStack); - } - return null; - } - - public static void removeNullStacksFromInventory(IInventory aInventory) { - if (aInventory != null) for (int i = 0, j = aInventory.getSizeInventory(); i < j; i++) { - ItemStack tStack = aInventory.getStackInSlot(i); - if (tStack != null && (tStack.stackSize == 0 || tStack.getItem() == null)) - aInventory.setInventorySlotContents(i, null); - } - } - - /** - * Initializes new empty texture page for casings page 0 is old CASING_BLOCKS - *

- * Then casings should be registered like this: for (byte i = MIN_USED_META; i < MAX_USED_META; i = (byte) (i + 1)) - * { Textures.BlockIcons.casingTexturePages[PAGE][i+START_INDEX] = new GT_CopiedBlockTexture(this, 6, i); } - * - * @param page 0 to 127 - * @return true if it made empty page, false if one already existed... - */ - public static boolean addTexturePage(byte page) { - if (Textures.BlockIcons.casingTexturePages[page] == null) { - Textures.BlockIcons.casingTexturePages[page] = new ITexture[128]; - return true; - } - return false; - } - - /** - * Return texture id from page and index, for use when determining hatches, but can also be precomputed from: - * (page<<7)+index - * - * @param page 0 to 127 page - * @param index 0 to 127 texture index - * @return casing texture 0 to 16383 - */ - public static int getTextureId(byte page, byte index) { - if (page >= 0 && index >= 0) { - return (page << 7) + index; - } - throw new RuntimeException("Index out of range: [" + page + "][" + index + "]"); - } - - /** - * Return texture id from page and index, for use when determining hatches, but can also be precomputed from: - * (page<<7)+index - * - * @param page 0 to 127 page - * @param startIndex 0 to 127 start texture index - * @param blockMeta meta of the block - * @return casing texture 0 to 16383 - */ - public static int getTextureId(byte page, byte startIndex, byte blockMeta) { - if (page >= 0 && startIndex >= 0 && blockMeta >= 0 && (startIndex + blockMeta) <= 127) { - return (page << 7) + (startIndex + blockMeta); - } - throw new RuntimeException( - "Index out of range: [" + page - + "][" - + startIndex - + "+" - + blockMeta - + "=" - + (startIndex + blockMeta) - + "]"); - } - - /** - * Return texture id from item stack, unoptimized but readable? - * - * @return casing texture 0 to 16383 - */ - public static int getTextureId(Block blockFromBlock, byte metaFromBlock) { - for (int page = 0; page < Textures.BlockIcons.casingTexturePages.length; page++) { - ITexture[] casingTexturePage = Textures.BlockIcons.casingTexturePages[page]; - if (casingTexturePage != null) { - for (int index = 0; index < casingTexturePage.length; index++) { - ITexture iTexture = casingTexturePage[index]; - if (iTexture instanceof IBlockContainer) { - Block block = ((IBlockContainer) iTexture).getBlock(); - byte meta = ((IBlockContainer) iTexture).getMeta(); - if (meta == metaFromBlock && blockFromBlock == block) { - return (page << 7) + index; - } - } - } - } - } - throw new RuntimeException( - "Probably missing mapping or different texture class used for: " + blockFromBlock.getUnlocalizedName() - + " meta:" - + metaFromBlock); - } - - /** - * Converts a Number to a String - */ - public static String parseNumberToString(int aNumber) { - boolean temp = true, negative = false; - - if (aNumber < 0) { - aNumber *= -1; - negative = true; - } - - StringBuilder tStringB = new StringBuilder(); - for (int i = 1000000000; i > 0; i /= 10) { - int tDigit = (aNumber / i) % 10; - if (temp && tDigit != 0) temp = false; - if (!temp) { - tStringB.append(tDigit); - if (i != 1) for (int j = i; j > 0; j /= 1000) if (j == 1) tStringB.append(","); - } - } - - String tString = tStringB.toString(); - - if (tString.equals(E)) tString = "0"; - - return negative ? "-" + tString : tString; - } - - public static NBTTagCompound getNBTContainingBoolean(NBTTagCompound aNBT, Object aTag, boolean aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - aNBT.setBoolean(aTag.toString(), aValue); - return aNBT; - } - - public static NBTTagCompound getNBTContainingByte(NBTTagCompound aNBT, Object aTag, byte aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - aNBT.setByte(aTag.toString(), aValue); - return aNBT; - } - - public static NBTTagCompound getNBTContainingShort(NBTTagCompound aNBT, Object aTag, short aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - aNBT.setShort(aTag.toString(), aValue); - return aNBT; - } - - public static NBTTagCompound getNBTContainingInteger(NBTTagCompound aNBT, Object aTag, int aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - aNBT.setInteger(aTag.toString(), aValue); - return aNBT; - } - - public static NBTTagCompound getNBTContainingFloat(NBTTagCompound aNBT, Object aTag, float aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - aNBT.setFloat(aTag.toString(), aValue); - return aNBT; - } - - public static NBTTagCompound getNBTContainingDouble(NBTTagCompound aNBT, Object aTag, double aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - aNBT.setDouble(aTag.toString(), aValue); - return aNBT; - } - - public static NBTTagCompound getNBTContainingString(NBTTagCompound aNBT, Object aTag, Object aValue) { - if (aNBT == null) aNBT = new NBTTagCompound(); - if (aValue == null) return aNBT; - aNBT.setString(aTag.toString(), aValue.toString()); - return aNBT; - } - - public static boolean isWearingFullFrostHazmat(EntityLivingBase aEntity) { - for (byte i = 1; i < 5; i++) { - ItemStack tStack = aEntity.getEquipmentInSlot(i); - - if (!isStackInList(tStack, GregTech_API.sFrostHazmatList) && !hasHazmatEnchant(tStack)) { - return false; - } - } - return true; - } - - public static boolean isWearingFullHeatHazmat(EntityLivingBase aEntity) { - for (byte i = 1; i < 5; i++) { - ItemStack tStack = aEntity.getEquipmentInSlot(i); - - if (!isStackInList(tStack, GregTech_API.sHeatHazmatList) && !hasHazmatEnchant(tStack)) { - return false; - } - } - - return true; - } - - public static boolean isWearingFullBioHazmat(EntityLivingBase aEntity) { - for (byte i = 1; i < 5; i++) { - ItemStack tStack = aEntity.getEquipmentInSlot(i); - - if (!isStackInList(tStack, GregTech_API.sBioHazmatList) && !hasHazmatEnchant(tStack)) { - return false; - } - } - return true; - } - - public static boolean isWearingFullRadioHazmat(EntityLivingBase aEntity) { - for (byte i = 1; i < 5; i++) { - ItemStack tStack = aEntity.getEquipmentInSlot(i); - - if (!isStackInList(tStack, GregTech_API.sRadioHazmatList) && !hasHazmatEnchant(tStack)) { - return false; - } - } - return true; - } - - public static boolean isWearingFullElectroHazmat(EntityLivingBase aEntity) { - for (byte i = 1; i < 5; i++) { - ItemStack tStack = aEntity.getEquipmentInSlot(i); - - if (!isStackInList(tStack, GregTech_API.sElectroHazmatList) && !hasHazmatEnchant(tStack)) { - return false; - } - } - return true; - } - - public static boolean isWearingFullGasHazmat(EntityLivingBase aEntity) { - for (byte i = 1; i < 5; i++) { - ItemStack tStack = aEntity.getEquipmentInSlot(i); - - if (!isStackInList(tStack, GregTech_API.sGasHazmatList) && !hasHazmatEnchant(tStack)) { - return false; - } - } - return true; - } - - public static boolean hasHazmatEnchant(ItemStack aStack) { - if (aStack == null) return false; - Map tEnchantments = EnchantmentHelper.getEnchantments(aStack); - Integer tLevel = tEnchantments.get(Enchantment_Hazmat.INSTANCE.effectId); - - return tLevel != null && tLevel >= 1; - } - - public static float getHeatDamageFromItem(ItemStack aStack) { - ItemData tData = GT_OreDictUnificator.getItemData(aStack); - return tData == null ? 0 - : (tData.mPrefix == null ? 0 : tData.mPrefix.mHeatDamage) - + (tData.hasValidMaterialData() ? tData.mMaterial.mMaterial.mHeatDamage : 0); - } - - public static int getRadioactivityLevel(ItemStack aStack) { - ItemData tData = GT_OreDictUnificator.getItemData(aStack); - if (tData != null && tData.hasValidMaterialData()) { - if (tData.mMaterial.mMaterial.mEnchantmentArmors instanceof Enchantment_Radioactivity) - return tData.mMaterial.mMaterial.mEnchantmentArmorsLevel; - if (tData.mMaterial.mMaterial.mEnchantmentTools instanceof Enchantment_Radioactivity) - return tData.mMaterial.mMaterial.mEnchantmentToolsLevel; - } - return EnchantmentHelper.getEnchantmentLevel(Enchantment_Radioactivity.INSTANCE.effectId, aStack); - } - - public static boolean isImmuneToBreathingGasses(EntityLivingBase aEntity) { - return isWearingFullGasHazmat(aEntity); - } - - public static boolean applyHeatDamage(EntityLivingBase entity, float damage) { - return applyHeatDamage(entity, damage, GT_DamageSources.getHeatDamage()); - } - - public static boolean applyHeatDamageFromItem(EntityLivingBase entity, float damage, ItemStack item) { - return applyHeatDamage(entity, damage, new DamageSourceHotItem(item)); - } - - private static boolean applyHeatDamage(EntityLivingBase aEntity, float aDamage, DamageSource source) { - if (aDamage > 0 && aEntity != null && !isWearingFullHeatHazmat(aEntity)) { - return aEntity.attackEntityFrom(source, aDamage); - } - return false; - } - - public static boolean applyFrostDamage(EntityLivingBase aEntity, float aDamage) { - if (aDamage > 0 && aEntity != null && !isWearingFullFrostHazmat(aEntity)) { - return aEntity.attackEntityFrom(GT_DamageSources.getFrostDamage(), aDamage); - } - return false; - } - - public static boolean applyElectricityDamage(EntityLivingBase aEntity, long aVoltage, long aAmperage) { - long aDamage = getTier(aVoltage) * aAmperage * 4; - if (aDamage > 0 && aEntity != null && !isWearingFullElectroHazmat(aEntity)) { - return aEntity.attackEntityFrom(GT_DamageSources.getElectricDamage(), aDamage); - } - return false; - } - - public static boolean applyRadioactivity(EntityLivingBase aEntity, int aLevel, int aAmountOfItems) { - if (aLevel > 0 && aEntity != null - && aEntity.getCreatureAttribute() != EnumCreatureAttribute.UNDEAD - && aEntity.getCreatureAttribute() != EnumCreatureAttribute.ARTHROPOD - && !isWearingFullRadioHazmat(aEntity)) { - PotionEffect tEffect = null; - aEntity.addPotionEffect( - new PotionEffect( - Potion.moveSlowdown.id, - aLevel * 140 * aAmountOfItems + Math.max( - 0, - ((tEffect = aEntity.getActivePotionEffect(Potion.moveSlowdown)) == null ? 0 - : tEffect.getDuration())), - Math.max(0, (5 * aLevel) / 7))); - aEntity.addPotionEffect( - new PotionEffect( - Potion.digSlowdown.id, - aLevel * 150 * aAmountOfItems + Math.max( - 0, - ((tEffect = aEntity.getActivePotionEffect(Potion.digSlowdown)) == null ? 0 - : tEffect.getDuration())), - Math.max(0, (5 * aLevel) / 7))); - aEntity.addPotionEffect( - new PotionEffect( - Potion.confusion.id, - aLevel * 130 * aAmountOfItems + Math.max( - 0, - ((tEffect = aEntity.getActivePotionEffect(Potion.confusion)) == null ? 0 - : tEffect.getDuration())), - Math.max(0, (5 * aLevel) / 7))); - aEntity.addPotionEffect( - new PotionEffect( - Potion.weakness.id, - aLevel * 150 * aAmountOfItems + Math.max( - 0, - ((tEffect = aEntity.getActivePotionEffect(Potion.weakness)) == null ? 0 - : tEffect.getDuration())), - Math.max(0, (5 * aLevel) / 7))); - aEntity.addPotionEffect( - new PotionEffect( - Potion.hunger.id, - aLevel * 130 * aAmountOfItems + Math.max( - 0, - ((tEffect = aEntity.getActivePotionEffect(Potion.hunger)) == null ? 0 : tEffect.getDuration())), - Math.max(0, (5 * aLevel) / 7))); - aEntity.addPotionEffect( - new PotionEffect( - 24 /* IC2 Radiation */, - aLevel * 180 * aAmountOfItems + Math.max( - 0, - ((tEffect = aEntity.getActivePotionEffect(Potion.potionTypes[24])) == null ? 0 - : tEffect.getDuration())), - Math.max(0, (5 * aLevel) / 7))); - return true; - } - return false; - } - - public static ItemStack setStack(ItemStack aSetStack, ItemStack aToStack) { - if (isStackInvalid(aSetStack) || isStackInvalid(aToStack)) return null; - aSetStack.func_150996_a(aToStack.getItem()); - aSetStack.stackSize = aToStack.stackSize; - Items.feather.setDamage(aSetStack, Items.feather.getDamage(aToStack)); - aSetStack.setTagCompound(aToStack.getTagCompound()); - return aSetStack; - } - - public static FluidStack[] copyFluidArray(FluidStack... aStacks) { - if (aStacks == null) return null; - FluidStack[] rStacks = new FluidStack[aStacks.length]; - for (int i = 0; i < aStacks.length; i++) if (aStacks[i] != null) rStacks[i] = aStacks[i].copy(); - return rStacks; - } - - public static ItemStack[] copyItemArray(ItemStack... aStacks) { - if (aStacks == null) return null; - ItemStack[] rStacks = new ItemStack[aStacks.length]; - for (int i = 0; i < aStacks.length; i++) rStacks[i] = copy(aStacks[i]); - return rStacks; - } - - /** - * @deprecated use {@link #copy(ItemStack)} instead - */ - @Deprecated - public static ItemStack copy(Object... aStacks) { - for (Object tStack : aStacks) if (isStackValid(tStack)) return ((ItemStack) tStack).copy(); - return null; - } - - public static ItemStack copy(ItemStack aStack) { - if (isStackValid(aStack)) return aStack.copy(); - return null; - } - - @Deprecated - private static ItemStack firstStackOrNull(Object... aStacks) { - for (Object tStack : aStacks) if (tStack instanceof ItemStack stack) return stack; - return null; - } - - @Nullable - public static ItemStack copyOrNull(@Nullable ItemStack stack) { - if (isStackValid(stack)) return stack.copy(); - return null; - } - - public static FluidStack copyAmount(int aAmount, FluidStack aStack) { - if (aStack == null) return null; - FluidStack rStack = aStack.copy(); - rStack.amount = aAmount; - return rStack; - } - - /** - * @deprecated use {@link #copyAmount(int, ItemStack)} instead - */ - @Deprecated - public static ItemStack copyAmount(long aAmount, Object... aStacks) { - return copyAmount(aAmount, firstStackOrNull(aStacks)); - } - - /** - * @deprecated use {@link #copyAmount(int, ItemStack)} instead - */ - @Deprecated - public static ItemStack copyAmount(long aAmount, ItemStack aStack) { - return copyAmount((int) aAmount, aStack); - } - - public static ItemStack copyAmount(int aAmount, ItemStack aStack) { - ItemStack rStack = copy(aStack); - if (isStackInvalid(rStack)) return null; - if (aAmount > 64) aAmount = 64; - else if (aAmount == -1) aAmount = 111; - else if (aAmount < 0) aAmount = 0; - rStack.stackSize = (byte) aAmount; - return rStack; - } - - public static ItemStack multiplyStack(int aMultiplier, ItemStack aStack) { - ItemStack rStack = copy(aStack); - if (isStackInvalid(rStack)) return null; - int tAmount = rStack.stackSize * aMultiplier; - if (tAmount > 64) tAmount = 64; - else if (tAmount == -1) tAmount = 111; - else if (tAmount < 0) tAmount = 0; - rStack.stackSize = (byte) tAmount; - return rStack; - } - - /** - * Unlike {@link #copyAmount(int, ItemStack)}, this method does not restrict stack size by 64. - */ - public static ItemStack copyAmountUnsafe(int aAmount, ItemStack aStack) { - ItemStack rStack = copy(aStack); - if (isStackInvalid(rStack)) return null; - else if (aAmount < 0) aAmount = 0; - rStack.stackSize = (int) aAmount; - return rStack; - } - - public static ItemStack copyMetaData(int aMetaData, ItemStack aStack) { - ItemStack rStack = copy(aStack); - if (isStackInvalid(rStack)) return null; - Items.feather.setDamage(rStack, aMetaData); - return rStack; - } - - /** - * @deprecated use {@link #copyAmountAndMetaData(int, int, ItemStack)} instead - */ - @Deprecated - public static ItemStack copyAmountAndMetaData(long aAmount, long aMetaData, ItemStack aStack) { - return copyAmountAndMetaData((int) aAmount, (int) aMetaData, aStack); - } - - public static ItemStack copyAmountAndMetaData(int aAmount, int aMetaData, ItemStack aStack) { - ItemStack rStack = copyAmount(aAmount, aStack); - if (isStackInvalid(rStack)) return null; - Items.feather.setDamage(rStack, aMetaData); - return rStack; - } - - /** - * returns a copy of an ItemStack with its Stacksize being multiplied by aMultiplier - */ - public static ItemStack mul(int aMultiplier, ItemStack aStack) { - ItemStack rStack = copy(aStack); - if (rStack == null) return null; - rStack.stackSize *= aMultiplier; - return rStack; - } - - /** - * Loads an ItemStack properly. - */ - public static ItemStack loadItem(NBTTagCompound aNBT, String aTagName) { - return loadItem(aNBT.getCompoundTag(aTagName)); - } - - public static FluidStack loadFluid(NBTTagCompound aNBT, String aTagName) { - return loadFluid(aNBT.getCompoundTag(aTagName)); - } - - /** - * Loads an ItemStack properly. - */ - public static ItemStack loadItem(NBTTagCompound aNBT) { - if (aNBT == null) return null; - ItemStack tRawStack = ItemStack.loadItemStackFromNBT(aNBT); - int tRealStackSize = 0; - if (tRawStack != null && aNBT.hasKey("Count", Constants.NBT.TAG_INT)) { - tRealStackSize = aNBT.getInteger("Count"); - tRawStack.stackSize = tRealStackSize; - } else if (tRawStack != null) { - tRealStackSize = tRawStack.stackSize; - } - ItemStack tRet = GT_OreDictUnificator.get(true, tRawStack); - if (tRet != null) tRet.stackSize = tRealStackSize; - return tRet; - } - - public static void saveItem(NBTTagCompound aParentTag, String aTagName, ItemStack aStack) { - if (aStack != null) aParentTag.setTag(aTagName, saveItem(aStack)); - } - - public static NBTTagCompound saveItem(ItemStack aStack) { - if (aStack == null) return new NBTTagCompound(); - NBTTagCompound t = new NBTTagCompound(); - aStack.writeToNBT(t); - if (aStack.stackSize > Byte.MAX_VALUE) t.setInteger("Count", aStack.stackSize); - return t; - } - - /** - * Loads an FluidStack properly. - */ - public static FluidStack loadFluid(NBTTagCompound aNBT) { - if (aNBT == null) return null; - return FluidStack.loadFluidStackFromNBT(aNBT); - } - - public static E selectItemInList(int aIndex, E aReplacement, List aList) { - if (aList == null || aList.isEmpty()) return aReplacement; - if (aList.size() <= aIndex) return aList.get(aList.size() - 1); - if (aIndex < 0) return aList.get(0); - return aList.get(aIndex); - } - - @SafeVarargs - public static E selectItemInList(int aIndex, E aReplacement, E... aList) { - if (aList == null || aList.length == 0) return aReplacement; - if (aList.length <= aIndex) return aList[aList.length - 1]; - if (aIndex < 0) return aList[0]; - return aList[aIndex]; - } - - public static boolean isStackInStackSet(ItemStack aStack, Set aSet) { - if (aStack == null) return false; - if (aSet.contains(aStack)) return true; - - return aSet.contains(GT_ItemStack.internalCopyStack(aStack, true)); - } - - public static boolean isStackInList(ItemStack aStack, Collection aList) { - if (aStack == null) { - return false; - } - return isStackInList(new GT_ItemStack(aStack), aList); - } - - public static boolean isStackInList(ItemStack aStack, Set aList) { - if (aStack == null) { - return false; - } - return isStackInList(new GT_ItemStack2(aStack), aList); - } - - public static boolean isStackInList(GT_ItemStack aStack, Collection aList) { - return aStack != null - && (aList.contains(aStack) || aList.contains(new GT_ItemStack(aStack.mItem, aStack.mStackSize, W))); - } - - public static boolean isStackInList(GT_ItemStack2 aStack, Set aList) { - return aStack != null - && (aList.contains(aStack) || aList.contains(new GT_ItemStack2(aStack.mItem, aStack.mStackSize, W))); - } - - /** - * re-maps all Keys of a Map after the Keys were weakened. - */ - public static Map reMap(Map aMap) { - Map tMap = null; - // We try to clone the Map first (most Maps are Cloneable) in order to retain as much state of the Map as - // possible when rehashing. For example, "Custom" HashMaps from fastutil may have a custom hash function which - // would not be used to rehash if we just create a new HashMap. - if (aMap instanceof Cloneable) { - try { - tMap = (Map) aMap.getClass() - .getMethod("clone") - .invoke(aMap); - } catch (Throwable e) { - GT_Log.err.println("Failed to clone Map of type " + aMap.getClass()); - e.printStackTrace(GT_Log.err); - } - } - - if (tMap == null) { - tMap = new HashMap<>(aMap); - } - - aMap.clear(); - aMap.putAll(tMap); - return aMap; - } - - /** - * re-maps all Keys of a Map after the Keys were weakened. - */ - public static SetMultimap reMap(SetMultimap aMap) { - @SuppressWarnings("unchecked") - Map.Entry[] entries = aMap.entries() - .toArray(new Map.Entry[0]); - aMap.clear(); - for (Map.Entry entry : entries) { - aMap.put(entry.getKey(), entry.getValue()); - } - return aMap; - } - - public static > LinkedHashMap sortMapByValuesAcending(Map map) { - return map.entrySet() - .stream() - .sorted(Map.Entry.comparingByValue()) - .collect(CollectorUtils.entriesToMap(LinkedHashMap::new)); - } - - /** - * Why the fuck do neither Java nor Guava have a Function to do this? - */ - public static > LinkedHashMap sortMapByValuesDescending(Map aMap) { - List> tEntrySet = new LinkedList<>(aMap.entrySet()); - tEntrySet.sort((aValue1, aValue2) -> { - return aValue2.getValue() - .compareTo(aValue1.getValue()); // FB: RV - RV_NEGATING_RESULT_OF_COMPARETO - }); - LinkedHashMap rMap = new LinkedHashMap<>(); - for (Map.Entry tEntry : tEntrySet) rMap.put(tEntry.getKey(), tEntry.getValue()); - return rMap; - } - - /** - * Translates a Material Amount into an Amount of Fluid in Fluid Material Units. - */ - public static long translateMaterialToFluidAmount(long aMaterialAmount, boolean aRoundUp) { - return translateMaterialToAmount(aMaterialAmount, L, aRoundUp); - } - - /** - * Translates a Material Amount into an Amount of Fluid. Second Parameter for things like Bucket Amounts (1000) and - * similar - */ - public static long translateMaterialToAmount(long aMaterialAmount, long aAmountPerUnit, boolean aRoundUp) { - return Math.max( - 0, - ((aMaterialAmount * aAmountPerUnit) / M) - + (aRoundUp && (aMaterialAmount * aAmountPerUnit) % M > 0 ? 1 : 0)); - } - - /** - * This checks if the Dimension is really a Dimension and not another Planet or something. Used for my Teleporter. - */ - public static boolean isRealDimension(int aDimensionID) { - if (aDimensionID <= 1 && aDimensionID >= -1 && !GregTech_API.sDimensionalList.contains(aDimensionID)) - return true; - return !GregTech_API.sDimensionalList.contains(aDimensionID) - && DimensionManager.isDimensionRegistered(aDimensionID); - } - - public static boolean moveEntityToDimensionAtCoords(Entity entity, int aDimension, double aX, double aY, - double aZ) { - // Credit goes to BrandonCore Author :!: - - if (entity == null || entity.worldObj.isRemote) return false; - if (entity.ridingEntity != null) entity.mountEntity(null); - if (entity.riddenByEntity != null) entity.riddenByEntity.mountEntity(null); - - World startWorld = entity.worldObj; - WorldServer destinationWorld = FMLCommonHandler.instance() - .getMinecraftServerInstance() - .worldServerForDimension(aDimension); - - if (destinationWorld == null) { - return false; - } - - boolean interDimensional = startWorld.provider.dimensionId != destinationWorld.provider.dimensionId; - if (!interDimensional) return false; - startWorld.updateEntityWithOptionalForce(entity, false); // added - - if (entity instanceof EntityPlayerMP player) { - player.closeScreen(); // added - player.dimension = aDimension; - player.playerNetServerHandler.sendPacket( - new S07PacketRespawn( - player.dimension, - player.worldObj.difficultySetting, - destinationWorld.getWorldInfo() - .getTerrainType(), - player.theItemInWorldManager.getGameType())); - ((WorldServer) startWorld).getPlayerManager() - .removePlayer(player); - - startWorld.playerEntities.remove(player); - startWorld.updateAllPlayersSleepingFlag(); - int i = entity.chunkCoordX; - int j = entity.chunkCoordZ; - if ((entity.addedToChunk) && (startWorld.getChunkProvider() - .chunkExists(i, j))) { - startWorld.getChunkFromChunkCoords(i, j) - .removeEntity(entity); - startWorld.getChunkFromChunkCoords(i, j).isModified = true; - } - startWorld.loadedEntityList.remove(entity); - startWorld.onEntityRemoved(entity); - } - - entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); - - destinationWorld.theChunkProviderServer.loadChunk((int) aX >> 4, (int) aZ >> 4); - - destinationWorld.theProfiler.startSection("placing"); - if (!(entity instanceof EntityPlayer)) { - NBTTagCompound entityNBT = new NBTTagCompound(); - entity.isDead = false; - entityNBT.setString("id", EntityList.getEntityString(entity)); - entity.writeToNBT(entityNBT); - entity.isDead = true; - entity = EntityList.createEntityFromNBT(entityNBT, destinationWorld); - if (entity == null) { - return false; - } - entity.dimension = destinationWorld.provider.dimensionId; - } - destinationWorld.spawnEntityInWorld(entity); - entity.setWorld(destinationWorld); - entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); - - destinationWorld.updateEntityWithOptionalForce(entity, false); - entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); - - if ((entity instanceof EntityPlayerMP player)) { - player.mcServer.getConfigurationManager() - .func_72375_a(player, destinationWorld); - player.playerNetServerHandler.setPlayerLocation(aX, aY, aZ, player.rotationYaw, player.rotationPitch); - } - - destinationWorld.updateEntityWithOptionalForce(entity, false); - - if (entity instanceof EntityPlayerMP player) { - player.theItemInWorldManager.setWorld(destinationWorld); - player.mcServer.getConfigurationManager() - .updateTimeAndWeatherForPlayer(player, destinationWorld); - player.mcServer.getConfigurationManager() - .syncPlayerInventory(player); - - for (PotionEffect potionEffect : player.getActivePotionEffects()) { - player.playerNetServerHandler.sendPacket(new S1DPacketEntityEffect(player.getEntityId(), potionEffect)); - } - - player.playerNetServerHandler.sendPacket( - new S1FPacketSetExperience(player.experience, player.experienceTotal, player.experienceLevel)); - FMLCommonHandler.instance() - .firePlayerChangedDimensionEvent( - player, - startWorld.provider.dimensionId, - destinationWorld.provider.dimensionId); - } - entity.setLocationAndAngles(aX, aY, aZ, entity.rotationYaw, entity.rotationPitch); - - destinationWorld.theProfiler.endSection(); - entity.fallDistance = 0; - return true; - } - - public static int getScaleCoordinates(double aValue, int aScale) { - return (int) Math.floor(aValue / aScale); - } - - public static int getCoordinateScan(ArrayList aList, EntityPlayer aPlayer, World aWorld, int aScanLevel, - int aX, int aY, int aZ, ForgeDirection side, float aClickX, float aClickY, float aClickZ) { - if (aList == null) return 0; - - ArrayList tList = new ArrayList<>(); - int rEUAmount = 0; - - TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ); - - final Block tBlock = aWorld.getBlock(aX, aY, aZ); - - addBaseInfo(aPlayer, aWorld, aX, aY, aZ, tList, tTileEntity, tBlock); - - if (tTileEntity != null) { - rEUAmount += addFluidHandlerInfo(side, tList, tTileEntity); - - try { - if (tTileEntity instanceof ic2.api.reactor.IReactorChamber chamber) { - rEUAmount += 500; - // Redirect the rest of the scans to the reactor itself - tTileEntity = (TileEntity) chamber.getReactor(); - } - } catch (Throwable e) { - if (D1) e.printStackTrace(GT_Log.err); - } - rEUAmount += addReactorInfo(tList, tTileEntity); - rEUAmount += addAlignmentInfo(tList, tTileEntity); - rEUAmount += addIC2WrenchableInfo(aPlayer, tList, tTileEntity); - rEUAmount += addIC2EnergyConductorInfo(tList, tTileEntity); - rEUAmount += addIC2EnergyStorageInfo(tList, tTileEntity); - rEUAmount += addUpgradableMachineInfo(tList, tTileEntity); - rEUAmount += addMachineProgressInfo(tList, tTileEntity); - rEUAmount += addCoverableInfo(side, tList, tTileEntity); - addEnergyContainerInfo(tList, tTileEntity); - addOwnerInfo(tList, tTileEntity); - addDeviceInfo(tList, tTileEntity); - - rEUAmount += addIC2CropInfo(tList, tTileEntity); - - rEUAmount += addForestryLeavesInfo(tList, tTileEntity); - } - - final Chunk currentChunk = aWorld.getChunkFromBlockCoords(aX, aZ); - addUndergroundFluidInfo(aPlayer, tList, currentChunk); - addPollutionInfo(tList, currentChunk); - - rEUAmount += addDebuggableBlockInfo(aPlayer, aX, aY, aZ, tList, tBlock); - - final BlockScanningEvent tEvent = new BlockScanningEvent( - aWorld, - aPlayer, - aX, - aY, - aZ, - side, - aScanLevel, - tBlock, - tTileEntity, - tList, - aClickX, - aClickY, - aClickZ); - tEvent.mEUCost = rEUAmount; - MinecraftForge.EVENT_BUS.post(tEvent); - if (!tEvent.isCanceled()) aList.addAll(tList); - return tEvent.mEUCost; - } - - private static void addBaseInfo(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, ArrayList tList, - TileEntity tTileEntity, Block tBlock) { - tList.add( - "----- X: " + EnumChatFormatting.AQUA - + formatNumbers(aX) - + EnumChatFormatting.RESET - + " Y: " - + EnumChatFormatting.AQUA - + formatNumbers(aY) - + EnumChatFormatting.RESET - + " Z: " - + EnumChatFormatting.AQUA - + formatNumbers(aZ) - + EnumChatFormatting.RESET - + " D: " - + EnumChatFormatting.AQUA - + aWorld.provider.dimensionId - + EnumChatFormatting.RESET - + " -----"); - try { - tList.add( - GT_Utility.trans("162", "Name: ") + EnumChatFormatting.BLUE - + ((tTileEntity instanceof IInventory inv) ? inv.getInventoryName() : tBlock.getUnlocalizedName()) - + EnumChatFormatting.RESET - + GT_Utility.trans("163", " MetaData: ") - + EnumChatFormatting.AQUA - + aWorld.getBlockMetadata(aX, aY, aZ) - + EnumChatFormatting.RESET); - tList.add( - GT_Utility.trans("164", "Hardness: ") + EnumChatFormatting.YELLOW - + tBlock.getBlockHardness(aWorld, aX, aY, aZ) - + EnumChatFormatting.RESET - + GT_Utility.trans("165", " Blast Resistance: ") - + EnumChatFormatting.YELLOW - + tBlock - .getExplosionResistance(aPlayer, aWorld, aX, aY, aZ, aPlayer.posX, aPlayer.posY, aPlayer.posZ) - + EnumChatFormatting.RESET); - if (tBlock.isBeaconBase(aWorld, aX, aY, aZ, aX, aY + 1, aZ)) tList.add( - EnumChatFormatting.GOLD + GT_Utility.trans("166", "Is valid Beacon Pyramid Material") - + EnumChatFormatting.RESET); - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this block's info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - } - - private static int addFluidHandlerInfo(ForgeDirection side, ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof IFluidHandler fluidHandler) { - rEUAmount += 500; - final FluidTankInfo[] tTanks = fluidHandler.getTankInfo(side); - if (tTanks != null) for (byte i = 0; i < tTanks.length; i++) { - tList.add( - GT_Utility.trans("167", "Tank ") + i - + ": " - + EnumChatFormatting.GREEN - + formatNumbers((tTanks[i].fluid == null ? 0 : tTanks[i].fluid.amount)) - + EnumChatFormatting.RESET - + " L / " - + EnumChatFormatting.YELLOW - + formatNumbers(tTanks[i].capacity) - + EnumChatFormatting.RESET - + " L " - + EnumChatFormatting.GOLD - + getFluidName(tTanks[i].fluid, true) - + EnumChatFormatting.RESET); - } - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this tile's fluid tank info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addDebuggableBlockInfo(EntityPlayer aPlayer, int aX, int aY, int aZ, ArrayList tList, - Block tBlock) { - int rEUAmount = 0; - try { - if (tBlock instanceof IDebugableBlock debugableBlock) { - rEUAmount += 500; - final ArrayList temp = debugableBlock.getDebugInfo(aPlayer, aX, aY, aZ, 3); - if (temp != null) tList.addAll(temp); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this block's debug info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static void addPollutionInfo(ArrayList tList, Chunk currentChunk) { - if (GT_Pollution.hasPollution(currentChunk)) { - tList.add( - GT_Utility.trans("202", "Pollution in Chunk: ") + EnumChatFormatting.RED - + formatNumbers(GT_Pollution.getPollution(currentChunk)) - + EnumChatFormatting.RESET - + GT_Utility.trans("203", " gibbl")); - } else { - tList.add( - EnumChatFormatting.GREEN + GT_Utility.trans("204", "No Pollution in Chunk! HAYO!") - + EnumChatFormatting.RESET); - } - } - - private static void addUndergroundFluidInfo(EntityPlayer aPlayer, ArrayList tList, Chunk currentChunk) { - if (aPlayer.capabilities.isCreativeMode) { - final FluidStack tFluid = undergroundOilReadInformation(currentChunk); // -# to only read - if (tFluid != null) tList.add( - EnumChatFormatting.GOLD + tFluid.getLocalizedName() - + EnumChatFormatting.RESET - + ": " - + EnumChatFormatting.YELLOW - + formatNumbers(tFluid.amount) - + EnumChatFormatting.RESET - + " L"); - else tList.add( - EnumChatFormatting.GOLD + GT_Utility.trans("201", "Nothing") - + EnumChatFormatting.RESET - + ": " - + EnumChatFormatting.YELLOW - + '0' - + EnumChatFormatting.RESET - + " L"); - } - } - - private static int addForestryLeavesInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (Mods.Forestry.isModLoaded() - && tTileEntity instanceof forestry.arboriculture.tiles.TileLeaves tileLeaves) { - final forestry.api.arboriculture.ITree tree = tileLeaves.getTree(); - if (tree != null) { - rEUAmount += 1000; - if (!tree.isAnalyzed()) tree.analyze(); - tree.addTooltip(tList); - } - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this leaves' info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addIC2CropInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof ic2.api.crops.ICropTile crop) { - rEUAmount += 1000; - if (crop.getScanLevel() < 4) crop.setScanLevel((byte) 4); - if (crop.getCrop() != null) { - tList.add( - GT_Utility.trans("187", "Type -- Crop-Name: ") + crop.getCrop() - .name() - + GT_Utility.trans("188", " Growth: ") - + crop.getGrowth() - + GT_Utility.trans("189", " Gain: ") - + crop.getGain() - + GT_Utility.trans("190", " Resistance: ") - + crop.getResistance()); - } - tList.add( - GT_Utility.trans("191", "Plant -- Fertilizer: ") + crop.getNutrientStorage() - + GT_Utility.trans("192", " Water: ") - + crop.getHydrationStorage() - + GT_Utility.trans("193", " Weed-Ex: ") - + crop.getWeedExStorage() - + GT_Utility.trans("194", " Scan-Level: ") - + crop.getScanLevel()); - tList.add( - GT_Utility.trans("195", "Environment -- Nutrients: ") + crop.getNutrients() - + GT_Utility.trans("196", " Humidity: ") - + crop.getHumidity() - + GT_Utility.trans("197", " Air-Quality: ") - + crop.getAirQuality()); - if (crop.getCrop() != null) { - final StringBuilder tStringB = new StringBuilder(); - for (final String tAttribute : crop.getCrop() - .attributes()) { - tStringB.append(", ") - .append(tAttribute); - } - final String tString = tStringB.toString(); - tList.add(GT_Utility.trans("198", "Attributes:") + tString.replaceFirst(",", E)); - tList.add( - GT_Utility.trans("199", "Discovered by: ") + crop.getCrop() - .discoveredBy()); - } - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this crop's info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static void addDeviceInfo(ArrayList tList, TileEntity tTileEntity) { - try { - if (tTileEntity instanceof IGregTechDeviceInformation info && info.isGivingInformation()) { - tList.addAll(Arrays.asList(info.getInfoData())); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - } - - private static void addOwnerInfo(ArrayList tList, TileEntity tTileEntity) { - try { - if (tTileEntity instanceof IGregTechTileEntity gtTE) { - tList.add( - GT_Utility.trans("186", "Owned by: ") + EnumChatFormatting.BLUE - + gtTE.getOwnerName() - + EnumChatFormatting.RESET); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's owner.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - } - - private static void addEnergyContainerInfo(ArrayList tList, TileEntity tTileEntity) { - try { - if (tTileEntity instanceof IBasicEnergyContainer energyContainer && energyContainer.getEUCapacity() > 0) { - tList.add( - GT_Utility.trans("179", "Max IN: ") + EnumChatFormatting.RED - + formatNumbers(energyContainer.getInputVoltage()) - + " (" - + GT_Values.VN[getTier(energyContainer.getInputVoltage())] - + ") " - + EnumChatFormatting.RESET - + GT_Utility.trans("182", " EU at ") - + EnumChatFormatting.RED - + formatNumbers(energyContainer.getInputAmperage()) - + EnumChatFormatting.RESET - + GT_Utility.trans("183", " A")); - tList.add( - GT_Utility.trans("181", "Max OUT: ") + EnumChatFormatting.RED - + formatNumbers(energyContainer.getOutputVoltage()) - + " (" - + GT_Values.VN[getTier(energyContainer.getOutputVoltage())] - + ") " - + EnumChatFormatting.RESET - + GT_Utility.trans("182", " EU at ") - + EnumChatFormatting.RED - + formatNumbers(energyContainer.getOutputAmperage()) - + EnumChatFormatting.RESET - + GT_Utility.trans("183", " A")); - tList.add( - GT_Utility.trans("184", "Energy: ") + EnumChatFormatting.GREEN - + formatNumbers(energyContainer.getStoredEU()) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + formatNumbers(energyContainer.getEUCapacity()) - + EnumChatFormatting.RESET - + " EU"); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's energy info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - } - - private static int addCoverableInfo(ForgeDirection side, ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof ICoverable coverable) { - rEUAmount += 300; - final String tString = coverable.getCoverInfoAtSide(side) - .getBehaviorDescription(); - if (tString != null && !tString.equals(E)) tList.add(tString); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's covers.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addMachineProgressInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof IMachineProgress progress) { - if (progress.isAllowedToWork() && !progress.hasThingsToDo()) { - tList.add(EnumChatFormatting.RED + "Disabled." + EnumChatFormatting.RESET); - } - if (progress.wasShutdown() && isStringValid( - progress.getLastShutDownReason() - .getDisplayString())) { - tList.add( - progress.getLastShutDownReason() - .getDisplayString()); - } - rEUAmount += 400; - int tValue = 0; - if (0 < (tValue = progress.getMaxProgress())) tList.add( - GT_Utility.trans("178", "Progress/Load: ") + EnumChatFormatting.GREEN - + formatNumbers(progress.getProgress()) - + EnumChatFormatting.RESET - + " / " - + EnumChatFormatting.YELLOW - + formatNumbers(tValue) - + EnumChatFormatting.RESET); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's progress.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addUpgradableMachineInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof IUpgradableMachine upgradableMachine) { - rEUAmount += 500; - if (upgradableMachine.hasMufflerUpgrade()) tList.add( - EnumChatFormatting.GREEN + GT_Utility.trans("177", "Has Muffler Upgrade") - + EnumChatFormatting.RESET); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's upgrades.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addIC2EnergyStorageInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof ic2.api.tile.IEnergyStorage storage) { - rEUAmount += 200; - tList.add( - GT_Utility.trans("176", "Contained Energy: ") + EnumChatFormatting.YELLOW - + formatNumbers(storage.getStored()) - + EnumChatFormatting.RESET - + " EU / " - + EnumChatFormatting.YELLOW - + formatNumbers(storage.getCapacity()) - + EnumChatFormatting.RESET - + " EU"); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's IC2 energy info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addIC2EnergyConductorInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof ic2.api.energy.tile.IEnergyConductor conductor) { - rEUAmount += 200; - tList.add( - GT_Utility.trans("175", "Conduction Loss: ") + EnumChatFormatting.YELLOW - + conductor.getConductionLoss() - + EnumChatFormatting.RESET); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's EU conduction info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addIC2WrenchableInfo(EntityPlayer aPlayer, ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof ic2.api.tile.IWrenchable wrenchable) { - rEUAmount += 100; - tList.add( - GT_Utility.trans("171", "Facing: ") + EnumChatFormatting.GREEN - + wrenchable.getFacing() - + EnumChatFormatting.RESET - + GT_Utility.trans("172", " / Chance: ") - + EnumChatFormatting.YELLOW - + (wrenchable.getWrenchDropRate() * 100) - + EnumChatFormatting.RESET - + "%"); - tList.add( - wrenchable.wrenchCanRemove(aPlayer) - ? EnumChatFormatting.GREEN + GT_Utility.trans("173", "You can remove this with a Wrench") - + EnumChatFormatting.RESET - : EnumChatFormatting.RED + GT_Utility.trans("174", "You can NOT remove this with a Wrench") - + EnumChatFormatting.RESET); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's IC@ wrenchability.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addAlignmentInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof IAlignmentProvider alignmentProvider) { - final IAlignment tAlignment = alignmentProvider.getAlignment(); - if (tAlignment != null) { - rEUAmount += 100; - tList.add( - GT_Utility.trans("219", "Extended Facing: ") + EnumChatFormatting.GREEN - + tAlignment.getExtendedFacing() - + EnumChatFormatting.RESET); - } - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this device's alignment info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - private static int addReactorInfo(ArrayList tList, TileEntity tTileEntity) { - int rEUAmount = 0; - try { - if (tTileEntity instanceof ic2.api.reactor.IReactor reactor) { - rEUAmount += 500; - tList.add( - GT_Utility.trans("168", "Heat: ") + EnumChatFormatting.GREEN - + formatNumbers(reactor.getHeat()) - + EnumChatFormatting.RESET - + " / " - + EnumChatFormatting.YELLOW - + formatNumbers(reactor.getMaxHeat()) - + EnumChatFormatting.RESET); - tList.add( - GT_Utility.trans("169", "HEM: ") + EnumChatFormatting.YELLOW - + reactor.getHeatEffectModifier() - + EnumChatFormatting.RESET); - } - } catch (Throwable e) { - tList.add(String.format("§cAn exception was thrown while fetching this reactor's info.§r")); - if (D1) e.printStackTrace(GT_Log.err); - } - return rEUAmount; - } - - public static String trans(String aKey, String aEnglish) { - return GT_LanguageManager.addStringLocalization("Interaction_DESCRIPTION_Index_" + aKey, aEnglish); - } - - public static String getTrans(String aKey) { - return GT_LanguageManager.getTranslation("Interaction_DESCRIPTION_Index_" + aKey); - } - - /** - * @return an Array containing the X and the Y Coordinate of the clicked Point, with the top left Corner as Origin, - * like on the Texture Sheet. return values should always be between [0.0F and 0.99F]. - */ - // TODO: use clamp() - public static float[] getClickedFacingCoords(ForgeDirection side, float aX, float aY, float aZ) { - return switch (side) { - case DOWN -> new float[] { Math.min(0.99F, Math.max(0, 1 - aX)), Math.min(0.99F, Math.max(0, aZ)) }; - case UP -> new float[] { Math.min(0.99F, Math.max(0, aX)), Math.min(0.99F, Math.max(0, aZ)) }; - case NORTH -> new float[] { Math.min(0.99F, Math.max(0, 1 - aX)), Math.min(0.99F, Math.max(0, 1 - aY)) }; - case SOUTH -> new float[] { Math.min(0.99F, Math.max(0, aX)), Math.min(0.99F, Math.max(0, 1 - aY)) }; - case WEST -> new float[] { Math.min(0.99F, Math.max(0, aZ)), Math.min(0.99F, Math.max(0, 1 - aY)) }; - case EAST -> new float[] { Math.min(0.99F, Math.max(0, 1 - aZ)), Math.min(0.99F, Math.max(0, 1 - aY)) }; - default -> new float[] { 0.5F, 0.5F }; - }; - } - - /** - * This Function determines the direction a Block gets when being Wrenched. returns -1 if invalid. Even though that - * could never happen. - */ - public static ForgeDirection determineWrenchingSide(ForgeDirection side, float aX, float aY, float aZ) { - ForgeDirection tBack = side.getOpposite(); - switch (side) { - case DOWN, UP -> { - if (aX < 0.25) { - if (aZ < 0.25) return tBack; - if (aZ > 0.75) return tBack; - return WEST; - } - if (aX > 0.75) { - if (aZ < 0.25) return tBack; - if (aZ > 0.75) return tBack; - return EAST; - } - if (aZ < 0.25) return NORTH; - if (aZ > 0.75) return SOUTH; - return side; - } - case NORTH, SOUTH -> { - if (aX < 0.25) { - if (aY < 0.25) return tBack; - if (aY > 0.75) return tBack; - return WEST; - } - if (aX > 0.75) { - if (aY < 0.25) return tBack; - if (aY > 0.75) return tBack; - return EAST; - } - if (aY < 0.25) return DOWN; - if (aY > 0.75) return UP; - return side; - } - case WEST, EAST -> { - if (aZ < 0.25) { - if (aY < 0.25) return tBack; - if (aY > 0.75) return tBack; - return NORTH; - } - if (aZ > 0.75) { - if (aY < 0.25) return tBack; - if (aY > 0.75) return tBack; - return SOUTH; - } - if (aY < 0.25) return DOWN; - if (aY > 0.75) return UP; - return side; - } - } - return UNKNOWN; - } - - private static DecimalFormat getDecimalFormat() { - return decimalFormatters.computeIfAbsent(Locale.getDefault(Locale.Category.FORMAT), locale -> { - DecimalFormat numberFormat = new DecimalFormat(); // uses the necessary locale inside anyway - numberFormat.setGroupingUsed(true); - numberFormat.setMaximumFractionDigits(2); - numberFormat.setRoundingMode(RoundingMode.HALF_UP); - DecimalFormatSymbols decimalFormatSymbols = numberFormat.getDecimalFormatSymbols(); - decimalFormatSymbols.setGroupingSeparator(','); // Use sensible separator for best clarity. - numberFormat.setDecimalFormatSymbols(decimalFormatSymbols); - return numberFormat; - }); - } - - public static String formatNumbers(BigInteger aNumber) { - return getDecimalFormat().format(aNumber); - } - - public static String formatNumbers(long aNumber) { - return getDecimalFormat().format(aNumber); - } - - public static String formatNumbers(double aNumber) { - return getDecimalFormat().format(aNumber); - } - - /* - * Check if stack has enough items of given type and subtract from stack, if there's no creative or 111 stack. - */ - public static boolean consumeItems(EntityPlayer player, ItemStack stack, Item item, int count) { - if (stack != null && stack.getItem() == item && stack.stackSize >= count) { - if ((!player.capabilities.isCreativeMode) && (stack.stackSize != 111)) stack.stackSize -= count; - return true; - } - return false; - } - - /* - * Check if stack has enough items of given gregtech material (will be oredicted) and subtract from stack, if - * there's no creative or 111 stack. - */ - public static boolean consumeItems(EntityPlayer player, ItemStack stack, gregtech.api.enums.Materials mat, - int count) { - if (stack != null && GT_OreDictUnificator.getItemData(stack).mMaterial.mMaterial == mat - && stack.stackSize >= count) { - if ((!player.capabilities.isCreativeMode) && (stack.stackSize != 111)) stack.stackSize -= count; - return true; - } - return false; - } - - public static ArrayList sortByValueToList(Map map) { - List> list = new LinkedList<>(map.entrySet()); - list.sort((o1, o2) -> o2.getValue() - o1.getValue()); - - ArrayList result = new ArrayList<>(); - for (Map.Entry e : list) result.add(e.getKey()); - return result; - } - - public static String joinListToString(List list) { - StringBuilder result = new StringBuilder(32); - for (String s : list) result.append(result.length() == 0 ? s : '|' + s); - return result.toString(); - } - - public static ItemStack getIntegratedCircuit(int config) { - return ItemList.Circuit_Integrated.getWithDamage(0, config); - } - - public static float getBlockHardnessAt(World aWorld, int aX, int aY, int aZ) { - return aWorld.getBlock(aX, aY, aZ) - .getBlockHardness(aWorld, aX, aY, aZ); - } - - public static FakePlayer getFakePlayer(IGregTechTileEntity aBaseMetaTileEntity) { - if (aBaseMetaTileEntity.getWorld() instanceof WorldServer) { - return FakePlayerFactory.get( - (WorldServer) aBaseMetaTileEntity.getWorld(), - new GameProfile(aBaseMetaTileEntity.getOwnerUuid(), aBaseMetaTileEntity.getOwnerName())); - } - return null; - } - - public static boolean eraseBlockByFakePlayer(FakePlayer aPlayer, int aX, int aY, int aZ, boolean isSimulate) { - if (aPlayer == null) return false; - World aWorld = aPlayer.worldObj; - BlockEvent.BreakEvent event = new BlockEvent.BreakEvent( - aX, - aY, - aZ, - aWorld, - aWorld.getBlock(aX, aY, aZ), - aWorld.getBlockMetadata(aX, aY, aZ), - aPlayer); - MinecraftForge.EVENT_BUS.post(event); - if (!event.isCanceled()) { - if (!isSimulate) return aWorld.setBlockToAir(aX, aY, aZ); - return true; - } - return false; - } - - public static boolean setBlockByFakePlayer(FakePlayer aPlayer, int aX, int aY, int aZ, Block aBlock, int aMeta, - boolean isSimulate) { - if (aPlayer == null) return false; - World aWorld = aPlayer.worldObj; - BlockEvent.PlaceEvent event = ForgeEventFactory - .onPlayerBlockPlace(aPlayer, new BlockSnapshot(aWorld, aX, aY, aZ, aBlock, aMeta), UNKNOWN); - if (!event.isCanceled()) { - if (!isSimulate) return aWorld.setBlock(aX, aY, aZ, aBlock, aMeta, 3); - return true; - } - return false; - } - - public static int findMatchingStackInList(List aStacks, ItemStack aStack) { - if (isStackInvalid(aStack)) return -1; - for (int i = 0, aStacksSize = aStacks.size(); i < aStacksSize; i++) { - ItemStack tStack = aStacks.get(i); - if (areStacksEqual(aStack, tStack)) return i; - } - return -1; - } - - public static Map convertItemListToMap(Collection itemStacks) { - Map result = new Object2LongOpenHashMap<>(); - for (ItemStack itemStack : itemStacks) { - if (itemStack != null && itemStack.stackSize > 0) { - GT_Utility.ItemId itemId = GT_Utility.ItemId.createNoCopy(itemStack); - result.merge(itemId, (long) itemStack.stackSize, Long::sum); - } - } - return result; - } - - public static Map convertFluidListToMap(Collection fluidStacks) { - Map result = new Reference2LongOpenHashMap<>(); - for (FluidStack fluidStack : fluidStacks) { - if (fluidStack != null && fluidStack.amount > 0) { - result.merge(fluidStack.getFluid(), (long) fluidStack.amount, Long::sum); - } - } - return result; - } - - /** - * @return Supplied collection that doesn't contain invalid MetaTileEntities - */ - public static , E extends MetaTileEntity> T filterValidMTEs(T metaTileEntities) { - metaTileEntities.removeIf(mte -> mte == null || !mte.isValid()); - return metaTileEntities; - } - - public static ForgeDirection getSideFromPlayerFacing(Entity player) { - if (player == null) return ForgeDirection.UNKNOWN; - if (player.rotationPitch >= 65) return ForgeDirection.UP; - if (player.rotationPitch <= -65) return ForgeDirection.DOWN; - final byte facing = COMPASS_DIRECTIONS[MathHelper.floor_double(0.5D + 4.0F * player.rotationYaw / 360.0F) - & 0x3]; - return ForgeDirection.getOrientation(facing); - } - - public static class ItemNBT { - - public static void setNBT(ItemStack aStack, NBTTagCompound aNBT) { - if (aNBT == null) { - aStack.setTagCompound(null); - return; - } - ArrayList tTagsToRemove = new ArrayList<>(); - for (String tKey : aNBT.func_150296_c()) { - NBTBase tValue = aNBT.getTag(tKey); - if (tValue == null || (tValue instanceof NBTPrimitive && ((NBTPrimitive) tValue).func_150291_c() == 0) - || (tValue instanceof NBTTagString && isStringInvalid(((NBTTagString) tValue).func_150285_a_()))) - tTagsToRemove.add(tKey); - } - for (String tKey : tTagsToRemove) aNBT.removeTag(tKey); - aStack.setTagCompound(aNBT.hasNoTags() ? null : aNBT); - } - - public static NBTTagCompound getNBT(ItemStack aStack) { - NBTTagCompound rNBT = aStack.getTagCompound(); - return rNBT == null ? new NBTTagCompound() : rNBT; - } - - public static void setPunchCardData(ItemStack aStack, String aPunchCardData) { - NBTTagCompound tNBT = getNBT(aStack); - tNBT.setString("GT.PunchCardData", aPunchCardData); - setNBT(aStack, tNBT); - } - - public static String getPunchCardData(ItemStack aStack) { - NBTTagCompound tNBT = getNBT(aStack); - return tNBT.getString("GT.PunchCardData"); - } - - public static void setLighterFuel(ItemStack aStack, long aFuel) { - NBTTagCompound tNBT = getNBT(aStack); - tNBT.setLong("GT.LighterFuel", aFuel); - setNBT(aStack, tNBT); - } - - public static long getLighterFuel(ItemStack aStack) { - NBTTagCompound tNBT = getNBT(aStack); - return tNBT.getLong("GT.LighterFuel"); - } - - public static void setMapID(ItemStack aStack, short aMapID) { - NBTTagCompound tNBT = getNBT(aStack); - tNBT.setShort("map_id", aMapID); - setNBT(aStack, tNBT); - } - - public static short getMapID(ItemStack aStack) { - NBTTagCompound tNBT = getNBT(aStack); - if (!tNBT.hasKey("map_id")) return -1; - return tNBT.getShort("map_id"); - } - - public static void setBookTitle(ItemStack aStack, String aTitle) { - NBTTagCompound tNBT = getNBT(aStack); - tNBT.setString("title", aTitle); - setNBT(aStack, tNBT); - } - - public static String getBookTitle(ItemStack aStack) { - NBTTagCompound tNBT = getNBT(aStack); - return tNBT.getString("title"); - } - - public static void setBookAuthor(ItemStack aStack, String aAuthor) { - NBTTagCompound tNBT = getNBT(aStack); - tNBT.setString("author", aAuthor); - setNBT(aStack, tNBT); - } - - public static String getBookAuthor(ItemStack aStack) { - NBTTagCompound tNBT = getNBT(aStack); - return tNBT.getString("author"); - } - - public static void setProspectionData(ItemStack aStack, int aX, int aY, int aZ, int aDim, FluidStack aFluid, - String... aOres) { - NBTTagCompound tNBT = getNBT(aStack); - StringBuilder tData = new StringBuilder(aX + "," + aY + "," + aZ + "," + aDim + ","); - if (aFluid != null) tData.append(aFluid.amount) - .append(",") - .append(aFluid.getLocalizedName()) - .append(","); // TODO - // CHECK - // IF - // THAT - // /5000 - // is - // needed - // (Not - // needed) - for (String tString : aOres) { - tData.append(tString) - .append(","); - } - tNBT.setString("prospection", tData.toString()); - setNBT(aStack, tNBT); - } - - public static void setAdvancedProspectionData(byte aTier, ItemStack aStack, int aX, short aY, int aZ, int aDim, - ArrayList aOils, ArrayList aOres, int aRadius) { - - setBookTitle(aStack, "Raw Prospection Data"); - - NBTTagCompound tNBT = getNBT(aStack); - - tNBT.setByte("prospection_tier", aTier); - tNBT.setString("prospection_pos", "Dim: " + aDim + "\nX: " + aX + " Y: " + aY + " Z: " + aZ); - - // ores - Collections.sort(aOres); - tNBT.setString("prospection_ores", joinListToString(aOres)); - - // oils - ArrayList tOilsTransformed = new ArrayList<>(aOils.size()); - for (String aStr : aOils) { - String[] aStats = aStr.split(","); - tOilsTransformed.add(aStats[0] + ": " + aStats[1] + "L " + aStats[2]); - } - - tNBT.setString("prospection_oils", joinListToString(tOilsTransformed)); - - String tOilsPosStr = "X: " + Math.floorDiv(aX, 16 * 8) * 16 * 8 - + " Z: " - + Math.floorDiv(aZ, 16 * 8) * 16 * 8 - + "\n"; - int xOff = aX - Math.floorDiv(aX, 16 * 8) * 16 * 8; - xOff = xOff / 16; - int xOffRemain = 7 - xOff; - - int zOff = aZ - Math.floorDiv(aZ, 16 * 8) * 16 * 8; - zOff = zOff / 16; - int zOffRemain = 7 - zOff; - - for (; zOff > 0; zOff--) { - tOilsPosStr = tOilsPosStr.concat("--------\n"); - } - for (; xOff > 0; xOff--) { - tOilsPosStr = tOilsPosStr.concat("-"); - } - - tOilsPosStr = tOilsPosStr.concat("P"); - - for (; xOffRemain > 0; xOffRemain--) { - tOilsPosStr = tOilsPosStr.concat("-"); - } - tOilsPosStr = tOilsPosStr.concat("\n"); - for (; zOffRemain > 0; zOffRemain--) { - tOilsPosStr = tOilsPosStr.concat("--------\n"); - } - tOilsPosStr = tOilsPosStr.concat( - " X: " + (Math.floorDiv(aX, 16 * 8) + 1) * 16 * 8 - + " Z: " - + (Math.floorDiv(aZ, 16 * 8) + 1) * 16 * 8); // +1 oilfied to find bottomright of [5] - - tNBT.setString("prospection_oils_pos", tOilsPosStr); - - tNBT.setString("prospection_radius", String.valueOf(aRadius)); - - setNBT(aStack, tNBT); - } - - public static void convertProspectionData(ItemStack aStack) { - NBTTagCompound tNBT = getNBT(aStack); - byte tTier = tNBT.getByte("prospection_tier"); - - if (tTier == 0) { // basic prospection data - String tData = tNBT.getString("prospection"); - String[] tDataArray = tData.split(","); - if (tDataArray.length > 6) { - tNBT.setString( - "author", - " Dim: " + tDataArray[3] - + "X: " - + tDataArray[0] - + " Y: " - + tDataArray[1] - + " Z: " - + tDataArray[2]); - NBTTagList tNBTList = new NBTTagList(); - StringBuilder tOres = new StringBuilder(" Prospected Ores: "); - for (int i = 6; tDataArray.length > i; i++) { - tOres.append(tDataArray[i]) - .append(" "); - } - tNBTList.appendTag( - new NBTTagString( - "Tier " + tTier - + " Prospecting Data From: X" - + tDataArray[0] - + " Z:" - + tDataArray[2] - + " Dim:" - + tDataArray[3] - + " Produces " - + tDataArray[4] - + "L " - + tDataArray[5] - + " " - + tOres)); - tNBT.setTag("pages", tNBTList); - } - } else { // advanced prospection data - String tPos = tNBT.getString("prospection_pos"); - String tRadius = tNBT.getString("prospection_radius"); - - String tOresStr = tNBT.getString("prospection_ores"); - String tOilsStr = tNBT.getString("prospection_oils"); - String tOilsPosStr = tNBT.getString("prospection_oils_pos"); - - String[] tOres = tOresStr.isEmpty() ? null : tOresStr.split("\\|"); - String[] tOils = tOilsStr.isEmpty() ? null : tOilsStr.split("\\|"); - - NBTTagList tNBTList = new NBTTagList(); - - String tPageText = "Prospector report\n" + tPos - + "\n\n" - + "Oils: " - + (tOils != null ? tOils.length : 0) - + "\n\n" - + "Ores within " - + tRadius - + " blocks\n\n" - + "Location is center of orevein\n\n" - + "Check NEI to confirm orevein type"; - tNBTList.appendTag(new NBTTagString(tPageText)); - - if (tOres != null) fillBookWithList(tNBTList, "Ores Found %s\n\n", "\n", 7, tOres); - - if (tOils != null) fillBookWithList(tNBTList, "Oils%s\n\n", "\n", 9, tOils); - - tPageText = """ - Oil notes - - Prospects from NW to SE 576 chunks(9 8x8 oilfields) - around and gives min-max amount - - [1][2][3] - [4][5][6] - [7][8][9] - - [5] - Prospector in this 8x8 area"""; - tNBTList.appendTag(new NBTTagString(tPageText)); - - tPageText = "Corners of [5] are \n" + tOilsPosStr + "\n" + "P - Prospector in 8x8 field"; - tNBTList.appendTag(new NBTTagString(tPageText)); - - tNBT.setString("author", tPos.replace("\n", " ")); - tNBT.setTag("pages", tNBTList); - } - setNBT(aStack, tNBT); - } - - public static void fillBookWithList(NBTTagList aBook, String aPageHeader, String aListDelimiter, - int aItemsPerPage, String[] list) { - String aPageFormatter = " %d/%d"; - int tTotalPages = list.length / aItemsPerPage + (list.length % aItemsPerPage > 0 ? 1 : 0); - int tPage = 0; - StringBuilder tPageText; - do { - tPageText = new StringBuilder(); - for (int i = tPage * aItemsPerPage; i < (tPage + 1) * aItemsPerPage && i < list.length; i += 1) - tPageText.append((tPageText.length() == 0) ? "" : aListDelimiter) - .append(list[i]); - - if (tPageText.length() > 0) { - String tPageCounter = tTotalPages > 1 ? String.format(aPageFormatter, tPage + 1, tTotalPages) : ""; - NBTTagString tPageTag = new NBTTagString(String.format(aPageHeader, tPageCounter) + tPageText); - aBook.appendTag(tPageTag); - } - - ++tPage; - } while (tPageText.length() > 0); - } - - public static void addEnchantment(ItemStack aStack, Enchantment aEnchantment, int aLevel) { - NBTTagCompound tNBT = getNBT(aStack), tEnchantmentTag; - if (!tNBT.hasKey("ench", 9)) tNBT.setTag("ench", new NBTTagList()); - NBTTagList tList = tNBT.getTagList("ench", 10); - - boolean temp = true; - - for (int i = 0; i < tList.tagCount(); i++) { - tEnchantmentTag = tList.getCompoundTagAt(i); - if (tEnchantmentTag.getShort("id") == aEnchantment.effectId) { - tEnchantmentTag.setShort("id", (short) aEnchantment.effectId); - tEnchantmentTag.setShort("lvl", (byte) aLevel); - temp = false; - break; - } - } - - if (temp) { - tEnchantmentTag = new NBTTagCompound(); - tEnchantmentTag.setShort("id", (short) aEnchantment.effectId); - tEnchantmentTag.setShort("lvl", (byte) aLevel); - tList.appendTag(tEnchantmentTag); - } - aStack.setTagCompound(tNBT); - } - } - - public static String toSubscript(long no) { - char[] chars = Long.toString(no) - .toCharArray(); - for (int i = 0; i < chars.length; i++) { - chars[i] += 8272; - } - return new String(chars); - } - - public static boolean isPartOfMaterials(ItemStack aStack, Materials aMaterials) { - return GT_OreDictUnificator.getAssociation(aStack) != null - && GT_OreDictUnificator.getAssociation(aStack).mMaterial.mMaterial.equals(aMaterials); - } - - public static boolean isPartOfOrePrefix(ItemStack aStack, OrePrefixes aPrefix) { - return GT_OreDictUnificator.getAssociation(aStack) != null - && GT_OreDictUnificator.getAssociation(aStack).mPrefix.equals(aPrefix); - } - - public static final ImmutableSet ORE_BLOCK_CLASSES = ImmutableSet.of( - "com.github.bartimaeusnek.bartworks.system.material.BW_MetaGenerated_Ores", - "com.github.bartimaeusnek.bartworks.system.material.BW_MetaGenerated_SmallOres", - "gtPlusPlus.core.block.base.BlockBaseOre"); - - public static boolean isOre(Block aBlock, int aMeta) { - return (aBlock instanceof GT_Block_Ores_Abstract) || isOre(new ItemStack(aBlock, 1, aMeta)) - || ORE_BLOCK_CLASSES.contains( - aBlock.getClass() - .getName()); - } - - public static boolean isOre(ItemStack aStack) { - int tItem = GT_Utility.stackToInt(aStack); - if (sOreTable.containsKey(tItem)) { - return sOreTable.get(tItem); - } - for (int id : OreDictionary.getOreIDs(aStack)) { - if (OreDictionary.getOreName(id) - .startsWith("ore")) { - sOreTable.put(tItem, true); - return true; - } - } - sOreTable.put(tItem, false); - return false; - } - - /** - * Do NOT mutate the returned {@code ItemStack}! We return {@code ItemStack} instead of {@code Block} so that - * we can include metadata. - */ - public static ItemStack getCobbleForOre(Block ore, short metaData) { - // We need to convert small ores to regular ores because small ores don't have associated ItemData. - // We take the modulus of the metadata by 16000 because that is the magic number to convert small ores to - // regular ores. - // See: GT_TileEntity_Ores.java - ItemData association = GT_OreDictUnificator - .getAssociation(new ItemStack(Item.getItemFromBlock(ore), 1, metaData % 16000)); - if (association != null) { - Supplier supplier = sOreToCobble.get(association.mPrefix); - if (supplier != null) { - return supplier.get(); - } - } - return new ItemStack(Blocks.cobblestone); - } - - public static Optional reverseShapelessRecipe(ItemStack output, Object... aRecipe) { - if (output == null) { - return Optional.empty(); - } - - List inputs = new ArrayList<>(); - - for (Object o : aRecipe) { - if (o instanceof ItemStack) { - ItemStack toAdd = ((ItemStack) o).copy(); - inputs.add(toAdd); - } else if (o instanceof String) { - ItemStack stack = GT_OreDictUnificator.get(o, 1); - if (stack == null) { - Optional oStack = OreDictionary.getOres((String) o) - .stream() - .findAny(); - if (oStack.isPresent()) { - ItemStack copy = oStack.get() - .copy(); - inputs.add(copy); - } - } else { - ItemStack copy = stack.copy(); - inputs.add(copy); - } - } else if (o instanceof Item) inputs.add(new ItemStack((Item) o)); - else if (o instanceof Block) inputs.add(new ItemStack((Block) o)); - else throw new IllegalStateException("A Recipe contains an invalid input! Output: " + output); - } - - inputs.removeIf(x -> x.getItem() instanceof GT_MetaGenerated_Tool); - - return Optional.of( - new GT_Recipe( - false, - new ItemStack[] { output }, - inputs.toArray(new ItemStack[0]), - null, - null, - null, - null, - 300, - 30, - 0)); - } - - public static Optional reverseShapedRecipe(ItemStack output, Object... aRecipe) { - if (output == null) { - return Optional.empty(); - } - - Map recipeAsMap = new HashMap<>(); - Map ingridients = new HashMap<>(); - Map amounts = new HashMap<>(); - boolean startFound = false; - for (int i = 0, aRecipeLength = aRecipe.length; i < aRecipeLength; i++) { - Object o = aRecipe[i]; - if (!startFound) { - if (o instanceof String) { - for (Character c : ((String) o).toCharArray()) amounts.merge(c, 1, (a, b) -> ++a); - } else if (o instanceof Character) startFound = true; - } else if (!(o instanceof Character)) ingridients.put((Character) aRecipe[i - 1], o); - } - for (Map.Entry characterObjectEntry : ingridients.entrySet()) { - for (Map.Entry characterIntegerEntry : amounts.entrySet()) { - if (characterObjectEntry.getKey() != characterIntegerEntry.getKey()) continue; - recipeAsMap.put(characterObjectEntry.getValue(), characterIntegerEntry.getValue()); - } - } - List inputs = new ArrayList<>(); - - for (Map.Entry o : recipeAsMap.entrySet()) { - final int amount = o.getValue(); - if (o.getKey() instanceof ItemStack) { - ItemStack toAdd = ((ItemStack) o.getKey()).copy(); - toAdd.stackSize = amount; - inputs.add(toAdd); - } else if (o.getKey() instanceof String dictName) { - // Do not register tools dictName in inputs - if (ToolDictNames.contains(dictName)) continue; - ItemStack stack = GT_OreDictUnificator.get(dictName, null, amount, false, true); - if (stack == null) { - Optional oStack = OreDictionary.getOres(dictName) - .stream() - .findAny(); - if (oStack.isPresent()) { - ItemStack copy = oStack.get() - .copy(); - copy.stackSize = amount; - inputs.add(copy); - } - } else { - ItemStack copy = stack.copy(); - copy.stackSize = amount; - inputs.add(copy); - } - } else if (o.getKey() instanceof Item) inputs.add(new ItemStack((Item) o.getKey(), amount)); - else if (o.getKey() instanceof Block) inputs.add(new ItemStack((Block) o.getKey(), amount)); - else throw new IllegalStateException("A Recipe contains an invalid input! Output: " + output); - } - - // Remove tools from inputs in case a recipe has one as a direct Item or ItemStack reference - inputs.removeIf(x -> x.getItem() instanceof GT_MetaGenerated_Tool); - - return Optional.of( - new GT_Recipe( - false, - new ItemStack[] { output }, - inputs.toArray(new ItemStack[0]), - null, - null, - null, - null, - 300, - 30, - 0)); - } - - /** - * Add an itemstack to player inventory, or drop on ground if full. Can be called on client but it probably won't - * work very well. - */ - public static void addItemToPlayerInventory(EntityPlayer aPlayer, ItemStack aStack) { - if (isStackInvalid(aStack)) return; - if (!aPlayer.inventory.addItemStackToInventory(aStack) && !aPlayer.worldObj.isRemote) { - EntityItem dropItem = aPlayer.entityDropItem(aStack, 0); - dropItem.delayBeforeCanPickup = 0; - } - } - - public static long getNonnullElementCount(Object[] tArray) { - return Arrays.stream(tArray) - .filter(Objects::nonNull) - .count(); - } - - public static int clamp(int val, int lo, int hi) { - return MathHelper.clamp_int(val, lo, hi); - } - - public static int ceilDiv(int lhs, int rhs) { - return (lhs + rhs - 1) / rhs; - } - - public static long ceilDiv(long lhs, long rhs) { - return (lhs + rhs - 1) / rhs; - } - - /** - * Hash an item stack for the purpose of storing hash across launches - */ - public static int persistentHash(ItemStack aStack, boolean aUseStackSize, boolean aUseNBT) { - if (aStack == null) return 0; - int result = Objects.hashCode(GameRegistry.findUniqueIdentifierFor(aStack.getItem())); - result = result * 31 + Items.feather.getDamage(aStack); - - if (aUseStackSize) result = result * 31 + aStack.stackSize; - if (aUseNBT) result = result * 31 + Objects.hashCode(aStack.stackTagCompound); - return result; - } - - /** - * Hash an item stack for the purpose of storing hash across launches - */ - public static int persistentHash(FluidStack aStack, boolean aUseStackSize, boolean aUseNBT) { - if (aStack == null) return 0; - int base = Objects.hashCode( - aStack.getFluid() - .getName()); - - if (aUseStackSize) base = base * 31 + aStack.amount; - if (aUseNBT) base = base * 31 + Objects.hashCode(aStack.tag); - return base; - } - - public static int getCasingTextureIndex(Block block, int meta) { - if (block instanceof IHasIndexedTexture) return ((IHasIndexedTexture) block).getTextureIndex(meta); - return Textures.BlockIcons.ERROR_TEXTURE_INDEX; - } - - public static boolean isCellEmpty(ItemStack itemStack) { - if (itemStack == null) return false; - ItemStack tStack = ItemList.Cell_Empty.get(1); - tStack.stackSize = itemStack.stackSize; - return GT_Utility.areStacksEqual(itemStack, tStack); - } - - /** - * Convert a cell to fluid. If given itemstack does not contain any fluid, return null. Will correctly multiple - * output fluid amount if input stack size is greater than 1. - */ - public static FluidStack convertCellToFluid(ItemStack itemStack) { - if (itemStack == null) return null; - if (getFluidForFilledItem(itemStack, true) != null) { - FluidStack fluidStack = getFluidForFilledItem(itemStack, true); - if (fluidStack != null) fluidStack.amount = fluidStack.amount * itemStack.stackSize; - return fluidStack; - } - return null; - } - - public static boolean isAnyIntegratedCircuit(ItemStack itemStack) { - if (itemStack == null) return false; - return itemStack.getItem() == ItemList.Circuit_Integrated.getItem() && 0 <= itemStack.getItemDamage() - && itemStack.getItemDamage() < 25; - } - - public static byte convertRatioToRedstone(long used, long max, int threshold, boolean inverted) { - byte signal; - if (used <= 0) { // Empty - signal = 0; - } else if (used >= max) { // Full - signal = 15; - } else { // Range 1-14 - signal = (byte) (1 + (14 * used) / max); - } - - if (inverted) { - signal = (byte) (15 - signal); - } - - if (threshold > 0) { - if (inverted && used >= threshold) { - return 0; - } else if (!inverted && used < threshold) { - return 0; - } - } - - return signal; - } - - public static ItemStack getNaniteAsCatalyst(Materials material) { - ItemStack aItem = material.getNanite(1); - return new ItemStack(aItem.getItem(), 0, aItem.getItemDamage()); - } - - public static Stream streamCompounds(NBTTagList list) { - if (list == null) return Stream.empty(); - return IntStream.range(0, list.tagCount()) - .mapToObj(list::getCompoundTagAt); - } - - public static boolean equals(ItemStack[] a, ItemStack[] b) { - // because stupid mojang didn't override equals for us - if (a == null && b == null) return true; - if ((a == null) != (b == null)) return false; - if (a.length != b.length) return false; - for (int i = 0; i < a.length; i++) { - if (!areStacksEqual(a[i], b[i], false)) return false; - } - return true; - } - - /** - * Guava ImmutableMap variant of Collectors.toMap. Optimized for serial streams. - */ - public static Collector> toImmutableMapSerial( - Function keyMapper, Function valueMapper) { - // petty type inference cannot work out the correct type parameter - return Collector., ImmutableMap>of( - ImmutableMap::builder, - (b, t) -> b.put(keyMapper.apply(t), valueMapper.apply(t)), - (b1, b2) -> b1.putAll(b2.build()), - ImmutableMap.Builder::build); - } - - public static boolean isArrayEmptyOrNull(Object[] arr) { - return arr == null || arr.length == 0; - } - - public static boolean isArrayOfLength(Object[] arr, int expectedLength) { - return arr != null && arr.length == expectedLength; - } - - @SafeVarargs - public static Collection concat(Collection... colls) { - return concat(Arrays.asList(colls)); - } - - public static Collection concat(Collection> colls) { - return new ConcatCollection<>(colls); - } - - private static class ConcatCollection extends AbstractCollection { - - private final Collection> colls; - private final int size; - - public ConcatCollection(Collection> lists) { - Collection> colls1 = null; - for (Collection list : lists) { - if (list == null || list.isEmpty()) { - colls1 = lists.stream() - .filter(c -> c != null && !c.isEmpty()) - .collect(Collectors.toList()); - break; - } - } - if (colls1 == null) colls1 = lists; - colls = colls1; - int sum = 0; - for (Collection list : colls) { - sum += list.size(); - } - size = sum; - } - - @Nonnull - @Override - public Iterator iterator() { - return colls.stream() - .flatMap(Collection::stream) - .iterator(); - } - - @Override - public int size() { - return size; - } - } - - @AutoValue - public abstract static class ItemId { - - public static ItemId create(NBTTagCompound tag) { - return new AutoValue_GT_Utility_ItemId( - Item.getItemById(tag.getShort("item")), - tag.getShort("meta"), - tag.hasKey("tag", Constants.NBT.TAG_COMPOUND) ? tag.getCompoundTag("tag") : null); - } - - /** - * This method copies NBT, as it is mutable. - */ - public static ItemId create(ItemStack itemStack) { - NBTTagCompound nbt = itemStack.getTagCompound(); - if (nbt != null) { - nbt = (NBTTagCompound) nbt.copy(); - } - - return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), Items.feather.getDamage(itemStack), nbt); - } - - /** - * This method copies NBT, as it is mutable. - */ - public static ItemId create(Item item, int metaData, @Nullable NBTTagCompound nbt) { - if (nbt != null) { - nbt = (NBTTagCompound) nbt.copy(); - } - return new AutoValue_GT_Utility_ItemId(item, metaData, nbt); - } - - /** - * This method stores metadata as wildcard and NBT as null. - */ - public static ItemId createAsWildcard(ItemStack itemStack) { - return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), W, null); - } - - /** - * This method stores NBT as null. - */ - public static ItemId createWithoutNBT(ItemStack itemStack) { - return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), Items.feather.getDamage(itemStack), null); - } - - /** - * This method does not copy NBT in order to save time. Make sure not to mutate it! - */ - public static ItemId createNoCopy(ItemStack itemStack) { - return new AutoValue_GT_Utility_ItemId( - itemStack.getItem(), - Items.feather.getDamage(itemStack), - itemStack.getTagCompound()); - } - - /** - * This method does not copy NBT in order to save time. Make sure not to mutate it! - */ - public static ItemId createNoCopy(Item item, int metaData, @Nullable NBTTagCompound nbt) { - return new AutoValue_GT_Utility_ItemId(item, metaData, nbt); - } - - protected abstract Item item(); - - protected abstract int metaData(); - - @Nullable - protected abstract NBTTagCompound nbt(); - - public NBTTagCompound writeToNBT() { - NBTTagCompound tag = new NBTTagCompound(); - tag.setShort("item", (short) Item.getIdFromItem(item())); - tag.setShort("meta", (short) metaData()); - if (nbt() != null) tag.setTag("tag", nbt()); - return tag; - } - - @Nonnull - public ItemStack getItemStack() { - ItemStack itemStack = new ItemStack(item(), 1, metaData()); - itemStack.setTagCompound(nbt()); - return itemStack; - } - } - - public static int getPlasmaFuelValueInEUPerLiterFromMaterial(Materials material) { - return getPlasmaFuelValueInEUPerLiterFromFluid(material.getPlasma(1)); - } - - public static int getPlasmaFuelValueInEUPerLiterFromFluid(FluidStack aLiquid) { - if (aLiquid == null) return 0; - GT_Recipe tFuel = RecipeMaps.plasmaFuels.getBackend() - .findFuel(aLiquid); - if (tFuel != null) return tFuel.mSpecialValue; - return 0; - } - - public static MovingObjectPosition getPlayerLookingTarget(EntityPlayer viewpoint) { - double reachDistance = viewpoint instanceof EntityPlayerMP mp ? mp.theItemInWorldManager.getBlockReachDistance() - : getClientReachDistance(); - Vec3 posVec = Vec3.createVectorHelper( - viewpoint.posX, - viewpoint.posY + (viewpoint.getEyeHeight() - viewpoint.getDefaultEyeHeight()), - viewpoint.posZ); - Vec3 lookVec = viewpoint.getLook(0); - Vec3 modifiedPosVec = posVec - .addVector(lookVec.xCoord * reachDistance, lookVec.yCoord * reachDistance, lookVec.zCoord * reachDistance); - - return viewpoint.worldObj.rayTraceBlocks(posVec, modifiedPosVec); - } - - public static float getClientReachDistance() { - return Minecraft.getMinecraft().playerController.getBlockReachDistance(); - } -} diff --git a/src/main/java/gregtech/api/util/GT_UtilityClient.java b/src/main/java/gregtech/api/util/GT_UtilityClient.java deleted file mode 100644 index 398c1f6b41..0000000000 --- a/src/main/java/gregtech/api/util/GT_UtilityClient.java +++ /dev/null @@ -1,52 +0,0 @@ -package gregtech.api.util; - -import java.lang.reflect.Field; -import java.util.List; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.item.EnumRarity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; - -import com.google.common.collect.Lists; - -import cpw.mods.fml.relauncher.ReflectionHelper; - -public class GT_UtilityClient { - - private static final Field isDrawingField = ReflectionHelper - .findField(Tessellator.class, "isDrawing", "field_78415_z"); - - public static boolean isDrawing(Tessellator tess) { - try { - return isDrawingField.getBoolean(tess); - } catch (IllegalAccessException e) { - e.printStackTrace(); - return false; - } - } - - public static List getTooltip(ItemStack aStack, boolean aGuiStyle) { - try { - List tooltip = aStack.getTooltip( - Minecraft.getMinecraft().thePlayer, - Minecraft.getMinecraft().gameSettings.advancedItemTooltips); - if (aGuiStyle) { - tooltip.set( - 0, - (aStack.getRarity() == null ? EnumRarity.common : aStack.getRarity()).rarityColor + tooltip.get(0)); - for (int i = 1; i < tooltip.size(); i++) { - tooltip.set(i, EnumChatFormatting.GRAY + tooltip.get(i)); - } - } - return tooltip; - } catch (RuntimeException e) { - // Collections.singletonList() can not be added to. we don't want that - if (aGuiStyle) return Lists.newArrayList( - (aStack.getRarity() == null ? EnumRarity.common : aStack.getRarity()).rarityColor - + aStack.getDisplayName()); - return Lists.newArrayList(aStack.getDisplayName()); - } - } -} diff --git a/src/main/java/gregtech/api/util/GT_Waila.java b/src/main/java/gregtech/api/util/GT_Waila.java deleted file mode 100644 index aaa68ba4c7..0000000000 --- a/src/main/java/gregtech/api/util/GT_Waila.java +++ /dev/null @@ -1,23 +0,0 @@ -package gregtech.api.util; - -public abstract class GT_Waila { - - public static String getMachineProgressString(boolean isActive, int maxProgresstime, int progresstime) { - return getMachineProgressString(isActive, (long) maxProgresstime, (long) progresstime); - } - - public static String getMachineProgressString(boolean isActive, long maxProgresstime, long progresstime) { - - if (!isActive) return "Idle"; - - StringBuilder ret = new StringBuilder("In progress: ") - .append(String.format("%,.2f", (double) progresstime / 20)) - .append("s / ") - .append(String.format("%,.2f", (double) maxProgresstime / 20)) - .append("s (") - .append(GT_Utility.formatNumbers((Math.round((double) progresstime / maxProgresstime * 1000) / 10.0))) - .append("%)"); - - return ret.toString(); - } -} diff --git a/src/main/java/gregtech/api/util/HatchElementBuilder.java b/src/main/java/gregtech/api/util/HatchElementBuilder.java new file mode 100644 index 0000000000..8b93861114 --- /dev/null +++ b/src/main/java/gregtech/api/util/HatchElementBuilder.java @@ -0,0 +1,546 @@ +package gregtech.api.util; + +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.IStructureElement; +import com.gtnewhorizon.structurelib.structure.IStructureElementChain; +import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; + +import gnu.trove.TIntCollection; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.set.hash.TIntHashSet; +import gregtech.api.interfaces.IHatchElement; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.common.blocks.ItemMachines; + +public class HatchElementBuilder { + + private interface Builtin { + } + + private IGTHatchAdder mAdder; + private int mCasingIndex = -1; + private int mDot = -1; + private BiPredicate mShouldSkip; + private BiFunction> mHatchItemFilter; + private Supplier mHatchItemType; + private Predicate mReject; + private boolean mCacheHint; + private boolean mNoStop; + private boolean mExclusive; + private EnumSet mDisallowedDirection = EnumSet.noneOf(ForgeDirection.class); + + private HatchElementBuilder() {} + + public static HatchElementBuilder builder() { + return new HatchElementBuilder<>(); + } + + // region composite + + /** + * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. TODO add doc + */ + @SafeVarargs + public final HatchElementBuilder anyOf(IHatchElement... elements) { + if (elements == null || elements.length == 0) throw new IllegalArgumentException(); + return adder( + Arrays.stream(elements) + .map( + e -> e.adder() + .rebrand()) + .reduce(IGTHatchAdder::orElse) + .get()).hatchClasses( + Arrays.stream(elements) + .map(IHatchElement::mteClasses) + .flatMap(Collection::stream) + .collect(Collectors.toList())) + .cacheHint( + () -> Arrays.stream(elements) + .map(IHatchElement::name) + .sorted() + .collect(Collectors.joining(" or ", "of type ", ""))); + } + + /** + * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. + *

+ * Will rotate through all elements TODO add doc + */ + @SafeVarargs + public final HatchElementBuilder atLeast(IHatchElement... elements) { + if (elements == null || elements.length == 0) throw new IllegalArgumentException(); + return atLeast( + Arrays.stream(elements) + .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))); + } + + /** + * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. + *

+ * Will rotate through all elements TODO add doc + */ + public final HatchElementBuilder atLeastList(List> elements) { + if (elements == null || elements.isEmpty()) throw new IllegalArgumentException(); + return atLeast( + elements.stream() + .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))); + } + + /** + * Set all of adder, hint and hatchItemFilter. Provide a reasonable default for shouldSkip. TODO add doc + */ + public final HatchElementBuilder atLeast(Map, ? extends Number> elements) { + if (elements == null || elements.isEmpty() || elements.containsKey(null) || elements.containsValue(null)) + throw new IllegalArgumentException(); + List> list = elements.keySet() + .stream() + .map(IHatchElement::mteClasses) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + // map cannot be null or empty, so assert Optional isPresent + return adder( + elements.keySet() + .stream() + .map( + e -> e.adder() + .rebrand()) + .reduce(IGTHatchAdder::orElse) + .orElseThrow(AssertionError::new)) + .hatchItemFilter( + obj -> GTStructureUtility.filterByMTEClass( + elements.entrySet() + .stream() + .filter( + entry -> entry.getKey() + .count(obj) + < entry.getValue() + .longValue()) + .flatMap( + entry -> entry.getKey() + .mteClasses() + .stream()) + .collect(Collectors.toList()))) + .shouldReject( + obj -> elements.entrySet() + .stream() + .allMatch( + e -> e.getKey() + .count(obj) + >= e.getValue() + .longValue())) + .shouldSkip( + (BiPredicate & Builtin) (c, + t) -> t != null && list.stream() + .anyMatch(clazz -> clazz.isInstance(t.getMetaTileEntity()))) + .cacheHint( + () -> elements.keySet() + .stream() + .map(IHatchElement::name) + .sorted() + .collect(Collectors.joining(" or ", "of type ", ""))); + } + // endregion + + // region primitives + + /** + * Mark this hatch element as the only candidate of given structure element. (e.g. muffler hatch on top of EBF) + * Currently, this will make the built IStructureElement to ignore gt_no_hatch directive from player + * + * Do note that {@link #buildAndChain(IStructureElement[])} and its overloads will force the resulting structure + * element + * to be non-exclusive. + */ + public HatchElementBuilder exclusive() { + mExclusive = true; + return this; + } + + public HatchElementBuilder adder(IGTHatchAdder aAdder) { + if (aAdder == null) throw new IllegalArgumentException(); + mAdder = aAdder; + return this; + } + + public HatchElementBuilder casingIndex(int aCasingIndex) { + if (aCasingIndex <= 0) throw new IllegalArgumentException(); + mCasingIndex = aCasingIndex; + return this; + } + + public HatchElementBuilder dot(int aDot) { + if (aDot <= 0) throw new IllegalArgumentException(); + mDot = aDot; + return this; + } + + public HatchElementBuilder shouldSkip(BiPredicate aShouldSkip) { + if (!(aShouldSkip instanceof Builtin) || mShouldSkip != null) { + if (!(mShouldSkip instanceof Builtin) && mShouldSkip != null) throw new IllegalStateException(); + if (aShouldSkip == null) throw new IllegalArgumentException(); + } + mShouldSkip = aShouldSkip; + return this; + } + + public HatchElementBuilder shouldReject(Predicate aShouldReject) { + if (aShouldReject == null) throw new IllegalArgumentException(); + mReject = aShouldReject; + return this; + } + + public HatchElementBuilder hatchItemFilter( + Function> aHatchItemFilter) { + if (aHatchItemFilter == null) throw new IllegalArgumentException(); + mHatchItemFilter = (t, s) -> aHatchItemFilter.apply(t); + return this; + } + + public HatchElementBuilder hatchItemFilterAnd( + Function> aHatchItemFilter) { + if (aHatchItemFilter == null) throw new IllegalArgumentException(); + BiFunction> tOldFilter = mHatchItemFilter; + mHatchItemFilter = (t, s) -> tOldFilter.apply(t, s) + .and(aHatchItemFilter.apply(t)); + return this; + } + + public HatchElementBuilder hatchItemFilter( + BiFunction> aHatchItemFilter) { + if (aHatchItemFilter == null) throw new IllegalArgumentException(); + mHatchItemFilter = aHatchItemFilter; + return this; + } + + public HatchElementBuilder hatchItemFilterAnd( + BiFunction> aHatchItemFilter) { + if (aHatchItemFilter == null) throw new IllegalArgumentException(); + BiFunction> tOldFilter = mHatchItemFilter; + mHatchItemFilter = (t, s) -> tOldFilter.apply(t, s) + .and(aHatchItemFilter.apply(t, s)); + return this; + } + + // region hint + public HatchElementBuilder hint(Supplier aSupplier) { + if (aSupplier == null) throw new IllegalArgumentException(); + mHatchItemType = aSupplier; + mCacheHint = false; + return this; + } + + public HatchElementBuilder cacheHint(Supplier aSupplier) { + if (aSupplier == null) throw new IllegalArgumentException(); + mHatchItemType = aSupplier; + mCacheHint = true; + return this; + } + + public HatchElementBuilder cacheHint() { + if (mHatchItemType == null) throw new IllegalStateException(); + mCacheHint = true; + return this; + } + // endregion + + public HatchElementBuilder continueIfSuccess() { + mNoStop = true; + return this; + } + + public HatchElementBuilder stopIfSuccess() { + mNoStop = false; + return this; + } + + /** + * Help automatic hatch side determination code by ruling out some directions. Note the automatic hatch side + * determination code will choose to use the default facing if the final allowed facing set is empty. + *

+ * This will clear the sides set by previous call to this or {@link #allowOnly(ForgeDirection...)} + *

+ * Usually mandatory for multis with multiple slices, and otherwise not needed if it contains a single slice only. + * + * @param facings disallowed direction in ABC coordinate system + */ + public HatchElementBuilder disallowOnly(ForgeDirection... facings) { + if (facings == null) throw new IllegalArgumentException(); + mDisallowedDirection = EnumSet.copyOf(Arrays.asList(facings)); + return this; + } + + /** + * Help automatic hatch side determination code by allowing only some directions. Note the automatic hatch side + * determination code will choose to use the default facing if the final allowed facing set is empty. + *

+ * This will clear the sides set by previous call to this or {@link #disallowOnly(ForgeDirection...)} + *

+ * Usually mandatory for multis with multiple slices, and otherwise not needed if it contains a single slice only. + * + * @param facings allowed direction in ABC coordinate system + */ + public HatchElementBuilder allowOnly(ForgeDirection... facings) { + if (facings == null) throw new IllegalArgumentException(); + mDisallowedDirection = EnumSet.complementOf(EnumSet.copyOf(Arrays.asList(facings))); + mDisallowedDirection.remove(ForgeDirection.UNKNOWN); + return this; + } + // endregion + + // region intermediate + public HatchElementBuilder hatchClass(Class clazz) { + return hatchItemFilter(c -> is -> clazz.isInstance(ItemMachines.getMetaTileEntity(is))) + .cacheHint(() -> "of class " + clazz.getSimpleName()) + .shouldSkip( + (BiPredicate & Builtin) (c, t) -> clazz + .isInstance(t.getMetaTileEntity())); + } + + @SafeVarargs + public final HatchElementBuilder hatchClasses(Class... classes) { + return hatchClasses(Arrays.asList(classes)); + } + + public final HatchElementBuilder hatchClasses(List> classes) { + List> list = new ArrayList<>(classes); + return hatchItemFilter(obj -> GTStructureUtility.filterByMTEClass(list)).cacheHint( + () -> list.stream() + .map(Class::getSimpleName) + .sorted() + .collect(Collectors.joining(" or ", "of class ", ""))) + .shouldSkip( + (BiPredicate & Builtin) (c, t) -> t != null && list.stream() + .anyMatch(clazz -> clazz.isInstance(t.getMetaTileEntity()))); + } + + public HatchElementBuilder hatchId(int aId) { + return hatchItemFilter( + c -> is -> GTUtility.isStackValid(is) && is.getItem() instanceof ItemMachines && is.getItemDamage() == aId) + .cacheHint(() -> "of id " + aId) + .shouldSkip( + (BiPredicate & Builtin) (c, t) -> t != null + && t.getMetaTileID() == aId); + } + + public HatchElementBuilder hatchIds(int... aIds) { + if (aIds == null || aIds.length == 0) throw new IllegalArgumentException(); + if (aIds.length == 1) return hatchId(aIds[0]); + TIntCollection coll = aIds.length < 16 ? new TIntArrayList(aIds) : new TIntHashSet(aIds); + return hatchItemFilter( + c -> is -> GTUtility.isStackValid(is) && is.getItem() instanceof ItemMachines + && coll.contains(is.getItemDamage())).cacheHint( + () -> Arrays.stream(coll.toArray()) + .sorted() + .mapToObj(String::valueOf) + .collect(Collectors.joining(" or ", "of id ", ""))) + .shouldSkip( + (BiPredicate & Builtin) (c, t) -> t != null + && coll.contains(t.getMetaTileID())); + } + + // endregion + + @SuppressWarnings("unchecked") + @SafeVarargs + public final IStructureElementChain buildAndChain(IStructureElement... elements) { + // just in case + mExclusive = false; + List> l = new ArrayList<>(); + l.add(build()); + l.addAll(Arrays.asList(elements)); + IStructureElement[] array = l.toArray(new IStructureElement[0]); + return () -> array; + } + + public final IStructureElementChain buildAndChain(Block block, int meta) { + return buildAndChain(ofBlock(block, meta)); + } + + public IStructureElement build() { + if (mAdder == null || mCasingIndex == -1 || mDot == -1) { + throw new IllegalArgumentException(); + } + if (mHatchItemFilter == null) { + // no item filter -> no placement + return new IStructureElementNoPlacement<>() { + + @Override + public boolean check(T t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IGregTechTileEntity + && mAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) mCasingIndex); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), mDot - 1); + return true; + } + }; + } + return new IStructureElement<>() { + + private String mHint = mHatchItemType == null ? "unspecified GT hatch" : mHatchItemType.get(); + + @Override + public boolean check(T t, World world, int x, int y, int z) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IGregTechTileEntity + && mAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) mCasingIndex); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), mDot - 1); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int i, int i1, int i2, ItemStack itemStack) { + // TODO + return false; + } + + private String getHint() { + if (mHint != null) return mHint; + String tHint = mHatchItemType.get(); + if (tHint == null) return "?"; + // TODO move this to some .lang instead of half ass it into the crappy gt lang file + tHint = GTLanguageManager.addStringLocalization("Hatch_Type_" + tHint.replace(' ', '_'), tHint); + if (mCacheHint) { + mHint = tHint; + if (mHint != null) + // yeet the getter, since its product is retrieved and cached + mHatchItemType = null; + } + return tHint; + } + + @Override + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + return BlocksToPlace.create(mHatchItemFilter.apply(t, trigger)); + } + + @Deprecated + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { + return survivalPlaceBlock( + t, + world, + x, + y, + z, + trigger, + AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + if (mShouldSkip != null) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IGregTechTileEntity + && mShouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return PlaceResult.SKIP; + } + if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) + return PlaceResult.REJECT; + if (mReject != null && mReject.test(t)) return PlaceResult.REJECT; + if (ChannelDataAccessor.hasSubChannel(trigger, "gt_no_hatch") && !mExclusive) { + String type = getHint(); + env.getChatter() + .accept(new ChatComponentTranslation("GT5U.autoplace.error.no_hatch", type)); + return PlaceResult.REJECT; + } + ItemStack taken = env.getSource() + .takeOne(mHatchItemFilter.apply(t, trigger), true); + if (GTUtility.isStackInvalid(taken)) { + String type = getHint(); + env.getChatter() + .accept(new ChatComponentTranslation("GT5U.autoplace.error.no_hatch", type)); + return PlaceResult.REJECT; + } + if (com.gtnewhorizon.structurelib.structure.StructureUtility.survivalPlaceBlock( + taken, + ItemStackPredicate.NBTMode.IGNORE, + null, + true, + world, + x, + y, + z, + env.getSource(), + env.getActor()) != PlaceResult.ACCEPT) { + return PlaceResult.REJECT; + } + // try to infer facing + EnumSet allowed = EnumSet.noneOf(ForgeDirection.class); + // first find which face of block is not contained in structure + if (env.getAPILevel() == AutoPlaceEnvironment.APILevel.Legacy) { + // a legacy decorator isn't passing down necessary information + // in that case, we just assume all facing is allowed + allowed.addAll(Arrays.asList(ForgeDirection.VALID_DIRECTIONS)); + } else { + for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { + // as noted on getWorldDirection Y axis should be flipped before use + if (env.isContainedInPiece(direction.offsetX, -direction.offsetY, direction.offsetZ)) continue; + // explicitly rejected, probably obstructed by another slice + if (mDisallowedDirection.contains(direction)) continue; + ForgeDirection rotated = env.getFacing() + .getWorldDirection( + (direction.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) != 0 + ? direction.getOpposite() + : direction); + allowed.add(rotated); + } + } + if (!allowed.isEmpty()) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IGregTechTileEntity) { + ForgeDirection result = null; + // find the first facing available, but prefer a facing that isn't up/down + for (ForgeDirection facing : allowed) { + result = facing; + if ((facing.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) == 0) break; // Horizontal + } + assert result != null; + ((IGregTechTileEntity) tileEntity).setFrontFacing(result); + } + } + return mNoStop ? PlaceResult.ACCEPT : PlaceResult.ACCEPT_STOP; + } + }; + } +} diff --git a/src/main/java/gregtech/api/util/IGTHatchAdder.java b/src/main/java/gregtech/api/util/IGTHatchAdder.java new file mode 100644 index 0000000000..35a30ad7de --- /dev/null +++ b/src/main/java/gregtech/api/util/IGTHatchAdder.java @@ -0,0 +1,28 @@ +package gregtech.api.util; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public interface IGTHatchAdder { + + /** + * Callback to add hatch, needs to check if hatch is valid (and add it) + * + * @param iGregTechTileEntity hatch + * @param aShort requested texture index, or null if not... + * @return managed to add hatch (structure still valid) + */ + boolean apply(T t, IGregTechTileEntity iGregTechTileEntity, Short aShort); + + /** + * hack to work around java generic issues. + */ + @SuppressWarnings("unchecked") + default IGTHatchAdder rebrand() { + return (IGTHatchAdder) this; + } + + default IGTHatchAdder orElse(IGTHatchAdder fallback) { + return (t, iGregTechTileEntity, aShort) -> IGTHatchAdder.this.apply(t, iGregTechTileEntity, aShort) + || fallback.apply(t, iGregTechTileEntity, aShort); + } +} diff --git a/src/main/java/gregtech/api/util/IGT_HatchAdder.java b/src/main/java/gregtech/api/util/IGT_HatchAdder.java deleted file mode 100644 index 21796f172e..0000000000 --- a/src/main/java/gregtech/api/util/IGT_HatchAdder.java +++ /dev/null @@ -1,28 +0,0 @@ -package gregtech.api.util; - -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; - -public interface IGT_HatchAdder { - - /** - * Callback to add hatch, needs to check if hatch is valid (and add it) - * - * @param iGregTechTileEntity hatch - * @param aShort requested texture index, or null if not... - * @return managed to add hatch (structure still valid) - */ - boolean apply(T t, IGregTechTileEntity iGregTechTileEntity, Short aShort); - - /** - * hack to work around java generic issues. - */ - @SuppressWarnings("unchecked") - default IGT_HatchAdder rebrand() { - return (IGT_HatchAdder) this; - } - - default IGT_HatchAdder orElse(IGT_HatchAdder fallback) { - return (t, iGregTechTileEntity, aShort) -> IGT_HatchAdder.this.apply(t, iGregTechTileEntity, aShort) - || fallback.apply(t, iGregTechTileEntity, aShort); - } -} diff --git a/src/main/java/gregtech/api/util/JubilanceMegaApiary.java b/src/main/java/gregtech/api/util/JubilanceMegaApiary.java new file mode 100644 index 0000000000..e24cad6778 --- /dev/null +++ b/src/main/java/gregtech/api/util/JubilanceMegaApiary.java @@ -0,0 +1,23 @@ +package gregtech.api.util; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IJubilanceProvider; + +public class JubilanceMegaApiary implements IJubilanceProvider { + + public static final JubilanceMegaApiary instance = new JubilanceMegaApiary(); + + protected JubilanceMegaApiary() {} + + @Override + public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { + return false; + } + + @Override + public String getDescription() { + return "Will only be produced in mega Apiary"; + } +} diff --git a/src/main/java/gregtech/api/util/MultiblockTooltipBuilder.java b/src/main/java/gregtech/api/util/MultiblockTooltipBuilder.java new file mode 100644 index 0000000000..e51f3a0524 --- /dev/null +++ b/src/main/java/gregtech/api/util/MultiblockTooltipBuilder.java @@ -0,0 +1,735 @@ +package gregtech.api.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; + +import com.google.common.collect.Multimaps; +import com.google.common.collect.SetMultimap; +import com.gtnewhorizon.structurelib.StructureLibAPI; + +/** + * This makes it easier to build multi tooltips, with a standardized format.
+ * Info section order should be:
+ * addMachineType
+ * addInfo, for what it does, special notes, etc.
+ * addSeparator, if you need it
+ * addPollutionAmount
+ *
+ * Structure order should be:
+ * beginStructureBlock
+ * addController
+ * addCasingInfo
+ * addOtherStructurePart, for secondary structure block info (pipes, coils, etc)
+ * addEnergyHatch/addDynamoHatch
+ * addMaintenanceHatch
+ * addMufflerHatch
+ * addInputBus/addInputHatch/addOutputBus/addOutputHatch, in that order
+ * Use addStructureInfo for any comments on nonstandard structure info wherever needed
+ * toolTipFinisher goes at the very end
+ *
+ * Originally created by kekzdealer + */ +public class MultiblockTooltipBuilder { + + private static final String TAB = " "; + private static final String COLON = ": "; + private static final String SEPARATOR = ", "; + + private final List iLines; + private final List sLines; + private final List hLines; + private final SetMultimap hBlocks; + + private String[] iArray; + private String[] sArray; + private String[] hArray; + + // Localized tooltips + private static final String TT_machineType = StatCollector.translateToLocal("GT5U.MBTT.MachineType"); + private static final String TT_dimensions = StatCollector.translateToLocal("GT5U.MBTT.Dimensions"); + private static final String TT_hollow = StatCollector.translateToLocal("GT5U.MBTT.Hollow"); + private static final String TT_structure = StatCollector.translateToLocal("GT5U.MBTT.Structure"); + private static final String TT_controller = StatCollector.translateToLocal("GT5U.MBTT.Controller"); + private static final String TT_minimum = StatCollector.translateToLocal("GT5U.MBTT.Minimum"); + private static final String TT_tiered = StatCollector.translateToLocal("GT5U.MBTT.Tiered"); + private static final String TT_maintenancehatch = StatCollector.translateToLocal("GT5U.MBTT.MaintenanceHatch"); + private static final String TT_energyhatch = StatCollector.translateToLocal("GT5U.MBTT.EnergyHatch"); + private static final String TT_dynamohatch = StatCollector.translateToLocal("GT5U.MBTT.DynamoHatch"); + private static final String TT_mufflerhatch = StatCollector.translateToLocal("GT5U.MBTT.MufflerHatch"); + private static final String TT_inputbus = StatCollector.translateToLocal("GT5U.MBTT.InputBus"); + private static final String TT_inputhatch = StatCollector.translateToLocal("GT5U.MBTT.InputHatch"); + private static final String TT_outputbus = StatCollector.translateToLocal("GT5U.MBTT.OutputBus"); + private static final String TT_outputhatch = StatCollector.translateToLocal("GT5U.MBTT.OutputHatch"); + private static final String TT_causes = StatCollector.translateToLocal("GT5U.MBTT.Causes"); + private static final String TT_pps = StatCollector.translateToLocal("GT5U.MBTT.PPS"); + private static final String TT_hold = StatCollector.translateToLocal("GT5U.MBTT.Hold"); + private static final String TT_todisplay = StatCollector.translateToLocal("GT5U.MBTT.Display"); + private static final String TT_structurehint = StatCollector.translateToLocal("GT5U.MBTT.StructureHint"); + private static final String TT_mod = StatCollector.translateToLocal("GT5U.MBTT.Mod"); + private static final String TT_air = StatCollector.translateToLocal("GT5U.MBTT.Air"); + private static final String[] TT_dots = IntStream.range(0, 16) + .mapToObj(i -> StatCollector.translateToLocal("structurelib.blockhint." + i + ".name")) + .toArray(String[]::new); + + public MultiblockTooltipBuilder() { + iLines = new LinkedList<>(); + sLines = new LinkedList<>(); + hLines = new LinkedList<>(); + hBlocks = Multimaps.newSetMultimap(new HashMap<>(), HashSet::new); + hBlocks.put(StructureLibAPI.HINT_BLOCK_META_AIR, TT_air); + } + + /** + * Add a line telling you what the machine type is. Usually, this will be the name of a SB version.
+ * Machine Type: machine + * + * @param machine Name of the machine type + * + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addMachineType(String machine) { + iLines.add(TT_machineType + COLON + EnumChatFormatting.YELLOW + machine + EnumChatFormatting.RESET); + return this; + } + + /** + * Add a basic line of information about this structure + * + * @param info The line to be added. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addInfo(String info) { + iLines.add(info); + return this; + } + + /** + * Add a number of basic lines of information about this structure + * + * @param infoStrings The lines to be added. + * @return Instance this method was called on. + */ + + public MultiblockTooltipBuilder addInfoAll(String... infoStrings) { + for (String str : infoStrings) { + iLines.add(str); + } + return this; + } + + /** + * Add a separator line like this:
+ * ----------------------------------------- + * + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addSeparator() { + iLines.add("-----------------------------------------"); + return this; + } + + /** + * Add a line telling how much this machine pollutes. + * + * @param pollution Amount of pollution per second when active + * + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addPollutionAmount(int pollution) { + iLines.add( + TT_causes + COLON + EnumChatFormatting.DARK_PURPLE + pollution + " " + EnumChatFormatting.GRAY + TT_pps); + return this; + } + + /** + * Begin adding structural information by adding a line about the structure's dimensions and then inserting a + * "Structure:" line. + * + * @param w Structure width. + * @param h Structure height. + * @param l Structure depth/length. + * @param hollow T/F, adds a (hollow) comment if true + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder beginStructureBlock(int w, int h, int l, boolean hollow) { + sLines.add( + EnumChatFormatting.WHITE + TT_dimensions + + COLON + + EnumChatFormatting.GOLD + + w + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + h + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + l + + EnumChatFormatting.GRAY + + " (" + + EnumChatFormatting.GOLD + + "W" + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + "H" + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + "L" + + EnumChatFormatting.GRAY + + ") " + + EnumChatFormatting.RED + + (hollow ? EnumChatFormatting.RED + TT_hollow : "")); + sLines.add(EnumChatFormatting.WHITE + TT_structure + COLON); + return this; + } + + /** + * Begin adding structural information by adding a line about the structure's dimensions
+ * and then inserting a "Structure:" line. Variable version displays min and max + * + * @param wmin Structure min width. + * @param wmax Structure max width. + * @param hmin Structure min height. + * @param hmax Structure max height. + * @param lmin Structure min depth/length. + * @param lmax Structure max depth/length. + * @param hollow T/F, adds a (hollow) comment if true + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder beginVariableStructureBlock(int wmin, int wmax, int hmin, int hmax, int lmin, + int lmax, boolean hollow) { + sLines.add( + EnumChatFormatting.WHITE + TT_dimensions + + COLON + + EnumChatFormatting.GOLD + + wmin + + (wmin != wmax ? "-" + wmax : "") + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + hmin + + (hmin != hmax ? "-" + hmax : "") + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + lmin + + (lmin != lmax ? "-" + lmax : "") + + EnumChatFormatting.GRAY + + " (" + + EnumChatFormatting.GOLD + + "W" + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + "H" + + EnumChatFormatting.GRAY + + "x" + + EnumChatFormatting.GOLD + + "L" + + EnumChatFormatting.GRAY + + ") " + + (hollow ? EnumChatFormatting.RED + TT_hollow : "")); + sLines.add(EnumChatFormatting.WHITE + TT_structure + COLON); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Controller: info + * + * @param info Positional information. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addController(String info) { + sLines.add(TAB + EnumChatFormatting.WHITE + TT_controller + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)minCountx casingName (minimum) (tiered) + * + * @param casingName Name of the Casing. + * @param minCount Minimum needed for valid structure check. + * @return Instance this method was called on. + * + * @deprecated Replaced by {@link #addCasingInfoMin(String, int, boolean)} + * + */ + @Deprecated + public MultiblockTooltipBuilder addCasingInfo(String casingName, int minCount) { + return addCasingInfoMin(casingName, minCount, false); + } + + /** + * Add a line of information about the structure:
+ * (indent)countx casingName (tiered) + * + * @param casingName Name of the Casing. + * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addCasingInfoExactly(String casingName, int count, boolean isTiered) { + return addCasingInfoExactlyColored( + casingName, + EnumChatFormatting.GRAY, + count, + EnumChatFormatting.GOLD, + isTiered); + } + + /** + * Add a line of information about the structure:
+ * (indent)countx casingName (tiered) + * + * @param casingName Name of the Casing. + * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) + * @param countColor Color of the casing count text + * @param textColor Color of the casing name text + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addCasingInfoExactlyColored(String casingName, EnumChatFormatting textColor, + int count, EnumChatFormatting countColor, boolean isTiered) { + sLines.add( + countColor + TAB + + count + + "x " + + EnumChatFormatting.RESET + + textColor + + casingName + + (isTiered ? " " + TT_tiered : "")); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)minCountx casingName (minimum) (tiered) + * + * @param casingName Name of the Casing. + * @param minCount Minimum needed for valid structure check. + * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addCasingInfoMin(String casingName, int minCount, boolean isTiered) { + return addCasingInfoMinColored( + casingName, + EnumChatFormatting.GRAY, + minCount, + EnumChatFormatting.GOLD, + isTiered); + } + + /** + * Add a line of information about the structure:
+ * (indent)minCountx casingName (minimum) (tiered) + * + * @param casingName Name of the Casing. + * @param minCount Minimum needed for valid structure check. + * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) + * @param countColor Color of the casing count text + * @param textColor Color of the casing name text + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addCasingInfoMinColored(String casingName, EnumChatFormatting textColor, + int minCount, EnumChatFormatting countColor, boolean isTiered) { + sLines.add( + countColor + TAB + + minCount + + "x " + + EnumChatFormatting.RESET + + textColor + + casingName + + " " + + TT_minimum + + (isTiered ? " " + TT_tiered : "")); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)minCountx - maxCountx casingName (minimum) (tiered) + * + * @param casingName Name of the Casing. + * @param minCount Minimum needed for valid structure check. + * @param maxCount Maximum needed for valid structure check. + * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addCasingInfoRange(String casingName, int minCount, int maxCount, + boolean isTiered) { + return addCasingInfoRangeColored( + casingName, + EnumChatFormatting.GRAY, + minCount, + maxCount, + EnumChatFormatting.GOLD, + isTiered); + } + + /** + * Add a line of information about the structure:
+ * (indent)minCountx - maxCountx casingName (minimum) (tiered) + * + * @param casingName Name of the Casing. + * @param minCount Minimum needed for valid structure check. + * @param maxCount Maximum needed for valid structure check. + * @param isTiered Flag if this casing accepts multiple tiers (e.g. coils) + * @param countColor Color of the casing count text + * @param textColor Color of the casing name text + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addCasingInfoRangeColored(String casingName, EnumChatFormatting textColor, + int minCount, int maxCount, EnumChatFormatting countColor, boolean isTiered) { + sLines.add( + countColor + TAB + + minCount + + "x" + + EnumChatFormatting.GRAY + + " - " + + countColor + + maxCount + + "x " + + EnumChatFormatting.RESET + + textColor + + casingName + + (isTiered ? " " + TT_tiered : "")); + return this; + } + + /** + * Use this method to add a structural part that isn't covered by the other methods.
+ * (indent)name: info + * + * @param name Name of the hatch or other component. + * @param info Positional information. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addOtherStructurePart(String name, String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + name + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Maintenance Hatch: info + * + * @param info Positional information. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addMaintenanceHatch(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_maintenancehatch + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Muffler Hatch: info + * + * @param info Location where the hatch goes + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addMufflerHatch(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_mufflerhatch + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Energy Hatch: info + * + * @param info Positional information. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addEnergyHatch(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_energyhatch + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Dynamo Hatch: info + * + * @param info Positional information. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addDynamoHatch(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_dynamohatch + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Input Bus: info + * + * @param info Location where the bus goes + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addInputBus(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputbus + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Input Hatch: info + * + * @param info Location where the hatch goes + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addInputHatch(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputhatch + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Output Bus: info + * + * @param info Location where the bus goes + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addOutputBus(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputbus + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Output Hatch: info + * + * @param info Location where the bus goes + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addOutputHatch(String info) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputhatch + COLON + EnumChatFormatting.GRAY + info); + return this; + } + + /** + * Use this method to add a structural part that isn't covered by the other methods.
+ * (indent)name: info + * + * @param name Name of the hatch or other component. + * @param info Positional information. + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addOtherStructurePart(String name, String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + name + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, name); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Maintenance Hatch: info + * + * @param info Positional information. + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addMaintenanceHatch(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_maintenancehatch + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_maintenancehatch); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Muffler Hatch: info + * + * @param info Location where the hatch goes + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addMufflerHatch(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_mufflerhatch + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_mufflerhatch); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Energy Hatch: info + * + * @param info Positional information. + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addEnergyHatch(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_energyhatch + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_energyhatch); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Dynamo Hatch: info + * + * @param info Positional information. + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addDynamoHatch(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_dynamohatch + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_dynamohatch); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Input Bus: info + * + * @param info Location where the bus goes + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addInputBus(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputbus + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_inputbus); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Input Hatch: info + * + * @param info Location where the hatch goes + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addInputHatch(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_inputhatch + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_inputhatch); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Output Bus: info + * + * @param info Location where the bus goes + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addOutputBus(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputbus + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_outputbus); + return this; + } + + /** + * Add a line of information about the structure:
+ * (indent)Output Hatch: info + * + * @param info Location where the bus goes + * @param dots The valid locations for this part when asked to display hints + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addOutputHatch(String info, int... dots) { + sLines.add(EnumChatFormatting.WHITE + TAB + TT_outputhatch + COLON + EnumChatFormatting.GRAY + info); + for (int dot : dots) hBlocks.put(dot, TT_outputhatch); + return this; + } + + /** + * Use this method to add non-standard structural info.
+ * (indent)info + * + * @param info The line to be added. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addStructureInfo(String info) { + sLines.add(TAB + info); + return this; + } + + /** + * Use this method to add non-standard structural info.
+ * (indent)info + * + * @param channel the name of subchannel + * @param purpose the purpose of subchannel + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addSubChannelUsage(String channel, String purpose) { + sLines.add(TAB + StatCollector.translateToLocalFormatted("GT5U.MBTT.subchannel", channel, purpose)); + return this; + } + + /** + * Use this method to add non-standard structural hint. This info will appear before the standard structural hint. + * + * @param info The line to be added. This should be an entry into minecraft's localization system. + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addStructureHint(String info) { + hLines.add(StatCollector.translateToLocal(info)); + return this; + } + + /** + * Use this method to add an entry to standard structural hint without creating a corresponding line in structure + * information + * + * @param name The name of block This should be an entry into minecraft's localization system. + * @param dots Possible locations of this block + * @return Instance this method was called on. + */ + public MultiblockTooltipBuilder addStructureHint(String name, int... dots) { + for (int dot : dots) hBlocks.put(dot, StatCollector.translateToLocal(name)); + return this; + } + + /** + * Call at the very end.
+ * Adds a final line with the mod name and information on how to display the structure guidelines.
+ * Ends the building process. + * + * @param mod Name of the mod that adds this multiblock machine + */ + public MultiblockTooltipBuilder toolTipFinisher(String mod) { + iLines.add( + TT_hold + " " + + EnumChatFormatting.BOLD + + "[LSHIFT]" + + EnumChatFormatting.RESET + + EnumChatFormatting.GRAY + + " " + + TT_todisplay); + iLines.add(TT_mod + COLON + EnumChatFormatting.GREEN + mod + EnumChatFormatting.GRAY); + hLines.add(TT_structurehint); + iArray = iLines.toArray(new String[0]); + sArray = sLines.toArray(new String[0]); + // e.getKey() - 1 because 1 dot is meta 0. + hArray = Stream.concat( + hLines.stream(), + hBlocks.asMap() + .entrySet() + .stream() + .map(e -> TT_dots[e.getKey() - 1] + COLON + String.join(SEPARATOR, e.getValue()))) + .toArray(String[]::new); + return this; + } + + public String[] getInformation() { + return iArray; + } + + public String[] getStructureInformation() { + return sArray; + } + + public String[] getStructureHint() { + return hArray; + } +} diff --git a/src/main/java/gregtech/api/util/OutputHatchWrapper.java b/src/main/java/gregtech/api/util/OutputHatchWrapper.java index b2e74d24cf..55f467198a 100644 --- a/src/main/java/gregtech/api/util/OutputHatchWrapper.java +++ b/src/main/java/gregtech/api/util/OutputHatchWrapper.java @@ -8,17 +8,17 @@ import net.minecraftforge.fluids.FluidTankInfo; import org.jetbrains.annotations.NotNull; import gregtech.api.interfaces.fluid.IFluidStore; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Output; +import gregtech.api.metatileentity.implementations.MTEHatchOutput; /** * Wrapper for output hatch to allow multiblocks to apply specific filter. */ public class OutputHatchWrapper implements IFluidStore { - private final GT_MetaTileEntity_Hatch_Output outputHatch; + private final MTEHatchOutput outputHatch; private final Predicate filter; - public OutputHatchWrapper(GT_MetaTileEntity_Hatch_Output outputHatch, Predicate filter) { + public OutputHatchWrapper(MTEHatchOutput outputHatch, Predicate filter) { this.outputHatch = outputHatch; this.filter = filter; } diff --git a/src/main/java/gregtech/api/util/OverclockCalculator.java b/src/main/java/gregtech/api/util/OverclockCalculator.java new file mode 100644 index 0000000000..0b27942355 --- /dev/null +++ b/src/main/java/gregtech/api/util/OverclockCalculator.java @@ -0,0 +1,621 @@ +package gregtech.api.util; + +import java.util.function.Function; +import java.util.function.Supplier; + +import javax.annotation.Nonnull; + +public class OverclockCalculator { + + // region variables + // region basic properties + /** + * EUt the recipe originally runs at + */ + private long recipeEUt = 0; + /** + * Voltage of the machine + */ + private long machineVoltage = 0; + /** + * Amperage of the machine + */ + private long machineAmperage = 1; + /** + * Duration of the recipe + */ + private int duration = 0; + /** + * A supplier used for machines which have a custom way of calculating base duration, like Neutron Activator + */ + private Supplier durationUnderOneTickSupplier; + /** + * The parallel the machine has when trying to overclock + */ + private int parallel = 1; + // endregion + // region extra factors + /** + * Discount for EUt at the beginning of calculating overclocks, like GT++ machines + */ + private double eutDiscount = 1; + /** + * Speeding/Slowing up/down the duration of a recipe at the beginning of calculating overclocks, like GT++ machines + */ + private double speedBoost = 1; + // endregion + // region overclock parameters + /** + * How much the energy would be multiplied by per overclock available + */ + private double eutIncreasePerOC = 4; + /** + * A supplier used for machines which have a custom way of calculating energy increase multipliers for every + * overclock, like Advanced Assembling Line + */ + private Function eutIncreasePerOCSupplier = getDefaultEutIncreasePerOCSupplier(); + /** + * How much the duration would be divided by per overclock made that isn't an overclock from HEAT + */ + private double durationDecreasePerOC = 2; + /** + * A supplier used for machines which have a custom way of calculating duration decrease multipliers for every + * overclock + */ + private Function durationDecreasePerOCSupplier = getDefaultDurationDecreasePerOCSupplier(); + /** + * Whether at least one of {@link #eutIncreasePerOCSupplier} and {@link #durationDecreasePerOCSupplier} has been set + */ + private boolean hasAtLeastOneSupplierBeenSet; + /** + * Whether to give EUt Discount when the duration goes below one tick + */ + private boolean oneTickDiscount; + /** + * Whether the multi should use amperage to overclock normally. + */ + private boolean amperageOC; + /** + * If the OC calculator should only do a given amount of overclocks. Mainly used in fusion reactors + */ + private boolean limitOverclocks; + /** + * Maximum amount of overclocks to perform, when limitOverclocks = true + */ + private int maxOverclocks; + /** + * How many overclocks have been performed + */ + private int overclockCount; + /** + * Should we actually try to calculate overclocking + */ + private boolean noOverclock; + /** + * The parallel the machine actually used. + */ + private int currentParallel; + // endregion + // region heat overclock + /** + * The min heat required for the recipe + */ + private int recipeHeat = 0; + /** + * The heat the machine has when starting the recipe + */ + private int machineHeat = 0; + /** + * How much the duration should be divided by for each 1800K above recipe heat + */ + private double durationDecreasePerHeatOC = 4; + /** + * Whether to enable overclocking with heat like the EBF every 1800 heat difference + */ + private boolean heatOC; + /** + * Whether to enable heat discounts every 900 heat difference + */ + private boolean heatDiscount; + /** + * The value used for discount final eut per 900 heat + */ + private double heatDiscountExponent = 0.95; + // endregion + // region result + /** + * variable to check whether the overclocks have been calculated + */ + private boolean calculated; + /** + * The calculated duration result. + */ + private int calculatedDuration; + /** + * The calculated energy consumption result. + */ + private long calculatedConsumption; + // endregion + // region constants + private static final int HEAT_DISCOUNT_THRESHOLD = 900; + private static final int HEAT_PERFECT_OVERCLOCK_THRESHOLD = 1800; + private static final double LOG2 = Math.log(2); + // endregion + // endregion + + /** + * Creates calculator that doesn't do OC at all. Will use recipe duration. + */ + public static OverclockCalculator ofNoOverclock(@Nonnull GTRecipe recipe) { + return ofNoOverclock(recipe.mEUt, recipe.mDuration); + } + + /** + * Creates calculator that doesn't do OC at all, with set duration. + */ + public static OverclockCalculator ofNoOverclock(long eut, int duration) { + return new OverclockCalculator().setRecipeEUt(eut) + .setDuration(duration) + .setEUt(eut) + .setNoOverclock(true); + } + + /** + * An Overclock helper for calculating overclocks in many different situations + */ + public OverclockCalculator() {} + + // region setters + /** + * @param recipeEUt Sets the Recipe's starting voltage + */ + @Nonnull + public OverclockCalculator setRecipeEUt(long recipeEUt) { + this.recipeEUt = recipeEUt; + return this; + } + + /** + * @param machineVoltage Sets the EUt that the machine can use. This is the voltage of the machine + */ + @Nonnull + public OverclockCalculator setEUt(long machineVoltage) { + this.machineVoltage = machineVoltage; + return this; + } + + /** + * @param duration Sets the duration of the recipe + */ + @Nonnull + public OverclockCalculator setDuration(int duration) { + this.duration = duration; + return this; + } + + /** + * @param machineAmperage Sets the Amperage that the machine can support + */ + @Nonnull + public OverclockCalculator setAmperage(long machineAmperage) { + this.machineAmperage = machineAmperage; + return this; + } + + /** + * Enables Perfect OC in calculation + */ + @Nonnull + public OverclockCalculator enablePerfectOC() { + this.durationDecreasePerOC = 4; + return this; + } + + /** + * Set if we should be calculating overclocking using EBF's perfectOC + */ + @Nonnull + public OverclockCalculator setHeatOC(boolean heatOC) { + this.heatOC = heatOC; + return this; + } + + /** + * Sets if we should add a heat discount at the end of calculating an overclock, just like the EBF + */ + @Nonnull + public OverclockCalculator setHeatDiscount(boolean heatDiscount) { + this.heatDiscount = heatDiscount; + return this; + } + + /** + * Sets the starting heat of the recipe + */ + @Nonnull + public OverclockCalculator setRecipeHeat(int recipeHeat) { + this.recipeHeat = recipeHeat; + return this; + } + + /** + * Sets the heat of the coils on the machine + */ + @Nonnull + public OverclockCalculator setMachineHeat(int machineHeat) { + this.machineHeat = machineHeat; + return this; + } + + /** + * Sets an EUtDiscount. 0.9 is 10% less energy. 1.1 is 10% more energy + */ + @Nonnull + public OverclockCalculator setEUtDiscount(float aEUtDiscount) { + this.eutDiscount = aEUtDiscount; + return this; + } + + /** + * Sets a Speed Boost for the multiblock. 0.9 is 10% faster. 1.1 is 10% slower + */ + @Nonnull + public OverclockCalculator setSpeedBoost(float aSpeedBoost) { + this.speedBoost = aSpeedBoost; + return this; + } + + /** + * Sets the parallel that the multiblock uses + */ + @Nonnull + public OverclockCalculator setParallel(int aParallel) { + this.parallel = aParallel; + return this; + } + + /** + * Sets the heat discount during OC calculation if HeatOC is used. Default: 0.95 = 5% discount Used like a EU/t + * Discount + */ + @Nonnull + public OverclockCalculator setHeatDiscountMultiplier(float heatDiscountExponent) { + this.heatDiscountExponent = heatDiscountExponent; + return this; + } + + /** + * Sets the Overclock that should be calculated when a heat OC is applied. + */ + @Nonnull + public OverclockCalculator setHeatPerfectOC(double heatPerfectOC) { + if (heatPerfectOC <= 0) throw new IllegalArgumentException("Heat OC can't be a negative number or zero"); + this.durationDecreasePerHeatOC = heatPerfectOC; + return this; + } + + /** + * Sets the amount that the eut would be multiplied by per overclock. Do not set as 1(ONE) if the duration decrease + * is also 1(ONE)! + */ + @Nonnull + public OverclockCalculator setEUtIncreasePerOC(double eutIncreasePerOC) { + if (eutIncreasePerOC <= 0) + throw new IllegalArgumentException("EUt increase can't be a negative number or zero"); + this.eutIncreasePerOC = eutIncreasePerOC; + return this; + } + + /** + * Sets the amount that the duration would be divided by per overclock. Do not set as 1(ONE) if the eut increase is + * also 1(ONE)! + */ + @Nonnull + public OverclockCalculator setDurationDecreasePerOC(double durationDecreasePerOC) { + if (durationDecreasePerOC <= 0) + throw new IllegalArgumentException("Duration decrease can't be a negative number or zero"); + this.durationDecreasePerOC = durationDecreasePerOC; + return this; + } + + /** + * Set One Tick Discount on EUt based on Duration Decrease Per Overclock. This functions the same as single blocks. + */ + @Nonnull + public OverclockCalculator setOneTickDiscount(boolean oneTickDiscount) { + this.oneTickDiscount = oneTickDiscount; + return this; + } + + /** + * Limit the amount of overclocks that can be performed, regardless of how much power is available. Mainly used for + * fusion reactors. + */ + @Nonnull + public OverclockCalculator limitOverclockCount(int maxOverclocks) { + this.limitOverclocks = true; + this.maxOverclocks = maxOverclocks; + return this; + } + + @Nonnull + public OverclockCalculator setAmperageOC(boolean amperageOC) { + this.amperageOC = amperageOC; + return this; + } + + /** + * Set a supplier for calculating custom duration for when its needed under one tick + */ + @Nonnull + public OverclockCalculator setDurationUnderOneTickSupplier(Supplier supplier) { + this.durationUnderOneTickSupplier = supplier; + return this; + } + + /** + * Sets if we should do overclocking or not + */ + @Nonnull + public OverclockCalculator setNoOverclock(boolean noOverclock) { + this.noOverclock = noOverclock; + return this; + } + + /** + * Set a supplier for calculating custom EUt increase multipliers for every overclock + */ + public OverclockCalculator setEutIncreasePerOCSupplier(Function eutIncreasePerOCSupplier) { + this.eutIncreasePerOCSupplier = eutIncreasePerOCSupplier; + this.hasAtLeastOneSupplierBeenSet = true; + return this; + } + + /** + * Set a supplier for calculating custom duration decrease multipliers for every overclock + */ + public OverclockCalculator setDurationDecreasePerOCSupplier( + Function durationDecreasePerOCSupplier) { + this.durationDecreasePerOCSupplier = durationDecreasePerOCSupplier; + this.hasAtLeastOneSupplierBeenSet = true; + return this; + } + + /** + * Set actually performed parallel + */ + public OverclockCalculator setCurrentParallel(int currentParallel) { + this.currentParallel = currentParallel; + // Sets parallel to the actually performed one if machine's parallel is underused. + this.parallel = Math.min(parallel, currentParallel); + return this; + } + + // endregion + // region calculate + /** + * Call this when all values have been put it. + */ + @Nonnull + public OverclockCalculator calculate() { + if (calculated) { + throw new IllegalStateException("Tried to calculate overclocks twice"); + } + calculateOverclock(); + calculated = true; + return this; + } + + private void calculateOverclock() { + double durationInDouble = durationUnderOneTickSupplier != null ? durationUnderOneTickSupplier.get() + : duration * speedBoost; + calculatedConsumption = recipeEUt; + double heatDiscountMultiplier = calculateHeatDiscountMultiplier(); + // Usually a safeguard when currentParallel is not set: We assume parallel is fully used. + currentParallel = Math.max(currentParallel, parallel); + + if (noOverclock) { + calculatedConsumption = calculateFinalRecipeEUt(heatDiscountMultiplier); + calculatedDuration = (int) Math.ceil(durationInDouble); + return; + } + + // First we need to overclock to reach 1 tick. + // Then we need to overclock under one tick to get more extra parallels. + // We stop overclocking if we've already reached 1 tick and got enough parallels to actually perform. + double requiredUnderOneTickMultiplier = durationInDouble * currentParallel / parallel; + if (hasAtLeastOneSupplierBeenSet) { // custom overclock + double currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); + double currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); + double machinePower = calculateMachinePower(); + double currentConsumption = calculateRecipePower(heatDiscountMultiplier); + double currentUnderOneTickMultiplier = 1; + // Whether we have enough power for the next overclock; + // whether we need more overclock to reach 1 tick and get enough extra parallel; + // whether we have reached the overclock limit + while (machinePower > currentConsumption * currentEutIncrease + && requiredUnderOneTickMultiplier > currentUnderOneTickMultiplier + && (!limitOverclocks || overclockCount < maxOverclocks)) { + currentConsumption *= currentEutIncrease; + durationInDouble /= currentDurationDecrease; + overclockCount++; + currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); + currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); + } + calculatedConsumption = (long) Math.max(currentConsumption, 1); + calculatedDuration = (int) Math.max(durationInDouble, 1); + } else { // general overclock + double recipePowerTier = calculateRecipePowerTier(heatDiscountMultiplier); + double machinePowerTier = calculateMachinePowerTier(); + + int maxOverclockCount = calculateAmountOfOverclocks(machinePowerTier, recipePowerTier); + if (limitOverclocks) maxOverclockCount = Math.min(maxOverclocks, maxOverclockCount); + if (!amperageOC) { + // Limit overclocks by voltage tier. + maxOverclockCount = Math.min(maxOverclockCount, calculateRecipeToMachineVoltageDifference()); + } + overclockCount = calculateAmountOfNeededOverclocks(maxOverclockCount, requiredUnderOneTickMultiplier); + + // If triggered, it indicates that recipe power > machine power. + // Not just a safeguard. This also means that you can run a 1.2A recipe on a single hatch for a regular gt + // multi. + // This is intended, including the fact that you don't get an OC with a one tier upgrade in that case. + overclockCount = Math.max(overclockCount, 0); + + int heatOverclockCount = Math.min(calculateMaxAmountOfHeatOverclocks(), overclockCount); + calculatedConsumption = (long) Math.floor(recipeEUt * Math.pow(eutIncreasePerOC, overclockCount)); + durationInDouble /= Math.pow(durationDecreasePerHeatOC, heatOverclockCount) + * Math.pow(durationDecreasePerOC, overclockCount - heatOverclockCount); + if (oneTickDiscount) { + calculatedConsumption = (long) Math + .floor(calculatedConsumption / Math.pow(durationDecreasePerOC, maxOverclockCount - overclockCount)); + calculatedConsumption = Math.max(calculatedConsumption, 1); + } + calculatedConsumption = calculateFinalRecipeEUt(heatDiscountMultiplier); + calculatedDuration = (int) Math.max(durationInDouble, 1); + } + } + + private double calculateRecipePower(double heatDiscountMultiplier) { + return recipeEUt * parallel * eutDiscount * heatDiscountMultiplier; + } + + private double calculateRecipePowerTier(double heatDiscountMultiplier) { + return calculatePowerTier(calculateRecipePower(heatDiscountMultiplier)); + } + + private double calculateMachinePower() { + return machineVoltage * (amperageOC ? machineAmperage : Math.min(machineAmperage, parallel)); + } + + private double calculateMachinePowerTier() { + return calculatePowerTier(calculateMachinePower()); + } + + private int calculateRecipeToMachineVoltageDifference() { + return (int) (Math.ceil(calculatePowerTier(machineVoltage)) - Math.ceil(calculatePowerTier(recipeEUt))); + } + + private double calculatePowerTier(double voltage) { + return 1 + Math.max(0, (Math.log(voltage) / LOG2) - 5) / 2; + } + + private long calculateFinalRecipeEUt(double heatDiscountMultiplier) { + return (long) Math.ceil(calculatedConsumption * eutDiscount * heatDiscountMultiplier * parallel); + } + + private int calculateMaxAmountOfHeatOverclocks() { + return heatOC ? (machineHeat - recipeHeat) / HEAT_PERFECT_OVERCLOCK_THRESHOLD : 0; + } + + /** + * Calculate maximum possible overclocks ignoring if we are going to go under 1 tick + */ + private int calculateAmountOfOverclocks(double machinePowerTier, double recipePowerTier) { + return (int) (machinePowerTier - recipePowerTier); + } + + private int calculateAmountOfNeededOverclocks(int maxOverclockCount, double requiredUnderOneTickMultiplier) { + int neededHeatOC = (int) Math.min( + calculateMaxAmountOfHeatOverclocks(), + Math.ceil(Math.log(requiredUnderOneTickMultiplier) / Math.log(durationDecreasePerHeatOC))); + neededHeatOC = Math.max(neededHeatOC, 0); + int neededNormalOC = (int) Math.ceil( + (Math.log(requiredUnderOneTickMultiplier) - Math.log(durationDecreasePerHeatOC) * neededHeatOC) + / Math.log(durationDecreasePerOC)); + neededNormalOC = Math.max(neededNormalOC, 0); + return Math.min(maxOverclockCount, neededHeatOC + neededNormalOC); + } + + private double calculateHeatDiscountMultiplier() { + int heatDiscounts = heatDiscount ? (machineHeat - recipeHeat) / HEAT_DISCOUNT_THRESHOLD : 0; + return Math.pow(heatDiscountExponent, heatDiscounts); + } + + // endregion + // region result getters + /** + * @return The consumption after overclock has been calculated + */ + public long getConsumption() { + if (!calculated) { + throw new IllegalStateException("Tried to get consumption before calculating"); + } + return calculatedConsumption; + } + + /** + * @return The duration of the recipe after overclock has been calculated + */ + public int getDuration() { + if (!calculated) { + throw new IllegalStateException("Tried to get duration before calculating"); + } + return calculatedDuration; + } + + /** + * @return Number of performed overclocks + */ + public int getPerformedOverclocks() { + if (!calculated) { + throw new IllegalStateException("Tried to get performed overclocks before calculating"); + } + return overclockCount; + } + + /** + * @return Whether the calculation has happened + */ + public boolean getCalculationStatus() { + return calculated; + } + + // endregion + // region misc + /** + * Returns duration as a double to show how much it is overclocking too much to determine extra parallel. This + * doesn't count as calculating + */ + public double calculateDurationUnderOneTick() { + double durationInDouble = durationUnderOneTickSupplier != null ? durationUnderOneTickSupplier.get() + : duration * speedBoost; + if (noOverclock) return durationInDouble; + double heatDiscountMultiplier = calculateHeatDiscountMultiplier(); + if (hasAtLeastOneSupplierBeenSet) { + int overclockCount = 0; + double currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); + double currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); + double machinePower = calculateMachinePower(); + double recipePower = calculateRecipePower(heatDiscountMultiplier); + while (machinePower > recipePower * currentEutIncrease + && (!limitOverclocks || overclockCount < maxOverclocks)) { + recipePower *= currentEutIncrease; + durationInDouble /= currentDurationDecrease; + overclockCount++; + currentEutIncrease = eutIncreasePerOCSupplier.apply(overclockCount + 1); + currentDurationDecrease = durationDecreasePerOCSupplier.apply(overclockCount + 1); + } + } else { + int maxOverclockCount = calculateAmountOfOverclocks( + calculateMachinePowerTier(), + calculateRecipePowerTier(heatDiscountMultiplier)); + if (limitOverclocks) maxOverclockCount = Math.min(maxOverclocks, maxOverclockCount); + int heatOverclocks = Math.min(calculateMaxAmountOfHeatOverclocks(), maxOverclockCount); + durationInDouble /= Math.pow(durationDecreasePerOC, maxOverclockCount - heatOverclocks) + * Math.pow(durationDecreasePerHeatOC, heatOverclocks); + } + return durationInDouble; + } + + private Function getDefaultEutIncreasePerOCSupplier() { + return overclockCount -> eutIncreasePerOC; + } + + private Function getDefaultDurationDecreasePerOCSupplier() { + return overclockCount -> overclockCount <= calculateMaxAmountOfHeatOverclocks() ? durationDecreasePerHeatOC + : durationDecreasePerOC; + } + + // endregion +} diff --git a/src/main/java/gregtech/api/util/PCBFactoryManager.java b/src/main/java/gregtech/api/util/PCBFactoryManager.java new file mode 100644 index 0000000000..2d3efa29d4 --- /dev/null +++ b/src/main/java/gregtech/api/util/PCBFactoryManager.java @@ -0,0 +1,25 @@ +package gregtech.api.util; + +import com.google.common.collect.HashBiMap; + +import gregtech.api.enums.Materials; + +public class PCBFactoryManager { + + private static final HashBiMap mPlasticTiers = HashBiMap.create(); + public static int mTiersOfPlastics = 0; + + public static void addPlasticTier(Materials aMaterial, int aTier) { + mPlasticTiers.put(aMaterial, aTier); + mTiersOfPlastics++; + } + + public static int getPlasticTier(Materials aMaterial) { + return mPlasticTiers.get(aMaterial); + } + + public static Materials getPlasticMaterialFromTier(int aTier) { + return mPlasticTiers.inverse() + .get(aTier); + } +} diff --git a/src/main/java/gregtech/api/util/ParallelHelper.java b/src/main/java/gregtech/api/util/ParallelHelper.java new file mode 100644 index 0000000000..0c995cba7d --- /dev/null +++ b/src/main/java/gregtech/api/util/ParallelHelper.java @@ -0,0 +1,713 @@ +package gregtech.api.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Objects; +import java.util.Random; +import java.util.function.Function; + +import javax.annotation.Nonnull; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.interfaces.tileentity.IRecipeLockable; +import gregtech.api.interfaces.tileentity.IVoidable; +import gregtech.api.logic.FluidInventoryLogic; +import gregtech.api.logic.ItemInventoryLogic; +import gregtech.api.objects.XSTR; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SingleRecipeCheck; + +@SuppressWarnings({ "unused", "UnusedReturnValue" }) +public class ParallelHelper { + + private static final double MAX_BATCH_MODE_TICK_TIME = 128; + /** + * Machine used for calculation + */ + private IVoidable machine; + /** + * Machine used for single recipe locking calculation + */ + private IRecipeLockable singleRecipeMachine; + /** + * Is locked to a single recipe? + */ + private boolean isRecipeLocked; + /** + * Recipe used when trying to calculate parallels + */ + private GTRecipe recipe; + /** + * EUt available to the multiblock (This should be the total eut available) + */ + private long availableEUt; + /** + * The current parallel possible for the multiblock + */ + private int currentParallel = 0; + /** + * The maximum possible parallel possible for the multiblock + */ + private int maxParallel = 1; + /** + * The Batch Modifier applied when batch mode is enabled. 1 does nothing. 2 doubles max possible + * parallel, but also duration + */ + private int batchModifier = 1; + /** + * The inputs of the multiblock for the current recipe check + */ + private ItemStack[] itemInputs; + /** + * The inputs of the machine for current recipe check + */ + private ItemInventoryLogic itemInputInventory; + /** + * The output item inventory of the machine + */ + private ItemInventoryLogic itemOutputInventory; + /** + * The outputs of the recipe with the applied parallel + */ + private ItemStack[] itemOutputs; + /** + * The inputs of the multiblock for the current recipe check + */ + private FluidStack[] fluidInputs; + /** + * The inputs of the machine for the current recipe check + */ + private FluidInventoryLogic fluidInputInventory; + /** + * The output fluid inventory of the machine; + */ + private FluidInventoryLogic fluidOutputInventory; + /** + * The outputs of the recipe with the applied parallel + */ + private FluidStack[] fluidOutputs; + /** + * Does the multi have void protection enabled for items + */ + private boolean protectExcessItem; + /** + * Does the multi have void protection enabled for fluids + */ + private boolean protectExcessFluid; + /** + * Should the Parallel Helper automatically consume for the multi + */ + private boolean consume; + /** + * Is batch mode turned on? + */ + private boolean batchMode; + /** + * Should the Parallel Helper automatically calculate the outputs of the recipe with current parallel? + */ + private boolean calculateOutputs; + /** + * Has the Parallel Helper been built? + */ + private boolean built; + /** + * What is the duration multiplier with batch mode enabled + */ + private double durationMultiplier; + /** + * Modifier which is applied on the recipe eut. Useful for GT++ machines + */ + private float eutModifier = 1; + /** + * Multiplier that is applied on the output chances + */ + private double chanceMultiplier = 1; + /** + * Multiplier by which the output will be multiplied + */ + private int outputMultiplier = 1; + /** + * Method for calculating max parallel from given inputs. + */ + private MaxParallelCalculator maxParallelCalculator = GTRecipe::maxParallelCalculatedByInputs; + /** + * Method for consuming inputs after determining how many parallels it can execute. + */ + private InputConsumer inputConsumer = GTRecipe::consumeInput; + + /** + * Calculator to use for overclocking + */ + private OverclockCalculator calculator; + @Nonnull + private CheckRecipeResult result = CheckRecipeResultRegistry.NONE; + + private Function customItemOutputCalculation; + + private Function customFluidOutputCalculation; + + /** + * MuTE Mode this is a mode for changing how the GT_ParallelHelper works as Mutes don't use ItemStack and FluidStack + * arrays for inputs + */ + private boolean muteMode = false; + + public ParallelHelper() {} + + /** + * Sets machine, with current configuration for void protection mode. + */ + @Nonnull + public ParallelHelper setMachine(IVoidable machine) { + return setMachine(machine, machine.protectsExcessItem(), machine.protectsExcessFluid()); + } + + /** + * Sets machine, with void protection mode forcibly. + */ + @Nonnull + public ParallelHelper setMachine(IVoidable machine, boolean protectExcessItem, boolean protectExcessFluid) { + this.protectExcessItem = protectExcessItem; + this.protectExcessFluid = protectExcessFluid; + this.machine = machine; + return this; + } + + /** + * Sets the recipe, which will be used for the parallel calculation + */ + @Nonnull + public ParallelHelper setRecipe(@Nonnull GTRecipe aRecipe) { + recipe = Objects.requireNonNull(aRecipe); + return this; + } + + @Nonnull + public ParallelHelper setRecipeLocked(IRecipeLockable singleRecipeMachine, boolean isRecipeLocked) { + this.singleRecipeMachine = singleRecipeMachine; + this.isRecipeLocked = isRecipeLocked; + return this; + } + + /** + * Sets the items available for the recipe check + */ + @Nonnull + public ParallelHelper setItemInputs(ItemStack... aItemInputs) { + this.itemInputs = aItemInputs; + return this; + } + + /** + * Sets the fluid inputs available for the recipe check + */ + @Nonnull + public ParallelHelper setFluidInputs(FluidStack... aFluidInputs) { + this.fluidInputs = aFluidInputs; + return this; + } + + /** + * Sets the available eut when trying for more parallels + */ + @Nonnull + public ParallelHelper setAvailableEUt(long aAvailableEUt) { + this.availableEUt = aAvailableEUt; + return this; + } + + /** + * Sets the modifier for recipe eut. 1 does nothing 0.9 is 10% less. 1.1 is 10% more + */ + @Nonnull + public ParallelHelper setEUtModifier(float aEUtModifier) { + this.eutModifier = aEUtModifier; + return this; + } + + /** + * Sets the multiplier that is applied on output chances. 1 does nothing. 0.9 is 10% less. 1.1 is 10% more. + * Only useful for item outputs for sure. + */ + @Nonnull + public ParallelHelper setChanceMultiplier(double chanceMultiplier) { + this.chanceMultiplier = chanceMultiplier; + return this; + } + + /** + * Sets the item/fluid output multiplier. 1 does nothing. 2 doubles the item and fluid outputs. + */ + @Nonnull + public ParallelHelper setOutputMultiplier(int outputMultiplier) { + this.outputMultiplier = outputMultiplier; + return this; + } + + @Nonnull + public ParallelHelper setCalculator(OverclockCalculator calculator) { + this.calculator = calculator; + return this; + } + + /** + * Set if we should consume inputs or not when trying for parallels + * + * @param consume Should we consume inputs + */ + @Nonnull + public ParallelHelper setConsumption(boolean consume) { + this.consume = consume; + return this; + } + + /** + * Sets the MaxParallel a multi can handle + */ + @Nonnull + public ParallelHelper setMaxParallel(int maxParallel) { + this.maxParallel = maxParallel; + return this; + } + + /** + * Enables Batch mode. Can do up to an additional processed recipes of mCurrentParallel * mBatchModifier A batch + * modifier of 1 does nothing + */ + @Nonnull + public ParallelHelper enableBatchMode(int batchModifier) { + this.batchMode = batchModifier > 1; + this.batchModifier = batchModifier; + return this; + } + + /** + * Sets if we should calculate outputs with the parallels we found or not + * + * @param calculateOutputs Should we calculate outputs with the helper or not + */ + @Nonnull + public ParallelHelper setOutputCalculation(boolean calculateOutputs) { + this.calculateOutputs = calculateOutputs; + return this; + } + + /** + * Set a custom way to calculate item outputs. You are given the amount of parallels and must return an ItemStack + * array + */ + @Nonnull + public ParallelHelper setCustomItemOutputCalculation(Function custom) { + customItemOutputCalculation = custom; + return this; + } + + /** + * Set a custom way to calculate item outputs. You are given the amount of parallels and must return a FluidStack + * array + */ + @Nonnull + public ParallelHelper setCustomFluidOutputCalculation(Function custom) { + customFluidOutputCalculation = custom; + return this; + } + + @Nonnull + public ParallelHelper setMuTEMode(boolean muteMode) { + this.muteMode = muteMode; + return this; + } + + @Nonnull + public ParallelHelper setItemInputInventory(ItemInventoryLogic itemInputInventory) { + this.itemInputInventory = itemInputInventory; + return this; + } + + @Nonnull + public ParallelHelper setFluidInputInventory(FluidInventoryLogic fluidInputInventory) { + this.fluidInputInventory = fluidInputInventory; + return this; + } + + /** + * Sets method for calculating max parallel from given inputs. + */ + public ParallelHelper setMaxParallelCalculator(MaxParallelCalculator maxParallelCalculator) { + this.maxParallelCalculator = maxParallelCalculator; + return this; + } + + /** + * Sets method for consuming inputs after determining how many parallels it can execute. + */ + public ParallelHelper setInputConsumer(InputConsumer inputConsumer) { + this.inputConsumer = inputConsumer; + return this; + } + + @Nonnull + public ParallelHelper setItemOutputInventory(ItemInventoryLogic itemOutputInventory) { + this.itemOutputInventory = itemOutputInventory; + return this; + } + + @Nonnull + public ParallelHelper setFluidOutputInventory(FluidInventoryLogic fluidOutputInventory) { + this.fluidOutputInventory = fluidOutputInventory; + return this; + } + + /** + * Finishes the GT_ParallelHelper. Anything changed after this will not effect anything + */ + @Nonnull + public ParallelHelper build() { + if (built) { + throw new IllegalStateException("Tried to build twice"); + } + if (recipe == null) { + throw new IllegalStateException("Recipe is not set"); + } + built = true; + determineParallel(); + return this; + } + + /** + * @return The current parallels possible by the multiblock + */ + public int getCurrentParallel() { + if (!built) { + throw new IllegalStateException("Tried to get parallels before building"); + } + return currentParallel; + } + + /** + * @return The duration multiplier if batch mode was enabled for the multiblock + */ + public double getDurationMultiplierDouble() { + if (!built) { + throw new IllegalStateException("Tried to get duration multiplier before building"); + } + if (batchMode && durationMultiplier > 0) { + return durationMultiplier; + } + return 1; + } + + /** + * @return The ItemOutputs from the recipe + */ + @Nonnull + public ItemStack[] getItemOutputs() { + if (!built || !calculateOutputs) { + throw new IllegalStateException( + "Tried to get item outputs before building or without enabling calculation of outputs"); + } + return itemOutputs; + } + + /** + * @return The FluidOutputs from the recipe + */ + @Nonnull + public FluidStack[] getFluidOutputs() { + if (!built || !calculateOutputs) { + throw new IllegalStateException( + "Tried to get fluid outputs before building or without enabling calculation of outputs"); + } + return fluidOutputs; + } + + /** + * @return The result of why a recipe could've failed or succeeded + */ + @Nonnull + public CheckRecipeResult getResult() { + if (!built) { + throw new IllegalStateException("Tried to get recipe result before building"); + } + return result; + } + + /** + * Called by build(). Determines the parallels and everything else that needs to be done at build time + */ + protected void determineParallel() { + if (maxParallel <= 0) { + return; + } + if (itemInputs == null) { + itemInputs = new ItemStack[0]; + } + if (fluidInputs == null) { + fluidInputs = new FluidStack[0]; + } + + if (!consume) { + copyInputs(); + } + + if (calculator == null) { + calculator = new OverclockCalculator().setEUt(availableEUt) + .setRecipeEUt(recipe.mEUt) + .setDuration(recipe.mDuration) + .setEUtDiscount(eutModifier); + } + + final int tRecipeEUt = (int) Math.ceil(recipe.mEUt * eutModifier); + if (availableEUt < tRecipeEUt) { + result = CheckRecipeResultRegistry.insufficientPower(tRecipeEUt); + return; + } + + // Save the original max parallel before calculating our overclocking under 1 tick + int originalMaxParallel = maxParallel; + calculator.setParallel(originalMaxParallel); + double tickTimeAfterOC = calculator.calculateDurationUnderOneTick(); + if (tickTimeAfterOC < 1) { + maxParallel = GTUtility.safeInt((long) (maxParallel / tickTimeAfterOC), 0); + } + + int maxParallelBeforeBatchMode = maxParallel; + if (batchMode) { + maxParallel = GTUtility.safeInt((long) maxParallel * batchModifier, 0); + } + + final ItemStack[] truncatedItemOutputs = recipe.mOutputs != null + ? Arrays.copyOfRange(recipe.mOutputs, 0, Math.min(machine.getItemOutputLimit(), recipe.mOutputs.length)) + : new ItemStack[0]; + final FluidStack[] truncatedFluidOutputs = recipe.mFluidOutputs != null ? Arrays + .copyOfRange(recipe.mFluidOutputs, 0, Math.min(machine.getFluidOutputLimit(), recipe.mFluidOutputs.length)) + : new FluidStack[0]; + + SingleRecipeCheck recipeCheck = null; + SingleRecipeCheck.Builder tSingleRecipeCheckBuilder = null; + if (isRecipeLocked && singleRecipeMachine != null) { + recipeCheck = singleRecipeMachine.getSingleRecipeCheck(); + if (recipeCheck == null) { + // Machine is configured to lock to a single recipe, but haven't built the recipe checker yet. + // Build the checker on next successful recipe. + RecipeMap recipeMap = singleRecipeMachine.getRecipeMap(); + if (recipeMap != null) { + tSingleRecipeCheckBuilder = SingleRecipeCheck.builder(recipeMap) + .setBefore(itemInputs, fluidInputs); + } + } + } + + // Let's look at how many parallels we can get with void protection + if (protectExcessItem || protectExcessFluid) { + if (machine == null && !muteMode) { + throw new IllegalStateException("Tried to calculate void protection, but machine is not set"); + } + VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper(); + voidProtectionHelper.setMachine(machine) + .setItemOutputs(truncatedItemOutputs) + .setFluidOutputs(truncatedFluidOutputs) + .setChangeGetter(recipe::getOutputChance) + .setOutputMultiplier(outputMultiplier) + .setChanceMultiplier(chanceMultiplier) + .setMaxParallel(maxParallel) + .setItemOutputInventory(itemOutputInventory) + .setFluidOutputInventory(fluidOutputInventory) + .setMuTEMode(muteMode) + .build(); + maxParallel = Math.min(voidProtectionHelper.getMaxParallel(), maxParallel); + if (voidProtectionHelper.isItemFull()) { + result = CheckRecipeResultRegistry.ITEM_OUTPUT_FULL; + return; + } + if (voidProtectionHelper.isFluidFull()) { + result = CheckRecipeResultRegistry.FLUID_OUTPUT_FULL; + return; + } + } + + maxParallelBeforeBatchMode = Math.min(maxParallel, maxParallelBeforeBatchMode); + + // determine normal parallel + int actualMaxParallel = tRecipeEUt > 0 ? (int) Math.min(maxParallelBeforeBatchMode, availableEUt / tRecipeEUt) + : maxParallelBeforeBatchMode; + if (recipeCheck != null) { + currentParallel = recipeCheck.checkRecipeInputs(true, actualMaxParallel, itemInputs, fluidInputs); + } else { + currentParallel = (int) maxParallelCalculator.calculate(recipe, actualMaxParallel, fluidInputs, itemInputs); + if (currentParallel > 0) { + if (tSingleRecipeCheckBuilder != null) { + // If recipe checker is not built yet, build and set it + inputConsumer.consume(recipe, 1, fluidInputs, itemInputs); + SingleRecipeCheck builtCheck = tSingleRecipeCheckBuilder.setAfter(itemInputs, fluidInputs) + .setRecipe(recipe) + .build(); + singleRecipeMachine.setSingleRecipeCheck(builtCheck); + inputConsumer.consume(recipe, currentParallel - 1, fluidInputs, itemInputs); + } else { + inputConsumer.consume(recipe, currentParallel, fluidInputs, itemInputs); + } + } + } + + if (currentParallel <= 0) { + result = CheckRecipeResultRegistry.INTERNAL_ERROR; + return; + } + + calculator.setCurrentParallel(currentParallel) + .calculate(); + // If Batch Mode is enabled determine how many extra parallels we can get + if (batchMode && currentParallel > 0 && calculator.getDuration() < MAX_BATCH_MODE_TICK_TIME) { + int tExtraParallels; + double batchMultiplierMax = MAX_BATCH_MODE_TICK_TIME / calculator.getDuration(); + final int maxExtraParallels = (int) Math.floor( + Math.min( + currentParallel * Math.min(batchMultiplierMax - 1, batchModifier - 1), + maxParallel - currentParallel)); + if (recipeCheck != null) { + tExtraParallels = recipeCheck.checkRecipeInputs(true, maxExtraParallels, itemInputs, fluidInputs); + } else { + tExtraParallels = (int) maxParallelCalculator + .calculate(recipe, maxExtraParallels, fluidInputs, itemInputs); + inputConsumer.consume(recipe, tExtraParallels, fluidInputs, itemInputs); + } + durationMultiplier = 1.0f + (float) tExtraParallels / currentParallel; + currentParallel += tExtraParallels; + } + + // If we want to calculate outputs we do it here + if (calculateOutputs && currentParallel > 0) { + calculateItemOutputs(truncatedItemOutputs); + calculateFluidOutputs(truncatedFluidOutputs); + } + result = CheckRecipeResultRegistry.SUCCESSFUL; + } + + protected void copyInputs() { + ItemStack[] itemInputsToUse; + FluidStack[] fluidInputsToUse; + itemInputsToUse = new ItemStack[itemInputs.length]; + for (int i = 0; i < itemInputs.length; i++) { + itemInputsToUse[i] = itemInputs[i].copy(); + } + fluidInputsToUse = new FluidStack[fluidInputs.length]; + for (int i = 0; i < fluidInputs.length; i++) { + fluidInputsToUse[i] = fluidInputs[i].copy(); + } + itemInputs = itemInputsToUse; + fluidInputs = fluidInputsToUse; + } + + private void calculateItemOutputs(ItemStack[] truncatedItemOutputs) { + if (customItemOutputCalculation != null) { + itemOutputs = customItemOutputCalculation.apply(currentParallel); + return; + } + if (truncatedItemOutputs.length == 0) return; + ArrayList itemOutputsList = new ArrayList<>(); + for (int i = 0; i < truncatedItemOutputs.length; i++) { + if (recipe.getOutput(i) == null) continue; + ItemStack origin = recipe.getOutput(i) + .copy(); + final long itemStackSize = origin.stackSize; + double chancedOutputMultiplier = calculateChancedOutputMultiplier( + (int) (recipe.getOutputChance(i) * chanceMultiplier), + currentParallel); + long items = (long) Math.ceil(itemStackSize * chancedOutputMultiplier * outputMultiplier); + addItemsLong(itemOutputsList, origin, items); + } + itemOutputs = itemOutputsList.toArray(new ItemStack[0]); + } + + private void calculateFluidOutputs(FluidStack[] truncatedFluidOutputs) { + if (customFluidOutputCalculation != null) { + fluidOutputs = customFluidOutputCalculation.apply(currentParallel); + return; + } + if (truncatedFluidOutputs.length == 0) return; + ArrayList fluidOutputsList = new ArrayList<>(); + for (int i = 0; i < truncatedFluidOutputs.length; i++) { + if (recipe.getFluidOutput(i) == null) continue; + FluidStack origin = recipe.getFluidOutput(i) + .copy(); + long fluids = (long) this.outputMultiplier * origin.amount * currentParallel; + + addFluidsLong(fluidOutputsList, origin, fluids); + } + fluidOutputs = fluidOutputsList.toArray(new FluidStack[0]); + } + + private static final Random rand = new Random(); + + public static double calculateChancedOutputMultiplier(int chanceInt, int parallel) { + // Multiply the integer part of the chance directly with parallel + double multiplier = Math.floorDiv(chanceInt, 10000) * parallel; + int transformedChanceInt = chanceInt % 10000; + if (transformedChanceInt == 0) return multiplier; + // Calculation of the Decimal Part of chance + double chance = transformedChanceInt / 10000.0; + double mean = parallel * chance; + double stdDev = Math.sqrt(parallel * chance * (1 - chance)); + // Check if everything within 3 standard deviations of mean is within the range + // of possible values (0 ~ currentParallel) + boolean isSuitableForFittingWithNormalDistribution = mean - 3 * stdDev >= 0 && mean + 3 * stdDev <= parallel; + if (isSuitableForFittingWithNormalDistribution) { + // Use Normal Distribution to fit Binomial Distribution + double tMultiplier = stdDev * rand.nextGaussian() + mean; + multiplier += Math.max(Math.min(tMultiplier, parallel), 0); + } else { + // Do Binomial Distribution by loop + for (int roll = 0; roll < parallel; roll++) { + if (transformedChanceInt > XSTR.XSTR_INSTANCE.nextInt(10000)) { + multiplier += 1; + } + } + } + return multiplier; + } + + public static void addItemsLong(ArrayList itemList, ItemStack origin, long amount) { + if (amount > 0) { + while (amount > Integer.MAX_VALUE) { + ItemStack item = origin.copy(); + item.stackSize = Integer.MAX_VALUE; + itemList.add(item); + amount -= Integer.MAX_VALUE; + } + ItemStack item = origin.copy(); + item.stackSize = (int) amount; + itemList.add(item); + } + } + + public static void addFluidsLong(ArrayList fluidList, FluidStack origin, long amount) { + if (amount > 0) { + while (amount > Integer.MAX_VALUE) { + FluidStack fluid = origin.copy(); + fluid.amount = Integer.MAX_VALUE; + fluidList.add(fluid); + amount -= Integer.MAX_VALUE; + } + FluidStack fluid = origin.copy(); + fluid.amount = (int) amount; + fluidList.add(fluid); + } + } + + @FunctionalInterface + public interface MaxParallelCalculator { + + double calculate(GTRecipe recipe, int maxParallel, FluidStack[] fluids, ItemStack[] items); + } + + @FunctionalInterface + public interface InputConsumer { + + void consume(GTRecipe recipe, int amountMultiplier, FluidStack[] aFluidInputs, ItemStack[] aInputs); + } +} diff --git a/src/main/java/gregtech/api/util/ProcessingArrayManager.java b/src/main/java/gregtech/api/util/ProcessingArrayManager.java new file mode 100644 index 0000000000..adbb8f76b8 --- /dev/null +++ b/src/main/java/gregtech/api/util/ProcessingArrayManager.java @@ -0,0 +1,51 @@ +package gregtech.api.util; + +import java.util.HashMap; + +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.SoundResource; +import gregtech.api.recipe.RecipeMap; + +@Deprecated +public class ProcessingArrayManager { + + private static final HashMap> mRecipeSaves = new HashMap<>(); + private static final HashMap machineSounds = new HashMap<>(); + + // Adds recipe Maps to the PA using the machines unlocalized name. + // Example: basicmachine.electrolyzer, with its recipe map will add the electrolyzer's recipe map to the PA + public static void addRecipeMapToPA(String aMachineName, RecipeMap aMap) { + if (aMachineName != null) { + mRecipeSaves.put(aMachineName, aMap); + } + } + + // Allows the PA to extract the recipe map for the machine inside it. + public static RecipeMap giveRecipeMap(String aMachineName) { + if (aMachineName != null) { + return mRecipeSaves.get(aMachineName); + } + return null; + } + + public static void addSoundResourceToPA(String machineName, SoundResource soundResource) { + if (machineName != null) { + machineSounds.put(machineName, soundResource); + } + } + + public static SoundResource getSoundResource(String machineName) { + if (machineName != null) { + return machineSounds.get(machineName); + } + return null; + } + + public static String getMachineName(ItemStack stack) { + int length = stack.getUnlocalizedName() + .length(); + return stack.getUnlocalizedName() + .substring(17, length - 8); // trim "gt.blockmachines." and ".tier.xx" + } +} diff --git a/src/main/java/gregtech/api/util/SemiFluidFuelHandler.java b/src/main/java/gregtech/api/util/SemiFluidFuelHandler.java index aa983a5804..50cad72f9c 100644 --- a/src/main/java/gregtech/api/util/SemiFluidFuelHandler.java +++ b/src/main/java/gregtech/api/util/SemiFluidFuelHandler.java @@ -1,6 +1,6 @@ package gregtech.api.util; -import static gregtech.api.util.GT_RecipeConstants.FUEL_VALUE; +import static gregtech.api.util.GTRecipeConstants.FUEL_VALUE; import static gtPlusPlus.api.recipe.GTPPRecipeMaps.semiFluidFuels; import java.util.HashMap; @@ -9,7 +9,7 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidContainerRegistry; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.enums.GT_Values; +import gregtech.api.enums.GTValues; import gregtech.api.recipe.RecipeMaps; import gtPlusPlus.api.objects.Logger; import gtPlusPlus.api.objects.data.Pair; @@ -23,9 +23,9 @@ public class SemiFluidFuelHandler { final FluidStack aHeavyOil = FluidUtils.getFluidStack("liquid_heavy_oil", 1000); final HashMap> aFoundFluidsFromItems = new HashMap<>(); // Find Fluids From items - for (final GT_Recipe r : RecipeMaps.denseLiquidFuels.getAllRecipes()) { + for (final GTRecipe r : RecipeMaps.denseLiquidFuels.getAllRecipes()) { - GT_Recipe g = r.copy(); + GTRecipe g = r.copy(); if (g != null && g.mEnabled && g.mInputs.length > 0 && g.mInputs[0] != null) { for (ItemStack i : g.mInputs) { @@ -71,7 +71,7 @@ public class SemiFluidFuelHandler { if (aFuelValue <= (128 * 3)) { - GT_Values.RA.stdBuilder() + GTValues.RA.stdBuilder() .fluidInputs(p.getKey()) .duration(0) .eut(0) diff --git a/src/main/java/gregtech/api/util/VoidProtectionHelper.java b/src/main/java/gregtech/api/util/VoidProtectionHelper.java index fdf47d06df..cf98e26b66 100644 --- a/src/main/java/gregtech/api/util/VoidProtectionHelper.java +++ b/src/main/java/gregtech/api/util/VoidProtectionHelper.java @@ -397,7 +397,7 @@ public class VoidProtectionHelper { int tSlotsFree = 0; int index = 0; for (ItemStack tItem : itemOutputs) { - // GT_RecipeBuilder doesn't handle null item output + // GTRecipeBuilder doesn't handle null item output if (tItem == null) continue; int itemStackSize = (int) (tItem.stackSize * outputMultiplier * Math.ceil(chanceMultiplier * chanceGetter.apply(index++) / 10000)); diff --git a/src/main/java/gregtech/api/util/item/ItemHolder.java b/src/main/java/gregtech/api/util/item/ItemHolder.java index 4675d0ba0e..51215c93cb 100644 --- a/src/main/java/gregtech/api/util/item/ItemHolder.java +++ b/src/main/java/gregtech/api/util/item/ItemHolder.java @@ -11,7 +11,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import gregtech.api.util.GT_Utility; +import gregtech.api.util.GTUtility; public class ItemHolder { @@ -67,7 +67,7 @@ public class ItemHolder { @Override public int hashCode() { - return GT_Utility.stackToInt(toStack()); + return GTUtility.stackToInt(toStack()); } @Nonnull diff --git a/src/main/java/gregtech/api/util/recipe/RecipeInputRequirements.java b/src/main/java/gregtech/api/util/recipe/RecipeInputRequirements.java index 590c104101..485ee991c5 100644 --- a/src/main/java/gregtech/api/util/recipe/RecipeInputRequirements.java +++ b/src/main/java/gregtech/api/util/recipe/RecipeInputRequirements.java @@ -12,7 +12,7 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; -import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GTRecipe; import gregtech.api.util.item.ItemHolder; public class RecipeInputRequirements { @@ -24,7 +24,7 @@ public class RecipeInputRequirements { protected Set fluidInputsMet = new HashSet<>(); protected boolean metAllFluid = false; - public RecipeInputRequirements(@Nonnull GT_Recipe recipe) { + public RecipeInputRequirements(@Nonnull GTRecipe recipe) { this(recipe.mInputs, recipe.mFluidInputs); } @@ -42,7 +42,7 @@ public class RecipeInputRequirements { } /** - * + * * @param itemInputs we have and want to fill this request * @return {@code true} when all item inputs are met */ @@ -59,7 +59,7 @@ public class RecipeInputRequirements { } /** - * + * * @param fluidInputs we have and want to fill this request * @return {@code true} when all fluid inputs are met */ diff --git a/src/main/java/gregtech/api/util/shutdown/ReasonOutOfFluid.java b/src/main/java/gregtech/api/util/shutdown/ReasonOutOfFluid.java index 0194afbc04..10684f5848 100644 --- a/src/main/java/gregtech/api/util/shutdown/ReasonOutOfFluid.java +++ b/src/main/java/gregtech/api/util/shutdown/ReasonOutOfFluid.java @@ -1,7 +1,7 @@ package gregtech.api.util.shutdown; -import static gregtech.api.util.GT_ModHandler.getWater; -import static gregtech.api.util.GT_Utility.formatNumbers; +import static gregtech.api.util.GTModHandler.getWater; +import static gregtech.api.util.GTUtility.formatNumbers; import java.util.Objects; diff --git a/src/main/java/gregtech/api/util/shutdown/ReasonOutOfItem.java b/src/main/java/gregtech/api/util/shutdown/ReasonOutOfItem.java index 8f51bd83b2..f512e2fa84 100644 --- a/src/main/java/gregtech/api/util/shutdown/ReasonOutOfItem.java +++ b/src/main/java/gregtech/api/util/shutdown/ReasonOutOfItem.java @@ -1,6 +1,6 @@ package gregtech.api.util.shutdown; -import static gregtech.api.util.GT_Utility.formatNumbers; +import static gregtech.api.util.GTUtility.formatNumbers; import java.util.Objects; diff --git a/src/main/java/gregtech/api/util/shutdown/ReasonOutOfStuff.java b/src/main/java/gregtech/api/util/shutdown/ReasonOutOfStuff.java index 72a75b062f..288c733a90 100644 --- a/src/main/java/gregtech/api/util/shutdown/ReasonOutOfStuff.java +++ b/src/main/java/gregtech/api/util/shutdown/ReasonOutOfStuff.java @@ -1,6 +1,6 @@ package gregtech.api.util.shutdown; -import static gregtech.api.util.GT_Utility.formatNumbers; +import static gregtech.api.util.GTUtility.formatNumbers; import java.util.Objects; diff --git a/src/main/java/gregtech/api/util/shutdown/ShutDownReasonRegistry.java b/src/main/java/gregtech/api/util/shutdown/ShutDownReasonRegistry.java index 298c5db237..1cdfb60ddb 100644 --- a/src/main/java/gregtech/api/util/shutdown/ShutDownReasonRegistry.java +++ b/src/main/java/gregtech/api/util/shutdown/ShutDownReasonRegistry.java @@ -1,6 +1,6 @@ package gregtech.api.util.shutdown; -import static gregtech.api.util.GT_ModHandler.getWater; +import static gregtech.api.util.GTModHandler.getWater; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/gregtech/api/world/GTWorldgen.java b/src/main/java/gregtech/api/world/GTWorldgen.java new file mode 100644 index 0000000000..da3a66ef7e --- /dev/null +++ b/src/main/java/gregtech/api/world/GTWorldgen.java @@ -0,0 +1,123 @@ +package gregtech.api.world; + +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraftforge.common.DimensionManager; + +import gregtech.common.WorldgenGTOreLayer; +import gregtech.common.WorldgenGTOreSmallPieces; + +public abstract class GTWorldgen { + + public final String mWorldGenName; + public final boolean mEnabled; + private final Map mDimensionMap = new ConcurrentHashMap<>(); + + @SuppressWarnings({ "unchecked", "rawtypes" }) // The adding of "this" needs a List which does not exist + public GTWorldgen(String aName, List aList, boolean aDefault) { + mWorldGenName = aName; + mEnabled = aDefault; + if (mEnabled) aList.add(this); + } + + /** + * @param aWorld The World Object + * @param aRandom The Random Generator to use + * @param aBiome The Name of the Biome (always != null) + * @param aDimensionType The Type of Worldgeneration to add. -1 = Nether, 0 = Overworld, +1 = End + * @param aChunkX xCoord of the Chunk + * @param aChunkZ zCoord of the Chunk + * @return if the Worldgeneration has been successfully completed + */ + public boolean executeWorldgen(World aWorld, Random aRandom, String aBiome, int aDimensionType, int aChunkX, + int aChunkZ, IChunkProvider aChunkGenerator, IChunkProvider aChunkProvider) { + return false; + } + + public int executeWorldgenChunkified(World aWorld, Random aRandom, String aBiome, int aDimensionType, int aChunkX, + int aChunkZ, int seedX, int seedZ, IChunkProvider aChunkGenerator, IChunkProvider aChunkProvider) { + return 4; // This is for the empty Orevein + } + + /** + * + * @param aDimName The Dimension Name + * @param aDimensionType The Type of Worldgeneration to add. -1 = Nether, 0 = Overworld, +1 = End + * @param aAllowedDimensionType The Type of allowed Worldgeneration + * @return if generation for this world is allowed for MoronTech (tm) OreGen (ATM (2.0.3.1Dev) only End, Nether, + * Overworld, Twilight Forest and Deep Dark) + */ + public boolean isGenerationAllowed(String aDimName, int aDimensionType, int aAllowedDimensionType) { + if (aDimName.equalsIgnoreCase("Underdark")) { + return false; + } + if (!(aDimName.equalsIgnoreCase("Overworld") || aDimName.equalsIgnoreCase("Nether") + || aDimName.equalsIgnoreCase("The End") + || aDimName.equalsIgnoreCase("Twilight Forest"))) return false; + + Boolean tAllowed = mDimensionMap.get(aDimName); + if (tAllowed == null) { + mDimensionMap.put(aDimName, aDimensionType == aAllowedDimensionType); + return aDimensionType == aAllowedDimensionType; + } + return tAllowed; + } + + public boolean isGenerationAllowed(World aWorld, int aAllowedDimensionType) { + World allowedWorld = DimensionManager.getWorld(aAllowedDimensionType); + if (allowedWorld != null && allowedWorld.provider != null) { + return isGenerationAllowed(aWorld, allowedWorld.provider.getClass()); + } else { + return aWorld.provider.dimensionId == aAllowedDimensionType; + } + } + + /** + * + * @param aWorld The World Object + * @param aAllowedDimensionTypes The Types of allowed Worldgeneration + * @return if generation for this world is allowed for MoronTech (tm) OreGen (ATM (2.0.3.1Dev) only End, Nether, + * Overworld, Twilight Forest and Deep Dark) + */ + public boolean isGenerationAllowed(World aWorld, Class... aAllowedDimensionTypes) { + String aDimName = aWorld.provider.getDimensionName(); + if (aDimName.equalsIgnoreCase("Underdark")) { + return false; + } + if (!(aDimName.equalsIgnoreCase("Overworld") || aDimName.equalsIgnoreCase("Nether") + || aDimName.equalsIgnoreCase("The End") + || aDimName.equalsIgnoreCase("Twilight Forest"))) return false; + + Boolean tAllowed = mDimensionMap.get(aDimName); + if (tAllowed == null) { + boolean value = false; + for (int i = 0; i < aAllowedDimensionTypes.length; i++) { + if (aAllowedDimensionTypes[i].isInstance(aWorld.provider)) { + value = true; + } + } + + // ugly, but idk how to do it better without hard depping on tf provider in ore constructors + if (this instanceof WorldgenGTOreSmallPieces ore) { + if (ore.twilightForest && aWorld.provider.dimensionId == 7) { + value = true; + } + } + + if (this instanceof WorldgenGTOreLayer ore) { + if (ore.twilightForest && aWorld.provider.dimensionId == 7) { + value = true; + } + } + + mDimensionMap.put(aDimName, value); + return value; + } + return tAllowed; + } +} diff --git a/src/main/java/gregtech/api/world/GT_Worldgen.java b/src/main/java/gregtech/api/world/GT_Worldgen.java deleted file mode 100644 index a3393324c2..0000000000 --- a/src/main/java/gregtech/api/world/GT_Worldgen.java +++ /dev/null @@ -1,123 +0,0 @@ -package gregtech.api.world; - -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; - -import net.minecraft.world.World; -import net.minecraft.world.chunk.IChunkProvider; -import net.minecraftforge.common.DimensionManager; - -import gregtech.common.GT_Worldgen_GT_Ore_Layer; -import gregtech.common.GT_Worldgen_GT_Ore_SmallPieces; - -public abstract class GT_Worldgen { - - public final String mWorldGenName; - public final boolean mEnabled; - private final Map mDimensionMap = new ConcurrentHashMap<>(); - - @SuppressWarnings({ "unchecked", "rawtypes" }) // The adding of "this" needs a List which does not exist - public GT_Worldgen(String aName, List aList, boolean aDefault) { - mWorldGenName = aName; - mEnabled = aDefault; - if (mEnabled) aList.add(this); - } - - /** - * @param aWorld The World Object - * @param aRandom The Random Generator to use - * @param aBiome The Name of the Biome (always != null) - * @param aDimensionType The Type of Worldgeneration to add. -1 = Nether, 0 = Overworld, +1 = End - * @param aChunkX xCoord of the Chunk - * @param aChunkZ zCoord of the Chunk - * @return if the Worldgeneration has been successfully completed - */ - public boolean executeWorldgen(World aWorld, Random aRandom, String aBiome, int aDimensionType, int aChunkX, - int aChunkZ, IChunkProvider aChunkGenerator, IChunkProvider aChunkProvider) { - return false; - } - - public int executeWorldgenChunkified(World aWorld, Random aRandom, String aBiome, int aDimensionType, int aChunkX, - int aChunkZ, int seedX, int seedZ, IChunkProvider aChunkGenerator, IChunkProvider aChunkProvider) { - return 4; // This is for the empty Orevein - } - - /** - * - * @param aDimName The Dimension Name - * @param aDimensionType The Type of Worldgeneration to add. -1 = Nether, 0 = Overworld, +1 = End - * @param aAllowedDimensionType The Type of allowed Worldgeneration - * @return if generation for this world is allowed for MoronTech (tm) OreGen (ATM (2.0.3.1Dev) only End, Nether, - * Overworld, Twilight Forest and Deep Dark) - */ - public boolean isGenerationAllowed(String aDimName, int aDimensionType, int aAllowedDimensionType) { - if (aDimName.equalsIgnoreCase("Underdark")) { - return false; - } - if (!(aDimName.equalsIgnoreCase("Overworld") || aDimName.equalsIgnoreCase("Nether") - || aDimName.equalsIgnoreCase("The End") - || aDimName.equalsIgnoreCase("Twilight Forest"))) return false; - - Boolean tAllowed = mDimensionMap.get(aDimName); - if (tAllowed == null) { - mDimensionMap.put(aDimName, aDimensionType == aAllowedDimensionType); - return aDimensionType == aAllowedDimensionType; - } - return tAllowed; - } - - public boolean isGenerationAllowed(World aWorld, int aAllowedDimensionType) { - World allowedWorld = DimensionManager.getWorld(aAllowedDimensionType); - if (allowedWorld != null && allowedWorld.provider != null) { - return isGenerationAllowed(aWorld, allowedWorld.provider.getClass()); - } else { - return aWorld.provider.dimensionId == aAllowedDimensionType; - } - } - - /** - * - * @param aWorld The World Object - * @param aAllowedDimensionTypes The Types of allowed Worldgeneration - * @return if generation for this world is allowed for MoronTech (tm) OreGen (ATM (2.0.3.1Dev) only End, Nether, - * Overworld, Twilight Forest and Deep Dark) - */ - public boolean isGenerationAllowed(World aWorld, Class... aAllowedDimensionTypes) { - String aDimName = aWorld.provider.getDimensionName(); - if (aDimName.equalsIgnoreCase("Underdark")) { - return false; - } - if (!(aDimName.equalsIgnoreCase("Overworld") || aDimName.equalsIgnoreCase("Nether") - || aDimName.equalsIgnoreCase("The End") - || aDimName.equalsIgnoreCase("Twilight Forest"))) return false; - - Boolean tAllowed = mDimensionMap.get(aDimName); - if (tAllowed == null) { - boolean value = false; - for (int i = 0; i < aAllowedDimensionTypes.length; i++) { - if (aAllowedDimensionTypes[i].isInstance(aWorld.provider)) { - value = true; - } - } - - // ugly, but idk how to do it better without hard depping on tf provider in ore constructors - if (this instanceof GT_Worldgen_GT_Ore_SmallPieces ore) { - if (ore.twilightForest && aWorld.provider.dimensionId == 7) { - value = true; - } - } - - if (this instanceof GT_Worldgen_GT_Ore_Layer ore) { - if (ore.twilightForest && aWorld.provider.dimensionId == 7) { - value = true; - } - } - - mDimensionMap.put(aDimName, value); - return value; - } - return tAllowed; - } -} -- cgit