From 9cf7c021796c95b7855b5717b500eaf4a781a11e Mon Sep 17 00:00:00 2001 From: Kanzaji <60540476+Kanzaji@users.noreply.github.com> Date: Sun, 1 Oct 2023 14:07:25 +0200 Subject: [PATCH] Add Support for Legacy IC2 (#12) * Update FancyGradle and Forge Maven link to make anything work properly * Create temporary patch as workaround to missing profiles. * Make JEI CompileOnly so the game actually boots TODO: Find out why JEI was crashing and how to fix it. * Update Forge to 13.23.5.2860 * Remove ASM Patch, as it was causing a crash for some reason * Another try at getting JEI working, sadly unsuccessful * Remove temporary workaround of the missing resources issue * Bring back ASM Patch, as it wasn't the cause of corrupted asm jar? No idea how that worked the first time * Few build.gradle changes that could or could not improve stability of in-dev client? * Separate patches for 221+ and legacy into other folders for base * Set Patching mode for base to Fuzzy so it will find more patches required to compile * Add working patches for 164 * IC2-Base ApplyPatches Folder Version Separation Make the IC2-Base ApplyPatches gather patches from the folders with version ranges, depending on the version specified in the properties * Revert back to offset due to fuzzy accepting stuff that shouldn't be necessarily accepted. * Remove broken patches for 164 * Update build.gradle.kts * Fix up Generate Patches for IC2-Base * Generate Patches so Base for 164 compiles * Finish Patches per version separation in dev env * Port relevant Patches from 221+ to 164 * Fix up build script, it actually works for 164 \o/ * Update mcmod.info because it felt weird with so little info * Add requirement of 221+ with addition to 164 * OPINION REQUIRED - Single Jar Multiple IC2 Versions support * Dev Env Setup for multiple version patch generation. Bin Patches are now saved, as they are required for the mod build with multiple version support. They are saved under `src\main\generatedResrouces` directory. ISSUE: Either Build is required to be runned twice, or generateBinPatches has to be launched before triggering the build. I wasn't able to get this to find freshly-generated files for whatever reason. ISSUE: Dev Builds work only on a version of IC2 that is used to compile it. Dev Bin Patches are inserted to the jar root, and other patches are excluded. * Add patches pack for original 2.8.221+ support * Few Small fixes about the patch version selection * Fix patches not being possible to generate after initial setup * Add setup task to seperate group * Add additional check in PatcherFMLPlugin --- build.gradle.kts | 34 +- gradle.properties | 3 +- projects/IC2-Base/build.gradle.kts | 120 +- .../ic2/core/GuiOverlayer.java.patch | 0 .../minecraft/ic2/core/IC2.java.patch | 0 .../core/audio/AudioManagerClient.java.patch | 0 .../ic2/core/block/BlockIC2Fence.java.patch | 0 .../ic2/core/block/BlockMultiID.java.patch | 0 .../ic2/core/block/BlockTileEntity.java.patch | 25 + .../ic2/core/block/TeBlockRegistry.java.patch | 0 .../InvSlotConsumableLiquid.java.patch | 0 .../InvSlotProcessableCanner.java.patch | 0 .../block/invslot/InvSlotUpgrade.java.patch | 11 + ...mptyFluidContainerRecipeManager.java.patch | 0 ...FillFluidContainerRecipeManager.java.patch | 0 .../ContainerIndustrialWorkbench.java.patch | 13 + .../machine/gui/GuiFluidRegulator.java.patch | 0 .../machine/gui/GuiMetalFormer.java.patch | 0 .../TileEntityBatchCrafter.java.patch | 41 + .../TileEntityCompressor.java.patch | 0 .../TileEntityFluidBottler.java.patch | 0 .../tileentity/TileEntityScanner.java.patch | 0 .../block/state/BlockStateUtil.java.patch | 0 .../core/block/state/EnumProperty.java.patch | 0 .../core/block/state/Ic2BlockState.java.patch | 0 .../block/state/MaterialProperty.java.patch | 0 .../transport/items/PipeModel.java.patch | 0 .../core/block/wiring/CableModel.java.patch | 0 .../block/wiring/GuiTransformer.java.patch | 0 .../ic2/core/command/CommandIc2.java.patch | 0 .../ic2/core/crop/CropModel.java.patch | 16 + .../ic2/core/energy/EnergyNetLocal.java.patch | 0 .../minecraft/ic2/core/energy/Grid.java.patch | 0 .../minecraft/ic2/core/energy/Tile.java.patch | 0 .../core/energy/grid/ChangeHandler.java.patch | 0 .../core/energy/grid/EventHandler.java.patch | 0 .../ic2/core/energy/grid/Grid.java.patch | 0 .../ic2/core/energy/grid/Tile.java.patch | 0 .../energy/leg/EnergyCalculatorLeg.java.patch | 0 .../ic2/core/gui/Ic2GuiFactory.java.patch | 17 + .../DynamicHandHeldContainer.java.patch | 22 + .../core/gui/dynamic/TextProvider.java.patch | 11 + .../ic2/core/init/BlocksItems.java.patch | 26 + .../ic2/core/init/Localization.java.patch | 0 .../item/armor/ItemArmorElectric.java.patch | 0 .../armor/ItemArmorQuantumSuit.java.patch | 0 .../item/armor/ItemArmorUtility.java.patch | 0 .../ic2/core/item/block/ItemCable.java.patch | 0 .../core/item/block/ItemFluidPipe.java.patch | 0 .../ic2/core/item/block/ItemPipe.java.patch | 0 .../core/item/tool/GuiToolMeter.java.patch | 0 .../ic2/core/item/tool/ItemDebug.java.patch | 0 .../item/tool/ItemElectricTool.java.patch | 0 .../tool/ItemElectricToolChainsaw.java.patch | 0 .../ic2/core/item/tool/ItemScanner.java.patch | 10 + .../core/item/tool/ItemToolPainter.java.patch | 0 .../core/item/tool/ItemToolWrench.java.patch | 0 .../item/tool/ItemToolWrenchNew.java.patch | 11 + .../ic2/core/item/type/CellType.java.patch | 0 .../core/model/MaskOverlayModel.java.patch | 0 .../ic2/core/model/ModelUtil.java.patch | 0 .../ic2/core/network/DataEncoder.java.patch | 0 .../ic2/core/network/GrowingBuffer.java.patch | 0 .../ic2/core/network/RpcHandler.java.patch | 0 .../ic2/core/profile/Profile.java.patch | 0 .../core/profile/ProfileManager.java.patch | 0 .../ic2/core/profile/ProfileParser.java.patch | 0 .../dynamic/DynamicRecipeManager.java.patch | 0 .../ic2/core/ref/BlockName.java.patch | 0 .../ic2/core/ref/IMultiItem.java.patch | 0 .../ic2/core/ref/ItemName.java.patch | 0 .../core/ref/MetaTeBlockProperty.java.patch | 0 .../ic2/core/util/LiquidUtil.java.patch | 0 .../ic2/core/util/ReflectionUtil.java.patch | 0 .../ic2/core/util/StackUtil.java.patch | 0 .../minecraft/ic2/core/util/Util.java.patch | 0 .../minecraft/ic2/core/uu/DropScan.java.patch | 0 .../ic2/core/uu/RecipeResolver.java.patch | 0 .../minecraft/ic2/core/uu/UuGraph.java.patch | 0 .../crafting/AdvRecipeWrapper.java.patch | 0 .../AdvShapelessRecipeWrapper.java.patch | 0 .../recipe/machine/CannerCategory.java.patch | 0 ...nsferHandlerIndustrialWorkbench.java.patch | 0 .../ic2/core/GuiOverlayer.java.patch | 20 + .../minecraft/ic2/core/IC2.java.patch | 154 ++ .../core/audio/AudioManagerClient.java.patch | 16 + .../ic2/core/block/BlockIC2Fence.java.patch | 29 + .../ic2/core/block/BlockMultiID.java.patch | 11 + .../ic2/core/block/BlockTileEntity.java.patch | 0 .../ic2/core/block/TeBlockRegistry.java.patch | 20 + .../InvSlotConsumableLiquid.java.patch | 20 + .../InvSlotProcessableCanner.java.patch | 11 + .../block/invslot/InvSlotUpgrade.java.patch | 0 ...mptyFluidContainerRecipeManager.java.patch | 11 + ...FillFluidContainerRecipeManager.java.patch | 20 + .../ContainerIndustrialWorkbench.java.patch | 0 .../machine/gui/GuiFluidRegulator.java.patch | 65 + .../machine/gui/GuiMetalFormer.java.patch | 16 + .../TileEntityBatchCrafter.java.patch | 0 .../TileEntityCompressor.java.patch | 11 + .../TileEntityFluidBottler.java.patch | 11 + .../tileentity/TileEntityScanner.java.patch | 17 + .../block/personal/TradingMarket.java.patch | 0 .../block/state/BlockStateUtil.java.patch | 11 + .../core/block/state/EnumProperty.java.patch | 11 + .../core/block/state/Ic2BlockState.java.patch | 11 + .../block/state/MaterialProperty.java.patch | 11 + .../transport/items/PipeModel.java.patch | 20 + .../core/block/wiring/CableModel.java.patch | 19 + .../block/wiring/GuiTransformer.java.patch | 15 + .../ic2/core/command/CommandIc2.java.patch | 11 + .../ic2/core/crop/CropModel.java.patch | 0 .../ic2/core/crop/IC2Crops.java.patch | 0 .../ic2/core/crop/TileEntityCrop.java.patch | 0 .../ic2/core/energy/EnergyNetLocal.java.patch | 30 + .../minecraft/ic2/core/energy/Grid.java.patch | 2048 +++++++++++++++++ .../minecraft/ic2/core/energy/Tile.java.patch | 15 + .../core/energy/grid/ChangeHandler.java.patch | 44 + .../core/energy/grid/EventHandler.java.patch | 18 + .../ic2/core/energy/grid/Grid.java.patch | 345 +++ .../ic2/core/energy/grid/Tile.java.patch | 36 + .../energy/leg/EnergyCalculatorLeg.java.patch | 15 + .../ic2/core/gui/Ic2GuiFactory.java.patch | 0 .../ic2/core/gui/PlayerHead.java.patch | 0 .../DynamicHandHeldContainer.java.patch | 0 .../core/gui/dynamic/TextProvider.java.patch | 0 .../ic2/core/init/BlocksItems.java.patch | 0 .../ic2/core/init/Localization.java.patch | 20 + .../item/armor/ItemArmorElectric.java.patch | 11 + .../armor/ItemArmorQuantumSuit.java.patch | 11 + .../item/armor/ItemArmorUtility.java.patch | 11 + .../ic2/core/item/block/ItemCable.java.patch | 11 + .../core/item/block/ItemFluidPipe.java.patch | 11 + .../ic2/core/item/block/ItemPipe.java.patch | 11 + .../core/item/tool/GuiToolMeter.java.patch | 19 + .../ic2/core/item/tool/ItemDebug.java.patch | 11 + .../item/tool/ItemElectricTool.java.patch | 41 + .../tool/ItemElectricToolChainsaw.java.patch | 13 + .../ic2/core/item/tool/ItemScanner.java.patch | 0 .../core/item/tool/ItemToolPainter.java.patch | 14 + .../core/item/tool/ItemToolWrench.java.patch | 11 + .../item/tool/ItemToolWrenchNew.java.patch | 0 .../ic2/core/item/type/CellType.java.patch | 13 + .../core/model/MaskOverlayModel.java.patch | 47 + .../ic2/core/model/ModelUtil.java.patch | 11 + .../ic2/core/network/DataEncoder.java.patch | 1421 ++++++++++++ .../ic2/core/network/GrowingBuffer.java.patch | 11 + .../ic2/core/network/RpcHandler.java.patch | 37 + .../ic2/core/profile/Profile.java.patch | 16 + .../core/profile/ProfileManager.java.patch | 34 + .../ic2/core/profile/ProfileParser.java.patch | 33 + .../dynamic/DynamicRecipeManager.java.patch | 128 ++ .../ic2/core/ref/BlockName.java.patch | 11 + .../ic2/core/ref/IMultiItem.java.patch | 11 + .../ic2/core/ref/ItemName.java.patch | 11 + .../core/ref/MetaTeBlockProperty.java.patch | 11 + .../ic2/core/util/LiquidUtil.java.patch | 11 + .../ic2/core/util/ReflectionUtil.java.patch | 26 + .../ic2/core/util/StackUtil.java.patch | 71 + .../minecraft/ic2/core/util/Util.java.patch | 19 + .../minecraft/ic2/core/uu/DropScan.java.patch | 20 + .../ic2/core/uu/RecipeResolver.java.patch | 30 + .../minecraft/ic2/core/uu/UuGraph.java.patch | 33 + .../crafting/AdvRecipeWrapper.java.patch | 54 + .../AdvShapelessRecipeWrapper.java.patch | 35 + .../recipe/machine/CannerCategory.java.patch | 75 + ...nsferHandlerIndustrialWorkbench.java.patch | 178 ++ projects/IC2-Patched/build.gradle.kts | 71 +- .../minecraft/ic2/core/WorldData.java.patch | 59 + .../ic2/core/block/RenderBlockWall.java.patch | 0 .../TileEntityBatchCrafter.java.patch | 11 + .../steam/BlockRefractoryBricks.java.patch | 0 .../block/steam/TileEntityCokeKiln.java.patch | 18 + .../steam/TileEntityCokeKilnGrate.java.patch | 0 .../steam/TileEntityCokeKilnHatch.java.patch | 0 .../box/TileEntityBronzeStorageBox.java.patch | 0 .../TileEntityIridiumStorageBox.java.patch | 0 .../box/TileEntityIronStorageBox.java.patch | 0 .../box/TileEntitySteelStorageBox.java.patch | 0 .../box/TileEntityWoodenStorageBox.java.patch | 0 .../tank/TileEntityBronzeTank.java.patch | 0 .../tank/TileEntityIridiumTank.java.patch | 0 .../tank/TileEntityIronTank.java.patch | 0 .../tank/TileEntitySteelTank.java.patch | 0 .../transport/TileEntityFluidPipe.java.patch | 20 + .../ic2/core/init/BlocksItems.java.patch | 14 + .../ic2/core/item/ItemCoke.java.patch | 0 .../ItemArmorNightvisionGoggles.java.patch | 0 .../armor/ItemArmorQuantumSuit.java.patch | 0 .../core/item/block/ItemFluidPipe.java.patch | 0 .../item/logistics/ItemPumpCover.java.patch | 0 .../core/item/tool/ItemToolCrowbar.java.patch | 18 + .../item/tool/ItemToolWrenchNew.java.patch | 18 + .../minecraft/ic2/core/WorldData.java.patch | 0 .../ic2/core/block/RenderBlockWall.java.patch | 22 + .../TileEntityBatchCrafter.java.patch | 0 .../TileEntityCropHarvester.java.patch | 0 .../TileEntityCropmatron.java.patch | 0 .../TileEntityTradingTerminal.java.patch | 0 .../steam/BlockRefractoryBricks.java.patch | 18 + .../block/steam/TileEntityCokeKiln.java.patch | 0 .../steam/TileEntityCokeKilnGrate.java.patch | 18 + .../steam/TileEntityCokeKilnHatch.java.patch | 18 + .../box/TileEntityBronzeStorageBox.java.patch | 11 + .../TileEntityIridiumStorageBox.java.patch | 11 + .../box/TileEntityIronStorageBox.java.patch | 11 + .../box/TileEntitySteelStorageBox.java.patch | 11 + .../box/TileEntityWoodenStorageBox.java.patch | 13 + .../tank/TileEntityBronzeTank.java.patch | 11 + .../tank/TileEntityIridiumTank.java.patch | 11 + .../tank/TileEntityIronTank.java.patch | 11 + .../tank/TileEntitySteelTank.java.patch | 11 + .../transport/TileEntityFluidPipe.java.patch | 0 .../ic2/core/init/BlocksItems.java.patch | 0 .../ic2/core/item/ItemCoke.java.patch | 13 + .../ItemArmorNightvisionGoggles.java.patch | 66 + .../armor/ItemArmorQuantumSuit.java.patch | 35 + .../core/item/block/ItemFluidPipe.java.patch | 18 + .../item/logistics/ItemPumpCover.java.patch | 18 + .../core/item/tool/ItemToolCrowbar.java.patch | 0 .../item/tool/ItemToolWrenchNew.java.patch | 0 settings.gradle.kts | 2 +- .../ic2patches.pack.lzma | Bin 0 -> 45556 bytes .../patches[2.8.221,+]/ic2patches.pack.lzma | Bin 0 -> 50526 bytes .../java/mods/su5ed/ic2patcher/Patcher.java | 2 +- .../su5ed/ic2patcher/asm/BinPatchManager.java | 50 +- .../ic2patcher/asm/PatcherFMLPlugin.java | 5 +- .../ic2patcher/util/IC2VersionExtractor.java | 53 + .../ic2patcher/util/VersionComparison.java | 27 + src/main/resources/mcmod.info | 4 +- 230 files changed, 6638 insertions(+), 55 deletions(-) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/GuiOverlayer.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/IC2.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/audio/AudioManagerClient.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/BlockIC2Fence.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/BlockMultiID.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockTileEntity.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/TeBlockRegistry.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/state/BlockStateUtil.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/state/EnumProperty.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/state/Ic2BlockState.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/state/MaterialProperty.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/transport/items/PipeModel.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/wiring/CableModel.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/command/CommandIc2.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/crop/CropModel.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/EnergyNetLocal.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/Grid.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/Tile.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/grid/EventHandler.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/grid/Grid.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/grid/Tile.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/init/Localization.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/block/ItemCable.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/block/ItemPipe.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/tool/ItemDebug.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemScanner.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/type/CellType.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/model/MaskOverlayModel.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/model/ModelUtil.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/network/DataEncoder.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/network/GrowingBuffer.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/network/RpcHandler.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/profile/Profile.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/profile/ProfileManager.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/profile/ProfileParser.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/ref/BlockName.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/ref/IMultiItem.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/ref/ItemName.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/util/LiquidUtil.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/util/ReflectionUtil.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/util/StackUtil.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/util/Util.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/uu/DropScan.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/uu/RecipeResolver.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/uu/UuGraph.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/GuiOverlayer.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/IC2.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/audio/AudioManagerClient.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockIC2Fence.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockMultiID.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/BlockTileEntity.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/TeBlockRegistry.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/personal/TradingMarket.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/BlockStateUtil.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/EnumProperty.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/Ic2BlockState.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/MaterialProperty.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/transport/items/PipeModel.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/CableModel.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/command/CommandIc2.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/crop/CropModel.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/crop/IC2Crops.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/crop/TileEntityCrop.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/EnergyNetLocal.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Grid.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Tile.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/EventHandler.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Grid.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Tile.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/gui/PlayerHead.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch (100%) rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/init/BlocksItems.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/init/Localization.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemCable.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemPipe.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemDebug.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/item/tool/ItemScanner.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch rename projects/IC2-Base/{patches => patches[2.8.221,+]}/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch (100%) create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/type/CellType.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/MaskOverlayModel.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/ModelUtil.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/DataEncoder.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/GrowingBuffer.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/RpcHandler.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/Profile.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileManager.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileParser.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/BlockName.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/IMultiItem.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/ItemName.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/LiquidUtil.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/ReflectionUtil.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/StackUtil.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/Util.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/DropScan.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/RecipeResolver.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/UuGraph.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch create mode 100644 projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/WorldData.java.patch rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/RenderBlockWall.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/ItemCoke.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.164,2.8.165]}/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/WorldData.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/RenderBlockWall.java.patch rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/machine/tileentity/TileEntityCropHarvester.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/machine/tileentity/TileEntityCropmatron.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/personal/TileEntityTradingTerminal.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/init/BlocksItems.java.patch (100%) create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/ItemCoke.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch create mode 100644 projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch (100%) rename projects/IC2-Patched/{patches => patches[2.8.221,+]}/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch (100%) create mode 100644 src/main/generatedResources/patches/patches[2.8.164,2.8.165]/ic2patches.pack.lzma create mode 100644 src/main/generatedResources/patches/patches[2.8.221,+]/ic2patches.pack.lzma create mode 100644 src/main/java/mods/su5ed/ic2patcher/util/IC2VersionExtractor.java create mode 100644 src/main/java/mods/su5ed/ic2patcher/util/VersionComparison.java diff --git a/build.gradle.kts b/build.gradle.kts index efe6587..f6ef7b8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,7 @@ plugins { idea id("net.minecraftforge.gradle") version "5.0.11" id("de.undercouch.download") version "4.1.1" - id("wtf.gofancy.fancygradle") version "1.0.0" + id("wtf.gofancy.fancygradle") version "1.1.+" } evaluationDependsOnChildren() @@ -29,6 +29,7 @@ val mappingsVersion: String by project val versionIC2: String by project val versionJEI: String by project +val versionForge: String by project version = getGitVersion() group = "mods.su5ed" @@ -56,26 +57,37 @@ minecraft { fancyGradle { patches { - patch(Patch.RESOURCES, Patch.COREMODS, Patch.CODE_CHICKEN_LIB, Patch.ASM) + Patch.RESOURCES + Patch.COREMODS + Patch.CODE_CHICKEN_LIB + Patch.ASM } } repositories { maven { + // JEI Repository name = "Progwml6 maven" url = uri("https://dvs1.progwml6.com/files/maven/") } maven { + // Mirror Maven for JEI + name = "ModMaven" + url = uri("https://modmaven.dev") + } + maven { + // IC2 Repository name = "ic2" url = uri("https://maven.ic2.player.to/") } } dependencies { - minecraft(group = "net.minecraftforge", name = "forge", version = "1.12.2-14.23.5.2855") + minecraft(group = "net.minecraftforge", name = "forge", version = "1.12.2-${versionForge}") implementation(project(":IC2-Patched")) - implementation(fg.deobf(group = "mezz.jei", name = "jei_1.12.2", version = versionJEI)) +// implementation(fg.deobf(group = "mezz.jei", name = "jei_1.12.2", version = versionJEI)) + compileOnly(fg.deobf(group = "mezz.jei", name = "jei_1.12.2", version = versionJEI)) } tasks { @@ -100,7 +112,9 @@ tasks { register("devJar") { val generateDevBinPatches = project(":IC2-Patched").tasks.getByName("generateDevBinPatches") dependsOn(generateDevBinPatches) - from(sourceSets.main.get().output) + from(sourceSets.main.get().output) { + exclude("patches"); + } from(generateDevBinPatches.output) manifest { @@ -117,7 +131,6 @@ tasks { dependsOn(generateBinPatches) from(sourceSets.main.get().output) - from (generateBinPatches.output) manifest { attributes( "FMLCorePlugin" to "mods.su5ed.ic2patcher.asm.PatcherFMLPlugin", @@ -127,6 +140,7 @@ tasks { } register("setup") { + group = "env setup" dependsOn(":IC2-Patched:setup") } @@ -147,6 +161,14 @@ artifacts { archives(tasks.getByName("releaseJar")) } +sourceSets { + main { + resources { + srcDir("src/main/generatedResources") + } + } +} + fun getGitVersion(): String { val jgitver = GitVersionCalculator.location(rootDir) .setNonQualifierBranches("master") diff --git a/gradle.properties b/gradle.properties index 9f8fd51..8fa2b11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,5 +6,6 @@ mappingsChannel=snapshot mappingsVersion=20171003-1.12 versionIC2=2.8.222 -versionJEI=4.15.0.293 +versionJEI=4.16.1.302 versionBuildCraft=7.99.24.7 +versionForge=14.23.5.2860 diff --git a/projects/IC2-Base/build.gradle.kts b/projects/IC2-Base/build.gradle.kts index 8e7c37d..efa4542 100644 --- a/projects/IC2-Base/build.gradle.kts +++ b/projects/IC2-Base/build.gradle.kts @@ -1,3 +1,4 @@ +import codechicken.diffpatch.util.PatchMode import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.minecraftforge.gradle.common.task.JarExec import net.minecraftforge.gradle.patcher.task.TaskApplyPatches @@ -32,6 +33,7 @@ val versionIC2: String by project val versionJEI: String by project val versionBuildCraft: String by project val versionForgeFlower: String by project +val versionForge: String by project val decompiledJar: File = File(buildDir, "decompileIC2/output.jar") val patchedJar: File = File(buildDir, "applyPatches/output.jar") @@ -68,9 +70,11 @@ tasks { group = taskGroup dependsOn("applyStyle") base = processedJar - patches = file("patches/minecraft") + + patches = getPatchesDirectory() rejects = File(buildDir, "$name/rejects.zip") output = patchedJar + patchMode = PatchMode.OFFSET isPrintSummary = true } @@ -86,7 +90,9 @@ tasks { group = taskGroup dependsOn("applyStylePatched") - from(zipTree(processedJarPatched)) + from(zipTree(processedJarPatched)) { + exclude("ic2/api/energy/usage.txt") + } into("src/main/java") } @@ -103,13 +109,30 @@ tasks { register("sourceJar") { dependsOn("classes") archiveClassifier.set("sources") - from(sourceSets.main.get().allJava) + from(sourceSets.main.get().allJava) { + exclude("*.txt") + } + } + + register("sourceJarW-ODep") { + // This dependency didn't allow for generatePatches to work correctly. +// dependsOn("classes") + archiveClassifier.set("sources") + from(sourceSets.main.get().allJava) { + exclude("*.txt") + } + } + + register("sourceJarWithResources") { + dependsOn("classes","extractResources") + archiveClassifier.set("sources-with-resources") + from(sourceSets.main.get().allSource) } register("generatePatches") { group = taskGroup - val sourceJar = getByName("sourceJar") - val outputDir = file("patches/minecraft") + val sourceJar = getByName("sourceJarW-ODep") + var outputDir = getPatchesDirectory() dependsOn(sourceJar, "applyStyle") base = processedJar modified = sourceJar.archiveFile.get().asFile @@ -134,12 +157,11 @@ tasks { } named("shadowJar") { - dependsOn("classes") + dependsOn("classes", "extractSources") configurations = listOf(project.configurations["shade"]) archiveClassifier.set("") - from("src/main/java/ic2") { include("profiles/**") include("sounds/**") @@ -183,7 +205,7 @@ repositories { } dependencies { - minecraft(group = "net.minecraftforge", name = "forge", version = "1.12.2-14.23.5.2855") + minecraft(group = "net.minecraftforge", name = "forge", version = "1.12.2-${versionForge}") ic2(group = "net.industrial-craft", name = "industrialcraft-2", version = "${versionIC2}-ex112", classifier = "dev") compileOnly(group = "mezz.jei", name = "jei_1.12.2", version = versionJEI) @@ -212,24 +234,76 @@ open class ApplyAstyle : DefaultTask() { val out = ZipOutputStream(FileOutputStream(output.get().asFile)) for (entry in zipFile.entries()) { - if (entry.name.startsWith("ic2") && entry.name.endsWith(".java")) { - val txt = BufferedReader(InputStreamReader(zipFile.getInputStream(entry))) - .run { - val builder = StringBuilder() - forEachLine(builder::appendLine) - builder.toString() - } - val reader = StringReader(txt) - - val newEntry = ZipEntry(entry.name) - out.putNextEntry(newEntry) - - val outString = reader.readText().trimEnd() + System.lineSeparator() - out.write(outString.toByteArray()) - out.closeEntry() + if (entry.name.startsWith("ic2")) { + if (entry.name.endsWith(".java")) { + val txt = BufferedReader(InputStreamReader(zipFile.getInputStream(entry))) + .run { + val builder = StringBuilder() + forEachLine(builder::appendLine) + builder.toString() + } + val reader = StringReader(txt) + + val newEntry = ZipEntry(entry.name) + out.putNextEntry(newEntry) + + val outString = reader.readText().trimEnd() + System.lineSeparator() + out.write(outString.toByteArray()) + out.closeEntry() + } else if (entry.name.startsWith("ic2/profiles") || entry.name.startsWith("ic2/sounds")) { + val newEntry = ZipEntry(entry.name) + out.putNextEntry(newEntry) + out.write(zipFile.getInputStream(entry).readBytes()) + out.closeEntry() + } } } out.close() } } + +/** + * Compares two versions separated by dots. Doesn't work with versions schema containing letters. + * Truth table: + * v1 > v2 => true + * v1 == v2 => true + * v1 < v2 => false + * v1 // v2 contain chars -> Integer parsing Exception + */ +fun compareVersions(v1:String, v2:String): Boolean { + val v1s = v1.split("."); + val v2s = v2.split("."); + + val length: Int = if (v1s.size > v2s.size) { v2s.size } else { v1s.size } + for (i in 0 until length) { + val v1i = Integer.parseInt(v1s[i]); + val v2i = Integer.parseInt(v2s[i]) + if (v1i > v2i) { + return true + } else if (v2i > v1i) { + return false; + } + } + return v1s.size >= v2s.size +} + +/** + * Used to get patches directory based on the IC2 Version specified in the Gradle properties. + */ +fun getPatchesDirectory(): File { + project(":IC2-Base").projectDir.listFiles { _, name -> + name.startsWith("patches[") && name.endsWith("]") + }?.forEach { file -> + val name = file.name.toString() + val versions = name.substring(name.indexOf("[")+1, name.indexOf("]")).split(",") + if (versions.size == 2) { + if (compareVersions(versionIC2, versions[0])) { + if (versions[1] == "+" || !compareVersions(versionIC2, versions[1])) { + return file("patches[${versions[0]},${versions[1]}]/minecraft") + } + } + } + } + return File("patches/minecraft") +} \ No newline at end of file diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/GuiOverlayer.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/GuiOverlayer.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/GuiOverlayer.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/GuiOverlayer.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/IC2.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/IC2.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/IC2.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/IC2.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/audio/AudioManagerClient.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/audio/AudioManagerClient.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/audio/AudioManagerClient.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/audio/AudioManagerClient.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/BlockIC2Fence.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockIC2Fence.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/BlockIC2Fence.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockIC2Fence.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/BlockMultiID.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockMultiID.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/BlockMultiID.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockMultiID.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockTileEntity.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockTileEntity.java.patch new file mode 100644 index 0000000..e014f72 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/BlockTileEntity.java.patch @@ -0,0 +1,25 @@ +--- a/ic2/core/block/BlockTileEntity.java ++++ b/ic2/core/block/BlockTileEntity.java +@@ -111,7 +111,7 @@ + private BlockTileEntity(String name, final ResourceLocation identifier) { + super((BlockName)null, TeBlockRegistry.getInfo(identifier).getDefaultMaterial()); + ModContainer modcontainer = Loader.instance().activeModContainer(); +- Optional optional = Loader.instance().getActiveModList().stream().filter((mod) -> { ++ Optional optional = Loader.instance().getActiveModList().stream().filter((mod) -> { + return identifier.getResourceDomain().equals(mod.getModId()); + }).findFirst(); + Loader loader = Loader.instance(); +@@ -673,10 +673,10 @@ + list.addAll(this.getDrops(world, pos, state, fortune)); + } + +- public List getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { +- TileEntityBlock tileentityblock = getTe(world, pos); ++ public List getDrops(IBlockAccess blockAccess, BlockPos pos, IBlockState state, int fortune) { ++ TileEntityBlock tileentityblock = getTe(blockAccess, pos); + if (tileentityblock == null) { +- World world = Util.getWorld(world); ++ World world = Util.getWorld(blockAccess); + if (world != null && world.isRemote || world == null && !IC2.platform.isSimulating()) { + return new ArrayList(); + } diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/TeBlockRegistry.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/TeBlockRegistry.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/TeBlockRegistry.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/TeBlockRegistry.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch new file mode 100644 index 0000000..a539db2 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/invslot/InvSlotUpgrade.java ++++ b/ic2/core/block/invslot/InvSlotUpgrade.java +@@ -31,7 +31,7 @@ + private List redstoneModifiers = Collections.emptyList(); + + public static InvSlotUpgrade createUnchecked(TileEntityInventory base, String name, int count) { +- return new InvSlotUpgrade((TileEntityInventory)((IUpgradableBlock)base), name, count); ++ return new InvSlotUpgrade((TileEntityInventory & IUpgradableBlock)base, name, count); + } + + public InvSlotUpgrade(T base, String name, int count) { diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch new file mode 100644 index 0000000..b2686dd --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch @@ -0,0 +1,13 @@ +--- a/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java ++++ b/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java +@@ -129,8 +129,8 @@ + } + + public boolean canMergeSlot(ItemStack stack, Slot slot) { +- for(Slot slot : this.outputs) { +- if (slot.inventory == slot.inventory) { ++ for(Slot output : this.outputs) { ++ if (output.inventory == slot.inventory) { + return false; + } + } diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch new file mode 100644 index 0000000..3072ad5 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch @@ -0,0 +1,41 @@ +--- a/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java ++++ b/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java +@@ -132,8 +132,9 @@ + this.progress = 0; + this.guiProgress = 0.0F; + +- for(final int i = 0; i < this.ingredientsRow.length; ++i) { +- this.ingredientsRow[i] = new InvSlot(this, "ingredient[" + i + ']', InvSlot.Access.I, 1) { ++ for(int i = 0; i < this.ingredientsRow.length; ++i) { ++ int finalI = i; ++ this.ingredientsRow[i] = new InvSlot(this, "ingredient[" + finalI + ']', InvSlot.Access.I, 1) { + public boolean accepts(ItemStack ingredient) { + IRecipe irecipe = TileEntityBatchCrafter.this.world.isRemote ? TileEntityBatchCrafter.this.findRecipe() : TileEntityBatchCrafter.this.recipe; + if (irecipe == null) { +@@ -141,14 +142,14 @@ + } else { + assert irecipe.matches(TileEntityBatchCrafter.this.crafting, TileEntityBatchCrafter.this.world); + +- ItemStack itemstack = TileEntityBatchCrafter.this.craftingGrid[i]; ++ ItemStack itemstack = TileEntityBatchCrafter.this.craftingGrid[finalI]; + + boolean flag; + try { +- TileEntityBatchCrafter.this.craftingGrid[i] = ingredient; ++ TileEntityBatchCrafter.this.craftingGrid[finalI] = ingredient; + flag = irecipe.matches(TileEntityBatchCrafter.this.crafting, TileEntityBatchCrafter.this.world); + } finally { +- TileEntityBatchCrafter.this.craftingGrid[i] = itemstack; ++ TileEntityBatchCrafter.this.craftingGrid[finalI] = itemstack; + } + + return flag; +@@ -157,7 +158,7 @@ + + public void onChanged() { + super.onChanged(); +- TileEntityBatchCrafter.this.ingredientChange(i); ++ TileEntityBatchCrafter.this.ingredientChange(finalI); + } + }; + } diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/state/BlockStateUtil.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/BlockStateUtil.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/state/BlockStateUtil.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/BlockStateUtil.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/state/EnumProperty.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/EnumProperty.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/state/EnumProperty.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/EnumProperty.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/state/Ic2BlockState.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/Ic2BlockState.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/state/Ic2BlockState.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/Ic2BlockState.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/state/MaterialProperty.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/MaterialProperty.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/state/MaterialProperty.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/state/MaterialProperty.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/transport/items/PipeModel.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/transport/items/PipeModel.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/transport/items/PipeModel.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/transport/items/PipeModel.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/wiring/CableModel.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/wiring/CableModel.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/wiring/CableModel.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/wiring/CableModel.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/command/CommandIc2.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/command/CommandIc2.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/command/CommandIc2.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/command/CommandIc2.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/crop/CropModel.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/crop/CropModel.java.patch new file mode 100644 index 0000000..d6fe292 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/crop/CropModel.java.patch @@ -0,0 +1,16 @@ +--- a/ic2/core/crop/CropModel.java ++++ b/ic2/core/crop/CropModel.java +@@ -52,11 +52,11 @@ + + for(CropCard cropcard : Crops.instance.getCrops()) { + for(ResourceLocation resourcelocation : cropcard.getTexturesLocation()) { +- textures.put(resourcelocation, (Object)null); ++ textures.put(resourcelocation, null); + } + } + +- textures.put(STICK, (Object)null); ++ textures.put(STICK, null); + } + + return textures.keySet(); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/EnergyNetLocal.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/EnergyNetLocal.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/EnergyNetLocal.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/EnergyNetLocal.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/Grid.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/Grid.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/Grid.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/Grid.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/Tile.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/Tile.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/Tile.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/Tile.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/EventHandler.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/EventHandler.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/EventHandler.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/EventHandler.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/Grid.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/Grid.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/Grid.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/Grid.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/Tile.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/Tile.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/grid/Tile.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/grid/Tile.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch new file mode 100644 index 0000000..ec32033 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch @@ -0,0 +1,17 @@ +--- a/ic2/core/gui/Ic2GuiFactory.java ++++ b/ic2/core/gui/Ic2GuiFactory.java +@@ -74,11 +74,11 @@ + Iterator iterator = config.sectionIterator(); + + while(iterator.hasNext()) { +- Config config = iterator.next(); +- if ("predefined".equals(config.name) && ".balance.uu-values.".equals(parentName)) { ++ Config childConfig = iterator.next(); ++ if ("predefined".equals(childConfig.name) && ".balance.uu-values.".equals(parentName)) { + list.add(new Ic2GuiFactory.IC2ConfigGuiScreen.UUListElement()); + } else { +- list.add(new DummyCategoryElement(config.name, "ic2.config.sub." + config.name, sinkCategoryLevel(config, parentName + config.name + '.'))); ++ list.add(new DummyCategoryElement(childConfig.name, "ic2.config.sub." + childConfig.name, sinkCategoryLevel(childConfig, parentName + childConfig.name + '.'))); + } + } + diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch new file mode 100644 index 0000000..18eb9a7 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch @@ -0,0 +1,22 @@ +--- a/ic2/core/gui/dynamic/DynamicHandHeldContainer.java ++++ b/ic2/core/gui/dynamic/DynamicHandHeldContainer.java +@@ -25,15 +25,15 @@ + super.onContainerEvent(event); + } + +- public ItemStack slotClick(int slot, int button, ClickType type, EntityPlayer player) { ++ public ItemStack slotClick(int slotIndex, int button, ClickType type, EntityPlayer player) { + boolean flag = false; + Slot slot = null; +- if (!player.getEntityWorld().isRemote && slot >= 0 && slot < this.inventorySlots.size()) { +- slot = (Slot)this.inventorySlots.get(slot); ++ if (!player.getEntityWorld().isRemote && slotIndex >= 0 && slotIndex < this.inventorySlots.size()) { ++ slot = (Slot)this.inventorySlots.get(slotIndex); + flag = ((HandHeldInventory)this.base).isThisContainer(slot.getStack()); + } + +- ItemStack itemstack = super.slotClick(slot, button, type, player); ++ ItemStack itemstack = super.slotClick(slotIndex, button, type, player); + if (flag && !slot.getHasStack()) { + ((HandHeldInventory)this.base).saveAndThrow(itemstack); + player.closeScreen(); diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch new file mode 100644 index 0000000..a828ce9 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/gui/dynamic/TextProvider.java ++++ b/ic2/core/gui/dynamic/TextProvider.java +@@ -56,7 +56,7 @@ + list = new ArrayList(); + } else if (c0 == '{' && c1 == ',') { + finish(stringbuilder1, list); +- list.add((Object)null); ++ list.add(null); + } else if (c0 == '{' && c1 == '}') { + finish(stringbuilder1, list); + TextProvider.AbstractTextProvider textprovider$abstracttextprovider2 = null; diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch new file mode 100644 index 0000000..d91784b --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch @@ -0,0 +1,26 @@ +--- a/ic2/core/init/BlocksItems.java ++++ b/ic2/core/init/BlocksItems.java +@@ -255,7 +255,7 @@ + ItemMulti.create(ItemName.plate, PlateResourceType.class); + ItemMulti.create(ItemName.casing, CasingResourceType.class); + ItemMulti itemmulti = new ItemNuclearResource(); +- itemmulti.setUpdateHandler((Enum)null, ItemHandlers.radioactiveUpdate); ++ itemmulti.setUpdateHandler(null, ItemHandlers.radioactiveUpdate); + ItemMulti itemmulti1 = ItemMulti.create(ItemName.misc_resource, MiscResourceType.class); + itemmulti1.setRarity(MiscResourceType.matter, EnumRarity.RARE); + itemmulti1.setRarity(MiscResourceType.iridium_ore, EnumRarity.RARE); +@@ -361,11 +361,11 @@ + ItemMulti itemmulti3 = new ItemClassicCell(); + itemmulti3.setUseHandler(CellType.empty, ItemHandlers.emptyCellFill); + itemmulti3.addCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, (stack) -> { +- CellType celltype = (CellType)cell.getType(stack); ++ CellType celltype = (CellType)itemmulti3.getType(stack); + CellType.CellFluidHandler celltype$cellfluidhandler; + if (celltype.isFluidContainer()) { +- cell.getClass(); +- celltype$cellfluidhandler = new CellType.CellFluidHandler(stack, cell::getType); ++ itemmulti3.getClass(); ++ celltype$cellfluidhandler = new CellType.CellFluidHandler(stack, itemmulti3::getType); + } else { + celltype$cellfluidhandler = null; + } diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/init/Localization.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/Localization.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/init/Localization.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/Localization.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/block/ItemCable.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemCable.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/block/ItemCable.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemCable.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/block/ItemPipe.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemPipe.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/block/ItemPipe.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemPipe.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemDebug.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemDebug.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemDebug.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemDebug.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemScanner.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemScanner.java.patch new file mode 100644 index 0000000..4cfa2ba --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemScanner.java.patch @@ -0,0 +1,10 @@ +--- a/ic2/core/item/tool/ItemScanner.java ++++ b/ic2/core/item/tool/ItemScanner.java +@@ -140,6 +140,6 @@ + return ((Integer)b.b).intValue() - ((Integer)a.b).intValue(); + } + }); +- return (int)list; ++ return list; + } + } diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch diff --git a/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch new file mode 100644 index 0000000..401ce1d --- /dev/null +++ b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/tool/ItemToolWrenchNew.java ++++ b/ic2/core/item/tool/ItemToolWrenchNew.java +@@ -94,7 +94,7 @@ + if (block instanceof IWrenchable) { + TileEntity tileentity = world.getTileEntity(pos); + return tileentity instanceof IPipe ? true : Arrays.stream((Object[])EnumFacing.VALUES).anyMatch((face) -> { +- return ((IWrenchable)block).canSetFacing(world, pos, face, player); ++ return ((IWrenchable)block).canSetFacing(world, pos, (EnumFacing) face, player); + }); + } else { + return false; diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/type/CellType.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/type/CellType.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/type/CellType.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/type/CellType.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/model/MaskOverlayModel.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/model/MaskOverlayModel.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/model/MaskOverlayModel.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/model/MaskOverlayModel.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/model/ModelUtil.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/model/ModelUtil.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/model/ModelUtil.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/model/ModelUtil.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/network/DataEncoder.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/network/DataEncoder.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/network/DataEncoder.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/network/DataEncoder.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/network/GrowingBuffer.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/network/GrowingBuffer.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/network/GrowingBuffer.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/network/GrowingBuffer.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/network/RpcHandler.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/network/RpcHandler.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/network/RpcHandler.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/network/RpcHandler.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/profile/Profile.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/profile/Profile.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/profile/Profile.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/profile/Profile.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/profile/ProfileManager.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/profile/ProfileManager.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/profile/ProfileManager.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/profile/ProfileManager.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/profile/ProfileParser.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/profile/ProfileParser.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/profile/ProfileParser.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/profile/ProfileParser.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/ref/BlockName.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/BlockName.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/ref/BlockName.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/BlockName.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/ref/IMultiItem.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/IMultiItem.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/ref/IMultiItem.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/IMultiItem.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/ref/ItemName.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/ItemName.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/ref/ItemName.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/ItemName.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/util/LiquidUtil.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/LiquidUtil.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/util/LiquidUtil.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/LiquidUtil.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/util/ReflectionUtil.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/ReflectionUtil.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/util/ReflectionUtil.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/ReflectionUtil.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/util/StackUtil.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/StackUtil.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/util/StackUtil.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/StackUtil.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/util/Util.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/Util.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/util/Util.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/util/Util.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/uu/DropScan.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/uu/DropScan.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/uu/DropScan.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/uu/DropScan.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/uu/RecipeResolver.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/uu/RecipeResolver.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/uu/RecipeResolver.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/uu/RecipeResolver.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/uu/UuGraph.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/uu/UuGraph.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/uu/UuGraph.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/core/uu/UuGraph.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch b/projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch rename to projects/IC2-Base/patches[2.8.164,2.8.165]/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/GuiOverlayer.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/GuiOverlayer.java.patch new file mode 100644 index 0000000..420a9cc --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/GuiOverlayer.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/GuiOverlayer.java ++++ b/ic2/core/GuiOverlayer.java +@@ -109,7 +109,7 @@ + i1 = i1 + (list.size() + 1) * 14; + } else { + list.addAll(itemstack5.getTooltip(this.mc.player, () -> { +- return hudMode == HudMode.ADVANCED; ++ return hudmode == HudMode.ADVANCED; + })); + if (list.size() > 1) { + for(int j1 = 1; j1 < list.size(); ++j1) { +@@ -136,7 +136,7 @@ + } + } else { + list1.addAll(itemstack6.getTooltip(this.mc.player, () -> { +- return hudMode == HudMode.ADVANCED; ++ return hudmode == HudMode.ADVANCED; + })); + if (list1.size() > 1) { + for(int l1 = 1; l1 < list1.size(); ++l1) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/IC2.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/IC2.java.patch new file mode 100644 index 0000000..90e7cc4 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/IC2.java.patch @@ -0,0 +1,154 @@ +--- a/ic2/core/IC2.java ++++ b/ic2/core/IC2.java +@@ -351,10 +351,8 @@ + } + } + +- Stream stream = list1.stream().map(IForgeRegistryEntry::getRegistryName); +- IForgeRegistryModifiable iforgeregistrymodifiable = (IForgeRegistryModifiable)ForgeRegistries.RECIPES; +- ((IForgeRegistryModifiable)ForgeRegistries.RECIPES).getClass(); +- stream.forEach(iforgeregistrymodifiable::remove); ++ Stream stream = list1.stream().map(IForgeRegistryEntry::getRegistryName); ++ stream.forEach(((IForgeRegistryModifiable)ForgeRegistries.RECIPES)::remove); + if (ConfigUtil.getBool(MainConfig.get(), "recipes/smeltToIc2Items")) { + Map map = FurnaceRecipes.instance().getSmeltingList(); + +@@ -617,69 +615,69 @@ + } else { + EnumFacing enumfacing1 = RotationUtil.rotateByRay(event.getTarget()); + IWrenchable iwrenchable = (IWrenchable)world.getBlockState(blockpos).getBlock(); +- List list = new ArrayList(); ++ List skippedSegments = new ArrayList(); + + for(EnhancedOverlay.Segment enhancedoverlay$segment : EnhancedOverlay.Segment.values()) { +- EnumFacing enumfacing2; ++ EnumFacing spin; + switch(enhancedoverlay$segment) { + case CENTRE: +- enumfacing2 = enumfacing; ++ spin = enumfacing; + break; + case TOP: + if (enumfacing.getAxis().isVertical()) { +- enumfacing2 = EnumFacing.NORTH; ++ spin = EnumFacing.NORTH; + } else { +- enumfacing2 = EnumFacing.UP; ++ spin = EnumFacing.UP; + } + break; + case BOTTOM: + if (enumfacing.getAxis().isVertical()) { +- enumfacing2 = EnumFacing.SOUTH; ++ spin = EnumFacing.SOUTH; + } else { +- enumfacing2 = EnumFacing.DOWN; ++ spin = EnumFacing.DOWN; + } + break; + case LEFT: + if (enumfacing.getAxis().isVertical()) { +- enumfacing2 = EnumFacing.WEST; ++ spin = EnumFacing.WEST; + } else { +- enumfacing2 = enumfacing.rotateY(); ++ spin = enumfacing.rotateY(); + } + break; + case RIGHT: + if (enumfacing.getAxis().isVertical()) { +- enumfacing2 = EnumFacing.EAST; ++ spin = EnumFacing.EAST; + } else { +- enumfacing2 = enumfacing.rotateYCCW(); ++ spin = enumfacing.rotateYCCW(); + } + break; + case TOP_LEFT: + case TOP_RIGHT: + case BOTTOM_LEFT: + case BOTTOM_RIGHT: +- enumfacing2 = enumfacing.getOpposite(); ++ spin = enumfacing.getOpposite(); + break; + default: + throw new IllegalStateException("Unexpected segment: " + enhancedoverlay$segment); + } + +- if (iwrenchable.canSetFacing(world, blockpos, enumfacing2, event.getPlayer())) { +- int i; +- int j; +- int k; +- if (enumfacing1 == enumfacing2) { +- k = 0; +- i = 0; +- j = 255; ++ if (iwrenchable.canSetFacing(world, blockpos, spin, event.getPlayer())) { ++ int green; ++ int red; ++ int blue; ++ if (enumfacing1 == spin) { ++ blue = 0; ++ green = 0; ++ red = 255; + } else { +- j = 0; +- i = 0; +- k = 255; ++ red = 0; ++ green = 0; ++ blue = 255; + } + +- EnhancedOverlay.forFace(enumfacing).drawArea(enhancedoverlay$segment, Tessellator.getInstance().getBuffer(), i, j, k); +- if (enumfacing1 == enumfacing2) { +- if (enumfacing.getOpposite() == enumfacing2) { ++ EnhancedOverlay.forFace(enumfacing).drawArea(enhancedoverlay$segment, Tessellator.getInstance().getBuffer(), green, red, blue); ++ if (enumfacing1 == spin) { ++ if (enumfacing.getOpposite() == spin) { + EnumFacing[] aenumfacing = null; + EnumFacing[] aenumfacing1 = null; + switch(enumfacing.getAxis()) { +@@ -695,8 +693,8 @@ + } + + if (aenumfacing != null) { +- for(EnumFacing enumfacing3 : aenumfacing) { +- map.put(enumfacing3, () -> { ++ for(EnumFacing face : aenumfacing) { ++ map.put(face, () -> { + GlStateManager.color((float)red / 255.0F, (float)green / 255.0F, (float)blue / 255.0F, 0.5F); + EnhancedOverlay.drawArea(face, EnhancedOverlay.Segment.TOP_LEFT, EnhancedOverlay.Segment.TOP, EnhancedOverlay.Segment.TOP_RIGHT, EnhancedOverlay.Segment.BOTTOM_LEFT, EnhancedOverlay.Segment.BOTTOM, EnhancedOverlay.Segment.BOTTOM_RIGHT); + }); +@@ -704,26 +702,26 @@ + } + + if (aenumfacing1 != null) { +- for(EnumFacing enumfacing4 : aenumfacing1) { +- map.put(enumfacing4, () -> { ++ for(EnumFacing face : aenumfacing1) { ++ map.put(face, () -> { + GlStateManager.color((float)red / 255.0F, (float)green / 255.0F, (float)blue / 255.0F, 0.5F); + EnhancedOverlay.drawArea(face, EnhancedOverlay.Segment.TOP_LEFT, EnhancedOverlay.Segment.LEFT, EnhancedOverlay.Segment.BOTTOM_LEFT, EnhancedOverlay.Segment.TOP_RIGHT, EnhancedOverlay.Segment.RIGHT, EnhancedOverlay.Segment.BOTTOM_RIGHT); + }); + } + } + } else if (enhancedoverlay$segment == EnhancedOverlay.Segment.CENTRE) { +- map.put(enumfacing2, () -> { ++ map.put(spin, () -> { + GlStateManager.color((float)red / 255.0F, (float)green / 255.0F, (float)blue / 255.0F, 0.5F); + EnhancedOverlay.drawArea(spin, (EnhancedOverlay.Segment[])skippedSegments.toArray(new EnhancedOverlay.Segment[skippedSegments.size()])); + }); + } else { +- map.put(enumfacing2, () -> { ++ map.put(spin, () -> { + EnhancedOverlay.forFace(spin).drawSide(Tessellator.getInstance().getBuffer(), red, green, blue); + }); + } + } + } else { +- list.add(enhancedoverlay$segment); ++ skippedSegments.add(enhancedoverlay$segment); + } + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/audio/AudioManagerClient.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/audio/AudioManagerClient.java.patch new file mode 100644 index 0000000..a22ced1 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/audio/AudioManagerClient.java.patch @@ -0,0 +1,16 @@ +--- a/ic2/core/audio/AudioManagerClient.java ++++ b/ic2/core/audio/AudioManagerClient.java +@@ -89,10 +89,10 @@ + @SubscribeEvent + public void onSoundSetup(SoundLoadEvent event) { + if (this.enabled) { +- Iterator thread = this.objectToAudioSourceMap.values().iterator(); ++ Iterator> it = this.objectToAudioSourceMap.values().iterator(); + +- while(thread.hasNext()) { +- for(AudioSourceClient audiosourceclient : (List)thread.next()) { ++ while(it.hasNext()) { ++ for(AudioSourceClient audiosourceclient : it.next()) { + if (audiosourceclient.isValid()) { + audiosourceclient.setInvalid(); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockIC2Fence.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockIC2Fence.java.patch new file mode 100644 index 0000000..7c15ed2 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockIC2Fence.java.patch @@ -0,0 +1,29 @@ +--- a/ic2/core/block/BlockIC2Fence.java ++++ b/ic2/core/block/BlockIC2Fence.java +@@ -184,7 +184,7 @@ + state = this.getActualState(state, world, pos); + } + +- addCollisionBoxToList(pos, mask, result, aabbs.get((Object)null)); ++ addCollisionBoxToList(pos, mask, result, aabbs.get(null)); + + for(IProperty iproperty : connectProperties.values()) { + if (((Boolean)state.getValue(iproperty)).booleanValue()) { +@@ -195,7 +195,7 @@ + } + + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { +- AxisAlignedBB axisalignedbb = aabbs.get((Object)null); ++ AxisAlignedBB axisalignedbb = aabbs.get(null); + double d0 = axisalignedbb.minX; + double d1 = 0.0D; + double d2 = axisalignedbb.minZ; +@@ -374,7 +374,7 @@ + Map, AxisAlignedBB> map = new IdentityHashMap, AxisAlignedBB>(connectProperties.size() + 1); + double d0 = 0.375D; + double d1 = 0.625D; +- map.put((Object)null, new AxisAlignedBB(0.375D, 0.0D, 0.375D, 0.625D, 1.5D, 0.625D)); ++ map.put(null, new AxisAlignedBB(0.375D, 0.0D, 0.375D, 0.625D, 1.5D, 0.625D)); + + for(EnumFacing enumfacing : EnumFacing.HORIZONTALS) { + double d2; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockMultiID.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockMultiID.java.patch new file mode 100644 index 0000000..ec79200 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockMultiID.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/BlockMultiID.java ++++ b/ic2/core/block/BlockMultiID.java +@@ -72,7 +72,7 @@ + throw new IllegalArgumentException("ambiguous constructor"); + } + +- constructor = constructor1; ++ constructor = (Constructor) constructor1; + } + } + diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/BlockTileEntity.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockTileEntity.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/BlockTileEntity.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/BlockTileEntity.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/TeBlockRegistry.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/TeBlockRegistry.java.patch new file mode 100644 index 0000000..797bc33 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/TeBlockRegistry.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/block/TeBlockRegistry.java ++++ b/ic2/core/block/TeBlockRegistry.java +@@ -212,7 +212,7 @@ + private final List idMap; + + TeBlockInfo(E universe) { +- this(universe.getClass()); ++ this((Class) universe.getClass()); + } + + TeBlockInfo(Class universe) { +@@ -232,7 +232,7 @@ + int i = ((IIdProvider)block).getId(); + + while(this.idMap.size() < i) { +- this.idMap.add((Object)null); ++ this.idMap.add(null); + } + + if (this.idMap.size() == i) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch new file mode 100644 index 0000000..751c83a --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotConsumableLiquid.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/block/invslot/InvSlotConsumableLiquid.java ++++ b/ic2/core/block/invslot/InvSlotConsumableLiquid.java +@@ -51,7 +51,7 @@ + } + + public FluidStack drain(Fluid fluid, int maxAmount, MutableObject output, boolean simulate) { +- output.setValue((Object)null); ++ output.setValue(null); + if (fluid != null && !this.acceptsLiquid(fluid)) { + return null; + } else if (this.opType != InvSlotConsumableLiquid.OpType.Drain && this.opType != InvSlotConsumableLiquid.OpType.Both) { +@@ -79,7 +79,7 @@ + } + + public int fill(FluidStack fs, MutableObject output, boolean simulate) { +- output.setValue((Object)null); ++ output.setValue(null); + if (fs != null && fs.amount > 0) { + if (this.opType != InvSlotConsumableLiquid.OpType.Fill && this.opType != InvSlotConsumableLiquid.OpType.Both) { + return 0; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch new file mode 100644 index 0000000..933d357 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotProcessableCanner.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/invslot/InvSlotProcessableCanner.java ++++ b/ic2/core/block/invslot/InvSlotProcessableCanner.java +@@ -101,7 +101,7 @@ + return this.getOutput(input, forAccept); + } + +- protected MachineRecipeResult getOutput(Object input, boolean forAccept) { ++ protected MachineRecipeResult getOutput(Object input, boolean forAccept) { + switch(((TileEntityCanner)this.base).getMode()) { + case BottleSolid: + return Recipes.cannerBottle.apply((ICannerBottleRecipeManager.RawInput)input, forAccept); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/invslot/InvSlotUpgrade.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch new file mode 100644 index 0000000..025a1c6 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java ++++ b/ic2/core/block/machine/EmptyFluidContainerRecipeManager.java +@@ -30,7 +30,7 @@ + return null; + } else { + Collection collection = StackUtil.isEmpty(liquidutil$fluidoperationresult.extraOutput) ? Collections.emptyList() : Collections.singletonList(liquidutil$fluidoperationresult.extraOutput); +- return (new MachineRecipe((Object)null, new IEmptyFluidContainerRecipeManager.Output(collection, liquidutil$fluidoperationresult.fluidChange))).getResult(liquidutil$fluidoperationresult.inPlaceOutput); ++ return (new MachineRecipe(null, new IEmptyFluidContainerRecipeManager.Output(collection, liquidutil$fluidoperationresult.fluidChange))).getResult(liquidutil$fluidoperationresult.inPlaceOutput); + } + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch new file mode 100644 index 0000000..d16c6fc --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/FillFluidContainerRecipeManager.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/block/machine/FillFluidContainerRecipeManager.java ++++ b/ic2/core/block/machine/FillFluidContainerRecipeManager.java +@@ -32,7 +32,7 @@ + } else { + Collection collection = StackUtil.isEmpty(liquidutil$fluidoperationresult.extraOutput) ? Collections.emptyList() : Collections.singletonList(liquidutil$fluidoperationresult.extraOutput); + FluidStack fluidstack = liquidutil$fluidoperationresult.fluidChange.amount >= input.fluid.amount ? null : new FluidStack(input.fluid, input.fluid.amount - liquidutil$fluidoperationresult.fluidChange.amount); +- return (new MachineRecipe((Object)null, collection)).getResult(new IFillFluidContainerRecipeManager.Input(liquidutil$fluidoperationresult.inPlaceOutput, fluidstack)); ++ return (new MachineRecipe(null, collection)).getResult(new IFillFluidContainerRecipeManager.Input(liquidutil$fluidoperationresult.inPlaceOutput, fluidstack)); + } + } + } else if (!acceptTest) { +@@ -40,7 +40,7 @@ + } else if (StackUtil.isEmpty(input.container) && input.fluid == null) { + return null; + } else { +- return !StackUtil.isEmpty(input.container) && !LiquidUtil.isFillableFluidContainer(input.container) ? null : (new MachineRecipe((Object)null, Collections.emptyList())).getResult(input); ++ return !StackUtil.isEmpty(input.container) && !LiquidUtil.isFillableFluidContainer(input.container) ? null : (new MachineRecipe(null, Collections.emptyList())).getResult(input); + } + } + diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/container/ContainerIndustrialWorkbench.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch new file mode 100644 index 0000000..3188933 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiFluidRegulator.java.patch @@ -0,0 +1,65 @@ +--- a/ic2/core/block/machine/gui/GuiFluidRegulator.java ++++ b/ic2/core/block/machine/gui/GuiFluidRegulator.java +@@ -29,48 +29,48 @@ + + protected void mouseClicked(int i, int j, int k) throws IOException { + super.mouseClicked(i, j, k); +- int i = (this.width - this.xSize) / 2; +- int j = (this.height - this.ySize) / 2; +- int k = i - i; +- int l = j - j; ++ int i1 = (this.width - this.xSize) / 2; ++ int j1 = (this.height - this.ySize) / 2; ++ int k1 = i1 - i1; ++ int l = j1 - j1; + TileEntityFluidRegulator tileentityfluidregulator = (TileEntityFluidRegulator)((ContainerFluidRegulator)this.container).base; +- if (k >= 102 && l >= 68 && k <= 110 && l <= 76) { ++ if (k1 >= 102 && l >= 68 && k1 <= 110 && l <= 76) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, -1000); + } + +- if (k >= 112 && l >= 68 && k <= 120 && l <= 76) { ++ if (k1 >= 112 && l >= 68 && k1 <= 120 && l <= 76) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, -100); + } + +- if (k >= 122 && l >= 68 && k <= 130 && l <= 76) { ++ if (k1 >= 122 && l >= 68 && k1 <= 130 && l <= 76) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, -10); + } + +- if (k >= 132 && l >= 68 && k <= 140 && l <= 76) { ++ if (k1 >= 132 && l >= 68 && k1 <= 140 && l <= 76) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, -1); + } + +- if (k >= 132 && l >= 44 && k <= 140 && l <= 52) { ++ if (k1 >= 132 && l >= 44 && k1 <= 140 && l <= 52) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, 1); + } + +- if (k >= 122 && l >= 44 && k <= 130 && l <= 52) { ++ if (k1 >= 122 && l >= 44 && k1 <= 130 && l <= 52) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, 10); + } + +- if (k >= 112 && l >= 44 && k <= 120 && l <= 52) { ++ if (k1 >= 112 && l >= 44 && k1 <= 120 && l <= 52) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, 100); + } + +- if (k >= 102 && l >= 44 && k <= 110 && l <= 52) { ++ if (k1 >= 102 && l >= 44 && k1 <= 110 && l <= 52) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, 1000); + } + +- if (k >= 151 && l >= 44 && k <= 161 && l <= 52) { ++ if (k1 >= 151 && l >= 44 && k1 <= 161 && l <= 52) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, 1001); + } + +- if (k >= 151 && l >= 68 && k <= 161 && l <= 76) { ++ if (k1 >= 151 && l >= 68 && k1 <= 161 && l <= 76) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent(tileentityfluidregulator, 1002); + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch new file mode 100644 index 0000000..a15a92c --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/gui/GuiMetalFormer.java.patch @@ -0,0 +1,16 @@ +--- a/ic2/core/block/machine/gui/GuiMetalFormer.java ++++ b/ic2/core/block/machine/gui/GuiMetalFormer.java +@@ -57,10 +57,11 @@ + } + })); + if (RecipeButton.canUse()) { +- for(final int i = 0; i < 3; ++i) { ++ for(int i = 0; i < 3; ++i) { ++ int finalI = i; + this.addElement((new RecipeButton(this, 52, 39, 46, 9, new String[]{"metal_former" + i})).withEnableHandler(new IEnableHandler() { + public boolean isEnabled() { +- return ((TileEntityMetalFormer)container.base).getMode() == i; ++ return ((TileEntityMetalFormer)container.base).getMode() == finalI; + } + })); + } diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch new file mode 100644 index 0000000..7611ac1 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCompressor.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/machine/tileentity/TileEntityCompressor.java ++++ b/ic2/core/block/machine/tileentity/TileEntityCompressor.java +@@ -78,7 +78,7 @@ + + if (fluidstack.amount <= 0) { + this.usingPumpRecipe = true; +- machinereciperesult = (new MachineRecipe((Object)null, Collections.singletonList(new ItemStack(Items.SNOWBALL)))).getResult((Object)null); ++ machinereciperesult = (new MachineRecipe(null, Collections.singletonList(new ItemStack(Items.SNOWBALL)))).getResult(null); + break; + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch new file mode 100644 index 0000000..46c3cb5 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java ++++ b/ic2/core/block/machine/tileentity/TileEntityFluidBottler.java +@@ -59,7 +59,7 @@ + this.outputSlot.add(processResult); + } + +- public MachineRecipeResult getOutput() { ++ public MachineRecipeResult getOutput() { + MachineRecipeResult machinereciperesult = Recipes.emptyFluidContainer.apply(this.drainInputSlot.get(), this.fluidTank.getFluid() == null ? null : this.fluidTank.getFluid().getFluid(), FluidContainerOutputMode.EmptyFullToOutput, false); + if (machinereciperesult != null && (machinereciperesult.getOutput()).fluid.amount <= this.fluidTank.getCapacity() - this.fluidTank.getFluidAmount() && this.outputSlot.canAdd((machinereciperesult.getOutput()).container)) { + return machinereciperesult; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch new file mode 100644 index 0000000..48a0f61 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityScanner.java.patch @@ -0,0 +1,17 @@ +--- a/ic2/core/block/machine/tileentity/TileEntityScanner.java ++++ b/ic2/core/block/machine/tileentity/TileEntityScanner.java +@@ -146,10 +146,10 @@ + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.progress = nbttagcompound.getInteger("progress"); +- NBTTagCompound nbttagcompound = nbttagcompound.getCompoundTag("currentStack"); +- this.currentStack = new ItemStack(nbttagcompound); +- nbttagcompound = nbttagcompound.getCompoundTag("pattern"); +- this.pattern = new ItemStack(nbttagcompound); ++ NBTTagCompound tag = nbttagcompound.getCompoundTag("currentStack"); ++ this.currentStack = new ItemStack(tag); ++ tag = nbttagcompound.getCompoundTag("pattern"); ++ this.pattern = new ItemStack(tag); + int i = nbttagcompound.getInteger("state"); + this.state = i < TileEntityScanner.State.values().length ? TileEntityScanner.State.values()[i] : TileEntityScanner.State.IDLE; + this.refreshInfo(); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/block/personal/TradingMarket.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/personal/TradingMarket.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/block/personal/TradingMarket.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/personal/TradingMarket.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/BlockStateUtil.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/BlockStateUtil.java.patch new file mode 100644 index 0000000..dbf7fdc --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/BlockStateUtil.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/state/BlockStateUtil.java ++++ b/ic2/core/block/state/BlockStateUtil.java +@@ -63,7 +63,7 @@ + + for(IProperty iproperty1 : state.getPropertyKeys()) { + if (iproperty1.getName().equals(name)) { +- iproperty = iproperty1; ++ iproperty = (IProperty) iproperty1; + break; + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/EnumProperty.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/EnumProperty.java.patch new file mode 100644 index 0000000..cb1362b --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/EnumProperty.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/state/EnumProperty.java ++++ b/ic2/core/block/state/EnumProperty.java +@@ -56,7 +56,7 @@ + boolean flag = Version.shouldEnable(oclass); + return (List)this.values.stream().filter((value) -> { + try { +- return Version.shouldEnable(valueClass.getField(value.name()), defaultState); ++ return Version.shouldEnable(oclass.getField(value.name()), flag); + } catch (NoSuchFieldException nosuchfieldexception) { + throw new RuntimeException("Impossible missing enum field!", nosuchfieldexception); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/Ic2BlockState.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/Ic2BlockState.java.patch new file mode 100644 index 0000000..5faa61b --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/Ic2BlockState.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/state/Ic2BlockState.java ++++ b/ic2/core/block/state/Ic2BlockState.java +@@ -169,7 +169,7 @@ + s = stringbuilder.toString(); + } + +- return (int)s; ++ return s; + } + + public boolean hasExtraProperties() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/MaterialProperty.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/MaterialProperty.java.patch new file mode 100644 index 0000000..33218bd --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/state/MaterialProperty.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/state/MaterialProperty.java ++++ b/ic2/core/block/state/MaterialProperty.java +@@ -105,7 +105,7 @@ + try { + for(Field field : Material.class.getFields()) { + if (field.getType() == Material.class) { +- Material material = (Material)field.get((Object)null); ++ Material material = (Material)field.get(null); + MATERIAL_TO_WRAP.put(material, new MaterialProperty.WrappedMaterial(material, field.getName())); + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/transport/items/PipeModel.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/transport/items/PipeModel.java.patch new file mode 100644 index 0000000..efa29bd --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/transport/items/PipeModel.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/block/transport/items/PipeModel.java ++++ b/ic2/core/block/transport/items/PipeModel.java +@@ -58,7 +58,7 @@ + + private static Map generateTextureLocations() { + Map map = new HashMap(); +- map.put(new ResourceLocation("ic2", "blocks/transport/pipe_side"), (Object)null); ++ map.put(new ResourceLocation("ic2", "blocks/transport/pipe_side"), null); + StringBuilder stringbuilder = new StringBuilder(); + stringbuilder.append("blocks/transport/"); + stringbuilder.append("pipe"); +@@ -67,7 +67,7 @@ + for(PipeSize pipesize : PipeSize.values()) { + stringbuilder.append('_'); + stringbuilder.append(pipesize.name()); +- map.put(new ResourceLocation("ic2", stringbuilder.toString()), (Object)null); ++ map.put(new ResourceLocation("ic2", stringbuilder.toString()), null); + stringbuilder.setLength(i); + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/CableModel.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/CableModel.java.patch new file mode 100644 index 0000000..57564cb --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/CableModel.java.patch @@ -0,0 +1,19 @@ +--- a/ic2/core/block/wiring/CableModel.java ++++ b/ic2/core/block/wiring/CableModel.java +@@ -81,13 +81,13 @@ + + for(Ic2Color ic2color : Ic2Color.values) { + stringbuilder.append(ic2color.name()); +- map.put(new ResourceLocation("ic2", stringbuilder.toString()), (Object)null); ++ map.put(new ResourceLocation("ic2", stringbuilder.toString()), null); + stringbuilder.setLength(l); + } + } else { +- map.put(new ResourceLocation("ic2", stringbuilder.toString()), (Object)null); ++ map.put(new ResourceLocation("ic2", stringbuilder.toString()), null); + if (cabletype == CableType.splitter || cabletype == CableType.detector) { +- map.put(new ResourceLocation("ic2", stringbuilder.toString() + "_active"), (Object)null); ++ map.put(new ResourceLocation("ic2", stringbuilder.toString() + "_active"), null); + } + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch new file mode 100644 index 0000000..d8e6253 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/block/wiring/GuiTransformer.java.patch @@ -0,0 +1,15 @@ +--- a/ic2/core/block/wiring/GuiTransformer.java ++++ b/ic2/core/block/wiring/GuiTransformer.java +@@ -33,9 +33,9 @@ + + protected void mouseClicked(int i, int j, int k) throws IOException { + super.mouseClicked(i, j, k); +- int i = i - this.guiLeft; +- int j = j - this.guiTop; +- if (i >= 150 && j >= 32 && i <= 167 && j <= 49) { ++ int i1 = i - this.guiLeft; ++ int j1 = j - this.guiTop; ++ if (i1 >= 150 && j1 >= 32 && i1 <= 167 && j1 <= 49) { + ((NetworkManager)IC2.network.get(false)).initiateClientTileEntityEvent((TileEntity)((ContainerTransformer)this.container).base, 3); + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/command/CommandIc2.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/command/CommandIc2.java.patch new file mode 100644 index 0000000..121e0b2 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/command/CommandIc2.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/command/CommandIc2.java ++++ b/ic2/core/command/CommandIc2.java +@@ -436,7 +436,7 @@ + if (this.pattern.matcher(s).matches()) { + if (this.meta == null) { + if (item instanceof IMultiItem) { +- for(ItemStack itemstack : ((IMultiItem)item).getAllStacks()) { ++ for(ItemStack itemstack : ((IMultiItem)item).getAllStacks()) { + assert itemstack != null : item + " produced a null stack in getAllStacks()"; + + this.dump(itemstack, s); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/crop/CropModel.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/crop/CropModel.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/crop/CropModel.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/crop/CropModel.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/crop/IC2Crops.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/crop/IC2Crops.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/crop/IC2Crops.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/crop/IC2Crops.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/crop/TileEntityCrop.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/crop/TileEntityCrop.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/crop/TileEntityCrop.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/crop/TileEntityCrop.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/EnergyNetLocal.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/EnergyNetLocal.java.patch new file mode 100644 index 0000000..754df9d --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/EnergyNetLocal.java.patch @@ -0,0 +1,30 @@ +--- a/ic2/core/energy/EnergyNetLocal.java ++++ b/ic2/core/energy/EnergyNetLocal.java +@@ -417,14 +417,14 @@ + for(IEnergyTile ienergytile : tile.subTiles) { + for(EnumFacing enumfacing : EnumFacing.VALUES) { + BlockPos blockpos = EnergyNet.instance.getPos(ienergytile).offset(enumfacing); +- Tile tile = this.registeredTiles.get(blockpos); +- if (tile != null && tile != node.tile) { +- for(Node node1 : tile.nodes) { ++ Tile registeredTile = this.registeredTiles.get(blockpos); ++ if (registeredTile != null && registeredTile != node.tile) { ++ for(Node node1 : registeredTile.nodes) { + if (!node1.isExtraNode()) { + boolean flag = false; + if ((node.nodeType == NodeType.Source || node.nodeType == NodeType.Conductor) && node1.nodeType != NodeType.Source) { + IEnergyEmitter ienergyemitter = (IEnergyEmitter)(ienergytile instanceof IEnergyEmitter ? ienergytile : node.tile.mainTile); +- IEnergyTile ienergytile1 = tile.getSubTileAt(blockpos); ++ IEnergyTile ienergytile1 = registeredTile.getSubTileAt(blockpos); + IEnergyAcceptor ienergyacceptor = (IEnergyAcceptor)(ienergytile1 instanceof IEnergyAcceptor ? ienergytile1 : node1.tile.mainTile); + flag = ienergyemitter.emitsEnergyTo((IEnergyAcceptor)node1.tile.mainTile, enumfacing) && ienergyacceptor.acceptsEnergyFrom((IEnergyEmitter)node.tile.mainTile, enumfacing.getOpposite()); + } +@@ -432,7 +432,7 @@ + boolean flag3 = false; + if (!flag && (node.nodeType == NodeType.Sink || node.nodeType == NodeType.Conductor) && node1.nodeType != NodeType.Sink) { + IEnergyAcceptor ienergyacceptor1 = (IEnergyAcceptor)(ienergytile instanceof IEnergyAcceptor ? ienergytile : node.tile.mainTile); +- IEnergyTile ienergytile2 = tile.getSubTileAt(blockpos); ++ IEnergyTile ienergytile2 = registeredTile.getSubTileAt(blockpos); + IEnergyEmitter ienergyemitter1 = (IEnergyEmitter)(ienergytile2 instanceof IEnergyEmitter ? ienergytile2 : node1.tile.mainTile); + flag3 = ienergyacceptor1.acceptsEnergyFrom((IEnergyEmitter)node1.tile.mainTile, enumfacing) && ienergyemitter1.emitsEnergyTo((IEnergyAcceptor)node.tile.mainTile, enumfacing.getOpposite()); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Grid.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Grid.java.patch new file mode 100644 index 0000000..308a7d4 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Grid.java.patch @@ -0,0 +1,2048 @@ +--- a/ic2/core/energy/Grid.java ++++ b/ic2/core/energy/Grid.java +@@ -9,25 +9,6 @@ + import ic2.core.energy.grid.NodeType; + import ic2.core.util.LogCategory; + import ic2.core.util.Util; +-import java.io.FileWriter; +-import java.io.IOException; +-import java.io.PrintStream; +-import java.util.ArrayList; +-import java.util.Arrays; +-import java.util.Collection; +-import java.util.Collections; +-import java.util.HashMap; +-import java.util.HashSet; +-import java.util.Iterator; +-import java.util.LinkedList; +-import java.util.List; +-import java.util.ListIterator; +-import java.util.Map; +-import java.util.Queue; +-import java.util.Set; +-import java.util.concurrent.ExecutionException; +-import java.util.concurrent.Future; +-import java.util.concurrent.RunnableFuture; + import net.minecraft.util.EnumFacing; + import net.minecraft.util.math.BlockPos; + import org.apache.logging.log4j.Level; +@@ -39,8 +20,17 @@ + import org.ejml.interfaces.decomposition.EigenDecomposition; + import org.ejml.ops.MatrixIO; + ++import java.io.FileWriter; ++import java.io.IOException; ++import java.io.OutputStreamWriter; ++import java.io.PrintStream; ++import java.util.*; ++import java.util.concurrent.ExecutionException; ++import java.util.concurrent.Future; ++import java.util.concurrent.RunnableFuture; ++ + class Grid { +- private final int uid = EnergyNetLocal.getNextGridUid(); ++ private final int uid; + private final EnergyNetLocal energyNet; + private final Map nodes = new HashMap(); + private boolean hasNonZeroVoltages = false; +@@ -53,6 +43,7 @@ + private boolean failed; + + Grid(EnergyNetLocal energyNet1) { ++ this.uid = EnergyNetLocal.getNextGridUid(); + this.energyNet = energyNet1; + energyNet1.grids.add(this); + } +@@ -65,413 +56,330 @@ + if (EnergyNetGlobal.debugGrid) { + IC2.log.debug(LogCategory.EnergyNet, "%d Add %s to %s neighbors: %s.", this.uid, node, this, neighbors); + } +- + this.invalidate(); +- +- assert !this.nodes.isEmpty() || neighbors.isEmpty(); +- +- assert this.nodes.isEmpty() || !neighbors.isEmpty() || node.isExtraNode(); +- +- assert node.links.isEmpty(); +- ++ assert (!this.nodes.isEmpty() || neighbors.isEmpty()); ++ assert (this.nodes.isEmpty() || !neighbors.isEmpty() || node.isExtraNode()); ++ assert (node.links.isEmpty()); + this.add(node); +- +- for(Node node : neighbors) { +- assert node != node; +- +- assert this.nodes.containsKey(Integer.valueOf(node.uid)); +- +- double d0 = (node.getInnerLoss() + node.getInnerLoss()) / 2.0D; +- NodeLink nodelink = new NodeLink(node, node, d0); +- node.links.add(nodelink); +- node.links.add(nodelink); ++ for (Node neighbor : neighbors) { ++ assert (neighbor != node); ++ assert (this.nodes.containsKey(neighbor.uid)); ++ double loss = (node.getInnerLoss() + neighbor.getInnerLoss()) / 2.0; ++ NodeLink link = new NodeLink(node, neighbor, loss); ++ node.links.add(link); ++ neighbor.links.add(link); + } +- + } + + void remove(Node node) { ++ Node neighbor; + if (EnergyNetGlobal.debugGrid) { + IC2.log.debug(LogCategory.EnergyNet, "%d Remove Node %s from %s with %d nodes.", this.uid, node, this, this.nodes.size()); + } +- + this.invalidate(); +- Iterator iterator = node.links.iterator(); +- +- while(iterator.hasNext()) { +- NodeLink nodelink = iterator.next(); +- Node node = nodelink.getNeighbor(node); +- boolean flag = false; +- Iterator iterator1 = node.links.iterator(); +- +- while(iterator1.hasNext()) { +- if (iterator1.next() == nodelink) { +- iterator1.remove(); +- flag = true; +- break; +- } +- } +- +- assert flag; +- +- if (node.links.isEmpty() && node.tile.removeExtraNode(node)) { +- iterator.remove(); +- this.nodes.remove(Integer.valueOf(node.uid)); +- node.clearGrid(); +- } ++ Iterator it = node.links.iterator(); ++ while (it.hasNext()) { ++ NodeLink link = it.next(); ++ neighbor = link.getNeighbor(node); ++ boolean found = false; ++ Iterator it2 = neighbor.links.iterator(); ++ while (it2.hasNext()) { ++ if (it2.next() != link) continue; ++ it2.remove(); ++ found = true; ++ break; ++ } ++ assert (found); ++ if (!neighbor.links.isEmpty() || !neighbor.tile.removeExtraNode(neighbor)) continue; ++ it.remove(); ++ this.nodes.remove(neighbor.uid); ++ neighbor.clearGrid(); + } +- +- this.nodes.remove(Integer.valueOf(node.uid)); ++ this.nodes.remove(node.uid); + node.clearGrid(); + if (node.links.isEmpty()) { + this.energyNet.grids.remove(this); + } else if (node.links.size() > 1 && node.nodeType == NodeType.Conductor) { +- iterator = new ArrayList(); +- +- for(int j = 0; j < node.links.size(); ++j) { +- Node node3 = ((NodeLink)node.links.get(j)).getNeighbor(node); +- Set set2 = new HashSet(); +- Queue queue = new LinkedList(Arrays.asList(node3)); +- +- Node node1; +- while((node1 = queue.poll()) != null) { +- if (set2.add(node1) && node1.nodeType == NodeType.Conductor) { +- for(NodeLink nodelink1 : node1.links) { +- Node node2 = nodelink1.getNeighbor(node1); +- if (!set2.contains(node2)) { +- queue.add(node2); +- } +- } ++ int i; ++ ArrayList nodeTable = new ArrayList(); ++ for (i = 0; i < node.links.size(); ++i) { ++ Node cNode; ++ neighbor = node.links.get(i).getNeighbor(node); ++ HashSet connectedNodes = new HashSet(); ++ LinkedList nodesToCheck = new LinkedList(Arrays.asList(neighbor)); ++ while ((cNode = (Node)nodesToCheck.poll()) != null) { ++ if (!connectedNodes.add(cNode) || cNode.nodeType != NodeType.Conductor) continue; ++ for (NodeLink link : cNode.links) { ++ Node nNode = link.getNeighbor(cNode); ++ if (connectedNodes.contains(nNode)) continue; ++ nodesToCheck.add(nNode); + } + } +- +- iterator.add(set2); ++ nodeTable.add(connectedNodes); + } +- +- assert iterator.size() == node.links.size(); +- +- for(int k = 1; k < node.links.size(); ++k) { +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Checking net %d with %d nodes.", this.uid, k, ((Set)iterator.get(k)).size()); +- } +- +- Set set1 = (Set)iterator.get(k); +- Node node4 = ((NodeLink)node.links.get(k)).getNeighbor(node); +- +- assert set1.contains(node4); +- +- boolean flag1 = true; +- +- for(int l = 0; l < k; ++l) { +- Set set3 = (Set)iterator.get(l); +- if (set3.contains(node4)) { ++ assert (nodeTable.size() == node.links.size()); ++ for (i = 1; i < node.links.size(); ++i) { ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Checking net %d with %d nodes.", this.uid, i, ((Set)nodeTable.get(i)).size()); ++ } ++ Set connectedNodes = (Set)nodeTable.get(i); ++ Node neighbor2 = node.links.get(i).getNeighbor(node); ++ assert (connectedNodes.contains(neighbor2)); ++ boolean split = true; ++ for (int j = 0; j < i; ++j) { ++ Set cmpList = (Set)nodeTable.get(j); ++ if (!cmpList.contains(neighbor2)) continue; ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Same as %d.", this.uid, j); ++ } ++ split = false; ++ break; ++ } ++ if (!split) continue; ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Moving nodes %s.", this.uid, connectedNodes); ++ } ++ Grid grid = new Grid(this.energyNet); ++ for (Node cNode : connectedNodes) { ++ boolean needsExtraNode = false; ++ if (!cNode.links.isEmpty() && cNode.nodeType != NodeType.Conductor) { ++ for (int j = 0; j < i; ++j) { ++ Set cmpList = (Set)nodeTable.get(j); ++ if (!cmpList.contains(cNode)) continue; ++ needsExtraNode = true; ++ break; ++ } ++ } ++ if (needsExtraNode) { + if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Same as %d.", this.uid, l); +- } +- +- flag1 = false; +- break; ++ IC2.log.debug(LogCategory.EnergyNet, "%s Create extra Node for %s.", this.uid, cNode); ++ } ++ Node extraNode = new Node(this.energyNet, cNode.tile, cNode.nodeType); ++ cNode.tile.addExtraNode(extraNode); ++ Iterator it2 = cNode.links.iterator(); ++ while (it2.hasNext()) { ++ NodeLink link = it2.next(); ++ if (!connectedNodes.contains(link.getNeighbor(cNode))) continue; ++ link.replaceNode(cNode, extraNode); ++ extraNode.links.add(link); ++ it2.remove(); ++ } ++ assert (!extraNode.links.isEmpty()); ++ grid.add(extraNode); ++ assert (extraNode.getGrid() != null); ++ continue; + } +- } +- +- if (flag1) { + if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Moving nodes %s.", this.uid, set1); +- } +- +- Grid grid = new Grid(this.energyNet); +- +- for(Node node5 : set1) { +- boolean flag2 = false; +- if (!node5.links.isEmpty() && node5.nodeType != NodeType.Conductor) { +- for(int i = 0; i < k; ++i) { +- Set set = (Set)iterator.get(i); +- if (set.contains(node5)) { +- flag2 = true; +- break; +- } +- } +- } +- +- if (flag2) { +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%s Create extra Node for %s.", this.uid, node5); +- } +- +- Node node6 = new Node(this.energyNet, node5.tile, node5.nodeType); +- node5.tile.addExtraNode(node6); +- Iterator iterator2 = node5.links.iterator(); +- +- while(iterator2.hasNext()) { +- NodeLink nodelink2 = iterator2.next(); +- if (set1.contains(nodelink2.getNeighbor(node5))) { +- nodelink2.replaceNode(node5, node6); +- node6.links.add(nodelink2); +- iterator2.remove(); +- } +- } +- +- assert !node6.links.isEmpty(); +- +- grid.add(node6); +- +- assert node6.getGrid() != null; +- } else { +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Move Node %s.", this.uid, node5); +- } +- +- assert this.nodes.containsKey(Integer.valueOf(node5.uid)); +- +- this.nodes.remove(Integer.valueOf(node5.uid)); +- node5.clearGrid(); +- grid.add(node5); +- +- assert node5.getGrid() != null; +- } +- } ++ IC2.log.debug(LogCategory.EnergyNet, "%d Move Node %s.", this.uid, cNode); ++ } ++ assert (this.nodes.containsKey(cNode.uid)); ++ this.nodes.remove(cNode.uid); ++ cNode.clearGrid(); ++ grid.add(cNode); ++ assert (cNode.getGrid() != null); + } + } + } +- + } + + void merge(Grid grid, Map nodeReplacements) { + if (EnergyNetGlobal.debugGrid) { + IC2.log.debug(LogCategory.EnergyNet, "%d Merge %s -> %s.", this.uid, grid, this); + } +- +- assert this.energyNet.grids.contains(grid); +- ++ assert (this.energyNet.grids.contains(grid)); + this.invalidate(); +- +- for(Node node : grid.nodes.values()) { +- boolean flag = false; ++ for (Node node : grid.nodes.values()) { ++ boolean found = false; + if (node.nodeType != NodeType.Conductor) { +- for(Node node1 : this.nodes.values()) { +- if (node1.tile == node.tile && node1.nodeType == node.nodeType) { +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Merge Node %s -> %s.", this.uid, node, node1); +- } +- +- flag = true; +- +- for(NodeLink nodelink : node.links) { +- nodelink.replaceNode(node, node1); +- node1.links.add(nodelink); +- } +- +- node1.tile.removeExtraNode(node); +- nodeReplacements.put(node, node1); +- break; +- } +- } +- } +- +- if (!flag) { +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Add Node %s.", this.uid, node); +- } +- +- node.clearGrid(); +- this.add(node); +- +- assert node.getGrid() != null; +- } ++ for (Node node2 : this.nodes.values()) { ++ if (node2.tile != node.tile || node2.nodeType != node.nodeType) continue; ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Merge Node %s -> %s.", this.uid, node, node2); ++ } ++ found = true; ++ for (NodeLink link : node.links) { ++ link.replaceNode(node, node2); ++ node2.links.add(link); ++ } ++ node2.tile.removeExtraNode(node); ++ nodeReplacements.put(node, node2); ++ break; ++ } ++ } ++ if (found) continue; ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Add Node %s.", this.uid, node); ++ } ++ node.clearGrid(); ++ this.add(node); ++ assert (node.getGrid() != null); + } +- + if (EnergyNetGlobal.debugGrid) { + IC2.log.debug(LogCategory.EnergyNet, "Remove %s.", grid); + } +- + this.energyNet.grids.remove(grid); + } + + void prepareCalculation() { +- assert this.calculation == null; +- ++ assert (this.calculation == null); + if (!this.activeSources.isEmpty()) { + this.activeSources.clear(); + } +- + if (!this.activeSinks.isEmpty()) { + this.activeSinks.clear(); + } +- +- List list = new ArrayList(); +- int i = 0; +- +- for(Node node : this.nodes.values()) { +- assert node.getGrid() == this; +- +- switch(node.nodeType) { +- case Source: +- IEnergySource ienergysource = (IEnergySource)node.tile.mainTile; +- node.setTier(ienergysource.getSourceTier()); +- node.setAmount(ienergysource.getOfferedEnergy()); +- if (node.getAmount() > 0.0D) { +- this.activeSources.add(Integer.valueOf(node.uid)); +- i = Math.max(node.getTier(), i); +- } else { +- node.setAmount(0.0D); +- } +- break; +- case Sink: +- IEnergySink ienergysink = (IEnergySink)node.tile.mainTile; +- node.setTier(ienergysink.getSinkTier()); +- node.setAmount(ienergysink.getDemandedEnergy()); +- if (node.getAmount() > 0.0D) { +- this.activeSinks.add(Integer.valueOf(node.uid)); +- if (node.getTier() == Integer.MAX_VALUE) { +- list.add(node); +- } +- } else { +- node.setAmount(0.0D); +- } +- break; +- case Conductor: +- node.setAmount(0.0D); ++ ArrayList dynamicTierNodes = new ArrayList(); ++ int maxSourceTier = 0; ++ for (Node node : this.nodes.values()) { ++ assert (node.getGrid() == this); ++ switch (node.nodeType) { ++ case Source: { ++ IEnergySource source = (IEnergySource)node.tile.mainTile; ++ node.setTier(source.getSourceTier()); ++ node.setAmount(source.getOfferedEnergy()); ++ if (node.getAmount() > 0.0) { ++ this.activeSources.add(node.uid); ++ maxSourceTier = Math.max(node.getTier(), maxSourceTier); ++ break; ++ } ++ node.setAmount(0.0); ++ break; ++ } ++ case Sink: { ++ IEnergySink sink = (IEnergySink)node.tile.mainTile; ++ node.setTier(sink.getSinkTier()); ++ node.setAmount(sink.getDemandedEnergy()); ++ if (node.getAmount() > 0.0) { ++ this.activeSinks.add(node.uid); ++ if (node.getTier() != Integer.MAX_VALUE) break; ++ dynamicTierNodes.add(node); ++ break; ++ } ++ node.setAmount(0.0); ++ break; ++ } ++ case Conductor: { ++ node.setAmount(0.0); ++ } + } +- +- assert node.getAmount() >= 0.0D; +- } +- +- for(Node node1 : list) { +- node1.setTier(i); +- } +- ++ assert (node.getAmount() >= 0.0); ++ } ++ for (Node node : dynamicTierNodes) { ++ node.setTier(maxSourceTier); ++ } + } + + Runnable startCalculation() { +- assert this.calculation == null; +- ++ assert (this.calculation == null); + if (this.failed) { + IC2.log.warn(LogCategory.EnergyNet, "Calculation failed previously, skipping calculation."); + return null; +- } else { +- boolean flag = this.hasNonZeroVoltages; +- if (!this.activeSinks.isEmpty() && !this.activeSources.isEmpty()) { +- flag = true; +- Iterator task = this.activeSources.iterator(); +- +- while(task.hasNext()) { +- int i = ((Integer)task.next()).intValue(); +- Node node = this.nodes.get(Integer.valueOf(i)); +- int j = 1; +- +- for(Node node1 : node.tile.nodes) { +- if (node1.uid != i && node1.nodeType == NodeType.Source && !node1.getGrid().activeSinks.isEmpty()) { +- assert node1.getGrid().activeSources.contains(Integer.valueOf(node1.uid)); +- +- assert node1.getGrid() != this; +- +- ++j; +- } +- } +- +- node.setAmount(node.getAmount() / (double)j); +- IEnergySource ienergysource = (IEnergySource)node.tile.mainTile; +- ienergysource.drawEnergy(node.getAmount()); +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %s %f EU", this.uid, node, -node.getAmount()); +- } ++ } ++ boolean run = this.hasNonZeroVoltages; ++ if (!this.activeSinks.isEmpty() && !this.activeSources.isEmpty()) { ++ run = true; ++ for (int nodeId : this.activeSources) { ++ Node node = this.nodes.get(nodeId); ++ int shareCount = 1; ++ for (Node shared : node.tile.nodes) { ++ if (shared.uid == nodeId || shared.nodeType != NodeType.Source || shared.getGrid().activeSinks.isEmpty()) continue; ++ assert (shared.getGrid().activeSources.contains(shared.uid)); ++ assert (shared.getGrid() != this); ++ ++shareCount; + } +- } +- +- if (flag) { +- RunnableFuture> runnablefuture = IC2.getInstance().threadPool.>makeTask(new GridCalculation(this)); +- this.calculation = runnablefuture; +- return runnablefuture; +- } else { +- return null; +- } +- } ++ node.setAmount(node.getAmount() / (double)shareCount); ++ IEnergySource source = (IEnergySource)node.tile.mainTile; ++ source.drawEnergy(node.getAmount()); ++ if (!EnergyNetGlobal.debugGrid) continue; ++ IC2.log.debug(LogCategory.EnergyNet, "%d %s %f EU", this.uid, node, -node.getAmount()); ++ } ++ } ++ if (run) { ++ RunnableFuture> task = IC2.getInstance().threadPool.makeTask(new GridCalculation(this)); ++ this.calculation = task; ++ return task; ++ } ++ return null; + } + + void finishCalculation() { +- if (this.calculation != null) { +- try { +- for(Node node : this.calculation.get()) { +- EnumFacing enumfacing; +- if (!node.links.isEmpty()) { +- enumfacing = ((NodeLink)node.links.get(0)).getDirFrom(node); +- } else { +- enumfacing = null; +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.warn(LogCategory.EnergyNet, "Can't determine direction for %s.", node); +- this.dumpNodeInfo(IC2.log.getPrintStream(LogCategory.EnergyNet, Level.DEBUG), false, node); +- this.dumpGraph(false); +- } ++ if (this.calculation == null) { ++ return; ++ } ++ try { ++ Iterable result = this.calculation.get(); ++ for (Node node : result) { ++ EnumFacing dir; ++ if (!node.links.isEmpty()) { ++ dir = node.links.get(0).getDirFrom(node); ++ } else { ++ dir = null; ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.warn(LogCategory.EnergyNet, "Can't determine direction for %s.", node); ++ this.dumpNodeInfo(IC2.log.getPrintStream(LogCategory.EnergyNet, Level.DEBUG), false, node); ++ this.dumpGraph(false); + } +- +- this.energyNet.addChange(node, enumfacing, node.getAmount(), node.getVoltage()); + } +- } catch (InterruptedException interruptedexception) { +- IC2.log.debug(LogCategory.EnergyNet, interruptedexception, "Calculation interrupted."); +- } catch (ExecutionException executionexception) { +- IC2.log.warn(LogCategory.EnergyNet, executionexception, "Calculation failed."); +- PrintStream printstream = IC2.log.getPrintStream(LogCategory.EnergyNet, Level.WARN); +- this.dumpStats(printstream, false); +- this.dumpMatrix(printstream, false, true, true); +- this.dumpGraph(false); +- this.failed = true; ++ this.energyNet.addChange(node, dir, node.getAmount(), node.getVoltage()); + } +- +- this.calculation = null; +- } ++ } ++ catch (InterruptedException e) { ++ IC2.log.debug(LogCategory.EnergyNet, e, "Calculation interrupted."); ++ } ++ catch (ExecutionException e) { ++ IC2.log.warn(LogCategory.EnergyNet, e, "Calculation failed."); ++ PrintStream ps = IC2.log.getPrintStream(LogCategory.EnergyNet, Level.WARN); ++ this.dumpStats(ps, false); ++ this.dumpMatrix(ps, false, true, true); ++ this.dumpGraph(false); ++ this.failed = true; ++ } ++ this.calculation = null; + } + + void updateStats() { + if (this.lastVoltagesNeedUpdate) { + this.lastVoltagesNeedUpdate = false; +- +- for(Node node : this.nodes.values()) { ++ for (Node node : this.nodes.values()) { + node.updateStats(); + } + } +- + } + + Iterable calculate() { + this.lastVoltagesNeedUpdate = true; +- if (!this.activeSources.isEmpty() && !this.activeSinks.isEmpty()) { +- StructureCache.Data structurecache$data = this.calculateDistribution(); +- this.calculateEffects(structurecache$data); +- this.activeSources.clear(); +- this.activeSinks.clear(); +- List list = new ArrayList(); +- +- for(Node node1 : structurecache$data.activeNodes) { +- if (node1.nodeType == NodeType.Sink || node1.nodeType == NodeType.Source) { +- list.add(node1.getTop()); +- } +- } +- +- this.hasNonZeroVoltages = true; +- return list; +- } else { +- for(Node node : this.nodes.values()) { +- node.setVoltage(0.0D); ++ if (this.activeSources.isEmpty() || this.activeSinks.isEmpty()) { ++ for (Node node : this.nodes.values()) { ++ node.setVoltage(0.0); + node.resetCurrents(); + } +- + if (!this.activeSources.isEmpty()) { + this.activeSources.clear(); + } +- + if (!this.activeSinks.isEmpty()) { + this.activeSinks.clear(); + } +- + this.hasNonZeroVoltages = false; + return new ArrayList(); + } ++ StructureCache.Data data = this.calculateDistribution(); ++ this.calculateEffects(data); ++ this.activeSources.clear(); ++ this.activeSinks.clear(); ++ ArrayList ret = new ArrayList(); ++ for (Node node : data.activeNodes) { ++ if (node.nodeType != NodeType.Sink && node.nodeType != NodeType.Source) continue; ++ ret.add(node.getTop()); ++ } ++ this.hasNonZeroVoltages = true; ++ return ret; + } + + private void add(Node node) { + node.setGrid(this); +- Node node = this.nodes.put(Integer.valueOf(node.uid), node); +- if (node != null) { +- throw new IllegalStateException("duplicate node uid, new " + node + ", old " + node); ++ Node prev = this.nodes.put(node.uid, node); ++ if (prev != null) { ++ throw new IllegalStateException("duplicate node uid, new " + node + ", old " + prev); + } + } + +@@ -481,725 +389,540 @@ + } + + private StructureCache.Data calculateDistribution() { +- long i = System.nanoTime(); +- StructureCache.Data structurecache$data = this.cache.get(this.activeSources, this.activeSinks); +- this.lastData = structurecache$data; +- if (!structurecache$data.isInitialized) { +- this.copyForOptimize(structurecache$data); +- this.optimize(structurecache$data); +- determineEmittingNodes(structurecache$data); +- int j = structurecache$data.activeNodes.size(); +- structurecache$data.networkMatrix = new DenseMatrix64F(j, j); +- structurecache$data.sourceMatrix = new DenseMatrix64F(j, 1); +- structurecache$data.resultMatrix = new DenseMatrix64F(j, 1); +- structurecache$data.solver = LinearSolverFactory.symmPosDef(j); ++ StructureCache.Data data; ++ long time = System.nanoTime(); ++ this.lastData = data = this.cache.get(this.activeSources, this.activeSinks); ++ if (!data.isInitialized) { ++ this.copyForOptimize(data); ++ this.optimize(data); ++ Grid.determineEmittingNodes(data); ++ int size = data.activeNodes.size(); ++ data.networkMatrix = new DenseMatrix64F(size, size); ++ data.sourceMatrix = new DenseMatrix64F(size, 1); ++ data.resultMatrix = new DenseMatrix64F(size, 1); ++ data.solver = LinearSolverFactory.symmPosDef(size); + if (!EnergyNetLocal.useLinearTransferModel) { +- populateNetworkMatrix(structurecache$data); +- initializeSolver(structurecache$data); +- if (structurecache$data.solver instanceof LinearSolver_B64_to_D64) { +- structurecache$data.networkMatrix = null; ++ Grid.populateNetworkMatrix(data); ++ Grid.initializeSolver(data); ++ if (data.solver instanceof LinearSolver_B64_to_D64) { ++ data.networkMatrix = null; + } + } +- +- structurecache$data.isInitialized = true; ++ data.isInitialized = true; + } +- + if (EnergyNetLocal.useLinearTransferModel) { +- populateNetworkMatrix(structurecache$data); +- initializeSolver(structurecache$data); ++ Grid.populateNetworkMatrix(data); ++ Grid.initializeSolver(data); + } +- +- this.populateSourceMatrix(structurecache$data); ++ this.populateSourceMatrix(data); + if (EnergyNetGlobal.debugGridVerbose) { + this.dumpMatrix(IC2.log.getPrintStream(LogCategory.EnergyNet, Level.TRACE), false, true, false); + } +- +- structurecache$data.solver.solve(structurecache$data.sourceMatrix, structurecache$data.resultMatrix); +- +- assert !structurecache$data.solver.modifiesB(); +- ++ data.solver.solve(data.sourceMatrix, data.resultMatrix); ++ assert (!data.solver.modifiesB()); + if (EnergyNetGlobal.debugGridVerbose) { + this.dumpMatrix(IC2.log.getPrintStream(LogCategory.EnergyNet, Level.TRACE), false, false, true); + } +- + if (EnergyNetGlobal.debugGrid) { +- i = System.nanoTime() - i; +- IC2.log.debug(LogCategory.EnergyNet, "%d The distribution calculation took %d us.", this.uid, i / 1000L); ++ time = System.nanoTime() - time; ++ IC2.log.debug(LogCategory.EnergyNet, "%d The distribution calculation took %d us.", this.uid, time / 1000L); + } +- +- return structurecache$data; ++ return data; + } + + private static void initializeSolver(StructureCache.Data data) { + if (!data.solver.setA(data.networkMatrix)) { +- int i = data.networkMatrix.numCols; ++ int size = data.networkMatrix.numCols; + if (data.solver.modifiesA()) { +- populateNetworkMatrix(data); ++ Grid.populateNetworkMatrix(data); + } +- +- data.solver = LinearSolverFactory.linear(i); ++ data.solver = LinearSolverFactory.linear(size); + if (!data.solver.setA(data.networkMatrix)) { ++ EigenDecomposition ed; + if (data.solver.modifiesA()) { +- populateNetworkMatrix(data); ++ Grid.populateNetworkMatrix(data); + } +- +- EigenDecomposition eigendecomposition = DecompositionFactory.eig(i, false); +- if (eigendecomposition.decompose(data.networkMatrix)) { +- int j = i; +- int k = i; +- StringBuilder stringbuilder = new StringBuilder("Eigen values: "); +- +- for(int l = 0; l < i; ++l) { +- Complex64F complex64f = eigendecomposition.getEigenvalue(l); +- if (complex64f.isReal()) { +- --j; +- } +- +- if (complex64f.real > 0.0D) { +- --k; +- } +- +- if (l != 0) { +- stringbuilder.append(", "); +- } +- +- stringbuilder.append((Object)complex64f); ++ if ((ed = DecompositionFactory.eig(size, false)).decompose(data.networkMatrix)) { ++ int complex = size; ++ int nonPositive = size; ++ StringBuilder sb = new StringBuilder("Eigen values: "); ++ for (int i = 0; i < size; ++i) { ++ Complex64F ev = ed.getEigenvalue(i); ++ if (ev.isReal()) { ++ --complex; ++ } ++ if (ev.real > 0.0) { ++ --nonPositive; ++ } ++ if (i != 0) { ++ sb.append(", "); ++ } ++ sb.append(ev); + } +- +- IC2.log.info(LogCategory.EnergyNet, stringbuilder.toString()); +- IC2.log.info(LogCategory.EnergyNet, "Total: %d, complex: %d, non positive: %d", i, j, k); ++ IC2.log.info(LogCategory.EnergyNet, sb.toString()); ++ IC2.log.info(LogCategory.EnergyNet, "Total: %d, complex: %d, non positive: %d", size, complex, nonPositive); + } else { + IC2.log.info(LogCategory.EnergyNet, "Unable to compute the eigen values."); + } +- +- if (eigendecomposition.inputModified()) { +- populateNetworkMatrix(data); ++ if (ed.inputModified()) { ++ Grid.populateNetworkMatrix(data); + } +- + throw new RuntimeException("Can't decompose network matrix."); + } + } +- + } + + private void calculateEffects(StructureCache.Data data) { +- long i = System.nanoTime(); +- +- for(Node node : this.nodes.values()) { ++ long time = System.nanoTime(); ++ for (Node node : this.nodes.values()) { + node.setVoltage(Double.NaN); + node.resetCurrents(); + } +- +- for(int j = 0; j < data.activeNodes.size(); ++j) { +- Node node4 = data.activeNodes.get(j); +- node4.setVoltage(data.resultMatrix.get(j)); +- switch(node4.nodeType) { +- case Source: +- double d3; +- if (EnergyNetLocal.useLinearTransferModel) { +- d3 = data.sourceMatrix.get(j) - node4.getVoltage() / node4.getResistance(); +- double d1 = d3 * node4.getVoltage(); +- +- assert d1 >= 0.0D : d1 + " (u=" + node4.getVoltage() + ")"; +- +- assert d1 <= node4.getAmount() : d1 + " <= " + node4.getAmount() + " (u=" + node4.getVoltage() + ")"; +- +- node4.setAmount(d1 - node4.getAmount()); +- } else { +- d3 = node4.getAmount(); +- node4.setAmount(0.0D); +- } +- +- assert node4.getAmount() <= 0.0D; +- +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %s %f EU, %f V, %f A.", this.uid, node4, -node4.getAmount(), node4.getVoltage(), -d3); +- } +- break; +- case Sink: +- double d0; +- if (EnergyNetLocal.useLinearTransferModel) { +- d0 = node4.getVoltage() / node4.getResistance(); +- node4.setAmount(node4.getVoltage() * d0); +- } else { +- d0 = node4.getVoltage(); +- node4.setAmount(d0); +- } +- +- assert node4.getAmount() >= 0.0D; +- +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %s %f EU, %f V, %f A.", this.uid, node4, node4.getAmount(), node4.getVoltage(), d0); +- } +- case Conductor: +- } +- } +- +- Set set = EnergyNetGlobal.verifyGrid() ? new HashSet() : null; +- +- for(Node node5 : data.activeNodes) { +- for(NodeLink nodelink1 : node5.links) { +- if (nodelink1.nodeA == node5) { +- Node node1 = nodelink1.nodeA.getTop(); +- Node node2 = nodelink1.nodeB.getTop(); +- double d2 = nodelink1.loss; +- +- for(Node node3 : nodelink1.skippedNodes) { +- assert node3.nodeType == NodeType.Conductor; +- +- node3 = node3.getTop(); +- if (!Double.isNaN(node3.getVoltage())) { +- assert false; +- break; +- } +- +- NodeLink nodelink = node1.getConnectionTo(node3); +- +- assert nodelink != null; +- +- assert !EnergyNetGlobal.verifyGrid() || set.add(nodelink); +- +- node3.setVoltage(Util.lerp(node1.getVoltage(), node2.getVoltage(), nodelink.loss / d2)); +- nodelink.updateCurrent(); +- node1 = node3; +- d2 -= nodelink.loss; +- } +- +- node1.getConnectionTo(node2).updateCurrent(); +- } +- } +- } +- +- i = System.nanoTime() - i; ++ block5: for (int row = 0; row < data.activeNodes.size(); ++row) { ++ Node node; ++ node = data.activeNodes.get(row); ++ node.setVoltage(data.resultMatrix.get(row)); ++ switch (node.nodeType) { ++ case Source: { ++ double current; ++ if (EnergyNetLocal.useLinearTransferModel) { ++ current = data.sourceMatrix.get(row) - node.getVoltage() / node.getResistance(); ++ double actualAmount = current * node.getVoltage(); ++ assert (actualAmount >= 0.0) : actualAmount + " (u=" + node.getVoltage() + ")"; ++ assert (actualAmount <= node.getAmount()) : actualAmount + " <= " + node.getAmount() + " (u=" + node.getVoltage() + ")"; ++ node.setAmount(actualAmount - node.getAmount()); ++ } else { ++ current = node.getAmount(); ++ node.setAmount(0.0); ++ } ++ assert (node.getAmount() <= 0.0); ++ if (!EnergyNetGlobal.debugGrid) continue block5; ++ IC2.log.debug(LogCategory.EnergyNet, "%d %s %f EU, %f V, %f A.", this.uid, node, -node.getAmount(), node.getVoltage(), -current); ++ continue block5; ++ } ++ case Sink: { ++ double current; ++ if (EnergyNetLocal.useLinearTransferModel) { ++ current = node.getVoltage() / node.getResistance(); ++ node.setAmount(node.getVoltage() * current); ++ } else { ++ current = node.getVoltage(); ++ node.setAmount(current); ++ } ++ assert (node.getAmount() >= 0.0); ++ if (!EnergyNetGlobal.debugGrid) continue block5; ++ IC2.log.debug(LogCategory.EnergyNet, "%d %s %f EU, %f V, %f A.", this.uid, node, node.getAmount(), node.getVoltage(), current); ++ continue block5; ++ } ++ } ++ } ++ HashSet visitedLinks = EnergyNetGlobal.verifyGrid() ? new HashSet() : null; ++ for (Node node : data.activeNodes) { ++ for (NodeLink link : node.links) { ++ if (link.nodeA != node) continue; ++ Node nodeA = link.nodeA.getTop(); ++ Node nodeB = link.nodeB.getTop(); ++ double totalLoss = link.loss; ++ for (Node skipped : link.skippedNodes) { ++ assert (skipped.nodeType == NodeType.Conductor); ++ if (!Double.isNaN((skipped = skipped.getTop()).getVoltage())) { ++ assert (false); ++ break; ++ } ++ NodeLink link2 = nodeA.getConnectionTo(skipped); ++ assert (link2 != null); ++ if (EnergyNetGlobal.verifyGrid()) assert (visitedLinks.add(link2)); ++ skipped.setVoltage(Util.lerp(nodeA.getVoltage(), nodeB.getVoltage(), link2.loss / totalLoss)); ++ link2.updateCurrent(); ++ nodeA = skipped; ++ totalLoss -= link2.loss; ++ } ++ nodeA.getConnectionTo(nodeB).updateCurrent(); ++ } ++ } ++ time = System.nanoTime() - time; + if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d The effect calculation took %d us.", this.uid, i / 1000L); ++ IC2.log.debug(LogCategory.EnergyNet, "%d The effect calculation took %d us.", this.uid, time / 1000L); + } +- + } + + private void copyForOptimize(StructureCache.Data data) { + data.optimizedNodes = new HashMap(); +- +- for(Node node : this.nodes.values()) { +- assert !node.links.isEmpty(); +- +- if (node.getAmount() > 0.0D || node.nodeType == NodeType.Conductor) { +- assert node.nodeType != NodeType.Sink || this.activeSinks.contains(Integer.valueOf(node.uid)); +- +- assert node.nodeType != NodeType.Source || this.activeSources.contains(Integer.valueOf(node.uid)); +- +- assert node.getGrid() != null; +- +- data.optimizedNodes.put(Integer.valueOf(node.uid), new Node(node)); +- } +- } +- +- for(Node node2 : data.optimizedNodes.values()) { +- assert !node2.links.isEmpty(); +- +- assert node2.getGrid() == this; +- +- ListIterator listiterator = node2.links.listIterator(); +- +- while(listiterator.hasNext()) { +- NodeLink nodelink = listiterator.next(); +- Node node1 = nodelink.getNeighbor(node2.uid); +- +- assert node1.getGrid() == this; +- +- if ((node1.nodeType == NodeType.Sink || node1.nodeType == NodeType.Source) && node1.getAmount() <= 0.0D) { +- listiterator.remove(); +- } else if (nodelink.nodeA.uid == node2.uid) { +- nodelink.nodeA = data.optimizedNodes.get(Integer.valueOf(nodelink.nodeA.uid)); +- nodelink.nodeB = data.optimizedNodes.get(Integer.valueOf(nodelink.nodeB.uid)); +- +- assert nodelink.nodeA != null && nodelink.nodeB != null; +- +- List list = new ArrayList(); +- +- for(Node node4 : nodelink.skippedNodes) { +- list.add(data.optimizedNodes.get(Integer.valueOf(node4.uid))); +- } +- +- nodelink.skippedNodes = list; +- } else { +- assert nodelink.nodeB.uid == node2.uid; +- +- boolean flag = false; +- +- for(NodeLink nodelink1 : (data.optimizedNodes.get(Integer.valueOf(nodelink.nodeA.uid))).links) { +- assert nodelink1.nodeA.uid != node2.uid; +- +- if (nodelink1.nodeB.uid == node2.uid && !node2.links.contains(nodelink1)) { +- assert nodelink1.nodeA.uid == nodelink.nodeA.uid; +- +- flag = true; +- listiterator.set(nodelink1); +- break; +- } +- } +- +- assert flag; +- } +- } +- } +- ++ for (Node node : this.nodes.values()) { ++ assert (!node.links.isEmpty()); ++ if (!(node.getAmount() > 0.0) && node.nodeType != NodeType.Conductor) continue; ++ assert (node.nodeType != NodeType.Sink || this.activeSinks.contains(node.uid)); ++ assert (node.nodeType != NodeType.Source || this.activeSources.contains(node.uid)); ++ assert (node.getGrid() != null); ++ data.optimizedNodes.put(node.uid, new Node(node)); ++ } ++ for (Node node : data.optimizedNodes.values()) { ++ assert (!node.links.isEmpty()); ++ assert (node.getGrid() == this); ++ ListIterator it = node.links.listIterator(); ++ while (it.hasNext()) { ++ NodeLink link = it.next(); ++ Node neighbor = link.getNeighbor(node.uid); ++ assert (neighbor.getGrid() == this); ++ if ((neighbor.nodeType == NodeType.Sink || neighbor.nodeType == NodeType.Source) && neighbor.getAmount() <= 0.0) { ++ it.remove(); ++ continue; ++ } ++ if (link.nodeA.uid == node.uid) { ++ link.nodeA = data.optimizedNodes.get(link.nodeA.uid); ++ link.nodeB = data.optimizedNodes.get(link.nodeB.uid); ++ assert (link.nodeA != null && link.nodeB != null); ++ ArrayList newSkippedNodes = new ArrayList(); ++ for (Node skippedNode : link.skippedNodes) { ++ newSkippedNodes.add(data.optimizedNodes.get(skippedNode.uid)); ++ } ++ link.skippedNodes = newSkippedNodes; ++ continue; ++ } ++ assert (link.nodeB.uid == node.uid); ++ boolean foundReverseLink = false; ++ for (NodeLink reverseLink : data.optimizedNodes.get((Object)Integer.valueOf((int)link.nodeA.uid)).links) { ++ assert (reverseLink.nodeA.uid != node.uid); ++ if (reverseLink.nodeB.uid != node.uid || node.links.contains(reverseLink)) continue; ++ assert (reverseLink.nodeA.uid == link.nodeA.uid); ++ foundReverseLink = true; ++ it.set(reverseLink); ++ break; ++ } ++ assert (foundReverseLink); ++ } ++ } + if (EnergyNetGlobal.verifyGrid()) { +- label177: +- for(Node node3 : data.optimizedNodes.values()) { +- assert !node3.links.isEmpty(); +- +- Iterator iterator1 = node3.links.iterator(); +- +- while(true) { +- if (!iterator1.hasNext()) { +- continue label177; +- } +- +- NodeLink nodelink2 = (NodeLink)iterator1.next(); +- if (!data.optimizedNodes.containsValue(nodelink2.nodeA)) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Link %s is broken.", this.uid, nodelink2); +- } +- +- assert data.optimizedNodes.containsValue(nodelink2.nodeA); +- +- assert data.optimizedNodes.containsValue(nodelink2.nodeB); +- +- assert nodelink2.nodeA != nodelink2.nodeB; +- +- if (!$assertionsDisabled && !nodelink2.getNeighbor(node3).links.contains(nodelink2)) { +- break; +- } ++ for (Node node : data.optimizedNodes.values()) { ++ assert (!node.links.isEmpty()); ++ for (NodeLink link : node.links) { ++ if (!data.optimizedNodes.containsValue(link.nodeA)) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Link %s is broken.", this.uid, link); ++ } ++ assert (data.optimizedNodes.containsValue(link.nodeA)); ++ assert (data.optimizedNodes.containsValue(link.nodeB)); ++ assert (link.nodeA != link.nodeB); ++ assert (link.getNeighbor((Node)node).links.contains(link)); + } +- +- throw new AssertionError(); +- } +- +- Iterator iterator = this.activeSources.iterator(); +- +- while(iterator.hasNext()) { +- int i = ((Integer)iterator.next()).intValue(); +- +- assert data.optimizedNodes.containsKey(Integer.valueOf(i)); +- } +- ++ } ++ Iterator iterator = this.activeSources.iterator(); ++ while (iterator.hasNext()) { ++ int uid = (Integer)iterator.next(); ++ assert (data.optimizedNodes.containsKey(uid)); ++ } + iterator = this.activeSinks.iterator(); +- +- while(iterator.hasNext()) { +- int j = ((Integer)iterator.next()).intValue(); +- +- assert data.optimizedNodes.containsKey(Integer.valueOf(j)); ++ while (iterator.hasNext()) { ++ int uid = (Integer)iterator.next(); ++ assert (data.optimizedNodes.containsKey(uid)); + } + } +- + } + + private void optimize(StructureCache.Data data) { +- while(true) { +- int i = 0; +- Iterator iterator = data.optimizedNodes.values().iterator(); +- +- label314: +- while(iterator.hasNext()) { +- Node node = iterator.next(); +- if (node.nodeType == NodeType.Conductor) { +- if (node.links.size() >= 2) { +- if (node.links.size() == 2) { +- iterator.remove(); +- ++i; +- NodeLink nodelink1 = node.links.get(0); +- NodeLink nodelink2 = node.links.get(1); +- Node node2 = nodelink1.getNeighbor(node); +- Node node4 = nodelink2.getNeighbor(node); +- if (node2 != node4) { +- nodelink1.loss += nodelink2.loss; +- if (nodelink1.nodeA == node) { +- nodelink1.nodeA = node4; +- nodelink1.dirFromA = nodelink2.getDirFrom(node4); +- if (nodelink2.nodeA == node) { +- assert nodelink2.nodeB == node4; +- +- Collections.reverse(nodelink2.skippedNodes); +- } else { +- assert nodelink2.nodeB == node && nodelink2.nodeA == node4; +- } +- +- nodelink2.skippedNodes.add(node); +- nodelink2.skippedNodes.addAll(nodelink1.skippedNodes); +- nodelink1.skippedNodes = nodelink2.skippedNodes; +- } else { +- nodelink1.nodeB = node4; +- nodelink1.dirFromB = nodelink2.getDirFrom(node4); +- if (nodelink2.nodeB == node) { +- assert nodelink2.nodeA == node4; +- +- Collections.reverse(nodelink2.skippedNodes); +- } else { +- assert nodelink2.nodeA == node && nodelink2.nodeB == node4; +- } +- +- nodelink1.skippedNodes.add(node); +- nodelink1.skippedNodes.addAll(nodelink2.skippedNodes); +- } +- +- assert nodelink1.nodeA != nodelink1.nodeB; +- +- assert nodelink1.nodeA == node2 || nodelink1.nodeB == node2; +- +- assert nodelink1.nodeA == node4 || nodelink1.nodeB == node4; +- +- boolean flag1 = false; +- ListIterator listiterator = node4.links.listIterator(); +- +- while(listiterator.hasNext()) { +- if (listiterator.next() == nodelink2) { +- flag1 = true; +- listiterator.set(nodelink1); +- break; +- } +- } +- +- assert flag1; +- } else { +- node2.links.remove(nodelink1); +- node4.links.remove(nodelink2); +- } +- } +- } else { +- iterator.remove(); +- ++i; +- Iterator linkA = node.links.iterator(); +- +- while(true) { +- if (!linkA.hasNext()) { +- continue label314; +- } +- +- NodeLink nodelink = (NodeLink)linkA.next(); +- boolean flag = false; +- Iterator iterator2 = nodelink.getNeighbor(node).links.iterator(); +- +- while(iterator2.hasNext()) { +- if (iterator2.next() == nodelink) { +- flag = true; +- iterator2.remove(); +- break; +- } +- } +- +- if (!$assertionsDisabled && !flag) { +- break; +- } +- } +- +- throw new AssertionError(); ++ int removed; ++ do { ++ removed = 0; ++ Iterator it = data.optimizedNodes.values().iterator(); ++ while (it.hasNext()) { ++ Node node = it.next(); ++ if (node.nodeType != NodeType.Conductor) continue; ++ if (node.links.size() < 2) { ++ it.remove(); ++ ++removed; ++ for (NodeLink link : node.links) { ++ boolean found = false; ++ Iterator it2 = link.getNeighbor((Node)node).links.iterator(); ++ while (it2.hasNext()) { ++ if (it2.next() != link) continue; ++ found = true; ++ it2.remove(); ++ break; ++ } ++ assert (found); + } +- } +- } +- +- if (i <= 0) { +- break; +- } +- } +- ++ continue; ++ } ++ if (node.links.size() != 2) continue; ++ it.remove(); ++ ++removed; ++ NodeLink linkA = node.links.get(0); ++ NodeLink linkB = node.links.get(1); ++ Node neighborA = linkA.getNeighbor(node); ++ Node neighborB = linkB.getNeighbor(node); ++ if (neighborA == neighborB) { ++ neighborA.links.remove(linkA); ++ neighborB.links.remove(linkB); ++ continue; ++ } ++ linkA.loss += linkB.loss; ++ if (linkA.nodeA == node) { ++ linkA.nodeA = neighborB; ++ linkA.dirFromA = linkB.getDirFrom(neighborB); ++ if (linkB.nodeA == node) { ++ assert (linkB.nodeB == neighborB); ++ Collections.reverse(linkB.skippedNodes); ++ } else assert (linkB.nodeB == node && linkB.nodeA == neighborB); ++ linkB.skippedNodes.add(node); ++ linkB.skippedNodes.addAll(linkA.skippedNodes); ++ linkA.skippedNodes = linkB.skippedNodes; ++ } else { ++ linkA.nodeB = neighborB; ++ linkA.dirFromB = linkB.getDirFrom(neighborB); ++ if (linkB.nodeB == node) { ++ assert (linkB.nodeA == neighborB); ++ Collections.reverse(linkB.skippedNodes); ++ } else assert (linkB.nodeA == node && linkB.nodeB == neighborB); ++ linkA.skippedNodes.add(node); ++ linkA.skippedNodes.addAll(linkB.skippedNodes); ++ } ++ assert (linkA.nodeA != linkA.nodeB); ++ assert (linkA.nodeA == neighborA || linkA.nodeB == neighborA); ++ assert (linkA.nodeA == neighborB || linkA.nodeB == neighborB); ++ boolean found = false; ++ ListIterator it2 = neighborB.links.listIterator(); ++ while (it2.hasNext()) { ++ if (it2.next() != linkB) continue; ++ found = true; ++ it2.set(linkA); ++ break; ++ } ++ assert (found); ++ } ++ } while (removed > 0); + if (EnergyNetGlobal.verifyGrid()) { +- label249: +- for(Node node1 : data.optimizedNodes.values()) { +- assert !node1.links.isEmpty(); +- +- Iterator iterator4 = node1.links.iterator(); +- +- NodeLink nodelink3; +- Node node3; +- while(true) { +- if (!iterator4.hasNext()) { +- continue label249; +- } +- +- nodelink3 = (NodeLink)iterator4.next(); +- if (!data.optimizedNodes.containsValue(nodelink3.nodeA)) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Link %s is broken.", this.uid, nodelink3); +- } +- +- assert data.optimizedNodes.containsValue(nodelink3.nodeA); +- +- assert data.optimizedNodes.containsValue(nodelink3.nodeB); +- +- assert !this.nodes.containsValue(nodelink3.nodeA); +- +- assert !this.nodes.containsValue(nodelink3.nodeB); +- +- assert this.nodes.containsValue(nodelink3.nodeA.getTop()); +- +- assert this.nodes.containsValue(nodelink3.nodeB.getTop()); +- +- assert nodelink3.nodeA != nodelink3.nodeB; +- +- assert nodelink3.getNeighbor(node1).links.contains(nodelink3); +- +- assert nodelink3.getNeighbor(node1).links.contains(nodelink3); +- +- assert !nodelink3.skippedNodes.contains(nodelink3.nodeA); +- +- assert !nodelink3.skippedNodes.contains(nodelink3.nodeB); +- +- assert Collections.disjoint(nodelink3.skippedNodes, data.optimizedNodes.values()); +- +- assert Collections.disjoint(nodelink3.skippedNodes, this.nodes.values()); +- +- assert (new HashSet(nodelink3.skippedNodes)).size() == nodelink3.skippedNodes.size(); +- +- node3 = node1.getTop(); +- List list; +- if (nodelink3.nodeA == node1) { +- list = nodelink3.skippedNodes; ++ for (Node node : data.optimizedNodes.values()) { ++ assert (!node.links.isEmpty()); ++ for (NodeLink link : node.links) { ++ List skippedNodes; ++ if (!data.optimizedNodes.containsValue(link.nodeA)) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Link %s is broken.", this.uid, link); ++ } ++ assert (data.optimizedNodes.containsValue(link.nodeA)); ++ assert (data.optimizedNodes.containsValue(link.nodeB)); ++ assert (!this.nodes.containsValue(link.nodeA)); ++ assert (!this.nodes.containsValue(link.nodeB)); ++ assert (this.nodes.containsValue(link.nodeA.getTop())); ++ assert (this.nodes.containsValue(link.nodeB.getTop())); ++ assert (link.nodeA != link.nodeB); ++ assert (link.nodeA == node || link.nodeB == node); ++ assert (link.getNeighbor((Node)node).links.contains(link)); ++ assert (!link.skippedNodes.contains(link.nodeA)); ++ assert (!link.skippedNodes.contains(link.nodeB)); ++ assert (Collections.disjoint(link.skippedNodes, data.optimizedNodes.values())); ++ assert (Collections.disjoint(link.skippedNodes, this.nodes.values())); ++ assert (new HashSet(link.skippedNodes).size() == link.skippedNodes.size()); ++ Node start = node.getTop(); ++ if (link.nodeA == node) { ++ skippedNodes = link.skippedNodes; + } else { +- list = new ArrayList(nodelink3.skippedNodes); +- Collections.reverse(list); +- } +- +- for(Node node5 : list) { +- assert node3.getConnectionTo(node5.getTop()) != null : node3 + " -> " + node5.getTop() + " not in " + node3.links + " (skipped " + list + ")"; +- +- node3 = node5.getTop(); +- } +- +- if (!$assertionsDisabled && node3.getConnectionTo(nodelink3.getNeighbor(node1).getTop()) == null) { +- break; +- } ++ skippedNodes = new ArrayList(link.skippedNodes); ++ Collections.reverse(skippedNodes); ++ } ++ for (Node skipped : skippedNodes) { ++ assert (start.getConnectionTo(skipped.getTop()) != null) : start + " -> " + skipped.getTop() + " not in " + start.links + " (skipped " + skippedNodes + ")"; ++ start = skipped.getTop(); ++ } ++ assert (start.getConnectionTo(link.getNeighbor(node).getTop()) != null) : start + " -> " + link.getNeighbor(node).getTop() + " not in " + start.links; + } +- +- throw new AssertionError(node3 + " -> " + nodelink3.getNeighbor(node1).getTop() + " not in " + node3.links); +- } +- +- Iterator iterator3 = this.activeSources.iterator(); +- +- while(iterator3.hasNext()) { +- int j = ((Integer)iterator3.next()).intValue(); +- +- assert data.optimizedNodes.containsKey(Integer.valueOf(j)); +- } +- +- iterator3 = this.activeSinks.iterator(); +- +- while(iterator3.hasNext()) { +- int k = ((Integer)iterator3.next()).intValue(); +- +- assert data.optimizedNodes.containsKey(Integer.valueOf(k)); ++ } ++ Iterator iterator = this.activeSources.iterator(); ++ while (iterator.hasNext()) { ++ int uid = (Integer)iterator.next(); ++ assert (data.optimizedNodes.containsKey(uid)); ++ } ++ iterator = this.activeSinks.iterator(); ++ while (iterator.hasNext()) { ++ int uid = (Integer)iterator.next(); ++ assert (data.optimizedNodes.containsKey(uid)); + } + } +- + } + + private static void determineEmittingNodes(StructureCache.Data data) { + data.activeNodes = new ArrayList(); +- int i = 0; +- +- for(Node node : data.optimizedNodes.values()) { +- switch(node.nodeType) { +- case Source: +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %d %s.", node.getGrid().uid, i++, node); +- } +- +- data.activeNodes.add(node); +- break; +- case Sink: +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %d %s.", node.getGrid().uid, i++, node); +- } +- +- data.activeNodes.add(node); +- break; +- case Conductor: +- if (EnergyNetGlobal.debugGrid) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %d %s.", node.getGrid().uid, i++, node); +- } +- +- data.activeNodes.add(node); ++ int index = 0; ++ for (Node node : data.optimizedNodes.values()) { ++ switch (node.nodeType) { ++ case Source: { ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d %d %s.", node.getGrid().uid, index++, node); ++ } ++ data.activeNodes.add(node); ++ break; ++ } ++ case Sink: { ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d %d %s.", node.getGrid().uid, index++, node); ++ } ++ data.activeNodes.add(node); ++ break; ++ } ++ case Conductor: { ++ if (EnergyNetGlobal.debugGrid) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d %d %s.", node.getGrid().uid, index++, node); ++ } ++ data.activeNodes.add(node); ++ } + } + } +- + } + + private static void populateNetworkMatrix(StructureCache.Data data) { +- for(int i = 0; i < data.activeNodes.size(); ++i) { +- Node node = data.activeNodes.get(i); +- +- for(int j = 0; j < data.activeNodes.size(); ++j) { +- double d0 = 0.0D; +- if (i != j) { +- Node node2 = data.activeNodes.get(j); +- +- for(NodeLink nodelink1 : node.links) { +- Node node1 = nodelink1.getNeighbor(node); +- if (node1 != node && node1 == node2) { +- d0 -= 1.0D / nodelink1.loss; +- +- assert nodelink1.loss >= 0.0D; +- } +- } +- } else { +- for(NodeLink nodelink : node.links) { +- if (nodelink.getNeighbor(node) != node) { +- d0 += 1.0D / nodelink.loss; +- +- assert nodelink.loss >= 0.0D; +- } +- } +- +- if (EnergyNetLocal.useLinearTransferModel) { +- if (node.nodeType == NodeType.Source) { +- double d2 = EnergyNet.instance.getPowerFromTier(node.getTier()); +- double d1 = Util.square(d2) / (node.getAmount() * 4.0D); +- +- assert d1 > 0.0D; +- +- d0 += 1.0D / d1; +- node.setResistance(d1); +- } else if (node.nodeType == NodeType.Sink) { +- double d3 = EnergyNet.instance.getPowerFromTier(node.getTier()); +- +- assert d3 > 0.0D; +- +- d0 += 1.0D / d3; +- node.setResistance(d3); +- } +- } else if (node.nodeType == NodeType.Sink) { +- ++d0; ++ for (int row = 0; row < data.activeNodes.size(); ++row) { ++ Node node = data.activeNodes.get(row); ++ for (int col = 0; col < data.activeNodes.size(); ++col) { ++ double value; ++ block11: { ++ block8: { ++ block9: { ++ block10: { ++ value = 0.0; ++ if (row != col) break block8; ++ for (NodeLink link : node.links) { ++ if (link.getNeighbor(node) == node) continue; ++ value += 1.0 / link.loss; ++ assert (link.loss >= 0.0); ++ } ++ if (!EnergyNetLocal.useLinearTransferModel) break block9; ++ if (node.nodeType != NodeType.Source) break block10; ++ double openCircuitVoltage = EnergyNet.instance.getPowerFromTier(node.getTier()); ++ double resistance = Util.square(openCircuitVoltage) / (node.getAmount() * 4.0); ++ assert (resistance > 0.0); ++ value += 1.0 / resistance; ++ node.setResistance(resistance); ++ break block11; ++ } ++ if (node.nodeType != NodeType.Sink) break block11; ++ double resistance = EnergyNet.instance.getPowerFromTier(node.getTier()); ++ assert (resistance > 0.0); ++ value += 1.0 / resistance; ++ node.setResistance(resistance); ++ break block11; ++ } ++ if (node.nodeType != NodeType.Sink) break block11; ++ value += 1.0; ++ break block11; ++ } ++ Node possibleNeighbor = data.activeNodes.get(col); ++ for (NodeLink link : node.links) { ++ Node neighbor = link.getNeighbor(node); ++ if (neighbor == node || neighbor != possibleNeighbor) continue; ++ value -= 1.0 / link.loss; ++ assert (link.loss >= 0.0); + } + } +- +- data.networkMatrix.set(i, j, d0); ++ data.networkMatrix.set(row, col, value); + } + } +- + } + + private void populateSourceMatrix(StructureCache.Data data) { +- for(int i = 0; i < data.activeNodes.size(); ++i) { +- Node node = data.activeNodes.get(i); +- double d0 = 0.0D; ++ for (int row = 0; row < data.activeNodes.size(); ++row) { ++ Node node = data.activeNodes.get(row); ++ double input = 0.0; + if (node.nodeType == NodeType.Source) { + if (EnergyNetLocal.useLinearTransferModel) { +- double d1 = EnergyNet.instance.getPowerFromTier(node.getTier()); +- d0 = d1 / node.getResistance(); ++ double openCircuitVoltage = EnergyNet.instance.getPowerFromTier(node.getTier()); ++ input = openCircuitVoltage / node.getResistance(); + } else { +- d0 = node.getAmount(); ++ input = node.getAmount(); + } +- +- assert d0 > 0.0D; ++ assert (input > 0.0); + } +- +- data.sourceMatrix.set(i, 0, d0); ++ data.sourceMatrix.set(row, 0, input); + } +- + } + + void dumpNodeInfo(PrintStream ps, boolean waitForFinish, Node node) { + if (waitForFinish) { + this.finishCalculation(); + } +- + ps.println("Node " + node + " info:"); +- ps.println(" type: " + node.nodeType); +- switch(node.nodeType) { +- case Source: +- IEnergySource ienergysource = (IEnergySource)node.tile.mainTile; +- ps.println(" offered: " + ienergysource.getOfferedEnergy()); +- ps.println(" tier: " + ienergysource.getSourceTier()); +- break; +- case Sink: +- IEnergySink ienergysink = (IEnergySink)node.tile.mainTile; +- ps.println(" demanded: " + ienergysink.getDemandedEnergy()); +- ps.println(" tier: " + ienergysink.getSinkTier()); +- case Conductor: ++ ps.println(" type: " + (Object)((Object)node.nodeType)); ++ switch (node.nodeType) { ++ case Conductor: { ++ break; ++ } ++ case Sink: { ++ IEnergySink sink = (IEnergySink)node.tile.mainTile; ++ ps.println(" demanded: " + sink.getDemandedEnergy()); ++ ps.println(" tier: " + sink.getSinkTier()); ++ break; ++ } ++ case Source: { ++ IEnergySource source = (IEnergySource)node.tile.mainTile; ++ ps.println(" offered: " + source.getOfferedEnergy()); ++ ps.println(" tier: " + source.getSourceTier()); ++ break; ++ } + } +- + ps.println(node.links.size() + " neighbor links:"); +- +- for(NodeLink nodelink : node.links) { +- ps.println(" " + nodelink.getNeighbor(node) + " " + nodelink.loss + " " + nodelink.skippedNodes); ++ for (NodeLink link : node.links) { ++ ps.println(" " + link.getNeighbor(node) + " " + link.loss + " " + link.skippedNodes); + } +- +- StructureCache.Data structurecache$data = this.lastData; +- if (structurecache$data != null && structurecache$data.isInitialized && structurecache$data.optimizedNodes != null) { +- if (!structurecache$data.optimizedNodes.containsKey(Integer.valueOf(node.uid))) { +- ps.println("Optimized away"); +- } else { +- Node node = structurecache$data.optimizedNodes.get(Integer.valueOf(node.uid)); +- ps.println(node.links.size() + " optimized neighbor links:"); +- +- for(NodeLink nodelink1 : node.links) { +- ps.println(" " + nodelink1.getNeighbor(node) + " " + nodelink1.loss + " " + nodelink1.skippedNodes); +- } +- } +- } else { ++ StructureCache.Data data = this.lastData; ++ if (data == null || !data.isInitialized || data.optimizedNodes == null) { + ps.println("No optimized data"); ++ } else if (!data.optimizedNodes.containsKey(node.uid)) { ++ ps.println("Optimized away"); ++ } else { ++ Node optimizedNode = data.optimizedNodes.get(node.uid); ++ ps.println(optimizedNode.links.size() + " optimized neighbor links:"); ++ for (NodeLink link : optimizedNode.links) { ++ ps.println(" " + link.getNeighbor(optimizedNode) + " " + link.loss + " " + link.skippedNodes); ++ } + } +- + } + + void dumpMatrix(PrintStream ps, boolean waitForFinish, boolean dumpNodesNetSrcMatrices, boolean dumpResultMatrix) { ++ StructureCache.Data data; + if (waitForFinish) { + this.finishCalculation(); + } +- + if (dumpNodesNetSrcMatrices) { + ps.println("Dumping matrices for " + this + "."); + } +- +- StructureCache.Data structurecache$data = this.lastData; +- if (structurecache$data == null) { ++ if ((data = this.lastData) == null) { + ps.println("Matrices unavailable"); + } else if (dumpNodesNetSrcMatrices || dumpResultMatrix) { +- if (!structurecache$data.isInitialized) { ++ if (!data.isInitialized) { + ps.println("Matrices potentially outdated"); + } +- + if (dumpNodesNetSrcMatrices) { + ps.println("Emitting node indizes:"); +- +- for(int i = 0; i < structurecache$data.activeNodes.size(); ++i) { +- Node node = structurecache$data.activeNodes.get(i); ++ for (int i = 0; i < data.activeNodes.size(); ++i) { ++ Node node = data.activeNodes.get(i); + ps.println(i + " " + node + " (amount=" + node.getAmount() + ", tier=" + node.getTier() + ")"); + } +- + ps.println("Network matrix:"); +- printMatrix(structurecache$data.networkMatrix, ps); ++ Grid.printMatrix(data.networkMatrix, ps); + ps.println("Source matrix:"); +- printMatrix(structurecache$data.sourceMatrix, ps); ++ Grid.printMatrix(data.sourceMatrix, ps); + } +- + if (dumpResultMatrix) { + ps.println("Result matrix:"); +- printMatrix(structurecache$data.resultMatrix, ps); ++ Grid.printMatrix(data.resultMatrix, ps); + } + } +- + } + + private static void printMatrix(DenseMatrix64F matrix, PrintStream ps) { + if (matrix == null) { + ps.println("null"); ++ return; ++ } ++ boolean isZero = true; ++ block0: for (int i = 0; i < matrix.numRows; ++i) { ++ for (int j = 0; j < matrix.numCols; ++j) { ++ if (matrix.get(i, j) == 0.0) continue; ++ isZero = false; ++ continue block0; ++ } ++ } ++ if (isZero) { ++ ps.println(matrix.numRows + "x" + matrix.numCols + ", all zero"); + } else { +- boolean flag = true; +- +- for(int i = 0; i < matrix.numRows; ++i) { +- for(int j = 0; j < matrix.numCols; ++j) { +- if (matrix.get(i, j) != 0.0D) { +- flag = false; +- break; +- } +- } +- } +- +- if (flag) { +- ps.println(matrix.numRows + "x" + matrix.numCols + ", all zero"); +- } else { +- MatrixIO.print(ps, matrix, "%.6f"); +- } +- ++ MatrixIO.print(ps, matrix, "%.6f"); + } + } + +@@ -1207,127 +930,109 @@ + if (waitForFinish) { + this.finishCalculation(); + } +- + ps.println("Grid " + this.uid + " info:"); + ps.println(this.nodes.size() + " nodes"); +- StructureCache.Data structurecache$data = this.lastData; +- if (structurecache$data != null && structurecache$data.isInitialized) { +- if (structurecache$data.activeNodes != null) { +- int i = 0; +- int j = 0; +- +- for(Node node : structurecache$data.activeNodes) { ++ StructureCache.Data data = this.lastData; ++ if (data != null && data.isInitialized) { ++ if (data.activeNodes != null) { ++ int srcCount = 0; ++ int dstCount = 0; ++ for (Node node : data.activeNodes) { + if (node.nodeType == NodeType.Source) { +- ++i; +- } else if (node.nodeType == NodeType.Sink) { +- ++j; ++ ++srcCount; ++ continue; + } ++ if (node.nodeType != NodeType.Sink) continue; ++ ++dstCount; + } +- +- ps.println("Active: " + i + " sources -> " + j + " sinks"); +- } +- +- if (structurecache$data.optimizedNodes != null) { +- ps.println(structurecache$data.optimizedNodes.size() + " nodes after optimization"); +- } +- +- if (structurecache$data.activeNodes != null) { +- ps.println(structurecache$data.activeNodes.size() + " emitting nodes"); ++ ps.println("Active: " + srcCount + " sources -> " + dstCount + " sinks"); ++ } ++ if (data.optimizedNodes != null) { ++ ps.println(data.optimizedNodes.size() + " nodes after optimization"); ++ } ++ if (data.activeNodes != null) { ++ ps.println(data.activeNodes.size() + " emitting nodes"); + } + } +- +- ps.printf("%d entries in cache, hitrate %.2f%%", this.cache.size(), 100.0D * (double)this.cache.hits / (double)(this.cache.hits + this.cache.misses)); ++ ps.printf("%d entries in cache, hitrate %.2f%%", this.cache.size(), 100.0 * (double)this.cache.hits / (double)(this.cache.hits + this.cache.misses)); + ps.println(); + } + ++ /* ++ * WARNING - Removed try catching itself - possible behaviour change. ++ */ + void dumpGraph(boolean waitForFinish) { + if (waitForFinish) { + this.finishCalculation(); + } +- +- StructureCache.Data structurecache$data = this.lastData; +- +- for(int i = 0; i < 2 && (i != 1 || structurecache$data != null && structurecache$data.isInitialized && structurecache$data.optimizedNodes != null); ++i) { +- FileWriter filewriter = null; +- ++ StructureCache.Data data = this.lastData; ++ for (int i = 0; i < 2 && (i != 1 || data != null && data.isInitialized && data.optimizedNodes != null); ++i) { ++ OutputStreamWriter out = null; + try { +- filewriter = new FileWriter("graph_" + this.uid + "_" + (i == 0 ? "raw" : "optimized") + ".txt"); +- filewriter.write("graph nodes {\n overlap=false;\n"); +- Collection collection = (i == 0 ? this.nodes : structurecache$data.optimizedNodes).values(); +- Set set = new HashSet(); +- +- for(Node node : collection) { +- filewriter.write(" \"" + node + "\";\n"); +- +- for(NodeLink nodelink : node.links) { +- Node node1 = nodelink.getNeighbor(node); +- if (!set.contains(node1)) { +- filewriter.write(" \"" + node + "\" -- \"" + node1 + "\" [label=\"" + nodelink.loss + "\"];\n"); +- } ++ out = new FileWriter("graph_" + this.uid + "_" + (i == 0 ? "raw" : "optimized") + ".txt"); ++ out.write("graph nodes {\n overlap=false;\n"); ++ Collection nodesToDump = (i == 0 ? this.nodes : data.optimizedNodes).values(); ++ HashSet dumpedConnections = new HashSet(); ++ for (Node node : nodesToDump) { ++ out.write(" \"" + node + "\";\n"); ++ for (NodeLink link : node.links) { ++ Node neighbor = link.getNeighbor(node); ++ if (dumpedConnections.contains(neighbor)) continue; ++ out.write(" \"" + node + "\" -- \"" + neighbor + "\" [label=\"" + link.loss + "\"];\n"); + } +- +- set.add(node); ++ dumpedConnections.add(node); + } +- +- filewriter.write("}\n"); +- } catch (IOException ioexception) { +- IC2.log.debug(LogCategory.EnergyNet, ioexception, "Graph saving failed."); +- } finally { ++ out.write("}\n"); ++ continue; ++ } ++ catch (IOException e) { ++ IC2.log.debug(LogCategory.EnergyNet, e, "Graph saving failed."); ++ continue; ++ } ++ finally { + try { +- if (filewriter != null) { +- filewriter.close(); ++ if (out != null) { ++ out.close(); + } +- } catch (IOException var19) { +- ; + } +- ++ catch (IOException iOException) {} + } + } +- + } + + GridInfo getInfo() { +- int i = 0; +- int j = Integer.MAX_VALUE; +- int k = Integer.MAX_VALUE; +- int l = Integer.MAX_VALUE; +- int i1 = Integer.MIN_VALUE; +- int j1 = Integer.MIN_VALUE; +- int k1 = Integer.MIN_VALUE; +- +- for(Node node : this.nodes.values()) { ++ int complexNodes = 0; ++ int minX = Integer.MAX_VALUE; ++ int minY = Integer.MAX_VALUE; ++ int minZ = Integer.MAX_VALUE; ++ int maxX = Integer.MIN_VALUE; ++ int maxY = Integer.MIN_VALUE; ++ int maxZ = Integer.MIN_VALUE; ++ for (Node node : this.nodes.values()) { + if (node.links.size() > 2) { +- ++i; ++ ++complexNodes; + } +- +- for(IEnergyTile ienergytile : node.tile.subTiles) { +- BlockPos blockpos = EnergyNet.instance.getPos(ienergytile); +- if (blockpos.getX() < j) { +- j = blockpos.getX(); +- } +- +- if (blockpos.getY() < k) { +- k = blockpos.getY(); +- } +- +- if (blockpos.getZ() < l) { +- l = blockpos.getZ(); +- } +- +- if (blockpos.getX() > i1) { +- i1 = blockpos.getX(); +- } +- +- if (blockpos.getY() > j1) { +- j1 = blockpos.getY(); +- } +- +- if (blockpos.getZ() > k1) { +- k1 = blockpos.getZ(); +- } ++ for (IEnergyTile tile : node.tile.subTiles) { ++ BlockPos pos = EnergyNet.instance.getPos(tile); ++ if (pos.getX() < minX) { ++ minX = pos.getX(); ++ } ++ if (pos.getY() < minY) { ++ minY = pos.getY(); ++ } ++ if (pos.getZ() < minZ) { ++ minZ = pos.getZ(); ++ } ++ if (pos.getX() > maxX) { ++ maxX = pos.getX(); ++ } ++ if (pos.getY() > maxY) { ++ maxY = pos.getY(); ++ } ++ if (pos.getZ() <= maxZ) continue; ++ maxZ = pos.getZ(); + } + } +- +- return new GridInfo(this.uid, this.nodes.size(), i, j, k, l, i1, j1, k1); ++ return new GridInfo(this.uid, this.nodes.size(), complexNodes, minX, minY, minZ, maxX, maxY, maxZ); + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Tile.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Tile.java.patch new file mode 100644 index 0000000..faf81f3 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/Tile.java.patch @@ -0,0 +1,15 @@ +--- a/ic2/core/energy/Tile.java ++++ b/ic2/core/energy/Tile.java +@@ -57,9 +57,9 @@ + if (node.isExtraNode()) { + flag = true; + } else { +- for(Node node : this.nodes) { +- if (node != node && node.nodeType == node.nodeType && node.isExtraNode()) { +- node.setExtraNode(false); ++ for(Node myNode : this.nodes) { ++ if (myNode != node && myNode.nodeType == node.nodeType && myNode.isExtraNode()) { ++ myNode.setExtraNode(false); + flag = true; + break; + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch new file mode 100644 index 0000000..1412802 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/ChangeHandler.java.patch @@ -0,0 +1,44 @@ +--- a/ic2/core/energy/grid/ChangeHandler.java ++++ b/ic2/core/energy/grid/ChangeHandler.java +@@ -115,9 +115,9 @@ + + ienergytile = (IEnergyTile)tile.next(); + blockpos = EnergyNet.instance.getPos(ienergytile); +- Tile tile; +- if ((tile = enet.registeredTiles.get(blockpos)) != null) { +- ienergytile1 = tile.getMainTile(); ++ Tile registeredTile; ++ if ((registeredTile = enet.registeredTiles.get(blockpos)) != null) { ++ ienergytile1 = registeredTile.getMainTile(); + boolean flag = false; + Iterator iterator1 = pendingChanges.iterator(); + +@@ -168,15 +168,15 @@ + for(IEnergyTile ienergytile1 : tile.subTiles) { + for(EnumFacing enumfacing : EnumFacing.VALUES) { + BlockPos blockpos = EnergyNet.instance.getPos(ienergytile1).offset(enumfacing); +- Tile tile = enet.registeredTiles.get(blockpos); +- if (tile != null && tile != node.tile) { +- for(Node node1 : tile.nodes) { ++ Tile registeredTile = enet.registeredTiles.get(blockpos); ++ if (registeredTile != null && registeredTile != node.tile) { ++ for(Node node1 : registeredTile.nodes) { + if (!node1.isExtraNode()) { + IEnergyTile ienergytile2 = node1.tile.getMainTile(); + boolean flag = false; + if ((node.nodeType == NodeType.Source || node.nodeType == NodeType.Conductor) && node1.nodeType != NodeType.Source) { + IEnergyEmitter ienergyemitter = (IEnergyEmitter)(ienergytile1 instanceof IEnergyEmitter ? ienergytile1 : ienergytile); +- IEnergyTile ienergytile3 = tile.getSubTileAt(blockpos); ++ IEnergyTile ienergytile3 = registeredTile.getSubTileAt(blockpos); + IEnergyAcceptor ienergyacceptor = (IEnergyAcceptor)(ienergytile3 instanceof IEnergyAcceptor ? ienergytile3 : ienergytile2); + flag = ienergyemitter.emitsEnergyTo((IEnergyAcceptor)ienergytile2, enumfacing) && ienergyacceptor.acceptsEnergyFrom((IEnergyEmitter)ienergytile, enumfacing.getOpposite()); + } +@@ -184,7 +184,7 @@ + boolean flag3 = false; + if (!flag && (node.nodeType == NodeType.Sink || node.nodeType == NodeType.Conductor) && node1.nodeType != NodeType.Sink) { + IEnergyAcceptor ienergyacceptor1 = (IEnergyAcceptor)(ienergytile1 instanceof IEnergyAcceptor ? ienergytile1 : ienergytile); +- IEnergyTile ienergytile4 = tile.getSubTileAt(blockpos); ++ IEnergyTile ienergytile4 = registeredTile.getSubTileAt(blockpos); + IEnergyEmitter ienergyemitter1 = (IEnergyEmitter)(ienergytile4 instanceof IEnergyEmitter ? ienergytile4 : ienergytile2); + flag3 = ienergyacceptor1.acceptsEnergyFrom((IEnergyEmitter)ienergytile2, enumfacing) && ienergyemitter1.emitsEnergyTo((IEnergyAcceptor)ienergytile, enumfacing.getOpposite()); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/EventHandler.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/EventHandler.java.patch new file mode 100644 index 0000000..3f830e2 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/EventHandler.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/energy/grid/EventHandler.java ++++ b/ic2/core/energy/grid/EventHandler.java +@@ -32,13 +32,13 @@ + IC2.log.warn(LogCategory.EnergyNet, "EnergyTileLoadEvent: posted for %s client-side, aborting", Util.toString(event.tile, event.getWorld(), EnergyNet.instance.getPos(event.tile))); + } else { + if (event.tile instanceof TileEntity) { +- EnergyNet.instance.addTile((TileEntity)((IEnergyTile)((TileEntity)event.tile))); ++ EnergyNet.instance.addTile((TileEntity & IEnergyTile)event.tile); + } else { + if (!(event.tile instanceof ILocatable)) { + throw new IllegalArgumentException("invalid tile type: " + event.tile); + } + +- EnergyNet.instance.addTile((ILocatable)((IEnergyTile)((ILocatable)event.tile))); ++ EnergyNet.instance.addTile((ILocatable & IEnergyTile)event.tile); + } + + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Grid.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Grid.java.patch new file mode 100644 index 0000000..a1794d2 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Grid.java.patch @@ -0,0 +1,345 @@ +--- a/ic2/core/energy/grid/Grid.java ++++ b/ic2/core/energy/grid/Grid.java +@@ -72,203 +72,156 @@ + if (EnergyNetSettings.logGridUpdatesVerbose) { + IC2.log.debug(LogCategory.EnergyNet, "%d Add %s to %s neighbors: %s.", this.uid, node, this, neighbors); + } +- + this.invalidate(); +- +- assert !this.nodes.isEmpty() || neighbors.isEmpty(); +- +- assert this.nodes.isEmpty() || !neighbors.isEmpty() || node.isExtraNode(); +- +- assert node.links.isEmpty(); +- ++ assert (!this.nodes.isEmpty() || neighbors.isEmpty()); ++ assert (this.nodes.isEmpty() || !neighbors.isEmpty() || node.isExtraNode()); ++ assert (node.links.isEmpty()); + this.add(node); +- +- for(Node node : neighbors) { +- assert node != node; +- +- assert this.nodes.containsKey(Integer.valueOf(node.uid)); +- +- double d0 = (node.getInnerLoss() + node.getInnerLoss()) / 2.0D; +- NodeLink nodelink = new NodeLink(node, node, d0); +- node.links.add(nodelink); +- node.links.add(nodelink); ++ for (Node neighbor : neighbors) { ++ assert (neighbor != node); ++ assert (this.nodes.containsKey(neighbor.uid)); ++ double loss = (node.getInnerLoss() + neighbor.getInnerLoss()) / 2.0; ++ NodeLink link = new NodeLink(node, neighbor, loss); ++ node.links.add(link); ++ neighbor.links.add(link); + } +- + } + + void remove(Node node) { + if (EnergyNetSettings.logGridUpdatesVerbose) { + IC2.log.debug(LogCategory.EnergyNet, "%d Remove Node %s from %s with %d nodes.", this.uid, node, this, this.nodes.size()); + } +- + this.invalidate(); +- Iterator iterator = node.links.iterator(); +- +- while(iterator.hasNext()) { +- NodeLink nodelink = iterator.next(); +- Node node = nodelink.getNeighbor(node); +- boolean flag = false; +- Iterator iterator1 = node.links.iterator(); +- +- while(iterator1.hasNext()) { +- if (iterator1.next() == nodelink) { +- iterator1.remove(); +- flag = true; +- break; +- } +- } +- +- assert flag; +- +- if (node.links.isEmpty() && node.tile.removeExtraNode(node)) { +- if (EnergyNetSettings.logGridUpdatesVerbose) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Removing isolated extra node %s.", this.uid, node); +- } +- +- assert node.getType() != NodeType.Conductor; +- +- iterator.remove(); +- this.nodes.remove(Integer.valueOf(node.uid)); +- node.clearGrid(); +- } ++ Iterator it = node.links.iterator(); ++ while (it.hasNext()) { ++ NodeLink link = it.next(); ++ Node neighbor = link.getNeighbor(node); ++ boolean found = false; ++ Iterator it2 = neighbor.links.iterator(); ++ while (it2.hasNext()) { ++ if (it2.next() != link) continue; ++ it2.remove(); ++ found = true; ++ break; ++ } ++ assert (found); ++ if (!neighbor.links.isEmpty() || !neighbor.tile.removeExtraNode(neighbor)) continue; ++ if (EnergyNetSettings.logGridUpdatesVerbose) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Removing isolated extra node %s.", this.uid, neighbor); ++ } ++ assert (neighbor.getType() != NodeType.Conductor); ++ it.remove(); ++ this.nodes.remove(neighbor.uid); ++ neighbor.clearGrid(); + } +- +- this.nodes.remove(Integer.valueOf(node.uid)); ++ this.nodes.remove(node.uid); + node.clearGrid(); +- int k = node.links.size(); +- if (k == 0) { +- assert this.nodes.isEmpty(); +- ++ int linkCount = node.links.size(); ++ if (linkCount == 0) { ++ assert (this.nodes.isEmpty()); + this.enet.removeGrid(this); +- } else if (k > 1 && node.nodeType == NodeType.Conductor) { +- Set[] set2 = new Set[k]; +- int[] aint = new int[k]; +- int l = 0; +- Queue queue = new ArrayDeque(); +- +- label232: +- for(int i = 0; i < k; ++i) { +- Node node1 = ((NodeLink)node.links.get(i)).getNeighbor(node); +- if (node1.getType() != NodeType.Conductor) { +- if (node1.links.isEmpty()) { +- set2[i] = Collections.singleton(node1); +- ++l; +- } else { +- aint[i] = -1; +- } +- } else { +- for(int j = 0; j < i; ++j) { +- Set set = set2[j]; +- if (set != null && set.contains(node1)) { +- aint[i] = j; +- continue label232; +- } +- } +- +- Set set5 = Collections.newSetFromMap(new IdentityHashMap()); +- queue.add(node1); +- set5.add(node1); +- +- Node node4; +- while((node4 = queue.poll()) != null) { +- for(NodeLink nodelink1 : node4.links) { +- Node node2 = nodelink1.getNeighbor(node4); +- if (set5.add(node2) && node2.getType() == NodeType.Conductor) { +- queue.add(node2); +- } +- } +- } +- +- assert !set5.contains(node); +- +- set2[i] = set5; +- ++l; +- } ++ } else if (linkCount > 1 && node.nodeType == NodeType.Conductor) { ++ int i; ++ Set[] nodeTable = new Set[linkCount]; ++ int[] mapping = new int[linkCount]; ++ int gridCount = 0; ++ ArrayDeque nodesToCheck = new ArrayDeque(); ++ block2: for (i = 0; i < linkCount; ++i) { ++ Node cNode; ++ Node neighbor = node.links.get(i).getNeighbor(node); ++ if (neighbor.getType() != NodeType.Conductor) { ++ if (neighbor.links.isEmpty()) { ++ nodeTable[i] = Collections.singleton(neighbor); ++ ++gridCount; ++ continue; ++ } ++ mapping[i] = -1; ++ continue; ++ } ++ for (int j = 0; j < i; ++j) { ++ Set nodes = nodeTable[j]; ++ if (nodes == null || !nodes.contains(neighbor)) continue; ++ mapping[i] = j; ++ continue block2; ++ } ++ Set connectedNodes = Collections.newSetFromMap(new IdentityHashMap()); ++ nodesToCheck.add(neighbor); ++ connectedNodes.add(neighbor); ++ while ((cNode = (Node)nodesToCheck.poll()) != null) { ++ for (NodeLink link : cNode.links) { ++ Node nNode = link.getNeighbor(cNode); ++ if (!connectedNodes.add(nNode) || nNode.getType() != NodeType.Conductor) continue; ++ nodesToCheck.add(nNode); ++ } ++ } ++ assert (!connectedNodes.contains(node)); ++ nodeTable[i] = connectedNodes; ++ ++gridCount; + } +- +- assert l > 0; +- ++ assert (gridCount > 0); + if (EnergyNetSettings.logGridUpdatesVerbose) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Neighbor connectivity (%d links, %d new grids):", this.uid, k, l); +- +- for(int i1 = 0; i1 < k; ++i1) { +- Set set3 = set2[i1]; +- if (set3 != null) { +- IC2.log.debug(LogCategory.EnergyNet, "%d %d: %s: %s (%d).", this.uid, i1, ((NodeLink)node.links.get(i1)).getNeighbor(node), set3, set3.size()); +- } else { +- IC2.log.debug(LogCategory.EnergyNet, "%d %d: %s contained in %d.", this.uid, i1, ((NodeLink)node.links.get(i1)).getNeighbor(node), aint[i1]); ++ IC2.log.debug(LogCategory.EnergyNet, "%d Neighbor connectivity (%d links, %d new grids):", this.uid, linkCount, gridCount); ++ for (i = 0; i < linkCount; ++i) { ++ Set nodes = nodeTable[i]; ++ if (nodes != null) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d %d: %s: %s (%d).", this.uid, i, node.links.get(i).getNeighbor(node), nodes, nodes.size()); ++ continue; + } ++ IC2.log.debug(LogCategory.EnergyNet, "%d %d: %s contained in %d.", this.uid, i, node.links.get(i).getNeighbor(node), mapping[i]); + } + } +- +- if (l <= 1) { ++ if (gridCount <= 1) { + return; + } +- +- for(int j1 = 1; j1 < k; ++j1) { +- Set set4 = set2[j1]; +- if (set4 != null) { +- Grid grid = new Grid(this.enet); ++ for (i = 1; i < linkCount; ++i) { ++ Set connectedNodes = nodeTable[i]; ++ if (connectedNodes == null) continue; ++ Grid grid = new Grid(this.enet); ++ if (EnergyNetSettings.logGridUpdatesVerbose) { ++ IC2.log.debug(LogCategory.EnergyNet, "%d Moving %d nodes from net %d to new grid %d.", this.uid, connectedNodes.size(), i, grid.uid); ++ } ++ for (Node cNode : connectedNodes) { ++ boolean needsExtraNode = false; ++ if (!cNode.links.isEmpty() && cNode.nodeType != NodeType.Conductor) { ++ for (int j = 0; j < i; ++j) { ++ Set nodes = nodeTable[j]; ++ if (nodes == null || !nodes.contains(cNode)) continue; ++ needsExtraNode = true; ++ break; ++ } ++ } ++ if (needsExtraNode) { ++ Node extraNode = new Node(this.enet.allocateNodeId(), cNode.tile, cNode.nodeType); ++ if (EnergyNetSettings.logGridUpdatesVerbose) { ++ IC2.log.debug(LogCategory.EnergyNet, "%s Create extra Node %d for %s in grid %d.", this.uid, extraNode.uid, cNode, grid.uid); ++ } ++ cNode.tile.addExtraNode(extraNode); ++ Iterator it2 = cNode.links.iterator(); ++ while (it2.hasNext()) { ++ NodeLink link = it2.next(); ++ Node neighbor = link.getNeighbor(cNode); ++ if (!connectedNodes.contains(neighbor)) continue; ++ assert (neighbor.nodeType == NodeType.Conductor); ++ link.replaceNode(cNode, extraNode); ++ extraNode.links.add(link); ++ it2.remove(); ++ } ++ assert (!extraNode.links.isEmpty()); ++ grid.add(extraNode); ++ assert (extraNode.getGrid() != null); ++ continue; ++ } + if (EnergyNetSettings.logGridUpdatesVerbose) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Moving %d nodes from net %d to new grid %d.", this.uid, set4.size(), j1, grid.uid); +- } +- +- for(Node node5 : set4) { +- boolean flag1 = false; +- if (!node5.links.isEmpty() && node5.nodeType != NodeType.Conductor) { +- for(int k1 = 0; k1 < j1; ++k1) { +- Set set1 = set2[k1]; +- if (set1 != null && set1.contains(node5)) { +- flag1 = true; +- break; +- } +- } +- } +- +- if (flag1) { +- Node node6 = new Node(this.enet.allocateNodeId(), node5.tile, node5.nodeType); +- if (EnergyNetSettings.logGridUpdatesVerbose) { +- IC2.log.debug(LogCategory.EnergyNet, "%s Create extra Node %d for %s in grid %d.", this.uid, node6.uid, node5, grid.uid); +- } +- +- node5.tile.addExtraNode(node6); +- Iterator iterator2 = node5.links.iterator(); +- +- while(iterator2.hasNext()) { +- NodeLink nodelink2 = iterator2.next(); +- Node node3 = nodelink2.getNeighbor(node5); +- if (set4.contains(node3)) { +- assert node3.nodeType == NodeType.Conductor; +- +- nodelink2.replaceNode(node5, node6); +- node6.links.add(nodelink2); +- iterator2.remove(); +- } +- } +- +- assert !node6.links.isEmpty(); +- +- grid.add(node6); +- +- assert node6.getGrid() != null; +- } else { +- if (EnergyNetSettings.logGridUpdatesVerbose) { +- IC2.log.debug(LogCategory.EnergyNet, "%d Move Node %s to grid %d.", this.uid, node5, grid.uid); +- } +- +- assert this.nodes.containsKey(Integer.valueOf(node5.uid)); +- +- this.nodes.remove(Integer.valueOf(node5.uid)); +- node5.clearGrid(); +- grid.add(node5); +- +- assert node5.getGrid() != null; +- } +- } ++ IC2.log.debug(LogCategory.EnergyNet, "%d Move Node %s to grid %d.", this.uid, cNode, grid.uid); ++ } ++ assert (this.nodes.containsKey(cNode.uid)); ++ this.nodes.remove(cNode.uid); ++ cNode.clearGrid(); ++ grid.add(cNode); ++ assert (cNode.getGrid() != null); + } + } + } +- + } + + void merge(Grid grid, Map nodeReplacements) { +@@ -324,9 +277,9 @@ + + private void add(Node node) { + node.setGrid(this); +- Node node = this.nodes.put(Integer.valueOf(node.uid), node); +- if (node != null) { +- throw new IllegalStateException("duplicate node uid, new " + node + ", old " + node); ++ Node prev = this.nodes.put(node.uid, node); ++ if (prev != null) { ++ throw new IllegalStateException("duplicate node uid, new " + node + ", old " + prev); + } + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Tile.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Tile.java.patch new file mode 100644 index 0000000..c6b007a --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/grid/Tile.java.patch @@ -0,0 +1,36 @@ +--- a/ic2/core/energy/grid/Tile.java ++++ b/ic2/core/energy/grid/Tile.java +@@ -52,24 +52,21 @@ + } + + boolean removeExtraNode(Node node) { +- boolean flag = false; ++ boolean canBeRemoved = false; + if (node.isExtraNode()) { +- flag = true; ++ canBeRemoved = true; + } else { +- for(Node node : this.nodes) { +- if (node != node && node.nodeType == node.nodeType && node.isExtraNode()) { +- node.setExtraNode(false); +- flag = true; +- break; +- } ++ for (Node otherNode : this.nodes) { ++ if (otherNode == node || otherNode.nodeType != node.nodeType || !otherNode.isExtraNode()) continue; ++ otherNode.setExtraNode(false); ++ canBeRemoved = true; ++ break; + } + } +- +- if (flag) { ++ if (canBeRemoved) { + this.nodes.remove(node); + } +- +- return flag; ++ return canBeRemoved; + } + + public Collection getSubTiles() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch new file mode 100644 index 0000000..2c6e371 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/energy/leg/EnergyCalculatorLeg.java.patch @@ -0,0 +1,15 @@ +--- a/ic2/core/energy/leg/EnergyCalculatorLeg.java ++++ b/ic2/core/energy/leg/EnergyCalculatorLeg.java +@@ -145,10 +145,10 @@ + return list; + } else { + List arraylist = new ArrayList(); +- Iterator iterator = data.energySourceToEnergyPathMap.values().iterator(); ++ Iterator> iterator = data.energySourceToEnergyPathMap.values().iterator(); + + while(iterator.hasNext()) { +- for(EnergyPath energypath : (List)iterator.next()) { ++ for(EnergyPath energypath : iterator.next()) { + if (node.getType() == NodeType.Sink) { + if (energypath.target == node) { + arraylist.add(energypath); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/Ic2GuiFactory.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/gui/PlayerHead.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/PlayerHead.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/gui/PlayerHead.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/PlayerHead.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/dynamic/DynamicHandHeldContainer.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/gui/dynamic/TextProvider.java.patch diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/init/BlocksItems.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/init/BlocksItems.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/init/BlocksItems.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/init/BlocksItems.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/init/Localization.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/init/Localization.java.patch new file mode 100644 index 0000000..1c3a20e --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/init/Localization.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/init/Localization.java ++++ b/ic2/core/init/Localization.java +@@ -132,7 +132,7 @@ + Field field = ReflectionUtil.getField(LanguageMap.class, Map.class); + + try { +- return (Map)field.get(method.invoke((Object)null)); ++ return (Map)field.get(method.invoke(null)); + } catch (Exception exception) { + throw new RuntimeException(exception); + } +@@ -147,7 +147,7 @@ + Field field1 = ReflectionUtil.getField(Locale.class, Map.class); + + try { +- return (Map)field1.get(field.get((Object)null)); ++ return (Map)field1.get(field.get(null)); + } catch (Exception exception) { + throw new RuntimeException(exception); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch new file mode 100644 index 0000000..fdb2b1c --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorElectric.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/armor/ItemArmorElectric.java ++++ b/ic2/core/item/armor/ItemArmorElectric.java +@@ -29,7 +29,7 @@ + protected final int tier; + + public ItemArmorElectric(ItemName name, String armorName, EntityEquipmentSlot armorType, double maxCharge, double transferLimit, int tier) { +- super(name, ArmorMaterial.DIAMOND, armorName, armorType, (Object)null); ++ super(name, ArmorMaterial.DIAMOND, armorName, armorType, null); + this.maxCharge = maxCharge; + this.tier = tier; + this.transferLimit = transferLimit; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch new file mode 100644 index 0000000..4ce8a8f --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/armor/ItemArmorQuantumSuit.java ++++ b/ic2/core/item/armor/ItemArmorQuantumSuit.java +@@ -212,7 +212,7 @@ + IC2.achievements.issueAchievement(player, "starveWithQHelmet"); + } + +- for(PotionEffect potioneffect : new LinkedList(player.getActivePotionEffects())) { ++ for(PotionEffect potioneffect : new LinkedList<>(player.getActivePotionEffects())) { + Potion potion = potioneffect.getPotion(); + Integer integer = potionRemovalCost.get(potion); + if (integer != null) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch new file mode 100644 index 0000000..15db7ad --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorUtility.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/armor/ItemArmorUtility.java ++++ b/ic2/core/item/armor/ItemArmorUtility.java +@@ -12,7 +12,7 @@ + + public class ItemArmorUtility extends ItemArmorIC2 implements ISpecialArmor { + public ItemArmorUtility(ItemName name, String armorName, EntityEquipmentSlot type) { +- super(name, ArmorMaterial.DIAMOND, armorName, type, (Object)null); ++ super(name, ArmorMaterial.DIAMOND, armorName, type, null); + } + + public int getItemEnchantability() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemCable.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemCable.java.patch new file mode 100644 index 0000000..cefb6a6 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemCable.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/block/ItemCable.java ++++ b/ic2/core/item/block/ItemCable.java +@@ -223,7 +223,7 @@ + Ic2Color ic2color = itemtoolpainter.getColor(itemstack1); + if (ic2color != null) { + runnable = () -> { +- painter.damagePainter(player, EnumHand.OFF_HAND, color); ++ itemtoolpainter.damagePainter(player, EnumHand.OFF_HAND, ic2color); + }; + tileentitycable = TileEntityCable.delegate(cabletype, i, ic2color); + break label33; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch new file mode 100644 index 0000000..556bd94 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/block/ItemFluidPipe.java ++++ b/ic2/core/item/block/ItemFluidPipe.java +@@ -62,7 +62,7 @@ + public void registerModels(ItemName name) { + ResourceLocation resourcelocation = Util.getName(this); + ModelLoader.setCustomMeshDefinition(this, (stackx) -> { +- return getModelLocation(loc, stack); ++ return getModelLocation(resourcelocation, stackx); + }); + + for(ItemStack itemstack : this.variants) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemPipe.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemPipe.java.patch new file mode 100644 index 0000000..c93aef4 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemPipe.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/block/ItemPipe.java ++++ b/ic2/core/item/block/ItemPipe.java +@@ -53,7 +53,7 @@ + public void registerModels(ItemName name) { + ResourceLocation resourcelocation = Util.getName(this); + ModelLoader.setCustomMeshDefinition(this, (stackx) -> { +- return getModelLocation(loc, stack); ++ return getModelLocation(resourcelocation, stackx); + }); + + for(ItemStack itemstack : this.variants) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch new file mode 100644 index 0000000..2f116a0 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/GuiToolMeter.java.patch @@ -0,0 +1,19 @@ +--- a/ic2/core/item/tool/GuiToolMeter.java ++++ b/ic2/core/item/tool/GuiToolMeter.java +@@ -31,11 +31,11 @@ + + protected void mouseClicked(int i, int j, int k) throws IOException { + super.mouseClicked(i, j, k); +- int i = (this.width - this.xSize) / 2; +- int j = (this.height - this.ySize) / 2; +- int k = i - i; +- int l = j - j; +- if (k >= 26 && l >= 111 && k <= 83 && l <= 123) { ++ int i1 = (this.width - this.xSize) / 2; ++ int j1 = (this.height - this.ySize) / 2; ++ int k1 = i - i1; ++ int l = j - j1; ++ if (k1 >= 26 && l >= 111 && k1 <= 83 && l <= 123) { + ((ContainerMeter)this.container).reset(); + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemDebug.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemDebug.java.patch new file mode 100644 index 0000000..6f9f065 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemDebug.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/tool/ItemDebug.java ++++ b/ic2/core/item/tool/ItemDebug.java +@@ -369,7 +369,7 @@ + } else if (object instanceof Map) { + ps.println(" values (" + ((Map)object).size() + "):"); + +- for(Entry entry : ((Map)object).entrySet()) { ++ for(Entry entry : ((Map)object).entrySet()) { + ps.print(" " + entry.getKey() + ": "); + dumpValueString(entry.getValue(), field, " ", ps); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch new file mode 100644 index 0000000..8d5af5b --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricTool.java.patch @@ -0,0 +1,41 @@ +--- a/ic2/core/item/tool/ItemElectricTool.java ++++ b/ic2/core/item/tool/ItemElectricTool.java +@@ -140,9 +140,9 @@ + } + + public void onUpdate(ItemStack itemstack, World world, Entity entity, int i, boolean flag) { +- boolean flag = flag && entity instanceof EntityLivingBase; ++ boolean flag2 = flag && entity instanceof EntityLivingBase; + if (IC2.platform.isRendering()) { +- if (flag && !this.wasEquipped) { ++ if (flag2 && !this.wasEquipped) { + if (this.audioSource == null) { + String s1 = this.getIdleSound((EntityLivingBase)entity, itemstack); + if (s1 != null) { +@@ -158,13 +158,13 @@ + if (s2 != null) { + IC2.audioManager.playOnce(entity, PositionSpec.Hand, s2, true, IC2.audioManager.getDefaultVolume()); + } +- } else if (!flag && this.audioSource != null) { ++ } else if (!flag2 && this.audioSource != null) { + if (entity instanceof EntityLivingBase) { + EntityLivingBase entitylivingbase = (EntityLivingBase)entity; +- ItemStack itemstack = entitylivingbase.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND); +- if (itemstack == null || itemstack.getItem() != this || itemstack == itemstack) { ++ ItemStack stack = entitylivingbase.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND); ++ if (stack == null || stack.getItem() != this || stack == itemstack) { + this.removeAudioSource(); +- String s = this.getStopSound(entitylivingbase, itemstack); ++ String s = this.getStopSound(entitylivingbase, stack); + if (s != null) { + IC2.audioManager.playOnce(entity, PositionSpec.Hand, s, true, IC2.audioManager.getDefaultVolume()); + } +@@ -174,7 +174,7 @@ + this.audioSource.updatePosition(); + } + +- this.wasEquipped = flag; ++ this.wasEquipped = flag2; + } + + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch new file mode 100644 index 0000000..e30ba24 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemElectricToolChainsaw.java.patch @@ -0,0 +1,13 @@ +--- a/ic2/core/item/tool/ItemElectricToolChainsaw.java ++++ b/ic2/core/item/tool/ItemElectricToolChainsaw.java +@@ -124,8 +124,8 @@ + if (block instanceof IShearable) { + IShearable ishearable = (IShearable)block; + if (ishearable.isShearable(itemstack, world, pos) && ElectricItem.manager.use(itemstack, this.operationEnergyCost, player)) { +- for(ItemStack itemstack : ishearable.onSheared(itemstack, world, pos, EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, itemstack))) { +- StackUtil.dropAsEntity(world, pos, itemstack); ++ for(ItemStack stack : ishearable.onSheared(itemstack, world, pos, EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, itemstack))) { ++ StackUtil.dropAsEntity(world, pos, stack); + } + + player.addStat(StatList.getBlockStats(block), 1); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemScanner.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemScanner.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemScanner.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemScanner.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch new file mode 100644 index 0000000..a207a7a --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolPainter.java.patch @@ -0,0 +1,14 @@ +--- a/ic2/core/item/tool/ItemToolPainter.java ++++ b/ic2/core/item/tool/ItemToolPainter.java +@@ -130,9 +130,9 @@ + UnmodifiableIterator unmodifiableiterator = state.getProperties().keySet().iterator(); + + while(unmodifiableiterator.hasNext()) { +- IProperty iproperty = (IProperty)unmodifiableiterator.next(); ++ IProperty iproperty = (IProperty)unmodifiableiterator.next(); + if (iproperty.getValueClass() == EnumDyeColor.class) { +- EnumDyeColor enumdyecolor = (EnumDyeColor)state.getValue(iproperty); ++ EnumDyeColor enumdyecolor = state.getValue(iproperty); + if (enumdyecolor != newColor && iproperty.getAllowedValues().contains(newColor)) { + world.setBlockState(pos, state.withProperty(iproperty, newColor)); + return true; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch new file mode 100644 index 0000000..ea46745 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrench.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/item/tool/ItemToolWrench.java ++++ b/ic2/core/item/tool/ItemToolWrench.java +@@ -119,7 +119,7 @@ + } + + block.onBlockDestroyedByPlayer(world, pos, iblockstate); +- List drops = iwrenchable.getWrenchDrops(world, pos, iblockstate, tileentity, player, 0); ++ List drops = iwrenchable.getWrenchDrops(world, pos, iblockstate, tileentity, player, 0); + if (drops != null && !drops.isEmpty()) { + for(ItemStack itemstack : drops) { + StackUtil.dropAsEntity(world, pos, itemstack); diff --git a/projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch similarity index 100% rename from projects/IC2-Base/patches/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch rename to projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/type/CellType.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/type/CellType.java.patch new file mode 100644 index 0000000..1c301b9 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/item/type/CellType.java.patch @@ -0,0 +1,13 @@ +--- a/ic2/core/item/type/CellType.java ++++ b/ic2/core/item/type/CellType.java +@@ -135,9 +135,7 @@ + + public CellFluidHandler(ItemStack container, Function typeGetter) { + super(container); +- this.typeGetter = () -> { +- return (void)((CellType)typeGetter.apply(this.container)); +- }; ++ this.typeGetter = () -> ((CellType)typeGetter.apply(this.container)); + } + + public FluidStack getFluid() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/MaskOverlayModel.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/MaskOverlayModel.java.patch new file mode 100644 index 0000000..86613da --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/MaskOverlayModel.java.patch @@ -0,0 +1,47 @@ +--- a/ic2/core/model/MaskOverlayModel.java ++++ b/ic2/core/model/MaskOverlayModel.java +@@ -127,26 +127,26 @@ + return bitset; + } + +- private static List searchAreas(BitSet pixels, int width) { +- List list = new ArrayList(); +- +- int k; +- int j1; +- for(idx = 0; (j1 = pixels.nextSetBit(j1)) != -1; j1 = j1 + k) { +- int i = j1 / width; +- int j = j1 - i * width; +- k = Math.min(width - j, pixels.nextClearBit(j1 + 1) - j1); +- int l = 1; +- +- for(int i1 = j1 + width; pixels.get(i1) && pixels.nextClearBit(i1 + 1) >= i1 + k; i1 += width) { +- pixels.clear(i1, i1 + k); +- ++l; ++ private static List searchAreas(BitSet pixels, int width) { ++ List ret = new ArrayList(); ++ int idx = 0; ++ while ((idx = pixels.nextSetBit(idx)) != -1) { ++ int y = idx / width; ++ int x = idx - y * width; ++ int areaWidth = Math.min(width - x, pixels.nextClearBit(idx + 1) - idx); ++ int areaHeight = 1; ++ int nextLineIdx = idx + width; ++ while (pixels.get(nextLineIdx) && pixels.nextClearBit(nextLineIdx + 1) >= nextLineIdx + areaWidth) { ++ pixels.clear(nextLineIdx, nextLineIdx + areaWidth); ++ ++areaHeight; ++ nextLineIdx += width; + } +- +- list.add(new MaskOverlayModel.Area(j, i, k, l)); ++ ++ ret.add(new Area(x, y, areaWidth, areaHeight)); ++ idx += areaWidth; + } +- +- return list; ++ ++ return ret; + } + + private static void generateQuads(List areas, int width, int height, float offset, int tint, List out) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/ModelUtil.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/ModelUtil.java.patch new file mode 100644 index 0000000..9f4c6d9 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/model/ModelUtil.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/model/ModelUtil.java ++++ b/ic2/core/model/ModelUtil.java +@@ -39,7 +39,7 @@ + } + + private > String getPropertyName(IProperty property, Comparable value) { +- return property.getName(value); ++ return property.getName((T) value); + } + }; + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/DataEncoder.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/DataEncoder.java.patch new file mode 100644 index 0000000..f55f95a --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/DataEncoder.java.patch @@ -0,0 +1,1421 @@ +--- a/ic2/core/network/DataEncoder.java ++++ b/ic2/core/network/DataEncoder.java +@@ -9,9 +9,12 @@ + import ic2.core.IC2; + import ic2.core.block.comp.TileEntityComponent; + import ic2.core.block.invslot.InvSlot; ++import ic2.core.network.GrowingBuffer; + import ic2.core.util.StackUtil; + import ic2.core.util.Tuple; + import ic2.core.util.Util; ++import java.io.DataInput; ++import java.io.DataOutput; + import java.io.IOException; + import java.lang.reflect.Array; + import java.util.Arrays; +@@ -42,704 +45,760 @@ + import net.minecraftforge.fluids.FluidTank; + + public final class DataEncoder { +- private static final Map, DataEncoder.EncodedType> classToTypeCache = Collections., DataEncoder.EncodedType>synchronizedMap(new IdentityHashMap()); +- private static final Map, INetworkCustomEncoder> classToAddonType = Collections., INetworkCustomEncoder>synchronizedMap(new IdentityHashMap()); ++ private static final Map, EncodedType> classToTypeCache = Collections.synchronizedMap(new IdentityHashMap()); ++ private static final Map, INetworkCustomEncoder> classToAddonType = Collections.synchronizedMap(new IdentityHashMap()); + + public static void encode(GrowingBuffer os, Object o) throws IOException { + try { +- encode(os, o, true); +- } catch (IllegalArgumentException illegalargumentexception) { +- IC2.platform.displayError(illegalargumentexception, "An unknown data type was attempted to be encoded for sending through\nmultiplayer.\nThis could happen due to a bug."); +- } +- ++ DataEncoder.encode(os, o, true); ++ } ++ catch (IllegalArgumentException e) { ++ IC2.platform.displayError(e, "An unknown data type was attempted to be encoded for sending through\nmultiplayer.\nThis could happen due to a bug.", new Object[0]); ++ } + } + + public static void encode(IGrowingBuffer os, Object o, boolean withType) throws IOException { +- DataEncoder.EncodedType dataencoder$encodedtype = typeFromObject(o); ++ EncodedType type = DataEncoder.typeFromObject(o); + if (withType) { +- os.writeByte(idFromType(dataencoder$encodedtype)); ++ os.writeByte(DataEncoder.idFromType(type)); + } +- +- switch(dataencoder$encodedtype) { +- case Addon: +- case UnSafeAddon: +- assert o != null; +- +- INetworkCustomEncoder inetworkcustomencoder = classToAddonType.get(o.getClass()); +- if (inetworkcustomencoder == null) { +- throw new IllegalStateException("Cannot encode an object without an encoder! Type was " + o.getClass()); ++ return; ++ /*switch (type) { ++ case Addon: ++ case UnSafeAddon: { ++ assert (o != null); ++ INetworkCustomEncoder ince = classToAddonType.get(o.getClass()); ++ if (ince == null) { ++ throw new IllegalStateException("Cannot encode an object without an encoder! Type was " + o.getClass()); ++ } ++ os.writeString(o.getClass().getName()); ++ ince.encode(os, o); ++ break; + } +- +- os.writeString(o.getClass().getName()); +- inetworkcustomencoder.encode(os, o); +- break; +- case Array: +- Class oclass = o.getClass().getComponentType(); +- int j = Array.getLength(o); +- if (oclass == Object.class && j > 0) { +- boolean flag = false; +- Class oclass1 = null; +- +- label203: +- for(int k = 0; k < j; ++k) { +- Object object = Array.get(o, k); +- if (oclass1 == null) { +- if (object instanceof Enum) { +- oclass1 = ((Enum)object).getDeclaringClass(); +- flag = true; +- } else if (object != null) { +- oclass1 = object.getClass(); +- +- assert oclass1 != Object.class; ++ case Array: { ++ Object value; ++ int i; ++ Class componentClass = o.getClass().getComponentType(); ++ int len = Array.getLength(o); ++ if (componentClass == Object.class && len > 0) { ++ boolean isEnum = false; ++ Class target = null; ++ block40: for (i = 0; i < len; ++i) { ++ value = Array.get(o, i); ++ if (target == null) { ++ if (value instanceof Enum) { ++ target = ((Enum)value).getDeclaringClass(); ++ isEnum = true; ++ continue; ++ } ++ if (value == null) continue; ++ target = value.getClass(); ++ assert (target != Object.class); ++ continue; + } +- } else if (object != null) { +- Class oclass2 = object.getClass(); +- if (oclass2 != oclass1 && !oclass1.isAssignableFrom(oclass2)) { +- if (flag || object instanceof Enum) { +- throw new IllegalArgumentException("Array of mixed enum entries"); +- } +- +- while((oclass1 = oclass1.getSuperclass()) != Object.class) { +- if (oclass1.isAssignableFrom(oclass2)) { +- continue label203; +- } +- } +- +- ++k; +- +- while(k < j) { +- if (Array.get(o, k) instanceof Enum) { ++ if (value != null) { ++ Class valueClass = value.getClass(); ++ if (valueClass != target && !target.isAssignableFrom(valueClass)) { ++ if (isEnum || value instanceof Enum) { + throw new IllegalArgumentException("Array of mixed enum entries"); + } +- +- ++k; ++ while ((target = target.getSuperclass()) != Object.class) { ++ if (!target.isAssignableFrom(valueClass)) continue; ++ continue block40; ++ } ++ ++i; ++ while (i < len) { ++ if (Array.get(o, i) instanceof Enum) { ++ throw new IllegalArgumentException("Array of mixed enum entries"); ++ } ++ ++i; ++ } ++ target = Object.class; ++ break; + } +- +- oclass1 = Object.class; +- break; +- } else { +- assert flag == (object instanceof Enum); ++ assert (isEnum == value instanceof Enum); ++ continue; + } +- } else if (flag) { ++ if (!isEnum) continue; + throw new IllegalArgumentException("Enum array with null entry"); + } +- } +- +- oclass = oclass1; +- } +- +- DataEncoder.EncodedType dataencoder$encodedtype1 = typeFromClass(oclass); +- os.writeByte(idFromType(dataencoder$encodedtype1)); +- os.writeBoolean(oclass.isPrimitive()); +- if (dataencoder$encodedtype1 == DataEncoder.EncodedType.Addon || dataencoder$encodedtype1 == DataEncoder.EncodedType.UnSafeAddon || dataencoder$encodedtype1 == DataEncoder.EncodedType.Enum) { +- os.writeString(oclass.getName()); +- } +- +- os.writeVarInt(j); +- boolean flag1 = false; +- +- for(int l = 0; l < j; ++l) { +- Object object1 = Array.get(o, l); +- if (object1 == null || typeFromClass(object1.getClass()) != dataencoder$encodedtype1) { +- flag1 = true; +- break; +- } +- } +- +- os.writeBoolean(flag1); +- +- for(int i1 = 0; i1 < j; ++i1) { +- encode(os, Array.get(o, i1), flag1); +- } +- break; +- case Block: +- encode(os, Util.getName((Block)o), false); +- break; +- case BlockPos: +- BlockPos blockpos = (BlockPos)o; +- os.writeInt(blockpos.getX()); +- os.writeInt(blockpos.getY()); +- os.writeInt(blockpos.getZ()); +- break; +- case Boolean: +- os.writeBoolean(((Boolean)o).booleanValue()); +- break; +- case Byte: +- os.writeByte(((Byte)o).byteValue()); +- break; +- case Character: +- os.writeChar(((Character)o).charValue()); +- break; +- case ChunkPos: +- ChunkPos chunkpos = (ChunkPos)o; +- os.writeInt(chunkpos.x); +- os.writeInt(chunkpos.z); +- break; +- case Collection: +- encode(os, ((Collection)o).toArray(), false); +- break; +- case Component: +- NBTTagCompound nbttagcompound = ((TileEntityComponent)o).writeToNbt(); +- encode(os, nbttagcompound == null ? new NBTTagCompound() : nbttagcompound, false); +- break; +- case CropCard: +- CropCard cropcard = (CropCard)o; +- os.writeString(cropcard.getOwner()); +- os.writeString(cropcard.getId()); +- break; +- case Double: +- os.writeDouble(((Double)o).doubleValue()); +- break; +- case ElectrolyzerRecipe: +- IElectrolyzerRecipeManager.ElectrolyzerRecipe ielectrolyzerrecipemanager$electrolyzerrecipe = (IElectrolyzerRecipeManager.ElectrolyzerRecipe)o; +- os.writeInt(ielectrolyzerrecipemanager$electrolyzerrecipe.inputAmount); +- os.writeInt(ielectrolyzerrecipemanager$electrolyzerrecipe.EUaTick); +- os.writeInt(ielectrolyzerrecipemanager$electrolyzerrecipe.ticksNeeded); +- IElectrolyzerRecipeManager.ElectrolyzerOutput[] aielectrolyzerrecipemanager$electrolyzeroutput = ielectrolyzerrecipemanager$electrolyzerrecipe.outputs; +- os.writeByte(aielectrolyzerrecipemanager$electrolyzeroutput.length); +- +- for(IElectrolyzerRecipeManager.ElectrolyzerOutput ielectrolyzerrecipemanager$electrolyzeroutput : aielectrolyzerrecipemanager$electrolyzeroutput) { +- os.writeString(ielectrolyzerrecipemanager$electrolyzeroutput.fluidName); +- os.writeInt(ielectrolyzerrecipemanager$electrolyzeroutput.fluidAmount); +- os.writeByte(ielectrolyzerrecipemanager$electrolyzeroutput.tankDirection.getIndex()); +- } +- +- return; +- case Enchantment: +- encode(os, Enchantment.REGISTRY.getNameForObject((Enchantment)o), false); +- break; +- case Enum: +- os.writeVarInt(((Enum)o).ordinal()); +- break; +- case Float: +- os.writeFloat(((Float)o).floatValue()); +- break; +- case Fluid: +- os.writeString(((Fluid)o).getName()); +- break; +- case FluidStack: +- FluidStack fluidstack = (FluidStack)o; +- encode(os, fluidstack.getFluid(), false); +- os.writeInt(fluidstack.amount); +- encode(os, fluidstack.tag, true); +- break; +- case FluidTank: +- FluidTank fluidtank = (FluidTank)o; +- encode(os, fluidtank.getFluid(), true); +- os.writeInt(fluidtank.getCapacity()); +- break; +- case GameProfile: +- GameProfile gameprofile = (GameProfile)o; +- encode(os, gameprofile.getId(), true); +- os.writeString(gameprofile.getName()); +- break; +- case Integer: +- os.writeInt(((Integer)o).intValue()); +- break; +- case InvSlot: +- InvSlot invslot = (InvSlot)o; +- ItemStack[] aitemstack = new ItemStack[invslot.size()]; +- +- for(int i = 0; i < invslot.size(); ++i) { +- aitemstack[i] = invslot.get(i); +- } +- +- encode(os, aitemstack, false); +- break; +- case Item: +- encode(os, Util.getName((Item)o), false); +- break; +- case ItemStack: +- ItemStack itemstack = (ItemStack)o; +- if (StackUtil.isEmpty(itemstack)) { +- os.writeByte(0); +- } else { +- os.writeByte(StackUtil.getSize(itemstack)); +- encode(os, itemstack.getItem(), false); +- os.writeShort(itemstack.getItemDamage()); +- encode(os, itemstack.getTagCompound(), true); +- } +- break; +- case Long: +- os.writeLong(((Long)o).longValue()); +- break; +- case NBTTagCompound: +- CompressedStreamTools.write((NBTTagCompound)o, os); +- break; +- case Null: +- if (!withType) { ++ componentClass = target; ++ } ++ EncodedType componentType = DataEncoder.typeFromClass(componentClass); ++ os.writeByte(DataEncoder.idFromType(componentType)); ++ os.writeBoolean(componentClass.isPrimitive()); ++ if (componentType == EncodedType.Addon || componentType == EncodedType.UnSafeAddon || componentType == EncodedType.Enum) { ++ os.writeString(componentClass.getName()); ++ } ++ os.writeVarInt(len); ++ boolean anyTypeMismatch = false; ++ for (i = 0; i < len; ++i) { ++ value = Array.get(o, i); ++ if (value != null && DataEncoder.typeFromClass(value.getClass()) == componentType) continue; ++ anyTypeMismatch = true; ++ break; ++ } ++ os.writeBoolean(anyTypeMismatch); ++ for (i = 0; i < len; ++i) { ++ DataEncoder.encode(os, Array.get(o, i), anyTypeMismatch); ++ } ++ break; ++ } ++ case Block: { ++ DataEncoder.encode(os, Util.getName((Block)o), false); ++ break; ++ } ++ case BlockPos: { ++ BlockPos pos = (BlockPos)o; ++ os.writeInt(pos.getX()); ++ os.writeInt(pos.getY()); ++ os.writeInt(pos.getZ()); ++ break; ++ } ++ case Boolean: { ++ os.writeBoolean((Boolean)o); ++ break; ++ } ++ case Byte: { ++ os.writeByte(((Byte)o).byteValue()); ++ break; ++ } ++ case Character: { ++ os.writeChar(((Character)o).charValue()); ++ break; ++ } ++ case ChunkPos: { ++ ChunkPos pos = (ChunkPos)o; ++ os.writeInt(pos.x); ++ os.writeInt(pos.z); ++ break; ++ } ++ case Collection: { ++ DataEncoder.encode(os, ((Collection)o).toArray(), false); ++ break; ++ } ++ case Component: { ++ NBTTagCompound nbt = ((TileEntityComponent)o).writeToNbt(); ++ DataEncoder.encode(os, nbt == null ? new NBTTagCompound() : nbt, false); ++ break; ++ } ++ case CropCard: { ++ CropCard cropCard = (CropCard)o; ++ os.writeString(cropCard.getOwner()); ++ os.writeString(cropCard.getId()); ++ break; ++ } ++ case Double: { ++ os.writeDouble((Double)o); ++ break; ++ } ++ case ElectrolyzerRecipe: { ++ IElectrolyzerRecipeManager.ElectrolyzerRecipe recipe = (IElectrolyzerRecipeManager.ElectrolyzerRecipe)o; ++ os.writeInt(recipe.inputAmount); ++ os.writeInt(recipe.EUaTick); ++ os.writeInt(recipe.ticksNeeded); ++ IElectrolyzerRecipeManager.ElectrolyzerOutput[] outputs = recipe.outputs; ++ os.writeByte(outputs.length); ++ for (IElectrolyzerRecipeManager.ElectrolyzerOutput output : outputs) { ++ os.writeString(output.fluidName); ++ os.writeInt(output.fluidAmount); ++ os.writeByte(output.tankDirection.getIndex()); ++ } ++ break; ++ } ++ case Enchantment: { ++ DataEncoder.encode(os, Enchantment.REGISTRY.getNameForObject(((Enchantment)o)), false); ++ break; ++ } ++ case Enum: { ++ os.writeVarInt(((Enum)o).ordinal()); ++ break; ++ } ++ case Float: { ++ os.writeFloat(((Float)o).floatValue()); ++ break; ++ } ++ case Fluid: { ++ os.writeString(((Fluid)o).getName()); ++ break; ++ } ++ case FluidStack: { ++ FluidStack fs = (FluidStack)o; ++ DataEncoder.encode(os, fs.getFluid(), false); ++ os.writeInt(fs.amount); ++ DataEncoder.encode(os, fs.tag, true); ++ break; ++ } ++ case FluidTank: { ++ FluidTank tank = (FluidTank)o; ++ DataEncoder.encode(os, tank.getFluid(), true); ++ os.writeInt(tank.getCapacity()); ++ break; ++ } ++ case GameProfile: { ++ GameProfile gp = (GameProfile)o; ++ DataEncoder.encode(os, gp.getId(), true); ++ os.writeString(gp.getName()); ++ break; ++ } ++ case Integer: { ++ os.writeInt((Integer)o); ++ break; ++ } ++ case InvSlot: { ++ InvSlot slot = (InvSlot)o; ++ ItemStack[] contents = new ItemStack[slot.size()]; ++ for (int i = 0; i < slot.size(); ++i) { ++ contents[i] = slot.get(i); ++ } ++ DataEncoder.encode(os, contents, false); ++ break; ++ } ++ case Item: { ++ DataEncoder.encode(os, Util.getName((Item)o), false); ++ break; ++ } ++ case ItemStack: { ++ ItemStack stack = (ItemStack)o; ++ if (StackUtil.isEmpty(stack)) { ++ os.writeByte(0); ++ break; ++ } ++ os.writeByte(StackUtil.getSize(stack)); ++ DataEncoder.encode(os, stack.getItem(), false); ++ os.writeShort(stack.getItemDamage()); ++ DataEncoder.encode(os, stack.getTagCompound(), true); ++ break; ++ } ++ case Long: { ++ os.writeLong((Long)o); ++ break; ++ } ++ case NBTTagCompound: { ++ CompressedStreamTools.write((NBTTagCompound)((NBTTagCompound)o), (DataOutput)os); ++ break; ++ } ++ case Null: { ++ if (withType) break; + throw new IllegalArgumentException("o has to be non-null without types"); + } +- break; +- case Object: +- throw new IllegalArgumentException("unhandled class: " + o.getClass()); +- case Potion: +- encode(os, Potion.REGISTRY.getNameForObject((Potion)o), false); +- break; +- case ResourceLocation: +- ResourceLocation resourcelocation = (ResourceLocation)o; +- os.writeString(resourcelocation.getResourceDomain()); +- os.writeString(resourcelocation.getResourcePath()); +- break; +- case Short: +- os.writeShort(((Short)o).shortValue()); +- break; +- case String: +- os.writeString((String)o); +- break; +- case TileEntity: +- TileEntity tileentity = (TileEntity)o; +- encode(os, tileentity.getWorld(), false); +- encode(os, tileentity.getPos(), false); +- break; +- case TupleT2: +- Tuple.T2 t2 = (Tuple.T2)o; +- encode(os, t2.a, true); +- encode(os, t2.b, true); +- break; +- case TupleT3: +- Tuple.T3 t3 = (Tuple.T3)o; +- encode(os, t3.a, true); +- encode(os, t3.b, true); +- encode(os, t3.c, true); +- break; +- case UUID: +- UUID uuid = (UUID)o; +- os.writeLong(uuid.getMostSignificantBits()); +- os.writeLong(uuid.getLeastSignificantBits()); +- break; +- case Vec3: +- Vec3d vec3d = (Vec3d)o; +- os.writeDouble(vec3d.x); +- os.writeDouble(vec3d.y); +- os.writeDouble(vec3d.z); +- break; +- case World: +- os.writeInt(((World)o).provider.getDimension()); +- break; +- default: +- throw new IllegalArgumentException("unhandled type: " + dataencoder$encodedtype); +- } +- ++ case Object: { ++ throw new IllegalArgumentException("unhandled class: " + o.getClass()); ++ } ++ case Potion: { ++ DataEncoder.encode(os, Potion.REGISTRY.getNameForObject(((Potion)o)), false); ++ break; ++ } ++ case ResourceLocation: { ++ ResourceLocation loc = (ResourceLocation)o; ++ os.writeString(loc.getResourceDomain()); ++ os.writeString(loc.getResourcePath()); ++ break; ++ } ++ case Short: { ++ os.writeShort(((Short)o).shortValue()); ++ break; ++ } ++ case String: { ++ os.writeString((String)o); ++ break; ++ } ++ case TileEntity: { ++ TileEntity te = (TileEntity)o; ++ DataEncoder.encode(os, te.getWorld(), false); ++ DataEncoder.encode(os, te.getPos(), false); ++ break; ++ } ++ case TupleT2: { ++ Tuple.T2 t = (Tuple.T2)o; ++ DataEncoder.encode(os, t.a, true); ++ DataEncoder.encode(os, t.b, true); ++ break; ++ } ++ case TupleT3: { ++ Tuple.T3 t = (Tuple.T3)o; ++ DataEncoder.encode(os, t.a, true); ++ DataEncoder.encode(os, t.b, true); ++ DataEncoder.encode(os, t.c, true); ++ break; ++ } ++ case UUID: { ++ UUID uuid = (UUID)o; ++ os.writeLong(uuid.getMostSignificantBits()); ++ os.writeLong(uuid.getLeastSignificantBits()); ++ break; ++ } ++ case Vec3: { ++ Vec3d v = (Vec3d)o; ++ os.writeDouble(v.x); ++ os.writeDouble(v.y); ++ os.writeDouble(v.z); ++ break; ++ } ++ case World: { ++ os.writeInt(((World)o).provider.getDimension()); ++ break; ++ } ++ default: { ++ throw new IllegalArgumentException("unhandled type: " + (Object)((Object)type)); ++ } ++ }*/ + } + + public static Object decode(IGrowingBuffer is) throws IOException { + try { +- return decode(is, typeFromId(is.readUnsignedByte())); +- } catch (IllegalArgumentException illegalargumentexception) { +- String s = "An unknown data type was received over multiplayer to be decoded.\nThis could happen due to corrupted data or a bug."; +- IC2.platform.displayError(illegalargumentexception, s); ++ return DataEncoder.decode(is, DataEncoder.typeFromId(is.readByte())); ++ } ++ catch (IllegalArgumentException e) { ++ String msg = "An unknown data type was received over multiplayer to be decoded.\nThis could happen due to corrupted data or a bug."; ++ IC2.platform.displayError(e, msg, new Object[0]); + return null; + } + } + + public static T decode(IGrowingBuffer is, Class clazz) throws IOException { +- DataEncoder.EncodedType dataencoder$encodedtype = typeFromClass(clazz); +- if (dataencoder$encodedtype.threadSafe) { +- return (T)decode(is, dataencoder$encodedtype); +- } else { +- throw new IllegalArgumentException("requesting decode for non thread safe type"); ++ EncodedType type = DataEncoder.typeFromClass(clazz); ++ if (type.threadSafe) { ++ return (T)DataEncoder.decode(is, type); + } ++ throw new IllegalArgumentException("requesting decode for non thread safe type"); + } + + public static > T decodeEnum(IGrowingBuffer is, Class clazz) throws IOException { +- int i = ((Integer)decode(is, DataEncoder.EncodedType.Enum)).intValue(); +- T[] at = clazz.getEnumConstants(); +- return (T)(i >= 0 && i < at.length ? at[i] : null); ++ int ordinal = (Integer)DataEncoder.decode(is, EncodedType.Enum); ++ Enum[] values = (Enum[])clazz.getEnumConstants(); ++ return (T)(ordinal >= 0 && ordinal < values.length ? values[ordinal] : null); + } + + public static Object decodeDeferred(GrowingBuffer is, Class clazz) throws IOException { +- DataEncoder.EncodedType dataencoder$encodedtype = typeFromClass(clazz); +- return decode(is, dataencoder$encodedtype); ++ EncodedType type = DataEncoder.typeFromClass(clazz); ++ return DataEncoder.decode((IGrowingBuffer)is, type); + } + +- public static Object decode(final IGrowingBuffer is, DataEncoder.EncodedType type) throws IOException { +- switch(type) { +- case Addon: +- case UnSafeAddon: +- String s = is.readString(); +- final INetworkCustomEncoder inetworkcustomencoder = classToAddonType.get(getClass(s)); +- if (inetworkcustomencoder == null) { +- throw new IllegalStateException("Cannot decode an object without a decoder! Type was " + s); +- } else { +- if (inetworkcustomencoder.isThreadSafe()) { +- return inetworkcustomencoder.decode(is); +- } ++ public static Object decode(final IGrowingBuffer is, EncodedType type) throws IOException { ++ switch (type) { ++ case Addon: ++ case UnSafeAddon: { ++ String aimTypeName = is.readString(); ++ final INetworkCustomEncoder ince = classToAddonType.get(DataEncoder.getClass(aimTypeName)); ++ if (ince == null) { ++ throw new IllegalStateException("Cannot decode an object without a decoder! Type was " + aimTypeName); ++ } ++ if (ince.isThreadSafe()) { ++ return ince.decode(is); ++ } ++ return new IResolvableValue(){ + +- return new DataEncoder.IResolvableValue() { ++ @Override + public Object get() { + try { +- return inetworkcustomencoder.decode(is); +- } catch (IOException ioexception) { +- throw new RuntimeException("Unexpected error", ioexception); ++ return ince.decode(is); ++ } ++ catch (IOException e) { ++ throw new RuntimeException("Unexpected error", e); + } + } + }; + } +- case Array: +- DataEncoder.EncodedType dataencoder$encodedtype = typeFromId(is.readUnsignedByte()); +- boolean flag1 = is.readBoolean(); +- boolean flag2 = dataencoder$encodedtype == DataEncoder.EncodedType.Enum; +- Class oclass1 = flag1 ? unbox(dataencoder$encodedtype.cls) : dataencoder$encodedtype.cls; +- if (oclass1 == null || flag2) { +- assert dataencoder$encodedtype == DataEncoder.EncodedType.Addon || dataencoder$encodedtype == DataEncoder.EncodedType.UnSafeAddon || flag2; +- +- oclass1 = getClass(is.readString()); +- } +- +- final Class oclass = oclass1; +- final int i2 = is.readVarInt(); +- boolean flag3 = is.readBoolean(); +- boolean flag = !dataencoder$encodedtype.threadSafe; +- final Object object; +- if (!flag) { +- object = Array.newInstance(oclass1, i2); +- } else { +- object = new Object[i2]; +- } +- +- if (!flag3) { +- if (flag2) { +- Object[] aobject = oclass1.getEnumConstants(); +- +- assert aobject != null; +- +- for(int k = 0; k < i2; ++k) { +- Array.set(object, k, aobject[((Integer)decode(is, dataencoder$encodedtype)).intValue()]); ++ case Array: { ++ Class component; ++ EncodedType componentType = DataEncoder.typeFromId(is.readUnsignedByte()); ++ boolean primitive = is.readBoolean(); ++ boolean isEnum = componentType == EncodedType.Enum; ++ Class clazz = component = primitive ? DataEncoder.unbox(componentType.cls) : componentType.cls; ++ if (component == null || isEnum) { ++ assert (componentType == EncodedType.Addon || componentType == EncodedType.UnSafeAddon || isEnum); ++ component = DataEncoder.getClass(is.readString()); ++ } ++ final Class componentClass = component; ++ final int len = is.readVarInt(); ++ boolean anyTypeMismatch = is.readBoolean(); ++ boolean needsResolving = !componentType.threadSafe; ++ Object array = !needsResolving ? Array.newInstance(componentClass, len) : new Object[len]; ++ if (!anyTypeMismatch) { ++ if (isEnum) { ++ Object[] constants = componentClass.getEnumConstants(); ++ assert (constants != null); ++ for (int i = 0; i < len; ++i) { ++ Array.set(array, i, constants[(Integer)DataEncoder.decode(is, componentType)]); ++ } ++ } else { ++ for (int i = 0; i < len; ++i) { ++ Array.set(array, i, DataEncoder.decode(is, componentType)); ++ } + } + } else { +- for(int j2 = 0; j2 < i2; ++j2) { +- Array.set(object, j2, decode(is, dataencoder$encodedtype)); +- } +- } +- } else { +- for(int k2 = 0; k2 < i2; ++k2) { +- DataEncoder.EncodedType dataencoder$encodedtype1 = typeFromId(is.readUnsignedByte()); +- if (!dataencoder$encodedtype1.threadSafe && !flag) { +- flag = true; +- if (oclass != Object.class) { +- Object object1 = new Object[i2]; +- System.arraycopy(object, 0, object1, 0, k2); +- object = object1; +- } +- } +- +- Array.set(object, k2, decode(is, dataencoder$encodedtype1)); +- } +- } +- +- if (!flag) { +- return object; +- } +- +- return new DataEncoder.IResolvableValue() { +- public Object get() { +- Object object3 = Array.newInstance(oclass, i2); +- +- for(int l2 = 0; l2 < i2; ++l2) { +- Array.set(object3, l2, DataEncoder.getValue(Array.get(object, l2))); +- } +- +- return object3; +- } +- }; +- case Block: +- return Util.getBlock((ResourceLocation)decode(is, DataEncoder.EncodedType.ResourceLocation)); +- case BlockPos: +- return new BlockPos(is.readInt(), is.readInt(), is.readInt()); +- case Boolean: +- return is.readBoolean(); +- case Byte: +- return is.readByte(); +- case Character: +- return is.readChar(); +- case ChunkPos: +- return new ChunkPos(is.readInt(), is.readInt()); +- case Collection: +- final Object object2 = decode(is, DataEncoder.EncodedType.Array); +- if (object2 instanceof DataEncoder.IResolvableValue) { +- return new DataEncoder.IResolvableValue>() { +- public List get() { +- return Arrays.asList(((DataEncoder.IResolvableValue)object2).get()); +- } +- }; +- } +- +- return Arrays.asList(object2); +- case Component: +- return (List)decode(is, DataEncoder.EncodedType.NBTTagCompound); +- case CropCard: +- return Crops.instance.getCropCard(is.readString(), is.readString()); +- case Double: +- return is.readDouble(); +- case ElectrolyzerRecipe: +- int i1 = is.readInt(); +- int j1 = is.readInt(); +- int l1 = is.readInt(); +- byte b1 = is.readByte(); +- IElectrolyzerRecipeManager.ElectrolyzerOutput[] aielectrolyzerrecipemanager$electrolyzeroutput = new IElectrolyzerRecipeManager.ElectrolyzerOutput[b1]; +- +- for(byte b0 = 0; b0 < b1; ++b0) { +- aielectrolyzerrecipemanager$electrolyzeroutput[b0] = new IElectrolyzerRecipeManager.ElectrolyzerOutput(is.readString(), is.readInt(), EnumFacing.getFront(is.readByte())); +- } +- +- return new IElectrolyzerRecipeManager.ElectrolyzerRecipe(i1, j1, l1, aielectrolyzerrecipemanager$electrolyzeroutput); +- case Enchantment: +- return (List)Enchantment.REGISTRY.getObject((ResourceLocation)decode(is, DataEncoder.EncodedType.ResourceLocation)); +- case Enum: +- return is.readVarInt(); +- case Float: +- return is.readFloat(); +- case Fluid: +- return FluidRegistry.getFluid(is.readString()); +- case FluidStack: +- FluidStack fluidstack = new FluidStack((Fluid)decode(is, DataEncoder.EncodedType.Fluid), is.readInt()); +- fluidstack.tag = (NBTTagCompound)decode(is); +- return fluidstack; +- case FluidTank: +- return new FluidTank((FluidStack)decode(is), is.readInt()); +- case GameProfile: +- return new GameProfile((UUID)decode(is), is.readString()); +- case Integer: +- return is.readInt(); +- case InvSlot: +- ItemStack[] aitemstack = (ItemStack[])decode(is, DataEncoder.EncodedType.Array); +- InvSlot invslot = new InvSlot(aitemstack.length); +- +- for(int k1 = 0; k1 < aitemstack.length; ++k1) { +- invslot.put(k1, aitemstack[k1]); +- } +- +- return invslot; +- case Item: +- return Util.getItem((ResourceLocation)decode(is, DataEncoder.EncodedType.ResourceLocation)); +- case ItemStack: +- int l = is.readByte(); +- if (l == 0) { +- return StackUtil.emptyStack; +- } +- +- Item item = (Item)decode(is, Item.class); +- int j = is.readShort(); +- NBTTagCompound nbttagcompound = (NBTTagCompound)decode(is); +- ItemStack itemstack = new ItemStack(item, l, j); +- itemstack.setTagCompound(nbttagcompound); +- return itemstack; +- case Long: +- return is.readLong(); +- case NBTTagCompound: +- return CompressedStreamTools.read(is, NBTSizeTracker.INFINITE); +- case Null: +- return null; +- case Object: +- return (List)(new Object()); +- case Potion: +- return (List)Potion.REGISTRY.getObject((ResourceLocation)decode(is, DataEncoder.EncodedType.ResourceLocation)); +- case ResourceLocation: +- return new ResourceLocation(is.readString(), is.readString()); +- case Short: +- return is.readShort(); +- case String: +- return is.readString(); +- case TileEntity: +- final DataEncoder.IResolvableValue iresolvablevalue = (DataEncoder.IResolvableValue)decode(is, DataEncoder.EncodedType.World); +- final BlockPos blockpos = (BlockPos)decode(is, DataEncoder.EncodedType.BlockPos); +- return new DataEncoder.IResolvableValue() { +- public TileEntity get() { +- World world = iresolvablevalue.get(); +- return world == null ? null : world.getTileEntity(blockpos); +- } +- }; +- case TupleT2: +- return new Tuple.T2(decode(is), decode(is)); +- case TupleT3: +- return new Tuple.T3(decode(is), decode(is), decode(is)); +- case UUID: +- return new UUID(is.readLong(), is.readLong()); +- case Vec3: +- return new Vec3d(is.readDouble(), is.readDouble(), is.readDouble()); +- case World: +- final int i = is.readInt(); +- return new DataEncoder.IResolvableValue() { +- public World get() { +- return IC2.platform.getWorld(i); +- } +- }; +- default: +- throw new IllegalArgumentException("unhandled type: " + type); ++ for (int i = 0; i < len; ++i) { ++ EncodedType cType = DataEncoder.typeFromId(is.readUnsignedByte()); ++ if (!cType.threadSafe && !needsResolving) { ++ needsResolving = true; ++ if (componentClass != Object.class) { ++ Object[] newArray = new Object[len]; ++ System.arraycopy(array, 0, newArray, 0, i); ++ array = newArray; ++ } ++ } ++ Array.set(array, i, DataEncoder.decode(is, cType)); ++ } ++ } ++ if (!needsResolving) { ++ return array; ++ } ++ final Object tmpArray = array; ++ return new IResolvableValue(){ ++ ++ @Override ++ public Object get() { ++ Object ret = Array.newInstance(componentClass, len); ++ for (int i = 0; i < len; ++i) { ++ Array.set(ret, i, DataEncoder.getValue(Array.get(tmpArray, i))); ++ } ++ return ret; ++ } ++ }; ++ } ++ case Block: { ++ return Util.getBlock((ResourceLocation)DataEncoder.decode(is, EncodedType.ResourceLocation)); ++ } ++ case BlockPos: { ++ return new BlockPos(is.readInt(), is.readInt(), is.readInt()); ++ } ++ case Boolean: { ++ return is.readBoolean(); ++ } ++ case Byte: { ++ return is.readByte(); ++ } ++ case Character: { ++ return Character.valueOf(is.readChar()); ++ } ++ case ChunkPos: { ++ return new ChunkPos(is.readInt(), is.readInt()); ++ } ++ case Collection: { ++ final Object ret = DataEncoder.decode(is, EncodedType.Array); ++ if (ret instanceof IResolvableValue) { ++ return new IResolvableValue>(){ ++ ++ @Override ++ public List get() { ++ return Arrays.asList((Object[])((IResolvableValue)ret).get()); ++ } ++ }; ++ } ++ return Arrays.asList((Object[])ret); ++ } ++ case Component: { ++ return DataEncoder.decode(is, EncodedType.NBTTagCompound); ++ } ++ case CropCard: { ++ return Crops.instance.getCropCard(is.readString(), is.readString()); ++ } ++ case Double: { ++ return is.readDouble(); ++ } ++ case ElectrolyzerRecipe: { ++ int inputAmount = is.readInt(); ++ int EUaTick = is.readInt(); ++ int ticksNeeded = is.readInt(); ++ byte max = is.readByte(); ++ IElectrolyzerRecipeManager.ElectrolyzerOutput[] outputs = new IElectrolyzerRecipeManager.ElectrolyzerOutput[max]; ++ for (byte i = 0; i < max; i = (byte)(i + 1)) { ++ outputs[i] = new IElectrolyzerRecipeManager.ElectrolyzerOutput(is.readString(), is.readInt(), EnumFacing.getFront((int)is.readByte())); ++ } ++ return new IElectrolyzerRecipeManager.ElectrolyzerRecipe(inputAmount, EUaTick, ticksNeeded, outputs); ++ } ++ case Enchantment: { ++ return Enchantment.REGISTRY.getObject(((ResourceLocation)DataEncoder.decode(is, EncodedType.ResourceLocation))); ++ } ++ case Enum: { ++ return is.readVarInt(); ++ } ++ case Float: { ++ return Float.valueOf(is.readFloat()); ++ } ++ case Fluid: { ++ return FluidRegistry.getFluid((String)is.readString()); ++ } ++ case FluidStack: { ++ FluidStack ret = new FluidStack((Fluid)DataEncoder.decode(is, EncodedType.Fluid), is.readInt()); ++ ret.tag = (NBTTagCompound)DataEncoder.decode(is); ++ return ret; ++ } ++ case FluidTank: { ++ return new FluidTank((FluidStack)DataEncoder.decode(is), is.readInt()); ++ } ++ case GameProfile: { ++ return new GameProfile((UUID)DataEncoder.decode(is), is.readString()); ++ } ++ case Integer: { ++ return is.readInt(); ++ } ++ case InvSlot: { ++ ItemStack[] contents = (ItemStack[])DataEncoder.decode(is, EncodedType.Array); ++ InvSlot ret = new InvSlot(contents.length); ++ for (int i = 0; i < contents.length; ++i) { ++ ret.put(i, contents[i]); ++ } ++ return ret; ++ } ++ case Item: { ++ return Util.getItem((ResourceLocation)DataEncoder.decode(is, EncodedType.ResourceLocation)); ++ } ++ case ItemStack: { ++ byte size = is.readByte(); ++ if (size == 0) { ++ return StackUtil.emptyStack; ++ } ++ Item item = DataEncoder.decode(is, Item.class); ++ short meta = is.readShort(); ++ NBTTagCompound nbt = (NBTTagCompound)DataEncoder.decode(is); ++ ItemStack ret = new ItemStack(item, (int)size, (int)meta); ++ ret.setTagCompound(nbt); ++ return ret; ++ } ++ case Long: { ++ return is.readLong(); ++ } ++ case NBTTagCompound: { ++ return CompressedStreamTools.read((DataInput)is, (NBTSizeTracker)NBTSizeTracker.INFINITE); ++ } ++ case Null: { ++ return null; ++ } ++ case Object: { ++ return new Object(); ++ } ++ case Potion: { ++ return Potion.REGISTRY.getObject(((ResourceLocation)DataEncoder.decode(is, EncodedType.ResourceLocation))); ++ } ++ case ResourceLocation: { ++ return new ResourceLocation(is.readString(), is.readString()); ++ } ++ case Short: { ++ return is.readShort(); ++ } ++ case String: { ++ return is.readString(); ++ } ++ case TileEntity: { ++ final IResolvableValue deferredWorld = (IResolvableValue)DataEncoder.decode(is, EncodedType.World); ++ final BlockPos pos = (BlockPos)DataEncoder.decode(is, EncodedType.BlockPos); ++ return new IResolvableValue(){ ++ ++ @Override ++ public TileEntity get() { ++ World world = (World)deferredWorld.get(); ++ if (world == null) { ++ return null; ++ } ++ return world.getTileEntity(pos); ++ } ++ }; ++ } ++ case TupleT2: { ++ return new Tuple.T2(DataEncoder.decode(is), DataEncoder.decode(is)); ++ } ++ case TupleT3: { ++ return new Tuple.T3(DataEncoder.decode(is), DataEncoder.decode(is), DataEncoder.decode(is)); ++ } ++ case UUID: { ++ return new UUID(is.readLong(), is.readLong()); ++ } ++ case Vec3: { ++ return new Vec3d(is.readDouble(), is.readDouble(), is.readDouble()); ++ } ++ case World: { ++ final int dimensionId = is.readInt(); ++ return new IResolvableValue(){ ++ ++ @Override ++ public World get() { ++ return IC2.platform.getWorld(dimensionId); ++ } ++ }; ++ } + } ++ throw new IllegalArgumentException("unhandled type: " + (Object)((Object)type)); + } + + public static T getValue(Object decoded) { +- return (T)(decoded instanceof DataEncoder.IResolvableValue ? ((DataEncoder.IResolvableValue)decoded).get() : decoded); ++ if (decoded instanceof IResolvableValue) { ++ return (T) ((IResolvableValue)decoded).get(); ++ } ++ return (T)decoded; + } + + public static boolean copyValue(T src, T dst) { +- if (src != null && dst != null) { +- if (dst instanceof ItemStack) { +- ItemStack itemstack = (ItemStack)src; +- ItemStack itemstack1 = (ItemStack)dst; +- if (itemstack.getItem() == itemstack1.getItem()) { +- itemstack1.setCount(itemstack.getCount()); +- StackUtil.setRawMeta(itemstack1, StackUtil.getRawMeta(itemstack)); +- itemstack1.setTagCompound(itemstack.getTagCompound()); +- return true; +- } else { +- return false; +- } +- } else { +- if (dst instanceof FluidTank) { +- FluidTank fluidtank = (FluidTank)src; +- FluidTank fluidtank1 = (FluidTank)dst; +- fluidtank1.setFluid(fluidtank.getFluid()); +- fluidtank1.setCapacity(fluidtank.getCapacity()); +- } else if (dst instanceof InvSlot) { +- InvSlot invslot = (InvSlot)src; +- InvSlot invslot1 = (InvSlot)dst; +- if (invslot.size() != invslot1.size()) { +- throw new RuntimeException("Can't sync InvSlots with mismatched sizes."); +- } +- +- for(int i = 0; i < invslot.size(); ++i) { +- if (!copyValue(invslot.get(i), invslot1.get(i))) { +- invslot1.put(i, invslot.get(i)); +- } +- } +- } else if (dst instanceof TileEntityComponent) { +- NBTTagCompound nbttagcompound = (NBTTagCompound)src; +- ((TileEntityComponent)dst).readFromNbt(nbttagcompound); +- } else { +- if (!(dst instanceof Collection)) { +- return false; +- } +- +- Collection collection = (Collection)src; +- Collection collection1 = (Collection)dst; +- collection1.clear(); +- collection1.addAll(collection); +- } +- ++ if (src == null || dst == null) { ++ return false; ++ } ++ if (dst instanceof ItemStack) { ++ ItemStack srcT = (ItemStack)src; ++ ItemStack dstT = (ItemStack)dst; ++ if (srcT.getItem() == dstT.getItem()) { ++ dstT.setCount(srcT.getCount()); ++ StackUtil.setRawMeta(dstT, StackUtil.getRawMeta(srcT)); ++ dstT.setTagCompound(srcT.getTagCompound()); + return true; + } ++ return false; ++ } ++ if (dst instanceof FluidTank) { ++ FluidTank srcT = (FluidTank)src; ++ FluidTank dstT = (FluidTank)dst; ++ dstT.setFluid(srcT.getFluid()); ++ dstT.setCapacity(srcT.getCapacity()); ++ } else if (dst instanceof InvSlot) { ++ InvSlot srcT = (InvSlot)src; ++ InvSlot dstT = (InvSlot)dst; ++ if (srcT.size() != dstT.size()) { ++ throw new RuntimeException("Can't sync InvSlots with mismatched sizes."); ++ } ++ for (int i = 0; i < srcT.size(); ++i) { ++ if (DataEncoder.copyValue(srcT.get(i), dstT.get(i))) continue; ++ dstT.put(i, srcT.get(i)); ++ } ++ } else if (dst instanceof TileEntityComponent) { ++ NBTTagCompound nbt = (NBTTagCompound)src; ++ ((TileEntityComponent)dst).readFromNbt(nbt); ++ } else if (dst instanceof Collection) { ++ Collection srcT = (Collection)src; ++ Collection dstT = (Collection)dst; ++ dstT.clear(); ++ dstT.addAll(srcT); + } else { + return false; + } ++ return true; + } + + private static Class box(Class clazz) { + if (clazz == Byte.TYPE) { + return Byte.class; +- } else if (clazz == Short.TYPE) { ++ } ++ if (clazz == Short.TYPE) { + return Short.class; +- } else if (clazz == Integer.TYPE) { ++ } ++ if (clazz == Integer.TYPE) { + return Integer.class; +- } else if (clazz == Long.TYPE) { ++ } ++ if (clazz == Long.TYPE) { + return Long.class; +- } else if (clazz == Float.TYPE) { ++ } ++ if (clazz == Float.TYPE) { + return Float.class; +- } else if (clazz == Double.TYPE) { ++ } ++ if (clazz == Double.TYPE) { + return Double.class; +- } else if (clazz == Boolean.TYPE) { ++ } ++ if (clazz == Boolean.TYPE) { + return Boolean.class; +- } else { +- return clazz == Character.TYPE ? Character.class : clazz; +- } ++ } ++ if (clazz == Character.TYPE) { ++ return Character.class; ++ } ++ return clazz; + } + + private static Class unbox(Class clazz) { + if (clazz == Byte.class) { + return Byte.TYPE; +- } else if (clazz == Short.class) { ++ } ++ if (clazz == Short.class) { + return Short.TYPE; +- } else if (clazz == Integer.class) { ++ } ++ if (clazz == Integer.class) { + return Integer.TYPE; +- } else if (clazz == Long.class) { ++ } ++ if (clazz == Long.class) { + return Long.TYPE; +- } else if (clazz == Float.class) { ++ } ++ if (clazz == Float.class) { + return Float.TYPE; +- } else if (clazz == Double.class) { ++ } ++ if (clazz == Double.class) { + return Double.TYPE; +- } else if (clazz == Boolean.class) { ++ } ++ if (clazz == Boolean.class) { + return Boolean.TYPE; +- } else { +- return clazz == Character.class ? Character.TYPE : clazz; +- } ++ } ++ if (clazz == Character.class) { ++ return Character.TYPE; ++ } ++ return clazz; + } + + private static Class getClass(String type) { + try { + return Class.forName(type); +- } catch (ClassNotFoundException classnotfoundexception) { +- throw new RuntimeException("Missing type from the class path expected by network: " + type, classnotfoundexception); ++ } ++ catch (ClassNotFoundException e) { ++ throw new RuntimeException("Missing type from the class path expected by network: " + type, e); + } + } + +- private static int idFromType(DataEncoder.EncodedType type) { ++ private static int idFromType(EncodedType type) { + return type.ordinal(); + } + +- private static DataEncoder.EncodedType typeFromId(int id) { +- if (id >= 0 && id < DataEncoder.EncodedType.types.length) { +- return DataEncoder.EncodedType.types[id]; +- } else { ++ private static EncodedType typeFromId(int id) { ++ if (id < 0 || id >= EncodedType.types.length) { + throw new IllegalArgumentException("invalid type id: " + id); + } +- } +- +- private static DataEncoder.EncodedType typeFromObject(Object o) { +- return o == null ? DataEncoder.EncodedType.Null : typeFromClass(o.getClass()); +- } +- +- private static DataEncoder.EncodedType typeFromClass(Class cls) { ++ return EncodedType.types[id]; ++ } ++ ++ private static EncodedType typeFromObject(Object o) { ++ if (o == null) { ++ return EncodedType.Null; ++ } ++ return DataEncoder.typeFromClass(o.getClass()); ++ } ++ ++ private static EncodedType typeFromClass(Class cls) { ++ EncodedType ret; + if (cls == null) { +- return DataEncoder.EncodedType.Null; +- } else if (cls.isArray()) { +- return DataEncoder.EncodedType.Array; +- } else { +- if (cls.isPrimitive()) { +- cls = box(cls); +- } +- +- DataEncoder.EncodedType dataencoder$encodedtype = DataEncoder.EncodedType.classToTypeMap.get(cls); +- if (dataencoder$encodedtype != null) { +- return dataencoder$encodedtype; +- } else { +- dataencoder$encodedtype = classToTypeCache.get(cls); +- if (dataencoder$encodedtype != null) { +- return dataencoder$encodedtype; +- } else { +- INetworkCustomEncoder inetworkcustomencoder = classToAddonType.get(cls); +- if (inetworkcustomencoder != null) { +- dataencoder$encodedtype = inetworkcustomencoder.isThreadSafe() ? DataEncoder.EncodedType.Addon : DataEncoder.EncodedType.UnSafeAddon; +- classToTypeCache.put(cls, dataencoder$encodedtype); +- return dataencoder$encodedtype; +- } else { +- for(DataEncoder.EncodedType dataencoder$encodedtype1 : DataEncoder.EncodedType.types) { +- if (dataencoder$encodedtype1.cls != null && dataencoder$encodedtype1.cls.isAssignableFrom(cls)) { +- classToTypeCache.put(cls, dataencoder$encodedtype1); +- return dataencoder$encodedtype1; +- } +- } +- +- throw new IllegalStateException("unmatched " + cls); +- } +- } +- } +- } ++ return EncodedType.Null; ++ } ++ if (cls.isArray()) { ++ return EncodedType.Array; ++ } ++ if (cls.isPrimitive()) { ++ cls = DataEncoder.box(cls); ++ } ++ if ((ret = EncodedType.classToTypeMap.get(cls)) != null) { ++ return ret; ++ } ++ ret = classToTypeCache.get(cls); ++ if (ret != null) { ++ return ret; ++ } ++ INetworkCustomEncoder ince = classToAddonType.get(cls); ++ if (ince != null) { ++ ret = ince.isThreadSafe() ? EncodedType.Addon : EncodedType.UnSafeAddon; ++ classToTypeCache.put(cls, ret); ++ return ret; ++ } ++ for (EncodedType type : EncodedType.types) { ++ if (type.cls == null || !type.cls.isAssignableFrom(cls)) continue; ++ classToTypeCache.put(cls, type); ++ return type; ++ } ++ throw new IllegalStateException("unmatched " + cls); + } + + public static void addNetworkEncoder(Class typeBeingEncoded, INetworkCustomEncoder customEncoder) { +- assert typeBeingEncoded != null && customEncoder != null; +- +- INetworkCustomEncoder inetworkcustomencoder = classToAddonType.put(typeBeingEncoded, customEncoder); +- if (inetworkcustomencoder != null) { +- throw new IllegalStateException("Duplicate mapping for class! " + inetworkcustomencoder.getClass().getName() + " and " + customEncoder.getClass().getName() + " both map for " + typeBeingEncoded.getName() + '.'); ++ assert (typeBeingEncoded != null && customEncoder != null); ++ INetworkCustomEncoder previous = classToAddonType.put(typeBeingEncoded, customEncoder); ++ if (previous != null) { ++ throw new IllegalStateException("Duplicate mapping for class! " + previous.getClass().getName() + " and " + customEncoder.getClass().getName() + " both map for " + typeBeingEncoded.getName() + '.'); + } + } + + public static enum EncodedType { +- Null((Class)null), +- Array((Class)null), ++ Null(null), ++ Array(null), + Byte(Byte.class), + Short(Short.class), + Integer(Integer.class), +@@ -773,15 +832,15 @@ + ElectrolyzerRecipe(IElectrolyzerRecipeManager.ElectrolyzerRecipe.class), + TupleT2(Tuple.T2.class), + TupleT3(Tuple.T3.class), +- Addon((Class)null), +- UnSafeAddon((Class)null, false), ++ Addon(null), ++ UnSafeAddon(null, false), + Collection(Collection.class), + Object(Object.class); + + final Class cls; + final boolean threadSafe; +- static final DataEncoder.EncodedType[] types = values(); +- static final Map, DataEncoder.EncodedType> classToTypeMap = new IdentityHashMap, DataEncoder.EncodedType>(types.length - 2); ++ static final EncodedType[] types; ++ static final Map, EncodedType> classToTypeMap; + + private EncodedType(Class cls) { + this(cls, true); +@@ -793,19 +852,19 @@ + } + + static { +- for(DataEncoder.EncodedType dataencoder$encodedtype : types) { +- if (dataencoder$encodedtype.cls != null) { +- classToTypeMap.put(dataencoder$encodedtype.cls, dataencoder$encodedtype); +- } ++ types = EncodedType.values(); ++ classToTypeMap = new IdentityHashMap(types.length - 2); ++ for (EncodedType type : types) { ++ if (type.cls == null) continue; ++ classToTypeMap.put(type.cls, type); + } +- + if (types.length > 255) { + throw new RuntimeException("too many types"); + } + } + } + +- private interface IResolvableValue { +- T get(); ++ private static interface IResolvableValue { ++ public T get(); + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/GrowingBuffer.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/GrowingBuffer.java.patch new file mode 100644 index 0000000..a816a47 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/GrowingBuffer.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/network/GrowingBuffer.java ++++ b/ic2/core/network/GrowingBuffer.java +@@ -214,7 +214,7 @@ + throw new IllegalArgumentException("only positive numbers are supported"); + } else { + while(true) { +- int i = i & 127; ++ i = i & 127; + i >>>= 7; + if (i != 0) { + i |= 128; diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/RpcHandler.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/RpcHandler.java.patch new file mode 100644 index 0000000..2cc0d63 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/network/RpcHandler.java.patch @@ -0,0 +1,37 @@ +--- a/ic2/core/network/RpcHandler.java ++++ b/ic2/core/network/RpcHandler.java +@@ -40,21 +40,21 @@ + } + + protected static void processRpcRequest(GrowingBuffer is, EntityPlayerMP player) throws IOException { +- int i = is.readInt(); +- String s = is.readString(); +- Object[] aobject = DataEncoder.decode(is); +- IRpcProvider irpcprovider = (IRpcProvider)providers.get(s); +- if (irpcprovider == null) { ++ int id = is.readInt(); ++ String providerClassName = is.readString(); ++ Object[] args = (Object[])DataEncoder.decode(is); ++ IRpcProvider provider = providers.get(providerClassName); ++ if (provider == null) { + IC2.log.warn(LogCategory.Network, "Invalid RPC request from %s.", player.getName()); +- } else { +- Object object = irpcprovider.executeRpc(aobject); +- GrowingBuffer growingbuffer = new GrowingBuffer(256); +- SubPacketType.Rpc.writeTo(growingbuffer); +- growingbuffer.writeInt(i); +- DataEncoder.encode(growingbuffer, object, true); +- growingbuffer.flip(); +- ((NetworkManager)IC2.network.get(true)).sendPacket(growingbuffer, true, player); ++ return; + } ++ Object result = provider.executeRpc(args); ++ GrowingBuffer buffer = new GrowingBuffer(256); ++ SubPacketType.Rpc.writeTo(buffer); ++ buffer.writeInt(id); ++ DataEncoder.encode(buffer, result, true); ++ buffer.flip(); ++ IC2.network.get(true).sendPacket(buffer, true, player); + } + + public RpcHandler() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/Profile.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/Profile.java.patch new file mode 100644 index 0000000..c157277 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/Profile.java.patch @@ -0,0 +1,16 @@ +--- a/ic2/core/profile/Profile.java ++++ b/ic2/core/profile/Profile.java +@@ -29,11 +29,11 @@ + for(RecipeChange recipechange : changes) { + if (recipechange.type != RecipeChange.ChangeType.REMOVAL) { + (map.computeIfAbsent(recipechange.name, (k) -> { +- return (void)(new ArrayList()); ++ return (new ArrayList()); + })).add(recipechange); + } else { + (map1.computeIfAbsent(recipechange.name, (k) -> { +- return (void)(new ArrayList()); ++ return (new ArrayList()); + })).add(recipechange); + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileManager.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileManager.java.patch new file mode 100644 index 0000000..be2bdde --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileManager.java.patch @@ -0,0 +1,34 @@ +--- a/ic2/core/profile/ProfileManager.java ++++ b/ic2/core/profile/ProfileManager.java +@@ -8,11 +8,8 @@ + import ic2.core.util.Config; + import ic2.core.util.LogCategory; + import ic2.core.util.ReflectionUtil; +-import java.io.ByteArrayInputStream; +-import java.io.File; +-import java.io.IOException; +-import java.io.InputStream; +-import java.io.SequenceInputStream; ++ ++import java.io.*; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; +@@ -64,7 +61,7 @@ + if (file1.exists()) { + for(File file2 : file1.listFiles()) { + if (file2.isDirectory()) { +- for(File file3 : file2.listFiles(new NameFileFilter("profile.xml"))) { ++ for(File file3 : file2.listFiles((FileFilter) new NameFileFilter("profile.xml"))) { + try { + Profile profile1 = ProfileParser.parse(new ProfileRoot(file3.getParentFile())); + if (!registerProfile(profile1)) { +@@ -229,7 +226,7 @@ + list3.removeAll(textureChanges); + + assert !list3.stream().anyMatch((packx) -> { +- return pack.getPackName().startsWith("IC2 Profile Pack for "); ++ return packx.getPackName().startsWith("IC2 Profile Pack for "); + }); + + list2.forEach(list3::add); diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileParser.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileParser.java.patch new file mode 100644 index 0000000..d5dfb1b --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/profile/ProfileParser.java.patch @@ -0,0 +1,33 @@ +--- a/ic2/core/profile/ProfileParser.java ++++ b/ic2/core/profile/ProfileParser.java +@@ -5,10 +5,8 @@ + import ic2.core.util.LogCategory; + import ic2.core.util.Util; + import ic2.core.util.XmlUtil; +-import java.io.BufferedInputStream; +-import java.io.File; +-import java.io.IOException; +-import java.io.InputStream; ++ ++import java.io.*; + import java.text.ParseException; + import java.util.ArrayList; + import java.util.Arrays; +@@ -243,7 +241,7 @@ + throw new RuntimeException("Non-replacement changes made alongside replacement: " + profileparser$node); + } + +- list.add((Object)null); ++ list.add(null); + break; + default: + assert parent.getType().validChildren.contains(profileparser$node.getType()); +@@ -313,7 +311,7 @@ + ProfileTarget profiletarget = root.offset(this.path); + Set set = new HashSet(); + if (!profiletarget.isFile()) { +- for(File file1 : profiletarget.asFile().listFiles(new WildcardFileFilter("*.INI", IOCase.INSENSITIVE))) { ++ for(File file1 : profiletarget.asFile().listFiles((FileFilter) new WildcardFileFilter("*.INI", IOCase.INSENSITIVE))) { + if (file1.isFile()) { + set.add(profiletarget.offset(file1.getName())); + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch new file mode 100644 index 0000000..7de41ef --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/recipe/dynamic/DynamicRecipeManager.java.patch @@ -0,0 +1,128 @@ +--- a/ic2/core/recipe/dynamic/DynamicRecipeManager.java ++++ b/ic2/core/recipe/dynamic/DynamicRecipeManager.java +@@ -93,74 +93,59 @@ + } + + protected DynamicRecipe getRecipe(Collection input) { ++ RecipeInputIngredient temp; ++ ListIterator itB; + if (input.isEmpty()) { + return null; +- } else { +- List list = new ArrayList(); +- +- for(RecipeInputIngredient recipeinputingredient : input) { +- Object object = recipeinputingredient.getUnspecific(); +- if (object instanceof Item) { +- if (this.recipeCacheItem.get(object) != null) { +- list.addAll(this.recipeCacheItem.get(object)); +- } +- } else if (object instanceof Fluid && this.recipeCacheFluid.containsKey(((Fluid)object).getName())) { +- list.addAll(this.recipeCacheFluid.get(((Fluid)object).getName())); +- } +- } +- +- if (!list.isEmpty()) { +- label104: +- for(DynamicRecipe dynamicrecipe : list) { +- if (input.size() == dynamicrecipe.getInputIngredients().size()) { +- ListIterator listiterator = (new ArrayList(dynamicrecipe.getInputIngredients())).listIterator(); +- +- for(RecipeInputIngredient recipeinputingredient1 : input) { +- if (!listiterator.hasNext()) { +- continue label104; +- } +- +- RecipeInputIngredient recipeinputingredient2 = listiterator.next(); +- if (recipeinputingredient2.matches(recipeinputingredient1.ingredient) && recipeinputingredient1.getCount() >= recipeinputingredient2.getCount()) { +- listiterator.remove(); +- +- while(listiterator.hasPrevious()) { +- listiterator.previous(); +- } +- } +- } +- +- return dynamicrecipe; +- } +- } +- } +- +- label79: +- for(DynamicRecipe dynamicrecipe1 : this.uncacheableRecipes) { +- if (input.size() == dynamicrecipe1.getInputIngredients().size()) { +- ListIterator listiterator1 = (new ArrayList(dynamicrecipe1.getInputIngredients())).listIterator(); +- +- for(RecipeInputIngredient recipeinputingredient3 : input) { +- if (!listiterator1.hasNext()) { +- continue label79; +- } +- +- RecipeInputIngredient recipeinputingredient4 = listiterator1.next(); +- if (recipeinputingredient4.matches(recipeinputingredient3.ingredient) && recipeinputingredient3.getCount() >= recipeinputingredient4.getCount()) { +- listiterator1.remove(); +- +- while(listiterator1.hasPrevious()) { +- listiterator1.previous(); +- } +- } +- } +- +- return dynamicrecipe1; +- } +- } +- +- return null; +- } ++ } ++ ArrayList recipes = new ArrayList(); ++ for (RecipeInputIngredient entry : input) { ++ Object unspecific = entry.getUnspecific(); ++ if (unspecific instanceof Item) { ++ if (this.recipeCacheItem.get(unspecific) == null) continue; ++ recipes.addAll(this.recipeCacheItem.get(unspecific)); ++ continue; ++ } ++ if (!(unspecific instanceof Fluid) || !this.recipeCacheFluid.containsKey(((Fluid)unspecific).getName())) continue; ++ recipes.addAll(this.recipeCacheFluid.get(((Fluid)unspecific).getName())); ++ } ++ if (!recipes.isEmpty()) { ++ block1: for (DynamicRecipe recipe : recipes) { ++ if (input.size() != recipe.getInputIngredients().size()) continue; ++ itB = new ArrayList(recipe.getInputIngredients()).listIterator(); ++ block2: for (RecipeInputIngredient entry : input) { ++ while (itB.hasNext()) { ++ temp = itB.next(); ++ if (!temp.matches(entry.ingredient) || entry.getCount() < temp.getCount()) continue; ++ itB.remove(); ++ while (itB.hasPrevious()) { ++ itB.previous(); ++ } ++ continue block2; ++ } ++ continue block1; ++ } ++ return recipe; ++ } ++ } ++ block5: for (DynamicRecipe recipe : this.uncacheableRecipes) { ++ if (input.size() != recipe.getInputIngredients().size()) continue; ++ itB = new ArrayList(recipe.getInputIngredients()).listIterator(); ++ block6: for (RecipeInputIngredient entry : input) { ++ while (itB.hasNext()) { ++ temp = itB.next(); ++ if (!temp.matches(entry.ingredient) || entry.getCount() < temp.getCount()) continue; ++ itB.remove(); ++ while (itB.hasPrevious()) { ++ itB.previous(); ++ } ++ continue block6; ++ } ++ continue block5; ++ } ++ return recipe; ++ } ++ return null; + } + + public DynamicRecipe findRecipe(ItemStack[] items, FluidStack[] fluids) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/BlockName.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/BlockName.java.patch new file mode 100644 index 0000000..2352fbd --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/BlockName.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/ref/BlockName.java ++++ b/ic2/core/ref/BlockName.java +@@ -80,7 +80,7 @@ + return null; + } else if (this.instance instanceof IMultiItem) { + IMultiItem imultiitem = (IMultiItem)this.instance; +- return imultiitem.getItemStack((IIdProvider)variant); ++ return imultiitem.getItemStack((T) variant); + } else if (variant == null) { + return this.getItemStack((String)null); + } else { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/IMultiItem.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/IMultiItem.java.patch new file mode 100644 index 0000000..8bcba97 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/IMultiItem.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/ref/IMultiItem.java ++++ b/ic2/core/ref/IMultiItem.java +@@ -22,7 +22,7 @@ + set.add(this.getItemStack(t)); + } + +- set.remove((Object)null); ++ set.remove(null); + set.remove(StackUtil.emptyStack); + return set; + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/ItemName.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/ItemName.java.patch new file mode 100644 index 0000000..06d5325 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/ItemName.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/ref/ItemName.java ++++ b/ic2/core/ref/ItemName.java +@@ -241,7 +241,7 @@ + return null; + } else if (this.instance instanceof IMultiItem) { + IMultiItem imultiitem = (IMultiItem)this.instance; +- return imultiitem.getItemStack((IIdProvider)variant); ++ return imultiitem.getItemStack((T) variant); + } else if (variant == null) { + return new ItemStack(this.instance); + } else { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch new file mode 100644 index 0000000..e64cd57 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/ref/MetaTeBlockProperty.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/ref/MetaTeBlockProperty.java ++++ b/ic2/core/ref/MetaTeBlockProperty.java +@@ -152,7 +152,7 @@ + if (entry1.getKey() != invalid.teBlock.getIdentifier()) { + Tuple.T2 tuple$t2 = entry1.getValue(); + Integer integer = (Integer)tuple$t2.a; +- Object object = tuple$t2.a = (TA)((Integer)tuple$t2.a).intValue() + 1; ++ Object object = tuple$t2.a = ((Integer)tuple$t2.a).intValue() + 1; + ((List)(entry1.getValue()).b).add(metateblockproperty$metatepair1); + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/LiquidUtil.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/LiquidUtil.java.patch new file mode 100644 index 0000000..cb4f8f4 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/LiquidUtil.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/util/LiquidUtil.java ++++ b/ic2/core/util/LiquidUtil.java +@@ -40,7 +40,7 @@ + + public static List getAllFluids() { + Set set = new HashSet(FluidRegistry.getRegisteredFluids().values()); +- set.remove((Object)null); ++ set.remove(null); + List list = new ArrayList(set); + Collections.sort(list, new Comparator() { + public int compare(Fluid a, Fluid b) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/ReflectionUtil.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/ReflectionUtil.java.patch new file mode 100644 index 0000000..899c4a2 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/ReflectionUtil.java.patch @@ -0,0 +1,26 @@ +--- a/ic2/core/util/ReflectionUtil.java ++++ b/ic2/core/util/ReflectionUtil.java +@@ -126,17 +126,16 @@ + + public static void setValue(Object object, Field field, Object value) { + if (field.getType().isEnum() && value instanceof Integer) { +- value = field.getType().getEnumConstants()[((Integer)value).intValue()]; ++ value = field.getType().getEnumConstants()[(Integer)value]; + } +- + try { +- Object object = field.get(object); +- if (!DataEncoder.copyValue(value, object)) { ++ Object oldValue = field.get(object); ++ if (!DataEncoder.copyValue(value, oldValue)) { + field.set(object, value); + } +- +- } catch (Exception exception) { +- throw new RuntimeException("can't set field " + field.getName() + " in " + object + " to " + value, exception); ++ } ++ catch (Exception e) { ++ throw new RuntimeException("can't set field " + field.getName() + " in " + object + " to " + value, e); + } + } + diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/StackUtil.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/StackUtil.java.patch new file mode 100644 index 0000000..d3b74a5 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/StackUtil.java.patch @@ -0,0 +1,71 @@ +--- a/ic2/core/util/StackUtil.java ++++ b/ic2/core/util/StackUtil.java +@@ -1116,25 +1116,25 @@ + } + + public static List getDrops(IBlockAccess world, BlockPos pos, IBlockState state, EntityPlayer player, int fortune, boolean silkTouch) { ++ ItemStack drop; + Block block = state.getBlock(); + if (block.isAir(state, world, pos)) { +- return Collections.emptyList(); +- } else { +- World world = null; +- if (silkTouch) { +- world = Util.getWorld(world); +- if (world == null) { +- throw new IllegalArgumentException("invalid world for silk touch: " + world); +- } +- +- if (player == null) { +- player = Ic2Player.get(world); +- } +- } +- +- ItemStack itemstack; +- return silkTouch && block.canSilkHarvest(world, pos, state, player) && !isEmpty(itemstack = getPickStack(world, pos, state, player)) ? Collections.singletonList(itemstack) : getDrops(world, pos, state, block, fortune); +- } ++ return Collections.emptyList(); ++ } ++ World rawWorld = null; ++ if (silkTouch) { ++ rawWorld = Util.getWorld(world); ++ if (rawWorld == null) { ++ throw new IllegalArgumentException("invalid world for silk touch: " + world); ++ } ++ if (player == null) { ++ player = Ic2Player.get(rawWorld); ++ } ++ } ++ if (silkTouch && block.canSilkHarvest(rawWorld, pos, state, player) && !StackUtil.isEmpty(drop = StackUtil.getPickStack(rawWorld, pos, state, player))) { ++ return Collections.singletonList(drop); ++ } ++ return StackUtil.getDrops(world, pos, state, block, fortune); + } + + public static boolean placeBlock(ItemStack stack, World world, BlockPos pos) { +@@ -1196,8 +1196,8 @@ + } + + public static boolean check2(Iterable> list) { +- for(List list : list) { +- if (!check(list)) { ++ for(List list1 : list) { ++ if (!check(list1)) { + return false; + } + } +@@ -1226,12 +1226,12 @@ + public static String toStringSafe2(Iterable> list) { + StringBuilder stringbuilder = new StringBuilder("["); + +- for(List list : list) { ++ for(List list1 : list) { + if (stringbuilder.length() > 1) { + stringbuilder.append(", "); + } + +- stringbuilder.append(toStringSafe(list)); ++ stringbuilder.append(toStringSafe(list1)); + } + + return stringbuilder.append(']').toString(); diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/Util.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/Util.java.patch new file mode 100644 index 0000000..921366c --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/util/Util.java.patch @@ -0,0 +1,19 @@ +--- a/ic2/core/util/Util.java ++++ b/ic2/core/util/Util.java +@@ -174,15 +174,7 @@ + } + + public static boolean hasAssertions() { +- boolean flag = false; +- if (!$assertionsDisabled) { +- flag = true; +- if (false) { +- throw new AssertionError(); +- } +- } +- +- return flag; ++ return !Util.class.desiredAssertionStatus(); + } + + public static boolean matchesOD(ItemStack stack, Object match) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/DropScan.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/DropScan.java.patch new file mode 100644 index 0000000..cc5d8ab --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/DropScan.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/uu/DropScan.java ++++ b/ic2/core/uu/DropScan.java +@@ -158,7 +158,7 @@ + try { + Method method = Thread.class.getDeclaredMethod("getThreads"); + method.setAccessible(true); +- Thread[] athread = (Thread[])method.invoke((Object)null); ++ Thread[] athread = (Thread[])method.invoke(null); + Field field = ReflectionUtil.getField(Thread.class, Runnable.class); + + for(Thread thread : athread) { +@@ -433,7 +433,7 @@ + + public void clear() { + this.extraChunks.clear(); +- Arrays.fill(this.chunks, (Object)null); ++ Arrays.fill(this.chunks, null); + } + + public String makeString() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/RecipeResolver.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/RecipeResolver.java.patch new file mode 100644 index 0000000..a87b893 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/RecipeResolver.java.patch @@ -0,0 +1,30 @@ +--- a/ic2/core/uu/RecipeResolver.java ++++ b/ic2/core/uu/RecipeResolver.java +@@ -27,19 +27,15 @@ + } + + private static List> toDoubleStackList(List list) { +- List> list = new ArrayList>(list.size()); +- +- for(Ingredient ingredient : list) { +- ItemStack[] aitemstack = ingredient.getMatchingStacks(); +- List list1 = new ArrayList(aitemstack.length); +- +- for(ItemStack itemstack : aitemstack) { +- list1.add(new LeanItemStack(itemstack)); ++ ArrayList> ret = new ArrayList>(list.size()); ++ for (Ingredient ingredient : list) { ++ ItemStack[] arr = ingredient.getMatchingStacks(); ++ ArrayList toAdd = new ArrayList(arr.length); ++ for (ItemStack stack : arr) { ++ toAdd.add(new LeanItemStack(stack)); + } +- +- list.add(list1); ++ ret.add(toAdd); + } +- +- return list; ++ return ret; + } + } diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/UuGraph.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/UuGraph.java.patch new file mode 100644 index 0000000..9bc878e --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/core/uu/UuGraph.java.patch @@ -0,0 +1,33 @@ +--- a/ic2/core/uu/UuGraph.java ++++ b/ic2/core/uu/UuGraph.java +@@ -172,22 +172,18 @@ + } + + private static void registerTransform(RecipeTransformation transform) { +- UuGraph.NodeTransform uugraph$nodetransform = new UuGraph.NodeTransform(transform); +- Iterator iterator = transform.inputs.iterator(); +- +- while(iterator.hasNext()) { +- for(LeanItemStack leanitemstack : (List)iterator.next()) { +- for(UuGraph.Node uugraph$node : getAll(leanitemstack)) { +- uugraph$node.provides.add(uugraph$nodetransform); ++ NodeTransform nt = new NodeTransform(transform); ++ for (List inputs : transform.inputs) { ++ for (LeanItemStack input : inputs) { ++ for (Node node : UuGraph.getAll(input)) { ++ node.provides.add(nt); + } + } + } +- +- for(LeanItemStack leanitemstack1 : transform.outputs) { +- UuGraph.Node uugraph$node1 = getInternal(leanitemstack1); +- uugraph$nodetransform.out.add(uugraph$node1); ++ for (LeanItemStack output : transform.outputs) { ++ Node node = UuGraph.getInternal(output); ++ nt.out.add(node); + } +- + } + + private static void finishCalculation() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch new file mode 100644 index 0000000..3d65da7 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java.patch @@ -0,0 +1,54 @@ +--- a/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java ++++ b/ic2/jeiIntegration/recipe/crafting/AdvRecipeWrapper.java +@@ -30,7 +30,7 @@ + if ((i >>> 8 - k & 1) != 0) { + list.add(this.recipe.input[j++]); + } else { +- list.add((Object)null); ++ list.add(null); + } + } + } +@@ -47,27 +47,22 @@ + } + + public static List> replaceRecipeInputs(List list) { +- List> list = new ArrayList>(list.size()); +- +- for(IRecipeInput irecipeinput : list) { +- if (irecipeinput == null) { +- list.add(Collections.emptyList()); +- } else { +- List list1 = new ArrayList(irecipeinput.getInputs()); +- ListIterator listiterator = list1.listIterator(); +- +- while(listiterator.hasNext()) { +- ItemStack itemstack = listiterator.next(); +- if (itemstack != null && itemstack.getItem() instanceof IElectricItem) { +- listiterator.set(StackUtil.copyWithWildCard(itemstack)); +- } +- } +- +- list.add(list1); +- } ++ ArrayList> out = new ArrayList>(list.size()); ++ for (IRecipeInput recipe : list) { ++ if (recipe == null) { ++ out.add(Collections.emptyList()); ++ continue; ++ } ++ ArrayList replace = new ArrayList(recipe.getInputs()); ++ ListIterator it = replace.listIterator(); ++ while (it.hasNext()) { ++ ItemStack stack = (ItemStack)it.next(); ++ if (stack == null || !(stack.getItem() instanceof IElectricItem)) continue; ++ it.set(StackUtil.copyWithWildCard(stack)); ++ } ++ out.add(replace); + } +- +- return list; ++ return out; + } + + public void getIngredients(IIngredients ingredients) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch new file mode 100644 index 0000000..a80d968 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java.patch @@ -0,0 +1,35 @@ +--- a/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java ++++ b/ic2/jeiIntegration/recipe/crafting/AdvShapelessRecipeWrapper.java +@@ -22,23 +22,15 @@ + } + + public List> getInputs() { +- List> list = new ArrayList>(this.recipe.input.length); +- +- for(IRecipeInput irecipeinput : this.recipe.input) { +- list.add(irecipeinput.getInputs()); +- } +- +- if (list.size() == 1 && ((List)list.get(0)).size() == 1) { +- ItemStack itemstack = (ItemStack)(list.get(0)).get(0); +- if (itemstack.getItem() == ItemName.painter.getInstance() && itemstack.getMetadata() == 32767) { +- Stream stream = Arrays.stream(Ic2Color.values); +- ItemName itemname = ItemName.painter; +- ItemName.painter.getClass(); +- list.set(0, stream.map(itemname::getItemStack).collect(Collectors.toList())); +- } +- } +- +- return list; ++ ItemStack stack; ++ ArrayList> ret = new ArrayList>(this.recipe.input.length); ++ for (IRecipeInput input : this.recipe.input) { ++ ret.add(input.getInputs()); ++ } ++ if (ret.size() == 1 && ((List)ret.get(0)).size() == 1 && (stack = (ItemStack)((List)ret.get(0)).get(0)).getItem() == ItemName.painter.getInstance() && stack.getMetadata() == Short.MAX_VALUE) { ++ ret.set(0, Arrays.stream(Ic2Color.values).map(ItemName.painter::getItemStack).collect(Collectors.toList())); ++ } ++ return ret; + } + + public void getIngredients(IIngredients ingredients) { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch new file mode 100644 index 0000000..355823d --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/recipe/machine/CannerCategory.java.patch @@ -0,0 +1,75 @@ +--- a/ic2/jeiIntegration/recipe/machine/CannerCategory.java ++++ b/ic2/jeiIntegration/recipe/machine/CannerCategory.java +@@ -17,9 +17,7 @@ + import java.util.List; + import java.util.Set; + import mezz.jei.api.IGuiHelper; +-import mezz.jei.api.gui.IDrawable; +-import mezz.jei.api.gui.IGuiFluidStackGroup; +-import mezz.jei.api.gui.IRecipeLayout; ++import mezz.jei.api.gui.*; + import mezz.jei.api.gui.IDrawableAnimated.StartDirection; + import mezz.jei.api.ingredients.IIngredients; + import mezz.jei.api.recipe.IRecipeWrapper; +@@ -50,37 +48,38 @@ + return new CannerCategory(CannerCategory.CanningActivity.CANNING, guiHelper); + } + +- protected CannerCategory(CannerCategory.CanningActivity activity, IGuiHelper guiHelper) { +- super(TeBlock.canner, activity.manager); ++ protected CannerCategory(CanningActivity activity, IGuiHelper guiHelper) { ++ super(TeBlock.canner, (T) activity.manager); + activity.createBackground(this.elements, guiHelper); +- this.elements.add(new Tuple.T2(guiHelper.createDrawable(GuiCanner.texture, 176, activity.overlayV, 50, 14), new SlotPosition(23, 65))); ++ this.elements.add(new Tuple.T2<>(guiHelper.createDrawable(GuiCanner.texture, 176, activity.overlayV, 50, 14), new SlotPosition(23, 65))); + this.emptyTank = guiHelper.createDrawable(GuiElement.commonTexture, 70, 100, 20, 55); + this.tankBackground = guiHelper.createDrawable(GuiElement.commonTexture, 6, 100, 20, 55); +- int i = -4; +- int j = -4; ++ int borderX = -4; ++ int borderY = -4; + this.tankOverlay = guiHelper.createDrawable(GuiElement.commonTexture, 38, 100, 20, 55, -4, -4, -4, -4); + this.name = activity.mode.name(); +- this.progress.add(new Tuple.T2(guiHelper.createAnimatedDrawable(guiHelper.createDrawable(GuiCanner.texture, 233, 0, 23, 14), 66, StartDirection.LEFT, false), new SlotPosition(34, 6))); +- List list = new ArrayList(2); +- List list1 = Collections.emptyList(); +- +- for(CannerCategory.CanningActivity.Slot cannercategory$canningactivity$slot : activity.slots) { +- switch(cannercategory$canningactivity$slot) { +- case ADDITIVE: +- list.add(new SlotPosition(39, 27)); +- break; +- case CAN: +- list.add(new SlotPosition(0, 0)); +- break; +- case OUTPUT: +- list1 = Collections.singletonList(new SlotPosition(78, 0)); ++ this.progress.add(new Tuple.T2<>(guiHelper.createAnimatedDrawable(guiHelper.createDrawable(GuiCanner.texture, 233, 0, 23, 14), 66, IDrawableAnimated.StartDirection.LEFT, false), new SlotPosition(34, 6))); ++ ArrayList inputs = new ArrayList(2); ++ List outputs = Collections.emptyList(); ++ block5: for (CanningActivity.Slot slot : activity.slots) { ++ switch (slot) { ++ case ADDITIVE: { ++ inputs.add(new SlotPosition(39, 27)); ++ continue block5; ++ } ++ case CAN: { ++ inputs.add(new SlotPosition(0, 0)); ++ continue block5; ++ } ++ case OUTPUT: { ++ outputs = Collections.singletonList(new SlotPosition(78, 0)); ++ } + } + } +- +- this.inputs = list; +- this.outputs = list1; ++ this.inputs = inputs; ++ this.outputs = outputs; + this.tanks = activity.tanks; +- this.notTanks = this.tanks.length == 0 ? EnumSet.allOf(CannerCategory.CanningActivity.Tank.class) : EnumSet.complementOf(EnumSet.copyOf(Arrays.asList(this.tanks))); ++ this.notTanks = this.tanks.length == 0 ? EnumSet.allOf(CanningActivity.Tank.class) : EnumSet.complementOf(EnumSet.copyOf(Arrays.asList(this.tanks))); + } + + public String getUid() { diff --git a/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch new file mode 100644 index 0000000..ea0c358 --- /dev/null +++ b/projects/IC2-Base/patches[2.8.221,+]/minecraft/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java.patch @@ -0,0 +1,178 @@ +--- a/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java ++++ b/ic2/jeiIntegration/transferhandlers/TransferHandlerIndustrialWorkbench.java +@@ -1,5 +1,6 @@ + package ic2.jeiIntegration.transferhandlers; + ++import ic2.core.block.invslot.InvSlot; + import ic2.core.block.machine.container.ContainerIndustrialWorkbench; + import java.util.ArrayList; + import java.util.Arrays; +@@ -17,6 +18,7 @@ + import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; + import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; + import mezz.jei.api.recipe.transfer.IRecipeTransferInfo; ++import mezz.jei.network.packets.PacketJei; + import mezz.jei.network.packets.PacketRecipeTransfer; + import mezz.jei.startup.StackHelper; + import mezz.jei.startup.StackHelper.MatchingItemsResult; +@@ -64,94 +66,75 @@ + + @Nullable + public IRecipeTransferError transferRecipe(ContainerIndustrialWorkbench container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer) { +- List> list = new ArrayList>(); +- recipeLayout.getItemStacks().getGuiIngredients().values().stream().filter(IGuiIngredient::isInput).filter((i) -> { +- return !i.getAllIngredients().isEmpty(); +- }).forEach(list::add); +- if (list.size() != 2) { ++ ArrayList ingredients = new ArrayList(); ++ recipeLayout.getItemStacks().getGuiIngredients().values().stream().filter(IGuiIngredient::isInput).filter(i -> !i.getAllIngredients().isEmpty()).forEach(ingredients::add); ++ if (ingredients.size() != 2) { + return this.handlerHelper.createInternalError(); +- } else { +- Slot slot = container.getSlot(container.indexOutputHammer - 2); +- Slot slot1 = container.getSlot(container.indexOutputCutter - 2); +- Slot slot2 = container.getSlot(container.indexOutputHammer - 1); +- Slot slot3 = container.getSlot(container.indexOutputCutter - 1); +- Slot[][] aslot = new Slot[][]{{slot, slot2}, {slot1, slot3}}; +- int i = -1; +- int j = -1; +- +- for(int k = 0; k < list.size(); ++k) { +- ItemStack itemstack = (ItemStack)((IGuiIngredient)list.get(k)).getDisplayedIngredient(); +- if (slot.isItemValid(itemstack)) { +- i = k; +- j = 0; +- break; +- } +- +- if (slot1.isItemValid(itemstack)) { +- i = k; +- j = 1; +- break; +- } ++ } ++ Slot toolLeft = container.getSlot(container.indexOutputHammer - 2); ++ Slot toolRight = container.getSlot(container.indexOutputCutter - 2); ++ Slot itemLeft = container.getSlot(container.indexOutputHammer - 1); ++ Slot itemRight = container.getSlot(container.indexOutputCutter - 1); ++ Slot[][] craftingSlots = new Slot[][]{{toolLeft, itemLeft}, {toolRight, itemRight}}; ++ int toolIdx = -1; ++ int craftingIdx = -1; ++ for (int i2 = 0; i2 < ingredients.size(); ++i2) { ++ ItemStack stack = (ItemStack)((IGuiIngredient)ingredients.get(i2)).getDisplayedIngredient(); ++ if (toolLeft.isItemValid(stack)) { ++ toolIdx = i2; ++ craftingIdx = 0; ++ break; + } +- +- if (i == -1) { ++ if (!toolRight.isItemValid(stack)) continue; ++ toolIdx = i2; ++ craftingIdx = 1; ++ break; ++ } ++ if (toolIdx == -1) { ++ return this.handlerHelper.createInternalError(); ++ } ++ HashMap adjustedIngredients = new HashMap(); ++ adjustedIngredients.put(0, ingredients.get(toolIdx)); ++ adjustedIngredients.put(1, ingredients.get(1 - toolIdx)); ++ HashMap availableItemStacks = new HashMap(); ++ int filledCraftSlotCount = 0; ++ int emptySlotCount = 0; ++ for (Slot slot : craftingSlots[craftingIdx]) { ++ ItemStack stack = slot.getStack(); ++ if (stack.isEmpty()) continue; ++ if (!slot.canTakeStack(player)) { ++ Log.get().error("Recipe Transfer helper {} does not work for container {}. Player can't move item out of Crafting Slot number {}", this.transferHelper.getClass(), ((Object)((Object)container)).getClass(), (Object)slot.slotNumber); + return this.handlerHelper.createInternalError(); +- } else { +- Map> map = new HashMap>(); +- map.put(Integer.valueOf(0), list.get(i)); +- map.put(Integer.valueOf(1), list.get(1 - i)); +- Map map1 = new HashMap(); +- int l = 0; +- int i1 = 0; +- +- for(Slot slot4 : aslot[j]) { +- ItemStack itemstack1 = slot4.getStack(); +- if (!itemstack1.isEmpty()) { +- if (!slot4.canTakeStack(player)) { +- Log.get().error("Recipe Transfer helper {} does not work for container {}. Player can't move item out of Crafting Slot number {}", this.transferHelper.getClass(), container.getClass(), Integer.valueOf(slot4.slotNumber)); +- return this.handlerHelper.createInternalError(); +- } +- +- ++l; +- map1.put(Integer.valueOf(slot4.slotNumber), itemstack1.copy()); +- } +- } +- +- List list1 = this.transferHelper.getInventorySlots(container); +- +- for(Slot slot5 : list1) { +- ItemStack itemstack2 = slot5.getStack(); +- if (!itemstack2.isEmpty()) { +- map1.put(Integer.valueOf(slot5.slotNumber), itemstack2.copy()); +- } else { +- ++i1; +- } +- } +- +- if (l - list.size() > i1) { +- String s = Translator.translateToLocal("jei.tooltip.error.recipe.transfer.inventory.full"); +- return this.handlerHelper.createUserErrorWithTooltip(s); +- } else { +- MatchingItemsResult matchingitemsresult = this.stackHelper.getMatchingItems(map1, map); +- if (matchingitemsresult.missingItems.size() > 0) { +- String s1 = Translator.translateToLocal("jei.tooltip.error.recipe.transfer.missing"); +- return this.handlerHelper.createUserErrorForSlots(s1, matchingitemsresult.missingItems); +- } else { +- List list2 = new ArrayList(); +- list1.stream().map((sx) -> { +- return s.slotNumber; +- }).forEach(list2::add); +- if (doTransfer) { +- List list3 = Arrays.asList(aslot[j][0].slotNumber, aslot[j][1].slotNumber); +- PacketRecipeTransfer packetrecipetransfer = new PacketRecipeTransfer(matchingitemsresult.matchingItems, list3, list2, maxTransfer, false); +- JustEnoughItems.getProxy().sendPacketToServer(packetrecipetransfer); +- } +- +- return null; +- } +- } +- } +- } ++ } ++ ++filledCraftSlotCount; ++ availableItemStacks.put(slot.slotNumber, stack.copy()); ++ } ++ List inventorySlots = this.transferHelper.getInventorySlots(container); ++ for (Slot slot : inventorySlots) { ++ ItemStack stack = slot.getStack(); ++ if (!stack.isEmpty()) { ++ availableItemStacks.put(slot.slotNumber, stack.copy()); ++ continue; ++ } ++ ++emptySlotCount; ++ } ++ if (filledCraftSlotCount - ingredients.size() > emptySlotCount) { ++ String message = Translator.translateToLocal((String)"jei.tooltip.error.recipe.transfer.inventory.full"); ++ return this.handlerHelper.createUserErrorWithTooltip(message); ++ } ++ StackHelper.MatchingItemsResult matchingItemsResult = this.stackHelper.getMatchingItems(availableItemStacks, adjustedIngredients); ++ if (matchingItemsResult.missingItems.size() > 0) { ++ String message = Translator.translateToLocal((String)"jei.tooltip.error.recipe.transfer.missing"); ++ return this.handlerHelper.createUserErrorForSlots(message, matchingItemsResult.missingItems); ++ } ++ ArrayList inventorySlotIndexes = new ArrayList(); ++ inventorySlots.stream().map(s -> s.slotNumber).forEach(inventorySlotIndexes::add); ++ if (doTransfer) { ++ List craftingSlotIndexes = Arrays.asList(craftingSlots[craftingIdx][0].slotNumber, craftingSlots[craftingIdx][1].slotNumber); ++ PacketRecipeTransfer packet = new PacketRecipeTransfer(matchingItemsResult.matchingItems, craftingSlotIndexes, inventorySlotIndexes, maxTransfer, false); ++ JustEnoughItems.getProxy().sendPacketToServer((PacketJei)packet); ++ } ++ return null; + } + } + diff --git a/projects/IC2-Patched/build.gradle.kts b/projects/IC2-Patched/build.gradle.kts index f4cde8c..7586991 100644 --- a/projects/IC2-Patched/build.gradle.kts +++ b/projects/IC2-Patched/build.gradle.kts @@ -1,3 +1,4 @@ +import codechicken.diffpatch.util.PatchMode import net.minecraftforge.gradle.patcher.task.TaskApplyPatches import net.minecraftforge.gradle.patcher.task.TaskGeneratePatches import org.apache.commons.io.FileUtils @@ -11,7 +12,7 @@ plugins { java id("de.undercouch.download") id("net.minecraftforge.gradle") - id("com.github.johnrengelman.shadow") version "6.1.0" + id("com.github.johnrengelman.shadow") version "7.1.2" } evaluationDependsOn(":IC2-Base") @@ -23,9 +24,10 @@ val taskGroup: String = "IC2 Patcher" val versionIC2: String by project val versionJEI: String by project val versionBuildCraft: String by project +val versionForge: String by project val patchedJar: File = File(buildDir, "applyPatches/output.jar") -val patchesDir: File = file("patches/minecraft") +val patchesDir: File = file(getPatchesDirectory() + "/minecraft") val ic2Dev: Configuration by configurations.creating val ic2Clean: Configuration by configurations.creating @@ -40,7 +42,7 @@ minecraft { tasks { register("applyPatches") { - val baseSourceJar = project(":IC2-Base").tasks.getByName("sourceJar") + val baseSourceJar = project(":IC2-Base").tasks.getByName("sourceJarWithResources") dependsOn(baseSourceJar) group = taskGroup @@ -48,6 +50,7 @@ tasks { patches = patchesDir rejects = File(buildDir, "$name/rejects.zip") output = patchedJar + patchMode = PatchMode.OFFSET isPrintSummary = true } @@ -75,6 +78,12 @@ tasks { register("sourceJar") { group = taskGroup archiveClassifier.set("sources") + from(sourceSets.main.get().allJava) + } + + register("sourceJarWithResources") { + group = taskGroup + archiveClassifier.set("sources-with-resources") from(sourceSets.main.get().allSource) } @@ -84,7 +93,8 @@ tasks { val sourceJar = getByName("sourceJar") val outputDir = patchesDir dependsOn(sourceJar) - + dependsOn(baseSourceJar) + base = baseSourceJar.archiveFile.get().asFile modified = sourceJar.archiveFile.get().asFile output = outputDir @@ -111,9 +121,7 @@ tasks { dependsOn("classes", "extractSources") configurations = listOf(project.configurations["shade"]) - archiveClassifier.set("") - from("src/main/java/ic2") { include("profiles/**") include("sounds/**") @@ -126,7 +134,7 @@ tasks { group = taskGroup cleanJar = ic2Clean.singleFile dirtyJar = File(buildDir, "reobfJar/output.jar") - output = File(buildDir, "$name/ic2patches.pack.lzma") + output = File(rootDir, "src/main/generatedResources/patches/" + getPatchesDirectory() + "/ic2patches.pack.lzma") configureBinPatchTask(this) } @@ -136,7 +144,7 @@ tasks { group = taskGroup cleanJar = ic2Dev.singleFile dirtyJar = shadowJar.archiveFile.get().asFile - output = File(buildDir, "$name/ic2patches.pack.lzma") + output = File(buildDir, "$name/patches/" + getPatchesDirectory() + "/ic2patches.pack.lzma") configureBinPatchTask(this) } @@ -191,7 +199,7 @@ repositories { } dependencies { - minecraft(group = "net.minecraftforge", name = "forge", version = "1.12.2-14.23.5.2855") + minecraft(group = "net.minecraftforge", name = "forge", version = "1.12.2-${versionForge}") ic2Dev(group = "net.industrial-craft", name = "industrialcraft-2", version = "${versionIC2}-ex112", classifier = "dev") ic2Clean(group = "net.industrial-craft", name = "industrialcraft-2", version = "${versionIC2}-ex112") @@ -203,3 +211,48 @@ dependencies { implementation(ejml) shade(ejml) } + +/** + * Compares two versions separated by dots. Doesn't work with versions schema containing letters. + * Truth table: + * v1 > v2 => true + * v1 == v2 => true + * v1 < v2 => false + * v1 // v2 contain chars -> Integer parsing Exception + */ +fun compareVersions(v1:String, v2:String): Boolean { + val v1s = v1.split("."); + val v2s = v2.split("."); + + val length: Int = if (v1s.size > v2s.size) { v2s.size } else { v1s.size } + for (i in 0 until length) { + val v1i = Integer.parseInt(v1s[i]); + val v2i = Integer.parseInt(v2s[i]) + if (v1i > v2i) { + return true + } else if (v2i > v1i) { + return false; + } + } + return v1s.size >= v2s.size +} + +/** + * Used to get patches directory based on the IC2 Version specified in the Gradle properties. + */ +fun getPatchesDirectory(): String { + project(":IC2-Patched").projectDir.listFiles { _, name -> + name.startsWith("patches[") && name.endsWith("]") + }?.forEach { file -> + val name = file.name.toString() + val versions = name.substring(name.indexOf("[")+1, name.indexOf("]")).split(",") + if (versions.size == 2) { + if (compareVersions(versionIC2, versions[0])) { + if (versions[1] == "+" || !compareVersions(versionIC2, versions[1])) { + return "patches[${versions[0]},${versions[1]}]" + } + } + } + } + return "patches" +} diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/WorldData.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/WorldData.java.patch new file mode 100644 index 0000000..4e17cf1 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/WorldData.java.patch @@ -0,0 +1,59 @@ +--- a/ic2/core/WorldData.java ++++ b/ic2/core/WorldData.java +@@ -2,6 +2,7 @@ + + import ic2.core.energy.grid.EnergyNetLocal; + import ic2.core.network.TeUpdateDataServer; ++import ic2.core.util.LogCategory; + import java.util.ArrayList; + import java.util.Collections; + import java.util.HashSet; +@@ -22,6 +23,7 @@ + public class WorldData { + private static ConcurrentMap idxClient = FMLCommonHandler.instance().getSide().isClient() ? new ConcurrentHashMap() : null; + private static ConcurrentMap idxServer = new ConcurrentHashMap(); ++ private final World world; + final Queue singleUpdates = new ConcurrentLinkedQueue(); + final Set continuousUpdates = new HashSet(); + boolean continuousUpdatesInUse = false; +@@ -42,7 +44,7 @@ + this.energyNet = null; + this.windSim = null; + } +- ++ this.world = world; + } + + public static WorldData get(World world) { +@@ -61,9 +63,16 @@ + if (worlddata1 != null) { + worlddata = worlddata1; + } ++ IC2.log.debug(LogCategory.EnergyNet, "World with id %d loaded.", world.provider.getDimension()); + + return worlddata; + } else { ++ if (load && world != worlddata.world) { ++ worlddata = new WorldData(world); ++ concurrentmap.put(world.provider.getDimension(), worlddata); ++ IC2.log.warn(LogCategory.EnergyNet, "The dimension %d had the wrong world referenced and was replaced with the current one.", world.provider.getDimension()); ++ IC2.log.warn(LogCategory.EnergyNet, "This is likely caused by missing or incorrect ordered world load / unload events."); ++ } + return worlddata; + } + } +@@ -71,6 +80,14 @@ + + public static void onWorldUnload(World world) { + getIndex(!world.isRemote).remove(Integer.valueOf(world.provider.getDimension())); ++ IC2.log.debug(LogCategory.EnergyNet, "World with id %d unloaded.", world.provider.getDimension()); ++ } ++ ++ public static void resetMaps() { ++ idxServer.clear(); ++ if (idxClient != null) { ++ idxClient.clear(); ++ } + } + + private static ConcurrentMap getIndex(boolean simulating) { diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/RenderBlockWall.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/RenderBlockWall.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/RenderBlockWall.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/RenderBlockWall.java.patch diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch new file mode 100644 index 0000000..d558c79 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java ++++ b/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java +@@ -297,7 +297,7 @@ + } + + protected void doCrafting() { +- for(int j = 0; j < this.operationsPerTick; ++j) { ++ for(int j = 0; j < this.operationsPerTick && canCraft(); ++j) { + List list = Collections.singletonList(this.recipeOutput); + + for(ItemStack itemstack : this.upgradeSlot) { diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch new file mode 100644 index 0000000..dd9e09d --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/block/steam/TileEntityCokeKiln.java ++++ b/ic2/core/block/steam/TileEntityCokeKiln.java +@@ -11,6 +11,7 @@ + import ic2.core.gui.dynamic.GuiParser; + import ic2.core.gui.dynamic.IGuiValueProvider; + import ic2.core.network.GuiSynced; ++import ic2.core.profile.NotClassic; + import ic2.core.recipe.dynamic.DynamicRecipe; + import ic2.core.recipe.dynamic.DynamicRecipeManager; + import ic2.core.recipe.dynamic.RecipeOutputFluidStack; +@@ -42,6 +43,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class TileEntityCokeKiln extends TileEntityInventory implements IMultiBlockController, IHasGui, IGuiValueProvider { + boolean disabled = true; + protected int tickRate = 20; diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch new file mode 100644 index 0000000..ac54d2b --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch @@ -0,0 +1,20 @@ +--- a/ic2/core/block/transport/TileEntityFluidPipe.java ++++ b/ic2/core/block/transport/TileEntityFluidPipe.java +@@ -423,6 +423,7 @@ + } + + public IFluidTankProperties[] getTankProperties() { ++ if (TileEntityFluidPipe.this.tank == null) return new IFluidTankProperties[0]; + return TileEntityFluidPipe.this.tank.getTankProperties(); + } + +@@ -454,7 +455,8 @@ + public FluidStack drain(int maxDrain, boolean doDrain) { + if (TileEntityFluidPipe.this.coversComponent.hasCover(this.side)) { + ICoverItem icoveritem = TileEntityFluidPipe.this.coversComponent.getCoverItem(this.side); +- if (!icoveritem.allowsOutput(new FluidStack(TileEntityFluidPipe.this.tank.getFluid(), maxDrain))) { ++ FluidStack fluid = TileEntityFluidPipe.this.tank.getFluid(); ++ if (fluid != null && !icoveritem.allowsOutput(new FluidStack(fluid, maxDrain))) { + return null; + } + } diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch new file mode 100644 index 0000000..64d1dc4 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/init/BlocksItems.java.patch @@ -0,0 +1,14 @@ +--- a/ic2/core/init/BlocksItems.java ++++ b/ic2/core/init/BlocksItems.java +@@ -281,8 +281,9 @@ + return !IC2.version.isClassic(); + } + }; +- new ItemBattery(ItemName.energy_crystal, 1000000.0D, 2048.0D, 3); +- (new ItemBattery(ItemName.lapotron_crystal, 1.0E7D, 8092.0D, 4)).setRarity(EnumRarity.UNCOMMON); ++ boolean classic = IC2.version.isClassic(); ++ new ItemBattery(ItemName.energy_crystal, classic ? 100000 : 1000000, classic ? 250 : 2048, classic ? 2 : 3); ++ (new ItemBattery(ItemName.lapotron_crystal, classic ? 1000000 : 1.0E7D, classic ? 600 : 8092.0D, classic ? 3 : 4)).setRarity(EnumRarity.UNCOMMON); + new ItemBatterySU(ItemName.single_use_battery, 1200, 1); + new ItemBatteryChargeHotbar(ItemName.charging_re_battery, 40000.0D, 128.0D, 1); + new ItemBatteryChargeHotbar(ItemName.advanced_charging_re_battery, 400000.0D, 1024.0D, 2); diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/ItemCoke.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/ItemCoke.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/ItemCoke.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/ItemCoke.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch rename to projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch new file mode 100644 index 0000000..4049963 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/item/tool/ItemToolCrowbar.java ++++ b/ic2/core/item/tool/ItemToolCrowbar.java +@@ -6,6 +6,7 @@ + import ic2.core.block.transport.cover.ICoverHolder; + import ic2.core.init.Localization; + import ic2.core.item.ItemToolIC2; ++import ic2.core.profile.NotClassic; + import ic2.core.ref.ItemName; + import ic2.core.util.RotationUtil; + import ic2.core.util.StackUtil; +@@ -28,6 +29,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class ItemToolCrowbar extends ItemToolIC2 implements IEnhancedOverlayProvider { + public ItemToolCrowbar() { + super(ItemName.crowbar, HarvestLevel.Iron, Collections.singleton(ToolClass.Crowbar)); diff --git a/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch new file mode 100644 index 0000000..4318005 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.164,2.8.165]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/item/tool/ItemToolWrenchNew.java ++++ b/ic2/core/item/tool/ItemToolWrenchNew.java +@@ -7,6 +7,7 @@ + import ic2.core.IHitSoundOverride; + import ic2.core.audio.PositionSpec; + import ic2.core.item.ItemToolIC2; ++import ic2.core.profile.NotClassic; + import ic2.core.ref.ItemName; + import ic2.core.util.RotationUtil; + import ic2.core.util.StackUtil; +@@ -32,6 +33,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class ItemToolWrenchNew extends ItemToolIC2 implements IEnhancedOverlayProvider, IHitSoundOverride { + public ItemToolWrenchNew() { + super(ItemName.wrench_new, HarvestLevel.Iron, Collections.singleton(ToolClass.Wrench)); diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/WorldData.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/WorldData.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/WorldData.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/WorldData.java.patch diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/RenderBlockWall.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/RenderBlockWall.java.patch new file mode 100644 index 0000000..e5c5d10 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/RenderBlockWall.java.patch @@ -0,0 +1,22 @@ +--- a/ic2/core/block/RenderBlockWall.java ++++ b/ic2/core/block/RenderBlockWall.java +@@ -69,15 +69,16 @@ + + for(EnumFacing enumfacing : EnumFacing.VALUES) { + int[] aint1 = colorMultipliers[enumfacing.ordinal()]; +- List list1 = baseModel.getQuads(state, enumfacing, 0L); ++ List list1 = new ArrayList<>(baseModel.getQuads(state, enumfacing, 0L)); + if (aint1 == null) { + list[enumfacing.ordinal()] = list1; + } else { + List list2 = new ArrayList(list1.size() + aint1.length); +- list2.addAll(list1); ++ if (aint1.length < 1) list2.addAll(list1); ++ else list1.clear(); + + for(int i : aint1) { +- generateQuad(enumfacing, 0.001F, intbuffer); ++ generateQuad(enumfacing, 0, intbuffer); + list2.add(BasicBakedBlockModel.createQuad(Arrays.copyOf(intbuffer.array(), intbuffer.position()), enumfacing, (TextureAtlasSprite)null)); + ((Buffer)intbuffer).rewind(); + } diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityBatchCrafter.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityCropHarvester.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCropHarvester.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityCropHarvester.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCropHarvester.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityCropmatron.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCropmatron.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/machine/tileentity/TileEntityCropmatron.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/machine/tileentity/TileEntityCropmatron.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/personal/TileEntityTradingTerminal.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/personal/TileEntityTradingTerminal.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/personal/TileEntityTradingTerminal.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/personal/TileEntityTradingTerminal.java.patch diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch new file mode 100644 index 0000000..54b324a --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/BlockRefractoryBricks.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/block/steam/BlockRefractoryBricks.java ++++ b/ic2/core/block/steam/BlockRefractoryBricks.java +@@ -1,6 +1,7 @@ + package ic2.core.block.steam; + + import ic2.core.block.BlockBase; ++import ic2.core.profile.NotClassic; + import ic2.core.ref.BlockName; + import net.minecraft.block.material.Material; + import net.minecraft.block.properties.IProperty; +@@ -9,6 +10,7 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.IBlockAccess; + ++@NotClassic + public class BlockRefractoryBricks extends BlockBase { + public BlockRefractoryBricks() { + super(BlockName.refractory_bricks, Material.ROCK); diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKiln.java.patch diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch new file mode 100644 index 0000000..145f3a5 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnGrate.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/block/steam/TileEntityCokeKilnGrate.java ++++ b/ic2/core/block/steam/TileEntityCokeKilnGrate.java +@@ -10,12 +10,15 @@ + import ic2.core.gui.dynamic.GuiParser; + import ic2.core.network.GuiSynced; + import java.util.Collections; ++ ++import ic2.core.profile.NotClassic; + import net.minecraft.client.gui.GuiScreen; + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.util.EnumFacing; + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class TileEntityCokeKilnGrate extends TileEntityInventory implements IHasGui { + protected final Fluids fluids = (Fluids)this.addComponent(new Fluids(this)); + @GuiSynced diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch new file mode 100644 index 0000000..54d7800 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/steam/TileEntityCokeKilnHatch.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/block/steam/TileEntityCokeKilnHatch.java ++++ b/ic2/core/block/steam/TileEntityCokeKilnHatch.java +@@ -7,6 +7,7 @@ + import ic2.core.gui.dynamic.DynamicContainer; + import ic2.core.gui.dynamic.DynamicGui; + import ic2.core.gui.dynamic.GuiParser; ++import ic2.core.profile.NotClassic; + import net.minecraft.client.gui.GuiScreen; + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; +@@ -14,6 +15,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class TileEntityCokeKilnHatch extends TileEntityInventory implements IHasGui { + protected final InvSlot inventory = new InvSlot(this, "inventory", InvSlot.Access.I, 1, InvSlot.InvSide.ANY); + diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch new file mode 100644 index 0000000..ff45574 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java ++++ b/ic2/core/block/storage/box/TileEntityBronzeStorageBox.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.box; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntityBronzeStorageBox extends TileEntityStorageBox { + public TileEntityBronzeStorageBox() { + super(45); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch new file mode 100644 index 0000000..8bf2578 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java ++++ b/ic2/core/block/storage/box/TileEntityIridiumStorageBox.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.box; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntityIridiumStorageBox extends TileEntityStorageBox { + public TileEntityIridiumStorageBox() { + super(126); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch new file mode 100644 index 0000000..21b1497 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityIronStorageBox.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/box/TileEntityIronStorageBox.java ++++ b/ic2/core/block/storage/box/TileEntityIronStorageBox.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.box; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntityIronStorageBox extends TileEntityStorageBox { + public TileEntityIronStorageBox() { + super(45); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch new file mode 100644 index 0000000..fd3bb30 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntitySteelStorageBox.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/box/TileEntitySteelStorageBox.java ++++ b/ic2/core/block/storage/box/TileEntitySteelStorageBox.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.box; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntitySteelStorageBox extends TileEntityStorageBox { + public TileEntitySteelStorageBox() { + super(63); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch new file mode 100644 index 0000000..3f250ab --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java.patch @@ -0,0 +1,13 @@ +--- a/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java ++++ b/ic2/core/block/storage/box/TileEntityWoodenStorageBox.java +@@ -1,8 +1,10 @@ + package ic2.core.block.storage.box; + ++import ic2.core.profile.NotClassic; + import net.minecraft.block.SoundType; + import net.minecraft.entity.Entity; + ++@NotClassic + public class TileEntityWoodenStorageBox extends TileEntityStorageBox { + public TileEntityWoodenStorageBox() { + super(27); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch new file mode 100644 index 0000000..7de6b8f --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityBronzeTank.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/tank/TileEntityBronzeTank.java ++++ b/ic2/core/block/storage/tank/TileEntityBronzeTank.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.tank; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntityBronzeTank extends TileEntityTank { + public TileEntityBronzeTank() { + super(32); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch new file mode 100644 index 0000000..ca3d32f --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIridiumTank.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/tank/TileEntityIridiumTank.java ++++ b/ic2/core/block/storage/tank/TileEntityIridiumTank.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.tank; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntityIridiumTank extends TileEntityTank { + public TileEntityIridiumTank() { + super(1024); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch new file mode 100644 index 0000000..8520e5c --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntityIronTank.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/tank/TileEntityIronTank.java ++++ b/ic2/core/block/storage/tank/TileEntityIronTank.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.tank; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntityIronTank extends TileEntityTank { + public TileEntityIronTank() { + super(32); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch new file mode 100644 index 0000000..a92a66e --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/storage/tank/TileEntitySteelTank.java.patch @@ -0,0 +1,11 @@ +--- a/ic2/core/block/storage/tank/TileEntitySteelTank.java ++++ b/ic2/core/block/storage/tank/TileEntitySteelTank.java +@@ -1,5 +1,8 @@ + package ic2.core.block.storage.tank; + ++import ic2.core.profile.NotClassic; ++ ++@NotClassic + public class TileEntitySteelTank extends TileEntityTank { + public TileEntitySteelTank() { + super(128); diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/block/transport/TileEntityFluidPipe.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/init/BlocksItems.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/init/BlocksItems.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/init/BlocksItems.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/init/BlocksItems.java.patch diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/ItemCoke.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/ItemCoke.java.patch new file mode 100644 index 0000000..005cd6d --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/ItemCoke.java.patch @@ -0,0 +1,13 @@ +--- a/ic2/core/item/ItemCoke.java ++++ b/ic2/core/item/ItemCoke.java +@@ -1,8 +1,10 @@ + package ic2.core.item; + ++import ic2.core.profile.NotClassic; + import ic2.core.ref.ItemName; + import net.minecraft.item.ItemStack; + ++@NotClassic + public class ItemCoke extends ItemIC2 { + public ItemCoke() { + super(ItemName.coke); diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch new file mode 100644 index 0000000..9f15fcb --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorNightvisionGoggles.java.patch @@ -0,0 +1,66 @@ +--- a/ic2/core/item/armor/ItemArmorNightvisionGoggles.java ++++ b/ic2/core/item/armor/ItemArmorNightvisionGoggles.java +@@ -4,8 +4,11 @@ + import ic2.api.item.IElectricItem; + import ic2.api.item.IItemHudInfo; + import ic2.core.IC2; ++import ic2.core.item.BaseElectricItem; + import ic2.core.item.ElectricItemManager; ++import ic2.core.item.IPseudoDamageItem; + import ic2.core.ref.ItemName; ++import ic2.core.util.LogCategory; + import ic2.core.util.StackUtil; + import java.util.LinkedList; + import java.util.List; +@@ -20,7 +23,7 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class ItemArmorNightvisionGoggles extends ItemArmorUtility implements IElectricItem, IItemHudInfo { ++public class ItemArmorNightvisionGoggles extends ItemArmorUtility implements IElectricItem, IItemHudInfo, IPseudoDamageItem { + public ItemArmorNightvisionGoggles() { + super(ItemName.nightvision_goggles, "nightvision", EntityEquipmentSlot.HEAD); + this.setMaxDamage(27); +@@ -53,6 +56,7 @@ + NBTTagCompound nbttagcompound = StackUtil.getOrCreateNbtData(stack); + boolean flag = nbttagcompound.getBoolean("active"); + byte b0 = nbttagcompound.getByte("toggleTimer"); ++ int i = player.getEntityWorld().getLightFromNeighbors(new BlockPos(player)); + if (IC2.keyboard.isAltKeyDown(player) && IC2.keyboard.isModeSwitchKeyDown(player) && b0 == 0) { + b0 = 10; + flag = !flag; +@@ -62,6 +66,8 @@ + IC2.platform.messagePlayer(player, "Nightvision enabled."); + } else { + IC2.platform.messagePlayer(player, "Nightvision disabled."); ++ if (i > 8) IC2.platform.removePotion(player, MobEffects.BLINDNESS); ++ else IC2.platform.removePotion(player, MobEffects.NIGHT_VISION); + } + } + } +@@ -73,7 +79,6 @@ + + boolean flag1 = false; + if (flag && IC2.platform.isSimulating() && ElectricItem.manager.use(stack, 1.0D, player)) { +- int i = player.getEntityWorld().getLightFromNeighbors(new BlockPos(player)); + if (i > 8) { + IC2.platform.removePotion(player, MobEffects.NIGHT_VISION); + player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 100, 0, true, true)); +@@ -99,5 +104,17 @@ + + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return false; ++ } ++ ++ public void setDamage(ItemStack stack, int damage) { ++ int i = this.getDamage(stack); ++ if (damage != i && BaseElectricItem.logIncorrectItemDamaging) { ++ IC2.log.warn(LogCategory.Armor, new Throwable(), "Detected invalid armor damage application (%d):", damage - i); ++ } ++ } ++ ++ @Override ++ public void setStackDamage(ItemStack var1, int var2) { ++ super.setDamage(var1, var2); + } + } diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch new file mode 100644 index 0000000..891a203 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/armor/ItemArmorQuantumSuit.java.patch @@ -0,0 +1,35 @@ +--- a/ic2/core/item/armor/ItemArmorQuantumSuit.java ++++ b/ic2/core/item/armor/ItemArmorQuantumSuit.java +@@ -278,6 +278,23 @@ + IC2.platform.profilerStartSection("QuantumBodyarmor"); + player.extinguish(); + IC2.platform.profilerEndSection(); ++ ++ if (player.isSneaking() && IC2.keyboard.isModeSwitchKeyDown(player) && b0 == 0) { ++ b0 = 10; ++ boolean disabled = !nbttagcompound.getBoolean("jetpackDisabled"); ++ if (IC2.platform.isSimulating()) { ++ nbttagcompound.setBoolean("jetpackDisabled", disabled); ++ IC2.platform.messagePlayer(player, "Jetpack "+(disabled ? "disabled" : "enabled")); ++ if (disabled) nbttagcompound.setBoolean("hoverMode", false); ++ } else if (disabled) { ++ IC2.audioManager.removeSources(player); ++ } ++ } ++ ++ if (IC2.platform.isSimulating() && b0 > 0) { ++ --b0; ++ nbttagcompound.setByte("toggleTimer", b0); ++ } + break; + case LEGS: + IC2.platform.profilerStartSection("QuantumLeggings"); +@@ -375,7 +392,7 @@ + } + + public boolean isJetpackActive(ItemStack stack) { +- return true; ++ return !StackUtil.getOrCreateNbtData(stack).getBoolean("jetpackDisabled"); + } + + public float getHoverMultiplier(ItemStack stack, boolean upwards) { diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch new file mode 100644 index 0000000..5eda019 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/block/ItemFluidPipe.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/item/block/ItemFluidPipe.java ++++ b/ic2/core/item/block/ItemFluidPipe.java +@@ -7,6 +7,7 @@ + import ic2.core.block.transport.items.PipeSize; + import ic2.core.block.transport.items.PipeType; + import ic2.core.item.ItemIC2; ++import ic2.core.profile.NotClassic; + import ic2.core.ref.BlockName; + import ic2.core.ref.IMultiItem; + import ic2.core.ref.ItemName; +@@ -43,6 +44,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class ItemFluidPipe extends ItemIC2 implements IMultiItem, IBoxable { + private final List variants = new ArrayList(); + diff --git a/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch new file mode 100644 index 0000000..96d1467 --- /dev/null +++ b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/logistics/ItemPumpCover.java.patch @@ -0,0 +1,18 @@ +--- a/ic2/core/item/logistics/ItemPumpCover.java ++++ b/ic2/core/item/logistics/ItemPumpCover.java +@@ -8,6 +8,7 @@ + import ic2.core.block.transport.cover.IFluidConsumingCover; + import ic2.core.init.Localization; + import ic2.core.item.ItemMulti; ++import ic2.core.profile.NotClassic; + import ic2.core.ref.ItemName; + import ic2.core.util.LiquidUtil; + import ic2.core.util.RotationUtil; +@@ -28,6 +29,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++@NotClassic + public class ItemPumpCover extends ItemMulti implements IFluidConsumingCover, IEnhancedOverlayProvider { + public ItemPumpCover() { + super(ItemName.cover, PumpCoverType.class); diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolCrowbar.java.patch diff --git a/projects/IC2-Patched/patches/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch b/projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch similarity index 100% rename from projects/IC2-Patched/patches/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch rename to projects/IC2-Patched/patches[2.8.221,+]/minecraft/ic2/core/item/tool/ItemToolWrenchNew.java.patch diff --git a/settings.gradle.kts b/settings.gradle.kts index 981d086..03f2c4f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -10,7 +10,7 @@ pluginManagement { repositories { gradlePluginPortal() maven { - url = uri("https://maven.minecraftforge.net/") + url = uri("https://files.minecraftforge.net/maven") } maven { name = "FancyGradle" diff --git a/src/main/generatedResources/patches/patches[2.8.164,2.8.165]/ic2patches.pack.lzma b/src/main/generatedResources/patches/patches[2.8.164,2.8.165]/ic2patches.pack.lzma new file mode 100644 index 0000000000000000000000000000000000000000..98a4921e9c937918498e7d2f3a41f6fd0c3e7f24 GIT binary patch literal 45556 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

-nJq+A( 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 YTJ#u^DiHP)Yw@}tEboFJ|MvpQT8EBy>;M1& literal 0 HcmV?d00001 diff --git a/src/main/generatedResources/patches/patches[2.8.221,+]/ic2patches.pack.lzma b/src/main/generatedResources/patches/patches[2.8.221,+]/ic2patches.pack.lzma new file mode 100644 index 0000000000000000000000000000000000000000..ee48f088453d59f8bcab7b016372949b5b1e7555 GIT binary patch literal 50526 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 H=z_eQtmn&6 literal 0 HcmV?d00001 diff --git a/src/main/java/mods/su5ed/ic2patcher/Patcher.java b/src/main/java/mods/su5ed/ic2patcher/Patcher.java index 8497329..4e4c0c9 100644 --- a/src/main/java/mods/su5ed/ic2patcher/Patcher.java +++ b/src/main/java/mods/su5ed/ic2patcher/Patcher.java @@ -16,7 +16,7 @@ import net.minecraftforge.registries.IForgeRegistryModifiable; import org.apache.logging.log4j.Logger; -@Mod(modid = "ic2patcher", name = "IC2 Patcher", dependencies = "required-after:ic2@[2.8.221-ex112,];") +@Mod(modid = "ic2patcher", name = "IC2 Patcher", dependencies = "required-after:ic2@[2.8.164-ex112],[2.8.221-ex112,);") public final class Patcher { public static Logger logger; diff --git a/src/main/java/mods/su5ed/ic2patcher/asm/BinPatchManager.java b/src/main/java/mods/su5ed/ic2patcher/asm/BinPatchManager.java index 1da0893..eb82998 100644 --- a/src/main/java/mods/su5ed/ic2patcher/asm/BinPatchManager.java +++ b/src/main/java/mods/su5ed/ic2patcher/asm/BinPatchManager.java @@ -28,7 +28,8 @@ import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import com.google.common.io.Files; -import net.minecraft.launchwrapper.LaunchClassLoader; +import mods.su5ed.ic2patcher.util.IC2VersionExtractor; +import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.patcher.ClassPatch; import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.fml.repackage.com.nothome.delta.GDiffPatcher; @@ -37,15 +38,17 @@ import org.apache.logging.log4j.Logger; import java.io.*; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Pack200; import java.util.regex.Pattern; +import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import static mods.su5ed.ic2patcher.util.VersionComparison.compareVersions; + /** * STOLEN from MinecraftForge's {@link net.minecraftforge.fml.common.patcher.ClassPatchManager ClassPatchManager} * @@ -62,7 +65,7 @@ public class BinPatchManager { private final GDiffPatcher patcher = new GDiffPatcher(); private ListMultimap patches; - private Map patchedClasses = Maps.newHashMap(); + private final Map patchedClasses = Maps.newHashMap(); private File tempDir; private BinPatchManager() { @@ -140,16 +143,45 @@ else if (patch.existsAtTarget && (inputData == null || inputData.length == 0)) { return inputData; } - public void setup(File modJar) { + public void setup(Map data) { + File modJar = (File) data.get("coremodLocation"); + File mcLocation = (File) data.get("mcLocation"); + Pattern binpatchMatcher = Pattern.compile(String.format("binpatch/%s/.*.binpatch", "merged")); JarInputStream jis = null; try { - try { - ZipFile zip = new ZipFile(modJar); - InputStream binpatchesCompressed = zip.getInputStream(zip.getEntry("ic2patches.pack.lzma")); + try (ZipFile zip = new ZipFile(modJar)) { + // Patches selection depending on the IC2 version. + Enumeration entries = zip.entries(); + String patches = "ic2patches.pack.lzma"; + String versionIC2 = IC2VersionExtractor.getIC2Version(mcLocation); + if (versionIC2 == null) throw new NullPointerException("Couldn't find IC2 Version! Is IC2 installed?"); + if (DEBUG) LOG.debug("Current IC2 version: " + versionIC2); + versionIC2 = versionIC2.substring(0, versionIC2.indexOf("-")); + + while (entries.hasMoreElements()) { + // As you can't list all entries under x entry, like with a normal directory, + // it's required to search all entries of the Jar. + String name = entries.nextElement().getName(); + if (!name.startsWith("patches/patches[") || !name.endsWith("]/ic2patches.pack.lzma")) continue; + + // Checking if IC2 Version is in the range specified by the Entry version range. + String[] versions = name.substring(name.indexOf("[")+1, name.indexOf("]")).split(","); + if (DEBUG) LOG.debug("Found patches for IC2 version: " + Arrays.toString(versions)); + + if (versions.length == 2 && compareVersions(versionIC2, versions[0])) { + if (Objects.equals(versions[1], "+") || !compareVersions(versionIC2, versions[1])) { + if (DEBUG) LOG.debug("Loading patches from " + name + " for IC2 versions " + Arrays.toString(versions)); + patches = name; + break; + } + } + } + + InputStream binpatchesCompressed = zip.getInputStream(zip.getEntry(patches)); if (binpatchesCompressed==null) { if (!FMLLaunchHandler.isDeobfuscatedEnvironment()) { - LOG.fatal("The binary patch set is missing, things are not going to work!"); + LOG.fatal("The binary patch set is missing for your version of IC2, things are not going to work!"); } return; } diff --git a/src/main/java/mods/su5ed/ic2patcher/asm/PatcherFMLPlugin.java b/src/main/java/mods/su5ed/ic2patcher/asm/PatcherFMLPlugin.java index 4311427..bb6067b 100644 --- a/src/main/java/mods/su5ed/ic2patcher/asm/PatcherFMLPlugin.java +++ b/src/main/java/mods/su5ed/ic2patcher/asm/PatcherFMLPlugin.java @@ -21,9 +21,8 @@ public String getModContainerClass() { @Override public void injectData(Map data) { - Object jar = data.get("coremodLocation"); - if (jar == null) return; - BinPatchManager.INSTANCE.setup((File) jar); + if (data.get("coremodLocation") == null || data.get("mcLocation") == null) return; + BinPatchManager.INSTANCE.setup(data); } @Override diff --git a/src/main/java/mods/su5ed/ic2patcher/util/IC2VersionExtractor.java b/src/main/java/mods/su5ed/ic2patcher/util/IC2VersionExtractor.java new file mode 100644 index 0000000..fad15cd --- /dev/null +++ b/src/main/java/mods/su5ed/ic2patcher/util/IC2VersionExtractor.java @@ -0,0 +1,53 @@ +package mods.su5ed.ic2patcher.util; + +import com.google.gson.Gson; + +import java.io.*; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +@SuppressWarnings("all") +public class IC2VersionExtractor { + + private static String ic2Version = null; + + /** + * Used to get cached IC2 Version extracted from the IC2 Jar. Requires {@link IC2VersionExtractor#getIC2Version(File)} to be called at least once. + * @return String with IC2 Version. + */ + public static String getIc2Version() throws IOException {return getIC2Version(null);} + + /** + * Used to get IC2 Version from the jar itself. If was called at least once, returns cached value. + * @param mcLocation File referencing MC Directory. If called more than once, can be null or {@link IC2VersionExtractor#getIC2Version()} can be used. + * @return String with IC2 Version extracted, or null if not found. + * @throws IOException when IO Exception occurs. + */ + public static String getIC2Version(File mcLocation) throws IOException { + if (mcLocation == null) return ic2Version; + + File mods = new File(mcLocation, "mods"); + + if (!mods.exists() || mods.listFiles() == null) return null; + + for (File file : mods.listFiles()) { + if (!file.exists() || file.isDirectory() || !file.getName().endsWith(".jar")) continue; + + try (ZipFile zip = new ZipFile(file)) { + ZipEntry mcModInfoEntry = zip.getEntry("mcmod.info"); + if (mcModInfoEntry == null) continue; + try { + // Unchecked Cast Warning* + Map mcModInfo = ((List>)new Gson().fromJson(new InputStreamReader(zip.getInputStream(mcModInfoEntry)), Object.class)).get(0); + if (!Objects.equals(mcModInfo.get("modid"), "ic2")) continue; + ic2Version = (String) mcModInfo.get("version"); + return ic2Version; + } catch (Exception ignored) {} + } + } + return null; + } +} diff --git a/src/main/java/mods/su5ed/ic2patcher/util/VersionComparison.java b/src/main/java/mods/su5ed/ic2patcher/util/VersionComparison.java new file mode 100644 index 0000000..64fd5e4 --- /dev/null +++ b/src/main/java/mods/su5ed/ic2patcher/util/VersionComparison.java @@ -0,0 +1,27 @@ +package mods.su5ed.ic2patcher.util; + +public class VersionComparison { + /** + * Compares two versions separated by dots. Doesn't work with versions schema containing letters. + * Truth table:
+ * v1 > v2 => true
+ * v1 == v2 => true
+ * v1 < v2 => false
+ * v1 // v2 contain chars -> Integer parsing Exception
+ */ + public static boolean compareVersions(String v1, String v2) { + String[] v1s = v1.split("\\."); + String[] v2s = v2.split("\\."); + + for (int i = 0; i < Math.min(v1s.length, v2s.length); i++) { + int v1i = Integer.parseInt(v1s[i]); + int v2i = Integer.parseInt(v2s[i]); + if (v1i > v2i) { + return true; + } else if (v2i > v1i) { + return false; + } + } + return v1s.length >= v2s.length; + } +} diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 64a72b9..7effe13 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -2,13 +2,13 @@ { "modid": "ic2patcher", "name": "IC2 Patcher", - "description": "Patches IC2", + "description": "This mod Patches IC2 to fix bugs that weren't fixed by IC2 Team.", "version": "${version}", "mcversion": "${mcversion}", "credits": "", "authorList": ["Su5eD"], "logoFile": "", - "url": "", + "url": "https://github.com/Su5eD/IC2-Patcher", "updateUrl": "", "parent": "", "screenshots": []