From aa47599278bd55eef126d398737501a71f984e39 Mon Sep 17 00:00:00 2001 From: mezz Date: Mon, 29 Jun 2015 22:15:39 -0700 Subject: [PATCH] Giant multiblock refactor --- api/forestry | 2 +- application.properties | 4 +- lang | 2 +- .../apiculture/BeeHousingInventory.java | 78 ++ .../apiculture/BeeHousingListener.java | 49 + .../apiculture/BeeHousingModifier.java | 117 ++ .../forestry/apiculture/BeekeepingLogic.java | 582 ++++----- .../apiculture/FakeBeekeepingLogic.java | 58 + .../apiculture/GuiHandlerApiculture.java | 36 +- .../forestry/apiculture/HasFlowersCache.java | 87 ++ .../forestry/apiculture/flowers/Flower.java | 7 + .../apiculture/flowers/FlowerProvider.java | 8 +- .../apiculture/flowers/FlowerRegistry.java | 132 +- .../apiculture/gadgets/BlockAlveary.java | 52 +- .../gadgets/StructureLogicAlveary.java | 149 --- .../apiculture/gadgets/TileAlveary.java | 267 ---- .../apiculture/gadgets/TileAlvearyPlain.java | 716 ----------- .../apiculture/gadgets/TileAlvearySieve.java | 196 --- .../gadgets/TileAlvearyStabiliser.java | 120 -- .../apiculture/gadgets/TileApiary.java | 315 ++--- .../apiculture/gadgets/TileBeeHousing.java | 177 +++ .../apiculture/gadgets/TileBeehouse.java | 490 +------ .../apiculture/genetics/AlleleBeeSpecies.java | 20 - .../genetics/AlleleEffectCreeper.java | 12 +- .../genetics/AlleleEffectFertile.java | 21 +- .../genetics/AlleleEffectFungification.java | 25 +- .../genetics/AlleleEffectGlacial.java | 8 +- .../genetics/AlleleEffectIgnition.java | 9 +- .../genetics/AlleleEffectMiasmic.java | 9 +- .../apiculture/genetics/AlleleEffectNone.java | 27 +- .../genetics/AlleleEffectRadioactive.java | 13 +- .../genetics/AlleleEffectRepulsion.java | 2 +- .../genetics/AlleleEffectSnowing.java | 18 +- .../genetics/AlleleEffectThrottled.java | 40 +- .../forestry/apiculture/genetics/Bee.java | 153 ++- .../genetics/BeeBranchDefinition.java | 3 +- .../apiculture/genetics/BeeDefinition.java | 2 - .../apiculture/genetics/BeeGenome.java | 4 - .../apiculture/genetics/BeeHelper.java | 16 +- .../apiculture/genetics/BeeMutation.java | 23 +- .../apiculture/genetics/BeekeepingMode.java | 104 +- .../genetics/JubilanceProviderHermit.java | 9 +- .../genetics/JubilanceRequiresResource.java | 6 +- .../apiculture/gui/ContainerAlveary.java | 19 +- .../gui/ContainerAlvearyHygroregulator.java | 4 +- .../apiculture/gui/ContainerAlvearySieve.java | 4 +- .../gui/ContainerAlvearySwarmer.java | 2 +- ...erApiary.java => ContainerBeeHousing.java} | 19 +- .../forestry/apiculture/gui/GuiAlveary.java | 16 +- .../gui/GuiAlvearyHygroregulator.java | 2 +- .../apiculture/gui/GuiAlvearySieve.java | 6 +- .../apiculture/gui/GuiAlvearySwarmer.java | 6 +- .../{GuiApiary.java => GuiBeeHousing.java} | 14 +- .../forestry/apiculture/items/ItemBeeGE.java | 7 +- .../apiculture/items/ItemHabitatLocator.java | 2 +- .../apiculture/items/ItemHiveFrame.java | 71 +- .../multiblock/AlvearyController.java | 466 +++++++ .../multiblock/FakeAlvearyController.java | 184 +++ .../multiblock/IAlvearyController.java | 24 + .../apiculture/multiblock/TileAlveary.java | 98 ++ .../TileAlvearyClimatiser.java | 89 +- .../apiculture/multiblock/TileAlvearyFan.java | 50 + .../multiblock/TileAlvearyHeater.java | 50 + .../TileAlvearyHygroregulator.java | 90 +- .../multiblock/TileAlvearyPlain.java | 210 +++ .../multiblock/TileAlvearySieve.java | 151 +++ .../multiblock/TileAlvearyStabiliser.java | 44 + .../TileAlvearySwarmer.java | 98 +- .../multiblock/TileAlvearyWithGui.java | 92 ++ .../network/PacketActiveUpdate.java | 13 +- .../network/PacketBeekeepingLogicActive.java | 58 + .../network/PacketHandlerApiculture.java | 4 + .../proxy/ClientProxyApiculture.java | 12 +- .../apiculture/proxy/ProxyApiculture.java | 4 +- .../trigger/TriggerMissingDrone.java | 13 +- .../trigger/TriggerMissingQueen.java | 11 +- .../apiculture/trigger/TriggerNoFrames.java | 9 +- .../worldgen/ComponentVillageBeeHouse.java | 68 +- .../gadgets/ForestryBlockLeaves.java | 8 +- .../arboriculture/gadgets/TileLeaves.java | 90 +- .../gadgets/TileTreeContainer.java | 47 +- .../genetics/AlleleTreeSpecies.java | 2 +- .../forestry/arboriculture/genetics/Tree.java | 27 +- .../arboriculture/genetics/TreeHelper.java | 32 +- .../arboriculture/genetics/TreeMutation.java | 6 - .../java/forestry/core/EnumErrorCode.java | 9 +- .../forestry/core/ErrorStateRegistry.java | 98 ++ .../java/forestry/core/EventHandlerCore.java | 3 +- src/main/java/forestry/core/ForestryCore.java | 6 +- src/main/java/forestry/core/GuiHandler.java | 8 +- .../java/forestry/core/GuiHandlerBase.java | 23 +- .../java/forestry/core/WorldGenerator.java | 1 - .../forestry/core/circuits/CircuitBoard.java | 33 +- .../core/circuits/ItemSolderingIron.java | 2 +- .../java/forestry/core/config/Config.java | 2 + .../core/delegates/AccessHandler.java | 149 +++ .../forestry/core/delegates/ErrorLogic.java | 75 ++ .../core/delegates/FakeAccessHandler.java | 83 ++ .../core/delegates/FakeErrorLogic.java | 64 + .../FakeErrorSource.java} | 60 +- .../forestry/core/fluids/FakeTankManager.java | 83 ++ .../forestry/core/fluids/ITankManager.java | 31 + .../forestry/core/fluids/TankManager.java | 15 +- .../java/forestry/core/gadgets/BlockBase.java | 37 +- .../forestry/core/gadgets/BlockForestry.java | 49 +- .../forestry/core/gadgets/BlockStructure.java | 89 +- .../java/forestry/core/gadgets/Engine.java | 6 +- .../forestry/core/gadgets/StructureLogic.java | 197 --- .../forestry/core/gadgets/TileAnalyzer.java | 10 +- .../java/forestry/core/gadgets/TileBase.java | 5 - .../forestry/core/gadgets/TileForestry.java | 291 +---- .../core/gadgets/TileNaturalistChest.java | 4 +- .../forestry/core/gadgets/TilePowered.java | 7 +- .../java/forestry/core/genetics/Genome.java | 1 + .../core/genetics/IGeneticDefinition.java | 1 - .../core/genetics/IndividualLiving.java | 2 - .../core/gui/ContainerLiquidTanks.java | 13 +- .../forestry/core/gui/ContainerSocketed.java | 5 +- .../java/forestry/core/gui/ContainerTile.java | 57 +- .../java/forestry/core/gui/ErrorLedger.java | 5 +- .../java/forestry/core/gui/GuiForestry.java | 16 +- .../forestry/core/gui/GuiForestryTitled.java | 12 +- .../java/forestry/core/gui/HintLedger.java | 5 +- src/main/java/forestry/core/gui/Ledger.java | 13 +- .../java/forestry/core/gui/LedgerManager.java | 78 +- .../java/forestry/core/gui/OwnerLedger.java | 52 +- .../forestry/core/gui/widgets/TankWidget.java | 11 +- ...trictedAccess.java => IAccessHandler.java} | 8 +- .../core/interfaces/IActivatable.java | 5 + .../forestry/core/interfaces/IClimatised.java | 1 - .../core/interfaces/ILiquidTankContainer.java | 4 +- .../forestry/core/interfaces/IOwnable.java | 4 +- .../interfaces/IRestrictedAccessTile.java} | 45 +- .../forestry/core/interfaces/ITitled.java | 5 + .../inventory/AdjacentInventoryCache.java | 4 + .../core/inventory/AlyzerInventory.java | 2 +- .../forestry/core/inventory/InvTools.java | 41 +- .../core/inventory/InventoryAdapter.java | 2 +- .../inventory/InventoryAdapterRestricted.java | 66 + .../core/inventory/TileInventoryAdapter.java | 7 +- .../core/multiblock/BlockMultiblockBase.java | 15 + .../core/multiblock/CoordTriplet.java | 168 +++ .../core/multiblock/IMultiblockPart.java | 193 +++ .../java/forestry/core/multiblock/LICENSE.txt | 21 + .../MultiblockClientTickHandler.java | 16 + .../multiblock/MultiblockControllerBase.java | 1132 +++++++++++++++++ .../multiblock/MultiblockEventHandler.java | 31 + .../core/multiblock/MultiblockRegistry.java | 128 ++ .../MultiblockServerTickHandler.java | 23 + .../multiblock/MultiblockTileEntityBase.java | 520 ++++++++ .../MultiblockValidationException.java | 13 + .../multiblock/MultiblockWorldRegistry.java | 415 ++++++ .../multiblock/rectangular/PartPosition.java | 28 + .../RectangularMultiblockControllerBase.java | 124 ++ .../RectangularMultiblockTileEntityBase.java | 105 ++ .../forestry/core/network/ILocatedPacket.java | 2 + .../network/IStreamableGui.java} | 45 +- .../core/network/PacketErrorUpdate.java | 19 +- ...ileGuiOpened.java => PacketGuiUpdate.java} | 21 +- .../forestry/core/network/PacketHandler.java | 27 +- .../java/forestry/core/network/PacketId.java | 6 +- .../core/network/PacketSocketUpdate.java | 4 +- .../core/proxy/ClientProxyCommon.java | 12 + .../core/proxy/ClientProxyRender.java | 14 - .../java/forestry/core/proxy/ProxyCommon.java | 6 + .../java/forestry/core/proxy/ProxyRender.java | 4 - .../forestry/core/utils/GeneticsUtil.java | 3 +- src/main/java/forestry/core/utils/Utils.java | 99 +- src/main/java/forestry/core/vect/IVect.java | 4 + .../java/forestry/core/vect/MutableVect.java | 32 + src/main/java/forestry/core/vect/Vect.java | 14 + .../forestry/energy/GuiHandlerEnergy.java | 16 +- .../circuits/CircuitElectricChange.java | 12 +- .../energy/circuits/CircuitFireDampener.java | 12 +- .../forestry/energy/gadgets/EngineBronze.java | 9 +- .../forestry/energy/gadgets/EngineCopper.java | 4 +- .../forestry/energy/gadgets/EngineTin.java | 12 +- .../energy/gadgets/MachineGenerator.java | 23 +- .../java/forestry/factory/DummyManagers.java | 21 - .../forestry/factory/GuiHandlerFactory.java | 40 +- .../factory/gadgets/MachineBottler.java | 19 +- .../factory/gadgets/MachineCarpenter.java | 37 +- .../factory/gadgets/MachineCentrifuge.java | 44 +- .../factory/gadgets/MachineFabricator.java | 24 +- .../factory/gadgets/MachineFermenter.java | 24 +- .../factory/gadgets/MachineMoistener.java | 55 +- .../factory/gadgets/MachineRaintank.java | 31 +- .../factory/gadgets/MachineSqueezer.java | 26 +- .../factory/gadgets/MachineStill.java | 28 +- .../forestry/factory/gui/GuiWorktable.java | 2 +- .../java/forestry/farming/FarmHelper.java | 39 +- .../java/forestry/farming/FarmTarget.java | 13 +- .../forestry/farming/GuiHandlerFarming.java | 6 +- .../farming/circuits/CircuitFarmLogic.java | 24 +- .../farming/gadgets/StructureLogicFarm.java | 129 +- .../forestry/farming/gadgets/TileControl.java | 115 -- .../forestry/farming/gadgets/TileFarm.java | 266 ---- .../farming/gadgets/TileFarmPlain.java | 1019 --------------- .../forestry/farming/gadgets/TileHatch.java | 111 -- .../forestry/farming/gui/ContainerFarm.java | 53 +- .../java/forestry/farming/gui/FarmLedger.java | 61 + .../java/forestry/farming/gui/GuiFarm.java | 123 +- .../gui/IFarmLedgerDelegate.java} | 44 +- .../forestry/farming/items/ItemFarmBlock.java | 4 +- .../farming/logic/CropBasicAgriCraft.java | 2 +- .../forestry/farming/logic/FarmLogic.java | 4 +- .../farming/logic/FarmLogicArboreal.java | 7 +- .../farming/logic/FarmLogicCocoa.java | 5 +- .../farming/logic/FarmLogicCrops.java | 7 +- .../farming/logic/FarmLogicEnder.java | 7 +- .../farming/logic/FarmLogicGourd.java | 7 +- .../farming/logic/FarmLogicHomogeneous.java | 13 +- .../farming/logic/FarmLogicInfernal.java | 7 +- .../farming/logic/FarmLogicOrchard.java | 7 +- .../forestry/farming/logic/FarmLogicPeat.java | 5 +- .../farming/logic/FarmLogicPoale.java | 7 +- .../farming/logic/FarmLogicRubber.java | 7 +- .../farming/logic/FarmLogicSucculent.java | 7 +- .../farming/logic/FarmLogicWatered.java | 16 +- .../{gadgets => multiblock}/BlockFarm.java | 23 +- .../EnumFarmBlockTexture.java} | 14 +- .../multiblock/FakeFarmController.java | 280 ++++ .../farming/multiblock/FarmController.java | 850 +++++++++++++ .../multiblock/FarmFertilizerManager.java | 91 ++ .../multiblock/FarmHydrationManager.java | 110 ++ .../farming/multiblock/FarmInventory.java | 248 ++++ .../farming/multiblock/IFarmController.java | 29 + .../farming/multiblock/TileControl.java | 71 ++ .../forestry/farming/multiblock/TileFarm.java | 219 ++++ .../farming/multiblock/TileFarmPlain.java | 36 + .../{gadgets => multiblock}/TileGearbox.java | 45 +- .../farming/multiblock/TileHatch.java | 93 ++ .../{gadgets => multiblock}/TileValve.java | 64 +- .../farming/render/FarmItemRenderer.java | 6 +- .../farming/render/FarmRenderingHandler.java | 2 +- .../farming/triggers/FarmingTriggers.java | 26 +- .../triggers/TriggerLowFertilizer.java | 15 +- .../farming/triggers/TriggerLowGermlings.java | 15 +- .../farming/triggers/TriggerLowLiquid.java | 23 +- .../farming/triggers/TriggerLowSoil.java | 20 +- .../lepidopterology/ButterflySpawner.java | 2 +- .../entities/AIButterflyPollinate.java | 4 +- .../lepidopterology/genetics/Butterfly.java | 15 +- .../java/forestry/mail/GuiHandlerMail.java | 16 +- .../forestry/mail/gadgets/MachineMailbox.java | 4 +- .../forestry/mail/gadgets/MachineTrader.java | 39 +- .../forestry/mail/gui/ContainerMailbox.java | 6 +- .../java/forestry/mail/gui/GuiTrader.java | 2 +- .../java/forestry/mail/items/ItemLetter.java | 2 +- .../forestry/plugins/PluginApiculture.java | 55 +- .../java/forestry/plugins/PluginEnergy.java | 1 - .../java/forestry/plugins/PluginFarming.java | 24 +- .../forestry/plugins/PluginHarvestCraft.java | 2 +- .../java/forestry/plugins/PluginNatura.java | 2 +- .../forestry/plugins/PluginPlantMegaPack.java | 5 +- .../java/forestry/plugins/PluginStorage.java | 12 +- .../forestry/storage/BackpackDefinition.java | 8 +- .../java/forestry/storage/CrateRegistry.java | 1 - .../config/forestry/hints.properties | 39 +- 259 files changed, 10117 insertions(+), 6495 deletions(-) create mode 100644 src/main/java/forestry/apiculture/BeeHousingInventory.java create mode 100644 src/main/java/forestry/apiculture/BeeHousingListener.java create mode 100644 src/main/java/forestry/apiculture/BeeHousingModifier.java create mode 100644 src/main/java/forestry/apiculture/FakeBeekeepingLogic.java create mode 100644 src/main/java/forestry/apiculture/HasFlowersCache.java delete mode 100644 src/main/java/forestry/apiculture/gadgets/StructureLogicAlveary.java delete mode 100755 src/main/java/forestry/apiculture/gadgets/TileAlveary.java delete mode 100755 src/main/java/forestry/apiculture/gadgets/TileAlvearyPlain.java delete mode 100755 src/main/java/forestry/apiculture/gadgets/TileAlvearySieve.java delete mode 100755 src/main/java/forestry/apiculture/gadgets/TileAlvearyStabiliser.java create mode 100644 src/main/java/forestry/apiculture/gadgets/TileBeeHousing.java mode change 100755 => 100644 src/main/java/forestry/apiculture/genetics/Bee.java mode change 100755 => 100644 src/main/java/forestry/apiculture/genetics/BeeMutation.java rename src/main/java/forestry/apiculture/gui/{ContainerApiary.java => ContainerBeeHousing.java} (67%) mode change 100755 => 100644 rename src/main/java/forestry/apiculture/gui/{GuiApiary.java => GuiBeeHousing.java} (76%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/apiculture/multiblock/AlvearyController.java create mode 100644 src/main/java/forestry/apiculture/multiblock/FakeAlvearyController.java create mode 100644 src/main/java/forestry/apiculture/multiblock/IAlvearyController.java create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlveary.java rename src/main/java/forestry/apiculture/{gadgets => multiblock}/TileAlvearyClimatiser.java (63%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlvearyFan.java create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlvearyHeater.java rename src/main/java/forestry/apiculture/{gadgets => multiblock}/TileAlvearyHygroregulator.java (80%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlvearyPlain.java create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlvearySieve.java create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlvearyStabiliser.java rename src/main/java/forestry/apiculture/{gadgets => multiblock}/TileAlvearySwarmer.java (74%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/apiculture/multiblock/TileAlvearyWithGui.java create mode 100644 src/main/java/forestry/apiculture/network/PacketBeekeepingLogicActive.java create mode 100644 src/main/java/forestry/core/ErrorStateRegistry.java create mode 100644 src/main/java/forestry/core/delegates/AccessHandler.java create mode 100644 src/main/java/forestry/core/delegates/ErrorLogic.java create mode 100644 src/main/java/forestry/core/delegates/FakeAccessHandler.java create mode 100644 src/main/java/forestry/core/delegates/FakeErrorLogic.java rename src/main/java/forestry/core/{utils/DelayTimer.java => delegates/FakeErrorSource.java} (57%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/core/fluids/FakeTankManager.java create mode 100644 src/main/java/forestry/core/fluids/ITankManager.java delete mode 100755 src/main/java/forestry/core/gadgets/StructureLogic.java rename src/main/java/forestry/core/interfaces/{IRestrictedAccess.java => IAccessHandler.java} (81%) rename src/main/java/forestry/{apiculture/gadgets/TileAlvearyHeater.java => core/interfaces/IRestrictedAccessTile.java} (64%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/core/interfaces/ITitled.java create mode 100644 src/main/java/forestry/core/inventory/InventoryAdapterRestricted.java create mode 100644 src/main/java/forestry/core/multiblock/BlockMultiblockBase.java create mode 100644 src/main/java/forestry/core/multiblock/CoordTriplet.java create mode 100644 src/main/java/forestry/core/multiblock/IMultiblockPart.java create mode 100644 src/main/java/forestry/core/multiblock/LICENSE.txt create mode 100644 src/main/java/forestry/core/multiblock/MultiblockClientTickHandler.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockControllerBase.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockEventHandler.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockRegistry.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockServerTickHandler.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockTileEntityBase.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockValidationException.java create mode 100644 src/main/java/forestry/core/multiblock/MultiblockWorldRegistry.java create mode 100644 src/main/java/forestry/core/multiblock/rectangular/PartPosition.java create mode 100644 src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockControllerBase.java create mode 100644 src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockTileEntityBase.java rename src/main/java/forestry/{apiculture/gadgets/TileAlvearyFan.java => core/network/IStreamableGui.java} (63%) mode change 100755 => 100644 rename src/main/java/forestry/core/network/{PacketTileGuiOpened.java => PacketGuiUpdate.java} (66%) mode change 100755 => 100644 src/main/java/forestry/core/network/PacketHandler.java delete mode 100755 src/main/java/forestry/farming/gadgets/TileControl.java delete mode 100755 src/main/java/forestry/farming/gadgets/TileFarm.java delete mode 100755 src/main/java/forestry/farming/gadgets/TileFarmPlain.java delete mode 100755 src/main/java/forestry/farming/gadgets/TileHatch.java create mode 100644 src/main/java/forestry/farming/gui/FarmLedger.java rename src/main/java/forestry/{core/interfaces/IErrorSource.java => farming/gui/IFarmLedgerDelegate.java} (69%) mode change 100755 => 100644 rename src/main/java/forestry/farming/{gadgets => multiblock}/BlockFarm.java (91%) mode change 100755 => 100644 rename src/main/java/forestry/farming/{gadgets/EnumFarmBlock.java => multiblock/EnumFarmBlockTexture.java} (88%) create mode 100644 src/main/java/forestry/farming/multiblock/FakeFarmController.java create mode 100644 src/main/java/forestry/farming/multiblock/FarmController.java create mode 100644 src/main/java/forestry/farming/multiblock/FarmFertilizerManager.java create mode 100644 src/main/java/forestry/farming/multiblock/FarmHydrationManager.java create mode 100644 src/main/java/forestry/farming/multiblock/FarmInventory.java create mode 100644 src/main/java/forestry/farming/multiblock/IFarmController.java create mode 100644 src/main/java/forestry/farming/multiblock/TileControl.java create mode 100644 src/main/java/forestry/farming/multiblock/TileFarm.java create mode 100644 src/main/java/forestry/farming/multiblock/TileFarmPlain.java rename src/main/java/forestry/farming/{gadgets => multiblock}/TileGearbox.java (82%) create mode 100644 src/main/java/forestry/farming/multiblock/TileHatch.java rename src/main/java/forestry/farming/{gadgets => multiblock}/TileValve.java (56%) mode change 100755 => 100644 diff --git a/api/forestry b/api/forestry index 53f418f4a..9189ad7be 160000 --- a/api/forestry +++ b/api/forestry @@ -1 +1 @@ -Subproject commit 53f418f4a4808272ec18bd224dbd5c2c8ea8cfed +Subproject commit 9189ad7be65a709f4407c0d15ea4372ec220880f diff --git a/application.properties b/application.properties index a2fd90419..32b268bb2 100644 --- a/application.properties +++ b/application.properties @@ -1,5 +1,5 @@ mcversion=1.7.10 forgeversion=10.13.3.1370-1.7.10 -version_major=3 -version_minor=7 +version_major=4 +version_minor=0 version_patch=0 diff --git a/lang b/lang index 5dddc3658..c7ca8074d 160000 --- a/lang +++ b/lang @@ -1 +1 @@ -Subproject commit 5dddc3658aba30d105ea73aed626cfc47151aa02 +Subproject commit c7ca8074d09ad1983db35b4caf25c159fd63f549 diff --git a/src/main/java/forestry/apiculture/BeeHousingInventory.java b/src/main/java/forestry/apiculture/BeeHousingInventory.java new file mode 100644 index 000000000..18f2b8754 --- /dev/null +++ b/src/main/java/forestry/apiculture/BeeHousingInventory.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.inventory.InvTools; +import forestry.core.inventory.InventoryAdapterRestricted; +import forestry.core.utils.GuiUtil; + +public class BeeHousingInventory extends InventoryAdapterRestricted implements IBeeHousingInventory { + public static final int SLOT_QUEEN = 0; + public static final int SLOT_DRONE = 1; + public static final int SLOT_PRODUCT_1 = 2; + public static final int SLOT_PRODUCT_COUNT = 7; + + public BeeHousingInventory(int size, String name, IAccessHandler accessHandler) { + super(size, name, accessHandler); + } + + @Override + public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { + EnumBeeType beeType = BeeManager.beeRoot.getType(itemStack); + + if (slotIndex == SLOT_QUEEN) { + return beeType == EnumBeeType.QUEEN || beeType == EnumBeeType.PRINCESS; + } else if (slotIndex == SLOT_DRONE) { + return beeType == EnumBeeType.DRONE; + } + return false; + } + + @Override + public boolean canExtractItem(int slotIndex, ItemStack itemstack, int side) { + if (!super.canExtractItem(slotIndex, itemstack, side)) { + return false; + } + return GuiUtil.isIndexInRange(slotIndex, SLOT_PRODUCT_1, SLOT_PRODUCT_COUNT); + } + + @Override + public final ItemStack getQueen() { + return getStackInSlot(SLOT_QUEEN); + } + + @Override + public final ItemStack getDrone() { + return getStackInSlot(SLOT_DRONE); + } + + @Override + public final void setQueen(ItemStack itemstack) { + setInventorySlotContents(SLOT_QUEEN, itemstack); + } + + @Override + public final void setDrone(ItemStack itemstack) { + setInventorySlotContents(SLOT_DRONE, itemstack); + } + + @Override + public final boolean addProduct(ItemStack product, boolean all) { + return InvTools.tryAddStack(this, product, SLOT_PRODUCT_1, SLOT_PRODUCT_COUNT, all, true); + } + +} diff --git a/src/main/java/forestry/apiculture/BeeHousingListener.java b/src/main/java/forestry/apiculture/BeeHousingListener.java new file mode 100644 index 000000000..f24d8deb1 --- /dev/null +++ b/src/main/java/forestry/apiculture/BeeHousingListener.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeListener; +import forestry.api.genetics.IIndividual; + +public class BeeHousingListener implements IBeeListener { + private final IBeeHousing beeHousing; + + public BeeHousingListener(IBeeHousing beeHousing) { + this.beeHousing = beeHousing; + } + + @Override + public void wearOutEquipment(int amount) { + for (IBeeListener beeListener : beeHousing.getBeeListeners()) { + beeListener.wearOutEquipment(amount); + } + } + + @Override + public void onQueenDeath() { + for (IBeeListener beeListener : beeHousing.getBeeListeners()) { + beeListener.onQueenDeath(); + } + } + + @Override + public boolean onPollenRetrieved(IIndividual pollen) { + for (IBeeListener beeListener : beeHousing.getBeeListeners()) { + if (beeListener.onPollenRetrieved(pollen)) { + return true; + } + } + + return false; + } + +} diff --git a/src/main/java/forestry/apiculture/BeeHousingModifier.java b/src/main/java/forestry/apiculture/BeeHousingModifier.java new file mode 100644 index 000000000..ede25600b --- /dev/null +++ b/src/main/java/forestry/apiculture/BeeHousingModifier.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; + +public class BeeHousingModifier implements IBeeModifier { + private final IBeeHousing beeHousing; + + public BeeHousingModifier(IBeeHousing beeHousing) { + this.beeHousing = beeHousing; + } + + @Override + public float getTerritoryModifier(IBeeGenome genome, final float currentModifier) { + float modifierValue = 1.0f; + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + modifierValue *= modifier.getTerritoryModifier(genome, modifierValue * currentModifier); + } + return modifierValue; + } + + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, final float currentModifier) { + float modifierValue = 1.0f; + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + modifierValue *= modifier.getMutationModifier(genome, mate, modifierValue * currentModifier); + } + return modifierValue; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, final float currentModifier) { + float modifierValue = 1.0f; + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + modifierValue *= modifier.getLifespanModifier(genome, mate, modifierValue * currentModifier); + } + return modifierValue; + } + + @Override + public float getProductionModifier(IBeeGenome genome, final float currentModifier) { + float modifierValue = 1.0f; + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + modifierValue *= modifier.getProductionModifier(genome, modifierValue * currentModifier); + } + return modifierValue; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, final float currentModifier) { + float modifierValue = 1.0f; + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + modifierValue *= modifier.getFloweringModifier(genome, modifierValue * currentModifier); + } + return modifierValue; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, final float currentModifier) { + float modifierValue = 1.0f; + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + modifierValue *= modifier.getGeneticDecay(genome, modifierValue * currentModifier); + } + return modifierValue; + } + + @Override + public boolean isSealed() { + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + if (modifier.isSealed()) { + return true; + } + } + return false; + } + + @Override + public boolean isSelfLighted() { + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + if (modifier.isSelfLighted()) { + return true; + } + } + return false; + } + + @Override + public boolean isSunlightSimulated() { + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + if (modifier.isSunlightSimulated()) { + return true; + } + } + return false; + } + + @Override + public boolean isHellish() { + for (IBeeModifier modifier : beeHousing.getBeeModifiers()) { + if (modifier.isHellish()) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/forestry/apiculture/BeekeepingLogic.java b/src/main/java/forestry/apiculture/BeekeepingLogic.java index 561ed71b7..b9ce832f6 100755 --- a/src/main/java/forestry/apiculture/BeekeepingLogic.java +++ b/src/main/java/forestry/apiculture/BeekeepingLogic.java @@ -10,6 +10,9 @@ ******************************************************************************/ package forestry.apiculture; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Set; import java.util.Stack; @@ -17,76 +20,97 @@ import java.util.Stack; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; import forestry.api.apiculture.BeeManager; import forestry.api.apiculture.EnumBeeType; import forestry.api.apiculture.IApiaristTracker; import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.IErrorLogic; import forestry.api.core.IErrorState; import forestry.api.genetics.IEffectData; import forestry.api.genetics.IIndividual; +import forestry.apiculture.network.PacketBeekeepingLogicActive; import forestry.core.EnumErrorCode; import forestry.core.config.Defaults; import forestry.core.config.ForestryItem; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.IStreamable; import forestry.core.proxy.Proxies; import forestry.plugins.PluginApiculture; -public class BeekeepingLogic implements IBeekeepingLogic { +public class BeekeepingLogic implements IBeekeepingLogic, IStreamable { - private static final int MAX_POLLINATION_ATTEMPTS = 20; private static final int totalBreedingTime = Defaults.APIARY_BREEDING_TIME; - private static final int ticksPerCheckQueenCanWork = 10; private final IBeeHousing housing; - private final boolean housingSupportsMultipleErrorStates; + private final IBeeModifier beeModifier; + private final IBeeListener beeListener; + + private int beeProgress; + private int beeProgressMax; - // Breeding - private int breedingTime; private int queenWorkCycleThrottle; private IEffectData effectData[] = new IEffectData[2]; - private IBee queen; - private IIndividual pollen; - private int attemptedPollinations = 0; + private final Stack spawn = new Stack(); - // Cached flowers check - private boolean hasFlowersCached = false; - private int hasFlowersCooldown = 0; - private Set queenCanWorkCached = Collections.emptySet(); - private int queenCanWorkCooldown = 0; + private final HasFlowersCache hasFlowersCache = new HasFlowersCache(); + private final QueenCanWorkCache queenCanWorkCache = new QueenCanWorkCache(); + private final PollenHandler pollenHandler = new PollenHandler(); + + // Client + private boolean active; + private IBee queen; + private ItemStack queenStack; // used to detect server changes and sync clientQueen public BeekeepingLogic(IBeeHousing housing) { this.housing = housing; - - Set errorStateSet = null; - try { - errorStateSet = housing.getErrorStates(); - } catch (Throwable ignored) { - } - - housingSupportsMultipleErrorStates = (errorStateSet != null); + this.beeModifier = new BeeHousingModifier(housing); + this.beeListener = new BeeHousingListener(housing); } // / SAVING & LOADING @Override public void readFromNBT(NBTTagCompound nbttagcompound) { - breedingTime = nbttagcompound.getInteger("BreedingTime"); + beeProgress = nbttagcompound.getInteger("BreedingTime"); queenWorkCycleThrottle = nbttagcompound.getInteger("Throttle"); + NBTTagCompound queenNBT = nbttagcompound.getCompoundTag("queen"); + queenStack = ItemStack.loadItemStackFromNBT(queenNBT); + queen = BeeManager.beeRoot.getMember(queenStack); + + setActive(nbttagcompound.getBoolean("Active")); + + hasFlowersCache.readFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Offspring", 10); for (int i = 0; i < nbttaglist.tagCount(); i++) { spawn.add(ItemStack.loadItemStackFromNBT(nbttaglist.getCompoundTagAt(i))); } - } @Override public void writeToNBT(NBTTagCompound nbttagcompound) { - nbttagcompound.setInteger("BreedingTime", breedingTime); + nbttagcompound.setInteger("BreedingTime", beeProgress); nbttagcompound.setInteger("Throttle", queenWorkCycleThrottle); + if (queenStack != null) { + NBTTagCompound queenNBT = new NBTTagCompound(); + queenStack.writeToNBT(queenNBT); + nbttagcompound.setTag("queen", queenNBT); + } + + nbttagcompound.setBoolean("Active", active); + + hasFlowersCache.writeToNBT(nbttagcompound); + Stack spawnCopy = new Stack(); spawnCopy.addAll(spawn); NBTTagList nbttaglist = new NBTTagList(); @@ -96,108 +120,112 @@ public class BeekeepingLogic implements IBeekeepingLogic { nbttaglist.appendTag(nbttagcompound1); } nbttagcompound.setTag("Offspring", nbttaglist); - - } - - // / STATE INFORMATION - @Override - public int getBreedingTime() { - return this.breedingTime; } @Override - public int getTotalBreedingTime() { - return totalBreedingTime; + public void writeData(DataOutputStreamForestry data) throws IOException { + data.writeBoolean(active); + if (active) { + data.writeItemStack(queenStack); + } } @Override - public IBee getQueen() { - return this.queen; + public void readData(DataInputStreamForestry data) throws IOException { + boolean active = data.readBoolean(); + setActive(active); + if (active) { + queenStack = data.readItemStack(); + queen = BeeManager.beeRoot.getMember(queenStack); + } } - @Override - public IBeeHousing getHousing() { - return this.housing; + /* Activatable */ + private void setActive(boolean active) { + if (this.active == active) { + return; + } + this.active = active; + + if (!housing.getWorld().isRemote) { + Proxies.net.sendNetworkPacket(new PacketBeekeepingLogicActive(housing)); + } } - @Override - public IEffectData[] getEffectData() { - return this.effectData; + public boolean isActive() { + return active; } /* UPDATING */ @Override public boolean canWork() { - if (housingSupportsMultipleErrorStates) { - Set errorStates = housing.getErrorStates(); - for (IErrorState errorState : errorStates) { - housing.setErrorCondition(false, errorState); + + IErrorLogic errorLogic = housing.getErrorLogic(); + errorLogic.clearErrors(); + + IBeeHousingInventory beeInventory = housing.getBeeInventory(); + + boolean hasSpace = addPendingProducts(beeInventory, spawn); + errorLogic.setCondition(!hasSpace, EnumErrorCode.NOSPACE); + + ItemStack queenStack = beeInventory.getQueen(); + + // check if we're breeding + if (ForestryItem.beePrincessGE.isItemEqual(queenStack)) { + boolean hasDrone = BeeManager.beeRoot.isDrone(beeInventory.getDrone()); + errorLogic.setCondition(!hasDrone, EnumErrorCode.NODRONE); + + setActive(false); // not active (no bee FX) when we are breeding + return !errorLogic.hasErrors(); + } + + if (ForestryItem.beeQueenGE.isItemEqual(queenStack)) { + if (!isQueenAlive(queenStack)) { + IBee dyingQueen = BeeManager.beeRoot.getMember(queenStack); + Collection spawned = killQueen(dyingQueen, housing, beeListener); + spawn.addAll(spawned); + queenStack = null; } + } else { + queenStack = null; } - boolean hasSpace = addPendingProducts(); - - if (hasBreedablePrincess()) { - return hasSpace; + if (!ItemStack.areItemStacksEqual(this.queenStack, queenStack)) { + this.queen = BeeManager.beeRoot.getMember(queenStack); + this.queenStack = queenStack; } - if (hasHealthyQueen()) { - boolean canWork = queenCanWork(); - boolean hasFlowers = hasFlowers(); - return hasSpace && canWork && hasFlowers; + if (errorLogic.setCondition(queen == null, EnumErrorCode.NOQUEEN)) { + setActive(false); + return false; } - return false; + Set queenErrors = queenCanWorkCache.queenCanWork(queen, housing); + for (IErrorState errorState : queenErrors) { + errorLogic.setCondition(true, errorState); + } + + boolean hasFlowers = hasFlowersCache.hasFlowers(queen, housing); + errorLogic.setCondition(!hasFlowers, EnumErrorCode.NOFLOWER); + + boolean canWork = !errorLogic.hasErrors(); + setActive(canWork); + return canWork; } @Override public void doWork() { - if (hasBreedablePrincess()) { + IBeeHousingInventory beeInventory = housing.getBeeInventory(); + ItemStack queenStack = beeInventory.getQueen(); + if (ForestryItem.beePrincessGE.isItemEqual(queenStack)) { tickBreed(); - } else if (queen != null) { - queenWorkTick(); - } - } - - @Override - public void update() { - if (canWork()) { - doWork(); - } - } - - private boolean hasFlowers() { - if (queen == null) { - return true; - } - - if (hasFlowersCooldown <= 0) { - hasFlowersCached = queen.hasFlower(housing); - hasFlowersCooldown = PluginApiculture.ticksPerBeeWorkCycle; - - // check more often if we haven't found flowers - if (!hasFlowersCached) { - hasFlowersCooldown /= 2; - } } else { - hasFlowersCooldown--; + queenWorkTick(queen); } - - if (housingSupportsMultipleErrorStates) { - housing.setErrorCondition(!hasFlowersCached, EnumErrorCode.NOFLOWER); - } else { - if (hasFlowersCached) { - housing.setErrorState(EnumErrorCode.OK); - } else { - housing.setErrorState(EnumErrorCode.NOFLOWER); - } - } - - return hasFlowersCached; } - private void queenWorkTick() { + private void queenWorkTick(IBee queen) { if (queen == null) { return; } @@ -210,90 +238,53 @@ public class BeekeepingLogic implements IBeekeepingLogic { if (queenWorkCycleThrottle >= PluginApiculture.ticksPerBeeWorkCycle) { queenWorkCycleThrottle = 0; - doProduction(); + doProduction(queen, housing, beeListener); queen.plantFlowerRandom(housing); - doPollination(); + pollenHandler.doPollination(queen, housing, beeListener); // Age the queen - queen.age(housing.getWorld(), housing.getLifespanModifier(queen.getGenome(), queen.getMate(), 0f)); - updateQueenItemNBT(); + float lifespanModifier = beeModifier.getLifespanModifier(queen.getGenome(), queen.getMate(), 1.0f); + queen.age(housing.getWorld(), lifespanModifier); + + // Write the changed queen back into the item stack. + NBTTagCompound nbttagcompound = new NBTTagCompound(); + queen.writeToNBT(nbttagcompound); + housing.getBeeInventory().getQueen().setTagCompound(nbttagcompound); } + + beeProgress = queen.getHealth(); + beeProgressMax = queen.getMaxHealth(); } - private void doProduction() { - if (queen == null) { - return; - } - + private static void doProduction(IBee queen, IBeeHousing beeHousing, IBeeListener beeListener) { // Produce and add stacks - ItemStack[] products = queen.produceStacks(housing); + ItemStack[] products = queen.produceStacks(beeHousing); if (products == null) { return; } - housing.wearOutEquipment(1); + beeListener.wearOutEquipment(1); + + IBeeHousingInventory beeInventory = beeHousing.getBeeInventory(); + for (ItemStack stack : products) { - housing.addProduct(stack, false); + beeInventory.addProduct(stack, false); } } - private void doPollination() { - if (queen == null) { - return; - } - - // Get pollen if none available yet - if (pollen == null) { - pollen = queen.retrievePollen(housing); - attemptedPollinations = 0; - if (pollen != null) { - if (housing.onPollenRetrieved(queen, pollen, false)) { - pollen = null; - } - } - } - if (pollen != null) { - attemptedPollinations++; - if (queen.pollinateRandom(housing, pollen) || attemptedPollinations >= MAX_POLLINATION_ATTEMPTS) { - pollen = null; - } - } - } - - private void updateQueenItemNBT() { - if (queen == null) { - return; - } - - // Write the changed queen back into the item stack. - NBTTagCompound nbttagcompound = new NBTTagCompound(); - queen.writeToNBT(nbttagcompound); - housing.getQueen().setTagCompound(nbttagcompound); - } - - private boolean addPendingProducts() { - EnumErrorCode housingErrorState = null; + private static boolean addPendingProducts(IBeeHousingInventory beeInventory, Stack spawn) { + boolean housingHasSpace = true; while (!spawn.isEmpty()) { ItemStack next = spawn.peek(); - if (housing.addProduct(next, true)) { + if (beeInventory.addProduct(next, true)) { spawn.pop(); - housingErrorState = EnumErrorCode.OK; } else { - housingErrorState = EnumErrorCode.NOSPACE; + housingHasSpace = false; break; } } - if (housingErrorState != null) { - if (housingSupportsMultipleErrorStates) { - boolean hasSpace = (housingErrorState == EnumErrorCode.OK); - housing.setErrorCondition(!hasSpace, EnumErrorCode.NOSPACE); - } else { - housing.setErrorState(housingErrorState); - } - } - - return housingErrorState != EnumErrorCode.NOSPACE; + return housingHasSpace; } /** Checks if a queen is alive. Much faster than reading the whole bee nbt */ @@ -303,170 +294,68 @@ public class BeekeepingLogic implements IBeekeepingLogic { return health > 0; } - private boolean hasHealthyQueen() { - boolean hasQueen = true; - EnumErrorCode housingErrorState = null; - - ItemStack queenStack = housing.getQueen(); - - if (queenStack == null || !ForestryItem.beeQueenGE.isItemEqual(queenStack)) { - housingErrorState = EnumErrorCode.NOQUEEN; - hasQueen = false; - queen = null; - } else if (!isQueenAlive(queenStack)) { - if (queen == null) { - queen = BeeManager.beeRoot.getMember(queenStack); - } - killQueen(); - housingErrorState = EnumErrorCode.OK; - hasQueen = false; - queen = null; - } - - if (housingSupportsMultipleErrorStates) { - housing.setErrorCondition(!hasQueen, EnumErrorCode.NOQUEEN); - } else { - if (housingErrorState != null) { - housing.setErrorState(housingErrorState); - } - } - - if (hasQueen && queen == null) { - queen = BeeManager.beeRoot.getMember(queenStack); - } - - return hasQueen; - } - - private boolean hasBreedablePrincess() { - boolean isBreedingPrincess = false; - if (ForestryItem.beePrincessGE.isItemEqual(housing.getQueen())) { - boolean hasDrone = ForestryItem.beeDroneGE.isItemEqual(housing.getDrone()); - if (housingSupportsMultipleErrorStates) { - housing.setErrorCondition(!hasDrone, EnumErrorCode.NODRONE); - } else { - if (hasDrone) { - housing.setErrorState(EnumErrorCode.OK); - } else { - housing.setErrorState(EnumErrorCode.NODRONE); - } - } - isBreedingPrincess = true; - } - - return isBreedingPrincess; - } - - private boolean queenCanWork() { - if (queenCanWorkCooldown > 0) { - queenCanWorkCooldown--; - } else { - if (queen == null) { - return false; - } - queenCanWorkCached = checkQueenCanWork(); - queenCanWorkCooldown = ticksPerCheckQueenCanWork; - } - - Set errorStates = queenCanWorkCached; - - if (errorStates.size() > 0) { - if (housingSupportsMultipleErrorStates) { - for (IErrorState errorState : errorStates) { - housing.setErrorCondition(true, errorState); - } - } else { - IErrorState state = errorStates.iterator().next(); - housing.setErrorState(state); - } - return false; - } else { - return true; - } - } - - private Set checkQueenCanWork() { - try { - return queen.getCanWork(housing); - } catch (Throwable ignored) { - // queen might not support getCanWork - } - - IErrorState state = queen.canWork(housing); - if (state != EnumErrorCode.OK) { - return Collections.singleton(state); - } - - return Collections.emptySet(); - } - // / BREEDING private void tickBreed() { - if (!tryBreed()) { - breedingTime = 0; + beeProgressMax = totalBreedingTime; + + IBeeHousingInventory beeInventory = housing.getBeeInventory(); + + ItemStack droneStack = beeInventory.getDrone(); + ItemStack princessStack = beeInventory.getQueen(); + + if (!ForestryItem.beeDroneGE.isItemEqual(droneStack) || !ForestryItem.beePrincessGE.isItemEqual(princessStack)) { + beeProgress = 0; return; } - if (breedingTime < totalBreedingTime) { - breedingTime++; + if (beeProgress < totalBreedingTime) { + beeProgress++; } - if (breedingTime < totalBreedingTime) { + if (beeProgress < totalBreedingTime) { return; } - // Breeding done, create new queen if slot available - if (!ForestryItem.beePrincessGE.isItemEqual(housing.getQueen())) { - return; - } - - // Replace - IBee princess = BeeManager.beeRoot.getMember(housing.getQueen()); - IBee drone = BeeManager.beeRoot.getMember(housing.getDrone()); + // Mate and replace princess with queen + IBee princess = BeeManager.beeRoot.getMember(princessStack); + IBee drone = BeeManager.beeRoot.getMember(droneStack); princess.mate(drone); NBTTagCompound nbttagcompound = new NBTTagCompound(); princess.writeToNBT(nbttagcompound); - ItemStack queen = ForestryItem.beeQueenGE.getItemStack(); - queen.setTagCompound(nbttagcompound); + queenStack = ForestryItem.beeQueenGE.getItemStack(); + queenStack.setTagCompound(nbttagcompound); - housing.setQueen(queen); - housing.onQueenChange(housing.getQueen()); + beeInventory.setQueen(queenStack); // Register the new queen with the breeding tracker - BeeManager.beeRoot.getBreedingTracker(housing.getWorld(), housing.getOwnerName()).registerQueen(princess); + BeeManager.beeRoot.getBreedingTracker(housing.getWorld(), housing.getOwner()).registerQueen(princess); // Remove drone - housing.getDrone().stackSize--; - if (housing.getDrone().stackSize <= 0) { - housing.setDrone(null); + beeInventory.getDrone().stackSize--; + if (beeInventory.getDrone().stackSize <= 0) { + beeInventory.setDrone(null); } // Reset breeding time - breedingTime = 0; + queen = princess; + beeProgress = princess.getHealth(); + beeProgressMax = princess.getMaxHealth(); } - private boolean tryBreed() { - if (housing.getDrone() == null || housing.getQueen() == null) { - return false; - } - - if (!ForestryItem.beeDroneGE.isItemEqual(housing.getDrone()) || !ForestryItem.beePrincessGE.isItemEqual(housing.getQueen())) { - return false; - } - - return housing.canBreed(); - - } - - private void killQueen() { + private static Collection killQueen(IBee queen, IBeeHousing beeHousing, IBeeListener beeListener) { if (queen == null) { - return; + return Collections.emptySet(); } + IBeeHousingInventory beeInventory = beeHousing.getBeeInventory(); + + Collection spawn; + if (queen.canSpawn()) { - spawnOffspring(queen); - housing.getQueen().stackSize = 0; - housing.setQueen(null); + spawn = spawnOffspring(queen, beeHousing); + beeListener.onQueenDeath(); + beeInventory.getQueen().stackSize = 0; + beeInventory.setQueen(null); } else { Proxies.log.warning("Tried to spawn offspring off an unmated queen. Devolving her to a princess."); @@ -475,28 +364,29 @@ public class BeekeepingLogic implements IBeekeepingLogic { queen.writeToNBT(nbttagcompound); convert.setTagCompound(nbttagcompound); - spawn.add(convert); - housing.setQueen(null); + spawn = Collections.singleton(convert); + beeInventory.setQueen(null); } - housing.onQueenChange(housing.getQueen()); + + return spawn; } /** * Creates the succeeding princess and between one and three drones. */ - private void spawnOffspring(IBee queen) { + private static Collection spawnOffspring(IBee queen, IBeeHousing beeHousing) { + + World world = beeHousing.getWorld(); Stack offspring = new Stack(); - IApiaristTracker breedingTracker = BeeManager.beeRoot.getBreedingTracker(housing.getWorld(), housing.getOwnerName()); - - housing.onQueenDeath(getQueen()); + IApiaristTracker breedingTracker = BeeManager.beeRoot.getBreedingTracker(world, beeHousing.getOwner()); // Princess - boolean secondPrincess = this.housing.getWorld().rand.nextInt(10000) < PluginApiculture.getSecondPrincessChance() * 100; + boolean secondPrincess = world.rand.nextInt(10000) < PluginApiculture.getSecondPrincessChance() * 100; int count = secondPrincess ? 2 : 1; while (count > 0) { count--; - IBee heiress = queen.spawnPrincess(housing); + IBee heiress = queen.spawnPrincess(beeHousing); if (heiress != null) { ItemStack princess = BeeManager.beeRoot.getMemberStack(heiress, EnumBeeType.PRINCESS.ordinal()); breedingTracker.registerPrincess(heiress); @@ -505,21 +395,93 @@ public class BeekeepingLogic implements IBeekeepingLogic { } // Drones - IBee[] larvae = queen.spawnDrones(housing); - for (IBee larva : larvae) { - ItemStack drone = BeeManager.beeRoot.getMemberStack(larva, EnumBeeType.DRONE.ordinal()); - breedingTracker.registerDrone(larva); - offspring.push(drone); + IBee[] drones = queen.spawnDrones(beeHousing); + for (IBee drone : drones) { + ItemStack droneStack = BeeManager.beeRoot.getMemberStack(drone, EnumBeeType.DRONE.ordinal()); + breedingTracker.registerDrone(drone); + offspring.push(droneStack); } + IBeeHousingInventory beeInventory = beeHousing.getBeeInventory(); + + Collection spawn = new ArrayList(); + while (!offspring.isEmpty()) { ItemStack spawned = offspring.pop(); - if (!housing.addProduct(spawned, true)) { + if (!beeInventory.addProduct(spawned, true)) { spawn.add(spawned); } } - housing.onPostQueenDeath(getQueen()); - + return spawn; } + + /* CLIENT */ + + @Override + public int getBeeProgressPercent() { + if (beeProgressMax == 0) { + return 0; + } + + return Math.round(beeProgress * 100f / beeProgressMax); + } + + @Override + public boolean canDoBeeFX() { + return active; + } + + @Override + public void doBeeFX() { + if (queen != null) { + queen.doFX(effectData, housing); + } + } + + private static class QueenCanWorkCache { + private static final int ticksPerCheckQueenCanWork = 10; + + private Set queenCanWorkCached = Collections.emptySet(); + private int queenCanWorkCooldown = 0; + + public Set queenCanWork(IBee queen, IBeeHousing beeHousing) { + if (queenCanWorkCooldown <= 0) { + queenCanWorkCached = queen.getCanWork(beeHousing); + queenCanWorkCooldown = ticksPerCheckQueenCanWork; + } else { + queenCanWorkCooldown--; + } + + return queenCanWorkCached; + } + } + + private static class PollenHandler { + private static final int MAX_POLLINATION_ATTEMPTS = 20; + + private IIndividual pollen; + private int attemptedPollinations = 0; + + public void doPollination(IBee queen, IBeeHousing beeHousing, IBeeListener beeListener) { + // Get pollen if none available yet + if (pollen == null) { + attemptedPollinations = 0; + pollen = queen.retrievePollen(beeHousing); + if (pollen != null) { + if (beeListener.onPollenRetrieved(pollen)) { + pollen = null; + } + } + } + + if (pollen != null) { + attemptedPollinations++; + if (queen.pollinateRandom(beeHousing, pollen) || attemptedPollinations >= MAX_POLLINATION_ATTEMPTS) { + pollen = null; + } + } + } + } + } diff --git a/src/main/java/forestry/apiculture/FakeBeekeepingLogic.java b/src/main/java/forestry/apiculture/FakeBeekeepingLogic.java new file mode 100644 index 000000000..4d0338125 --- /dev/null +++ b/src/main/java/forestry/apiculture/FakeBeekeepingLogic.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.apiculture.IBeekeepingLogic; + +public class FakeBeekeepingLogic implements IBeekeepingLogic { + public static final FakeBeekeepingLogic instance = new FakeBeekeepingLogic(); + + private FakeBeekeepingLogic() { + + } + + @Override + public boolean canWork() { + return false; + } + + @Override + public void doWork() { + + } + + @Override + public int getBeeProgressPercent() { + return 0; + } + + @Override + public boolean canDoBeeFX() { + return false; + } + + @Override + public void doBeeFX() { + + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + } +} diff --git a/src/main/java/forestry/apiculture/GuiHandlerApiculture.java b/src/main/java/forestry/apiculture/GuiHandlerApiculture.java index b294c33a8..ecaac7826 100755 --- a/src/main/java/forestry/apiculture/GuiHandlerApiculture.java +++ b/src/main/java/forestry/apiculture/GuiHandlerApiculture.java @@ -15,10 +15,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.World; import forestry.api.apiculture.BeeManager; -import forestry.apiculture.gadgets.TileAlvearyHygroregulator; -import forestry.apiculture.gadgets.TileAlvearyPlain; -import forestry.apiculture.gadgets.TileAlvearySieve; -import forestry.apiculture.gadgets.TileAlvearySwarmer; import forestry.apiculture.gadgets.TileApiary; import forestry.apiculture.gadgets.TileBeehouse; import forestry.apiculture.genetics.BeeHelper; @@ -26,20 +22,24 @@ import forestry.apiculture.gui.ContainerAlveary; import forestry.apiculture.gui.ContainerAlvearyHygroregulator; import forestry.apiculture.gui.ContainerAlvearySieve; import forestry.apiculture.gui.ContainerAlvearySwarmer; -import forestry.apiculture.gui.ContainerApiary; +import forestry.apiculture.gui.ContainerBeeHousing; import forestry.apiculture.gui.ContainerHabitatLocator; import forestry.apiculture.gui.ContainerImprinter; import forestry.apiculture.gui.GuiAlveary; import forestry.apiculture.gui.GuiAlvearyHygroregulator; import forestry.apiculture.gui.GuiAlvearySieve; import forestry.apiculture.gui.GuiAlvearySwarmer; -import forestry.apiculture.gui.GuiApiary; +import forestry.apiculture.gui.GuiBeeHousing; import forestry.apiculture.gui.GuiBeealyzer; import forestry.apiculture.gui.GuiHabitatLocator; import forestry.apiculture.gui.GuiImprinter; import forestry.apiculture.items.ItemBeealyzer.BeealyzerInventory; import forestry.apiculture.items.ItemHabitatLocator.HabitatLocatorInventory; import forestry.apiculture.items.ItemImprinter.ImprinterInventory; +import forestry.apiculture.multiblock.TileAlvearyHygroregulator; +import forestry.apiculture.multiblock.TileAlvearyPlain; +import forestry.apiculture.multiblock.TileAlvearySieve; +import forestry.apiculture.multiblock.TileAlvearySwarmer; import forestry.core.GuiHandlerBase; import forestry.core.gui.ContainerAlyzer; import forestry.core.network.GuiId; @@ -59,19 +59,19 @@ public class GuiHandlerApiculture extends GuiHandlerBase { switch (GuiId.values()[cleanId]) { case AlvearyGUI: - return new GuiAlveary(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearyPlain.class)); + return new GuiAlveary(player.inventory, getTile(world, x, y, z, player, TileAlvearyPlain.class)); case AlvearySieveGUI: - return new GuiAlvearySieve(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearySieve.class)); + return new GuiAlvearySieve(player.inventory, getTile(world, x, y, z, player, TileAlvearySieve.class)); case AlvearySwarmerGUI: - return new GuiAlvearySwarmer(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearySwarmer.class)); + return new GuiAlvearySwarmer(player.inventory, getTile(world, x, y, z, player, TileAlvearySwarmer.class)); case ApiaristChestGUI: return getNaturalistChestGui(BeeHelper.UID, player, world, x, y, z, guiData); case ApiaryGUI: - return new GuiApiary(player.inventory, getTileForestry(world, x, y, z, player, TileApiary.class)); + return new GuiBeeHousing(player.inventory, getTile(world, x, y, z, player, TileApiary.class)); case BeealyzerGUI: equipped = player.getCurrentEquippedItem(); @@ -82,7 +82,7 @@ public class GuiHandlerApiculture extends GuiHandlerBase { return new GuiBeealyzer(player, new BeealyzerInventory(player, equipped)); case BeehouseGUI: - return new GuiApiary(player.inventory, getTileForestry(world, x, y, z, player, TileBeehouse.class)); + return new GuiBeeHousing(player.inventory, getTile(world, x, y, z, player, TileBeehouse.class)); case HabitatLocatorGUI: equipped = player.getCurrentEquippedItem(); @@ -93,7 +93,7 @@ public class GuiHandlerApiculture extends GuiHandlerBase { return new GuiHabitatLocator(player, new HabitatLocatorInventory(player, equipped)); case HygroregulatorGUI: - return new GuiAlvearyHygroregulator(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearyHygroregulator.class)); + return new GuiAlvearyHygroregulator(player.inventory, getTile(world, x, y, z, player, TileAlvearyHygroregulator.class)); case ImprinterGUI: equipped = player.getCurrentEquippedItem(); @@ -122,20 +122,20 @@ public class GuiHandlerApiculture extends GuiHandlerBase { case AlvearyGUI: synchApiaristTracker(world, player); - return new ContainerAlveary(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearyPlain.class)); + return new ContainerAlveary(player.inventory, getTile(world, x, y, z, player, TileAlvearyPlain.class)); case AlvearySieveGUI: - return new ContainerAlvearySieve(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearySieve.class)); + return new ContainerAlvearySieve(player.inventory, getTile(world, x, y, z, player, TileAlvearySieve.class)); case AlvearySwarmerGUI: - return new ContainerAlvearySwarmer(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearySwarmer.class)); + return new ContainerAlvearySwarmer(player.inventory, getTile(world, x, y, z, player, TileAlvearySwarmer.class)); case ApiaristChestGUI: return getNaturalistChestContainer(BeeHelper.UID, player, world, x, y, z, guiData); case ApiaryGUI: synchApiaristTracker(world, player); - return new ContainerApiary(player.inventory, getTileForestry(world, x, y, z, player, TileApiary.class), true); + return new ContainerBeeHousing(player.inventory, getTile(world, x, y, z, player, TileApiary.class), true); case BeealyzerGUI: equipped = player.getCurrentEquippedItem(); @@ -148,7 +148,7 @@ public class GuiHandlerApiculture extends GuiHandlerBase { case BeehouseGUI: synchApiaristTracker(world, player); - return new ContainerApiary(player.inventory, getTileForestry(world, x, y, z, player, TileBeehouse.class), false); + return new ContainerBeeHousing(player.inventory, getTile(world, x, y, z, player, TileBeehouse.class), false); case HabitatLocatorGUI: equipped = player.getCurrentEquippedItem(); @@ -159,7 +159,7 @@ public class GuiHandlerApiculture extends GuiHandlerBase { return new ContainerHabitatLocator(player, new HabitatLocatorInventory(player, equipped)); case HygroregulatorGUI: - return new ContainerAlvearyHygroregulator(player.inventory, getTileForestry(world, x, y, z, player, TileAlvearyHygroregulator.class)); + return new ContainerAlvearyHygroregulator(player.inventory, getTile(world, x, y, z, player, TileAlvearyHygroregulator.class)); case ImprinterGUI: synchApiaristTracker(world, player); diff --git a/src/main/java/forestry/apiculture/HasFlowersCache.java b/src/main/java/forestry/apiculture/HasFlowersCache.java new file mode 100644 index 000000000..b77846a27 --- /dev/null +++ b/src/main/java/forestry/apiculture/HasFlowersCache.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; + +import forestry.api.apiculture.FlowerManager; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.core.INBTTagable; +import forestry.api.genetics.IFlowerProvider; +import forestry.plugins.PluginApiculture; + +public class HasFlowersCache implements INBTTagable { + private static final String nbtKey = "hasFlowerCache"; + + private ChunkCoordinates flowerCoords = null; + private int cooldown = 0; + + public boolean hasFlowers(IBee queen, IBeeHousing beeHousing) { + IFlowerProvider flowerProvider = queen.getGenome().getFlowerProvider(); + String flowerType = flowerProvider.getFlowerType(); + World world = beeHousing.getWorld(); + + if (flowerCoords != null) { + if (world.getTotalWorldTime() % 100 != 0) { + return true; + } + + if (FlowerManager.flowerRegistry.isAcceptedFlower(flowerType, world, flowerCoords.posX, flowerCoords.posY, flowerCoords.posZ)) { + return true; + } else { + flowerCoords = null; + cooldown = 0; + } + } + + if (cooldown <= 0) { + flowerCoords = FlowerManager.flowerRegistry.getAcceptedFlowerCoordinates(beeHousing, queen, flowerType); + cooldown = PluginApiculture.ticksPerBeeWorkCycle; + } else { + cooldown--; + } + + return flowerCoords != null; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + if (!nbttagcompound.hasKey(nbtKey)) { + return; + } + + NBTTagCompound hasFlowerCacheNBT = nbttagcompound.getCompoundTag(nbtKey); + if (hasFlowerCacheNBT.hasKey("flowerX")) { + int x = hasFlowerCacheNBT.getInteger("flowerX"); + int y = hasFlowerCacheNBT.getInteger("flowerY"); + int z = hasFlowerCacheNBT.getInteger("flowerZ"); + flowerCoords = new ChunkCoordinates(x, y, z); + } + + cooldown = hasFlowerCacheNBT.getInteger("cooldown"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + NBTTagCompound hasFlowerCacheNBT = new NBTTagCompound(); + if (flowerCoords != null) { + hasFlowerCacheNBT.setInteger("flowerX", flowerCoords.posX); + hasFlowerCacheNBT.setInteger("flowerY", flowerCoords.posY); + hasFlowerCacheNBT.setInteger("flowerZ", flowerCoords.posZ); + } + hasFlowerCacheNBT.setInteger("cooldown", cooldown); + + nbttagcompound.setTag(nbtKey, hasFlowerCacheNBT); + } +} diff --git a/src/main/java/forestry/apiculture/flowers/Flower.java b/src/main/java/forestry/apiculture/flowers/Flower.java index fd96ca6d2..1678f8d6c 100644 --- a/src/main/java/forestry/apiculture/flowers/Flower.java +++ b/src/main/java/forestry/apiculture/flowers/Flower.java @@ -10,6 +10,8 @@ ******************************************************************************/ package forestry.apiculture.flowers; +import java.util.Objects; + import net.minecraft.block.Block; import net.minecraftforge.oredict.OreDictionary; @@ -48,6 +50,11 @@ final class Flower implements IFlower { return this.weight.compareTo(other.getWeight()); } + @Override + public int hashCode() { + return Objects.hash(block, meta); + } + @Override public Block getBlock() { return block; diff --git a/src/main/java/forestry/apiculture/flowers/FlowerProvider.java b/src/main/java/forestry/apiculture/flowers/FlowerProvider.java index 403548dbc..8db663df8 100644 --- a/src/main/java/forestry/apiculture/flowers/FlowerProvider.java +++ b/src/main/java/forestry/apiculture/flowers/FlowerProvider.java @@ -11,7 +11,7 @@ package forestry.apiculture.flowers; import java.util.EnumSet; -import java.util.List; +import java.util.Set; import net.minecraft.item.ItemStack; import net.minecraft.world.World; @@ -36,8 +36,8 @@ public class FlowerProvider implements IFlowerProvider { } @Override - public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { - return FlowerManager.flowerRegistry.isAcceptedFlower(this.flowerType, world, individual, x, y, z); + public String getFlowerType() { + return flowerType; } @Override @@ -70,7 +70,7 @@ public class FlowerProvider implements IFlowerProvider { } @Override - public List getFlowers() { + public Set getFlowers() { return FlowerManager.flowerRegistry.getAcceptableFlowers(this.flowerType); } diff --git a/src/main/java/forestry/apiculture/flowers/FlowerRegistry.java b/src/main/java/forestry/apiculture/flowers/FlowerRegistry.java index 97c78cdc0..18fe416fe 100644 --- a/src/main/java/forestry/apiculture/flowers/FlowerRegistry.java +++ b/src/main/java/forestry/apiculture/flowers/FlowerRegistry.java @@ -11,26 +11,27 @@ package forestry.apiculture.flowers; import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; import net.minecraft.block.Block; +import net.minecraft.block.BlockFlowerPot; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFlowerPot; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import net.minecraftforge.oredict.OreDictionary; @@ -38,10 +39,17 @@ import net.minecraftforge.oredict.OreDictionary; import cpw.mods.fml.common.registry.GameRegistry; import forestry.api.apiculture.FlowerManager; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.genetics.IFlower; import forestry.api.genetics.IFlowerGrowthRule; import forestry.api.genetics.IFlowerRegistry; import forestry.api.genetics.IIndividual; +import forestry.apiculture.BeeHousingModifier; +import forestry.core.vect.MutableVect; +import forestry.core.vect.Vect; import forestry.plugins.PluginManager; public final class FlowerRegistry implements IFlowerRegistry { @@ -57,19 +65,19 @@ public final class FlowerRegistry implements IFlowerRegistry { FlowerManager.FlowerTypeWheat, FlowerManager.FlowerTypeGourd ); - private final ArrayListMultimap registeredFlowers; + + private final HashMultimap registeredBlocks; // quick first check + private final HashMultimap registeredFlowers; // full check + private final ArrayListMultimap growthRules; private final Map> chances; - private boolean hasDeprecatedFlowersImported; - public FlowerRegistry() { - this.registeredFlowers = ArrayListMultimap.create(); + this.registeredBlocks = HashMultimap.create(); + this.registeredFlowers = HashMultimap.create(); this.growthRules = ArrayListMultimap.create(); this.chances = new HashMap>(); - this.hasDeprecatedFlowersImported = false; - registerVanillaGrowthRules(); } @@ -100,73 +108,107 @@ public final class FlowerRegistry implements IFlowerRegistry { } Flower newFlower = new Flower(block, meta, weight); - Integer index; for (String flowerType : flowerTypes) { - List flowers = this.registeredFlowers.get(flowerType); + Set flowers = this.registeredFlowers.get(flowerType); - index = flowers.indexOf(newFlower); - if (index == -1) { - flowers.add(newFlower); - } else if (flowers.get(index).getMeta() != newFlower.getMeta()) { - flowers.add(newFlower); - } else if (flowers.get(index).getWeight() < newFlower.getWeight() && flowers.get(index).getMeta() == newFlower.getMeta()) { - flowers.get(index).setWeight(newFlower.getWeight()); + if (flowers.contains(newFlower)) { + throw new IllegalArgumentException("Flower type already exists: " + flowerType + " for flower " + block); } + flowers.add(newFlower); + + Set blocks = this.registeredBlocks.get(flowerType); + blocks.add(block); if (this.chances.containsKey(flowerType)) { this.chances.remove(flowerType); } - - Collections.sort(this.registeredFlowers.get(flowerType)); } } + private static Vect getArea(IBeeGenome genome, IBeeModifier beeModifier) { + int[] genomeTerritory = genome.getTerritory(); + float housingModifier = beeModifier.getTerritoryModifier(genome, 1f); + return new Vect(genomeTerritory).multiply(housingModifier * 3.0f); + } + @Override - public boolean isAcceptedFlower(String flowerType, World world, IIndividual individual, int x, int y, int z) { - internalInitialize(); + public ChunkCoordinates getAcceptedFlowerCoordinates(IBeeHousing beeHousing, IBee bee, String flowerType) { + if (!this.registeredFlowers.containsKey(flowerType)) { + return null; + } + + Set acceptedBlocks = this.registeredBlocks.get(flowerType); + Set acceptedFlowers = this.registeredFlowers.get(flowerType); + World world = beeHousing.getWorld(); + + IBeeModifier beeModifier = new BeeHousingModifier(beeHousing); + + Vect area = getArea(bee.getGenome(), beeModifier); + Vect housingPos = new Vect(beeHousing.getCoordinates()).add(-area.x / 2, -area.y / 2, -area.z / 2); + + MutableVect posCurrent = new MutableVect(0, 0, 0); + while (posCurrent.advancePositionInArea(area)) { + + Vect posBlock = Vect.add(housingPos, posCurrent); + + if (isAcceptedFlower(flowerType, acceptedBlocks, acceptedFlowers, world, posBlock.x, posBlock.y, posBlock.z)) { + return new ChunkCoordinates(posBlock.x, posBlock.y, posBlock.z); + } + } + + return null; + } + + @Override + public boolean isAcceptedFlower(String flowerType, World world, int x, int y, int z) { if (!this.registeredFlowers.containsKey(flowerType)) { return false; } + Set acceptedBlocks = this.registeredBlocks.get(flowerType); + Set acceptedFlowers = this.registeredFlowers.get(flowerType); + + return isAcceptedFlower(flowerType, acceptedBlocks, acceptedFlowers, world, x, y, z); + } + + private static boolean isAcceptedFlower(String flowerType, Set acceptedBlocks, Set acceptedFlowers, World world, int x, int y, int z) { Block block = world.getBlock(x, y, z); - if (block.isAir(world, x, y, z) || block.equals(Blocks.bedrock) || block.equals(Blocks.dirt) || block.equals(Blocks.grass)) { - return false; - } + final int meta; - int meta; - - TileEntity tile = world.getTileEntity(x, y, z); - if (tile instanceof TileEntityFlowerPot) { + if (block instanceof BlockFlowerPot) { + TileEntity tile = world.getTileEntity(x, y, z); TileEntityFlowerPot tileFlowerPot = (TileEntityFlowerPot) tile; Item item = tileFlowerPot.getFlowerPotItem(); block = Block.getBlockFromItem(item); meta = tileFlowerPot.getFlowerPotData(); } else { + if (!acceptedBlocks.contains(block)) { + return false; + } meta = world.getBlockMetadata(x, y, z); } - if (PluginManager.Module.AGRICRAFT.isEnabled() && (flowerType == FlowerManager.FlowerTypeWheat || flowerType == FlowerManager.FlowerTypeNether)) { + + if (PluginManager.Module.AGRICRAFT.isEnabled() && (flowerType.equals(FlowerManager.FlowerTypeWheat) || flowerType.equals(FlowerManager.FlowerTypeNether))) { Block cropBlock = GameRegistry.findBlock("AgriCraft", "crops"); - if(block == cropBlock) { + if (block == cropBlock) { ArrayList drops = block.getDrops(world, x, y, z, 7, 0); - if (drops.get(1).getItem() == Items.wheat_seeds && flowerType == FlowerManager.FlowerTypeWheat) { + if (drops.get(1).getItem() == Items.wheat_seeds && flowerType.equals(FlowerManager.FlowerTypeWheat)) { return true; } - if (drops.get(1).getItem() == Items.nether_wart && flowerType == FlowerManager.FlowerTypeNether) { + if (drops.get(1).getItem() == Items.nether_wart && flowerType.equals(FlowerManager.FlowerTypeNether)) { return true; } } } - + Flower flower = new Flower(block, meta, 0); - List acceptedFlowers = this.registeredFlowers.get(flowerType); return acceptedFlowers.contains(flower); } @Override public boolean growFlower(String flowerType, World world, IIndividual individual, int x, int y, int z) { - internalInitialize(); if (!this.growthRules.containsKey(flowerType)) { return false; } @@ -181,9 +223,7 @@ public final class FlowerRegistry implements IFlowerRegistry { } @Override - public List getAcceptableFlowers(String flowerType) { - internalInitialize(); - + public Set getAcceptableFlowers(String flowerType) { return this.registeredFlowers.get(flowerType); } @@ -225,22 +265,6 @@ public final class FlowerRegistry implements IFlowerRegistry { return this.chances.get(flowerType); } - /* - * Method to support deprecated FlowerManager.plainFlowers - */ - @SuppressWarnings("deprecation") - private void internalInitialize() { - if (!hasDeprecatedFlowersImported) { - for (ItemStack plainFlower : FlowerManager.plainFlowers) { - Block flowerBlock = Block.getBlockFromItem(plainFlower.getItem()); - int meta = plainFlower.getItemDamage(); - registerPlantableFlower(flowerBlock, meta, 1.0, FlowerManager.FlowerTypeVanilla, FlowerManager.FlowerTypeSnow); - } - - hasDeprecatedFlowersImported = true; - } - } - private void registerVanillaGrowthRules() { registerGrowthRule(new VanillaDirtGrassGrowthRule(), FlowerManager.FlowerTypeVanilla, FlowerManager.FlowerTypeSnow); registerGrowthRule(new VanillaSnowGrowthRule(), FlowerManager.FlowerTypeSnow); diff --git a/src/main/java/forestry/apiculture/gadgets/BlockAlveary.java b/src/main/java/forestry/apiculture/gadgets/BlockAlveary.java index cbb890193..4c870a708 100755 --- a/src/main/java/forestry/apiculture/gadgets/BlockAlveary.java +++ b/src/main/java/forestry/apiculture/gadgets/BlockAlveary.java @@ -28,7 +28,16 @@ import cpw.mods.fml.relauncher.SideOnly; import forestry.api.core.Tabs; import forestry.apiculture.MaterialBeehive; +import forestry.apiculture.multiblock.TileAlveary; +import forestry.apiculture.multiblock.TileAlvearyFan; +import forestry.apiculture.multiblock.TileAlvearyHeater; +import forestry.apiculture.multiblock.TileAlvearyHygroregulator; +import forestry.apiculture.multiblock.TileAlvearyPlain; +import forestry.apiculture.multiblock.TileAlvearySieve; +import forestry.apiculture.multiblock.TileAlvearyStabiliser; +import forestry.apiculture.multiblock.TileAlvearySwarmer; import forestry.core.gadgets.BlockStructure; +import forestry.core.multiblock.MultiblockRegistry; import forestry.core.render.TextureManager; public class BlockAlveary extends BlockStructure { @@ -78,17 +87,17 @@ public class BlockAlveary extends BlockStructure { @Override public TileEntity createTileEntity(World world, int metadata) { switch (metadata) { - case TileAlvearySwarmer.BLOCK_META: + case TileAlveary.SWARMER_META: return new TileAlvearySwarmer(); - case TileAlvearyFan.BLOCK_META: + case TileAlveary.FAN_META: return new TileAlvearyFan(); - case TileAlvearyHeater.BLOCK_META: + case TileAlveary.HEATER_META: return new TileAlvearyHeater(); - case TileAlvearyHygroregulator.BLOCK_META: + case TileAlveary.HYGRO_META: return new TileAlvearyHygroregulator(); - case TileAlvearyStabiliser.BLOCK_META: + case TileAlveary.STABILIZER_META: return new TileAlvearyStabiliser(); - case TileAlvearySieve.BLOCK_META: + case TileAlveary.SIEVE_META: return new TileAlvearySieve(); default: return new TileAlvearyPlain(); @@ -143,27 +152,27 @@ public class BlockAlveary extends BlockStructure { @Override public IIcon getIcon(int side, int metadata) { if ((metadata <= 1 - || metadata == TileAlvearySieve.BLOCK_META || metadata == TileAlvearySwarmer.BLOCK_META || metadata == TileAlvearyStabiliser.BLOCK_META) + || metadata == TileAlveary.SIEVE_META || metadata == TileAlveary.SWARMER_META || metadata == TileAlveary.STABILIZER_META) && (side == 1 || side == 0)) { return icons[BOTTOM]; } switch (metadata) { - case TileAlvearyPlain.BLOCK_META: + case TileAlveary.PLAIN_META: return icons[PLAIN]; - case 1: + case TileAlveary.ENTRANCE_META: return icons[ENTRANCE]; - case TileAlvearySwarmer.BLOCK_META: + case TileAlveary.SWARMER_META: return icons[ALVEARY_SWARMER_OFF]; - case TileAlvearyFan.BLOCK_META: + case TileAlveary.FAN_META: return icons[ALVEARY_FAN_OFF]; - case TileAlvearyHeater.BLOCK_META: + case TileAlveary.HEATER_META: return icons[ALVEARY_HEATER_OFF]; - case TileAlvearyHygroregulator.BLOCK_META: + case TileAlveary.HYGRO_META: return icons[ALVEARY_HYGRO]; - case TileAlvearyStabiliser.BLOCK_META: + case TileAlveary.STABILIZER_META: return icons[STABILISER]; - case TileAlvearySieve.BLOCK_META: + case TileAlveary.SIEVE_META: return icons[SIEVE]; default: return null; @@ -242,4 +251,17 @@ public class BlockAlveary extends BlockStructure { } } + + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block block) { + super.onNeighborBlockChange(world, x, y, z, block); + + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof TileAlveary) { + TileAlveary tileAlveary = (TileAlveary) tileEntity; + + // We must check that the slabs on top were not removed + MultiblockRegistry.addDirtyController(world, tileAlveary.getMultiblockController()); + } + } } diff --git a/src/main/java/forestry/apiculture/gadgets/StructureLogicAlveary.java b/src/main/java/forestry/apiculture/gadgets/StructureLogicAlveary.java deleted file mode 100644 index 29a4e80ec..000000000 --- a/src/main/java/forestry/apiculture/gadgets/StructureLogicAlveary.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -import java.util.HashSet; -import java.util.Set; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; - -import net.minecraftforge.oredict.OreDictionary; - -import forestry.api.apiculture.IAlvearyComponent; -import forestry.api.core.ITileStructure; -import forestry.core.gadgets.BlockStructure.EnumStructureState; -import forestry.core.gadgets.StructureLogic; -import forestry.core.utils.Schemata; -import forestry.core.utils.Schemata.EnumStructureBlock; -import forestry.core.vect.Vect; - -public class StructureLogicAlveary extends StructureLogic { - - /* CONSTANTS */ - public static final String UID_ALVEARY = "alveary"; - public static final Schemata SCHEMATA_ALVEARY = new Schemata("alveary3x3", 5, 6, 5, - "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", - "FFFFF", "FAAAF", "FAAAF", "FABAF", "FCCCF", "FFFFF", - "FFFFF", "FAAAF", "FAAAF", "FBMBF", "FCCCF", "FFFFF", - "FFFFF", "FAAAF", "FAAAF", "FABAF", "FCCCF", "FFFFF", - "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF").setOffsets(-2, -3, -2); - - private static final Set slabBlocks = new HashSet(); - private static final Set slabOreDictIds = new HashSet(); - - static { - int slabWoodId = OreDictionary.getOreID("slabWood"); - slabOreDictIds.add(slabWoodId); - } - - public StructureLogicAlveary(ITileStructure structure) { - super(UID_ALVEARY, structure); - schematas = new Schemata[]{SCHEMATA_ALVEARY}; - metaOnValid.put(EnumStructureBlock.BLOCK_B, 1); - } - - @Override - protected EnumStructureState determineMasterState(Schemata schemata, boolean rotate) { - - Vect dimensions = schemata.getDimensions(rotate); - int offsetX = schemata.getxOffset(); - int offsetZ = schemata.getzOffset(); - if (rotate) { - offsetX = schemata.getzOffset(); - offsetZ = schemata.getxOffset(); - } - - for (int i = 0; i < dimensions.x; i++) { - for (int j = 0; j < schemata.getHeight(); j++) { - for (int k = 0; k < dimensions.z; k++) { - int x = structureTile.xCoord + i + offsetX; - int y = structureTile.yCoord + j + schemata.getyOffset(); - int z = structureTile.zCoord + k + offsetZ; - - if (!structureTile.getWorldObj().blockExists(x, y, z)) { - return EnumStructureState.INDETERMINATE; - } - - EnumStructureBlock required = schemata.getAt(i, j, k, rotate); - if (required == EnumStructureBlock.ANY) { - continue; - } - - TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); - Block block = structureTile.getWorldObj().getBlock(x, y, z); - - switch (required) { - case AIR: - if (!block.isAir(structureTile.getWorldObj(), x, y, z)) { - return EnumStructureState.INVALID; - } - break; - case BLOCK_A: - if (tile == null || !(tile instanceof IAlvearyComponent)) { - return EnumStructureState.INVALID; - } - if (!((ITileStructure) tile).getTypeUID().equals(UID_ALVEARY)) { - return EnumStructureState.INVALID; - } - break; - case MASTER: - case BLOCK_B: - if (tile == null || !(tile instanceof TileAlvearyPlain)) { - return EnumStructureState.INVALID; - } - break; - case BLOCK_C: - if (!isWoodSlabBlock(block)) { - return EnumStructureState.INVALID; - } - if ((structureTile.getWorldObj().getBlockMetadata(x, y, z) & 8) != 0) { - return EnumStructureState.INVALID; - } - break; - case BLOCK_D: - if (block != Blocks.spruce_stairs) { - return EnumStructureState.INVALID; - } - break; - case FOREIGN: - if (tile instanceof ITileStructure) { - return EnumStructureState.INVALID; - } - break; - default: - return EnumStructureState.INDETERMINATE; - } - } - } - } - - return EnumStructureState.VALID; - } - - private static boolean isWoodSlabBlock(Block block) { - int[] oreIds = OreDictionary.getOreIDs(new ItemStack(block)); - for (int oreId : oreIds) { - if (slabOreDictIds.contains(oreId)) { - return true; - } - } - - return slabBlocks.contains(block); - } - - public static void addSlabBlock(Block block) { - slabBlocks.add(block); - } - -} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlveary.java b/src/main/java/forestry/apiculture/gadgets/TileAlveary.java deleted file mode 100755 index 91881eb11..000000000 --- a/src/main/java/forestry/apiculture/gadgets/TileAlveary.java +++ /dev/null @@ -1,267 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -import java.io.IOException; -import java.util.Collection; -import java.util.LinkedList; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; - -import net.minecraftforge.common.util.ForgeDirection; - -import cpw.mods.fml.common.Optional; - -import forestry.api.apiculture.IAlvearyComponent; -import forestry.api.apiculture.IBeeListener; -import forestry.api.apiculture.IBeeModifier; -import forestry.api.core.IStructureLogic; -import forestry.api.core.ITileStructure; -import forestry.apiculture.trigger.ApicultureTriggers; -import forestry.core.config.Defaults; -import forestry.core.config.ForestryBlock; -import forestry.core.gadgets.TileForestry; -import forestry.core.inventory.FakeInventoryAdapter; -import forestry.core.inventory.IInventoryAdapter; -import forestry.core.network.DataInputStreamForestry; -import forestry.core.network.DataOutputStreamForestry; -import forestry.core.proxy.Proxies; - -import buildcraft.api.statements.ITriggerExternal; - -public abstract class TileAlveary extends TileForestry implements IAlvearyComponent { - - private final IStructureLogic structureLogic; - private boolean isMaster; - protected int masterX, masterZ; - protected int masterY = -99; - protected final int componentBlockMeta; - - public TileAlveary(int componentBlockMeta) { - this.structureLogic = new StructureLogicAlveary(this); - this.componentBlockMeta = componentBlockMeta; - } - - /* UPDATING */ - @Override - public void initialize() { - if (!ForestryBlock.alveary.isBlockEqual(worldObj, xCoord, yCoord, zCoord)) { - Proxies.log.info("Updating alveary block at %s/%s/%s.", xCoord, yCoord, zCoord); - worldObj.setBlock(xCoord, yCoord, zCoord, ForestryBlock.alveary.block(), componentBlockMeta, Defaults.FLAG_BLOCK_SYNCH); - validate(); - worldObj.setTileEntity(xCoord, yCoord, zCoord, this); - } - } - - protected void updateServerSide() { - // Periodic validation if needed - if (updateOnInterval(200) && (!isIntegratedIntoStructure() || isMaster())) { - validateStructure(); - } - } - - /* TEXTURES */ - public int getIcon(int side, int metadata) { - return BlockAlveary.PLAIN; - } - - /* LOADING & SAVING */ - @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - this.isMaster = nbttagcompound.getBoolean("IsMaster"); - this.masterX = nbttagcompound.getInteger("MasterX"); - this.masterY = nbttagcompound.getInteger("MasterY"); - this.masterZ = nbttagcompound.getInteger("MasterZ"); - - // Init for master state - if (isMaster) { - makeMaster(); - } - - super.readFromNBT(nbttagcompound); - - structureLogic.readFromNBT(nbttagcompound); - } - - @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - - nbttagcompound.setBoolean("IsMaster", isMaster); - nbttagcompound.setInteger("MasterX", masterX); - nbttagcompound.setInteger("MasterY", masterY); - nbttagcompound.setInteger("MasterZ", masterZ); - - structureLogic.writeToNBT(nbttagcompound); - } - - protected void createInventory() { - } - - @Override - public void writeData(DataOutputStreamForestry data) throws IOException { - super.writeData(data); - data.writeBoolean(isMaster); - - // so the client can know if it is part of an integrated structure - data.writeVarInt(masterY); - } - - @Override - public void readData(DataInputStreamForestry data) throws IOException { - super.readData(data); - if (data.readBoolean()) { - makeMaster(); - } - - // so the client can know if it is part of an integrated structure - masterY = data.readVarInt(); - } - - /* ITILESTRUCTURE */ - @Override - public String getTypeUID() { - return structureLogic.getTypeUID(); - } - - @Override - public void validateStructure() { - structureLogic.validateStructure(); - } - - @Override - public void makeMaster() { - setCentralTE(null); - isMaster = true; - - if (getInternalInventory() instanceof FakeInventoryAdapter) { - createInventory(); - } - - if (worldObj != null && !worldObj.isRemote) { - setNeedsNetworkUpdate(); - } - } - - @Override - public void onStructureReset() { - setCentralTE(null); - if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord) == 1) { - worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 0); - } - isMaster = false; - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - } - - @Override - public ITileStructure getCentralTE() { - - if (!isIntegratedIntoStructure()) { - return null; - } - - if (!isMaster()) { - TileEntity tile = worldObj.getTileEntity(masterX, masterY, masterZ); - if (tile instanceof ITileStructure) { - ITileStructure master = (ITileStructure) worldObj.getTileEntity(masterX, masterY, masterZ); - if (master.isMaster()) { - return master; - } else { - return null; - } - } else { - return null; - } - } else { - return this; - } - - } - - private boolean isSameTile(TileEntity tile) { - return tile.xCoord == xCoord && tile.yCoord == yCoord && tile.zCoord == zCoord; - } - - @Override - public void setCentralTE(TileEntity tile) { - if (tile == null || tile == this || isSameTile(tile)) { - this.masterX = this.masterZ = 0; - this.masterY = -99; - return; - } - - this.isMaster = false; - this.masterX = tile.xCoord; - this.masterY = tile.yCoord; - this.masterZ = tile.zCoord; - } - - @Override - public boolean isMaster() { - return isMaster; - } - - protected boolean hasMaster() { - return masterY >= 0; - } - - @Override - public boolean isIntegratedIntoStructure() { - return isMaster || masterY >= 0; - } - - @Override - public IInventoryAdapter getStructureInventory() { - return getInternalInventory(); - } - - /* IALVEARY COMPONENT */ - @Override - public boolean hasFunction() { - return false; - } - - @Override - public void addTemperatureChange(float change, float boundaryDown, float boundaryUp) { - } - - @Override - public void addHumidityChange(float change, float boundaryDown, float boundaryUp) { - } - - @Override - public void registerBeeModifier(IBeeModifier modifier) { - } - - @Override - public void removeBeeModifier(IBeeModifier modifier) { - } - - @Override - public void registerBeeListener(IBeeListener event) { - } - - @Override - public void removeBeeListener(IBeeListener event) { - } - - /* ITRIGGERPROVIDER */ - @Optional.Method(modid = "BuildCraftAPI|statements") - @Override - public Collection getExternalTriggers(ForgeDirection side, TileEntity tile) { - LinkedList res = new LinkedList(); - res.add(ApicultureTriggers.missingQueen); - res.add(ApicultureTriggers.missingDrone); - return res; - } - -} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearyPlain.java b/src/main/java/forestry/apiculture/gadgets/TileAlvearyPlain.java deleted file mode 100755 index c39597b5a..000000000 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearyPlain.java +++ /dev/null @@ -1,716 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -import java.io.IOException; -import java.util.LinkedHashSet; -import java.util.Set; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.ICrafting; -import net.minecraft.inventory.ISidedInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; - -import com.mojang.authlib.GameProfile; - -import forestry.api.apiculture.BeeManager; -import forestry.api.apiculture.IBee; -import forestry.api.apiculture.IBeeGenome; -import forestry.api.apiculture.IBeeHousing; -import forestry.api.apiculture.IBeeListener; -import forestry.api.apiculture.IBeeModifier; -import forestry.api.apiculture.IBeekeepingLogic; -import forestry.api.core.BiomeHelper; -import forestry.api.core.EnumHumidity; -import forestry.api.core.EnumTemperature; -import forestry.api.core.ForestryAPI; -import forestry.api.core.IErrorState; -import forestry.api.core.ITileStructure; -import forestry.api.genetics.IIndividual; -import forestry.apiculture.gui.ContainerAlveary; -import forestry.apiculture.network.PacketActiveUpdate; -import forestry.core.EnumErrorCode; -import forestry.core.config.Config; -import forestry.core.interfaces.IActivatable; -import forestry.core.interfaces.IClimatised; -import forestry.core.interfaces.IErrorSource; -import forestry.core.interfaces.IHintSource; -import forestry.core.inventory.IInventoryAdapter; -import forestry.core.inventory.InvTools; -import forestry.core.inventory.TileInventoryAdapter; -import forestry.core.network.DataInputStreamForestry; -import forestry.core.network.DataOutputStreamForestry; -import forestry.core.network.GuiId; -import forestry.core.proxy.Proxies; - -public class TileAlvearyPlain extends TileAlveary implements ISidedInventory, IBeeHousing, IClimatised, IHintSource, IActivatable { - - // / CONSTANTS - public static final int SLOT_QUEEN = 0; - public static final int SLOT_DRONE = 1; - public static final int SLOT_PRODUCT_1 = 2; - public static final int SLOT_PRODUCT_COUNT = 7; - public static final int BLOCK_META = 0; - - // / MEMBERS - protected IBeekeepingLogic beekeepingLogic; - protected BiomeGenBase biome; - protected float tempChange = 0.0f; - protected float humidChange = 0.0f; - - // CLIENT - private boolean active; - private int displayHealthMax = 0; - private int displayHealth = 0; - private IBee displayQueen; - - public TileAlvearyPlain() { - super(0); - } - - @Override - public void openGui(EntityPlayer player) { - if (isMaster()) { - player.openGui(ForestryAPI.instance, GuiId.AlvearyGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); - } else if (this.hasMaster()) { - player.openGui(ForestryAPI.instance, GuiId.AlvearyGUI.ordinal(), worldObj, masterX, masterY, masterZ); - } - } - - @Override - public void validate() { - super.validate(); - setBiomeInformation(); - } - - private void setBiomeInformation() { - this.biome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); - } - - /* LOADING & SAVING */ - @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - super.readFromNBT(nbttagcompound); - - this.tempChange = nbttagcompound.getFloat("TempChange"); - this.humidChange = nbttagcompound.getFloat("HumidChange"); - - if (beekeepingLogic != null) { - beekeepingLogic.readFromNBT(nbttagcompound); - } - } - - @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - - nbttagcompound.setFloat("TempChange", tempChange); - nbttagcompound.setFloat("HumidChange", humidChange); - - if (beekeepingLogic != null) { - beekeepingLogic.writeToNBT(nbttagcompound); - } - } - - @Override - public void writeData(DataOutputStreamForestry data) throws IOException { - super.writeData(data); - data.writeBoolean(active); - if (active) { - ItemStack queen = getStackInSlot(SLOT_QUEEN); - data.writeItemStack(queen); - } - } - - @Override - public void readData(DataInputStreamForestry data) throws IOException { - super.readData(data); - active = data.readBoolean(); - if (active) { - ItemStack queen = data.readItemStack(); - setInventorySlotContents(SLOT_QUEEN, queen); - } - } - - @Override - public boolean isActive() { - return active; - } - - @Override - public void setActive(boolean active) { - if (this.active == active) { - return; - } - this.active = active; - - if (!worldObj.isRemote) { - Proxies.net.sendNetworkPacket(new PacketActiveUpdate(this)); - } - } - - /* UPDATING */ - @Override - public void initialize() { - super.initialize(); - setBiomeInformation(); - } - - @Override - protected void updateServerSide() { - super.updateServerSide(); - - if (beekeepingLogic == null) { - return; - } - if (!isMaster()) { - return; - } - - boolean canWork = beekeepingLogic.canWork(); - setActive(canWork); - if (canWork) { - beekeepingLogic.doWork(); - } - - // Equalize humidity and temperature - equalizeTemperature(); - equalizeHumidity(); - } - - @Override - protected void updateClientSide() { - if (isMaster() && active && (displayQueen != null) && updateOnInterval(2)) { - displayQueen.doFX(beekeepingLogic.getEffectData(), this); - - if (updateOnInterval(50)) { - float fxX = xCoord + 0.5F; - float fxY = yCoord + 0.25F + (worldObj.rand.nextFloat() * 6F) / 16F; - float fxZ = zCoord + 0.5F; - float f3 = 1.6F; - float f4 = worldObj.rand.nextFloat() * f3 - 0.5F; - - Proxies.common.addEntitySwarmFX(worldObj, (fxX - f3), fxY, (fxZ + f4), 0F, 0F, 0F); - Proxies.common.addEntitySwarmFX(worldObj, (fxX + f3), fxY, (fxZ + f4), 0F, 0F, 0F); - Proxies.common.addEntitySwarmFX(worldObj, (fxX + f4), fxY, (fxZ - f3), 0F, 0F, 0F); - Proxies.common.addEntitySwarmFX(worldObj, (fxX + f4), fxY, (fxZ + f3), 0F, 0F, 0F); - } - } - } - - private void equalizeTemperature() { - if (tempChange == 0) { - return; - } - - tempChange -= 0.05f * tempChange; - if (tempChange <= 0.001f && tempChange >= -0.001f) { - tempChange = 0; - } - } - - private void equalizeHumidity() { - if (humidChange == 0) { - return; - } - - humidChange -= 0.05f * humidChange; - if (humidChange <= 0.001f && humidChange >= 0.001f) { - humidChange = 0; - } - } - - /* STATE INFORMATION */ - private int getHealthDisplay() { - if (displayQueen == null) { - return 0; - } - - if (displayQueen.getMate() != null) { - return displayQueen.getHealth(); - } else { - return displayHealth; - } - } - - private int getMaxHealthDisplay() { - if (displayQueen == null) { - return 0; - } - - if (displayQueen.getMate() != null) { - return displayQueen.getMaxHealth(); - } else { - return displayHealthMax; - } - } - - public int getHealthScaled(int i) { - if (getMaxHealthDisplay() == 0) { - return 0; - } - - return (getHealthDisplay() * i) / getMaxHealthDisplay(); - } - - /* STRUCTURE MANAGMENT */ - @Override - protected void createInventory() { - setInternalInventory(new AlvearyInventoryAdapter(this)); - } - - @Override - public void makeMaster() { - super.makeMaster(); - if (beekeepingLogic == null) { - this.beekeepingLogic = BeeManager.beeRoot.createBeekeepingLogic(this); - } - } - - @Override - public void onStructureReset() { - super.onStructureReset(); - modifiers.clear(); - eventHandlers.clear(); - - setActive(false); - } - - /* IALVEARYCOMPONENT */ - private final Set modifiers = new LinkedHashSet(); - private final Set eventHandlers = new LinkedHashSet(); - - @Override - public void registerBeeModifier(IBeeModifier modifier) { - modifiers.add(modifier); - } - - @Override - public void removeBeeModifier(IBeeModifier modifier) { - modifiers.remove(modifier); - } - - @Override - public void registerBeeListener(IBeeListener modifier) { - eventHandlers.add(modifier); - } - - @Override - public void removeBeeListener(IBeeListener modifier) { - eventHandlers.remove(modifier); - } - - @Override - public void addTemperatureChange(float change, float boundaryDown, float boundaryUp) { - float temperature = biome.getFloatTemperature(xCoord, yCoord, zCoord); - tempChange = Math.min(boundaryUp - temperature, Math.max(boundaryDown - temperature, tempChange + change)); - } - - @Override - public void addHumidityChange(float change, float boundaryDown, float boundaryUp) { - float humidity = biome.rainfall; - humidChange = Math.min(boundaryUp - humidity, Math.max(boundaryDown - humidity, humidChange + change)); - } - - /* IBEEHOUSING */ - @Override - public int getXCoord() { - return xCoord; - } - - @Override - public int getYCoord() { - return yCoord; - } - - @Override - public int getZCoord() { - return zCoord; - } - - @Override - public ItemStack getQueen() { - return getStackInSlot(SLOT_QUEEN); - } - - @Override - public ItemStack getDrone() { - return getStackInSlot(SLOT_DRONE); - } - - @Override - public void setQueen(ItemStack itemstack) { - setInventorySlotContents(SLOT_QUEEN, itemstack); - } - - @Override - public ItemStack decrStackSize(int slotIndex, int amount) { - ItemStack itemStack = super.decrStackSize(slotIndex, amount); - if (slotIndex == SLOT_QUEEN) { - handleQueenChange(); - } - return itemStack; - } - - @Override - public void setInventorySlotContents(int slotIndex, ItemStack itemStack) { - super.setInventorySlotContents(slotIndex, itemStack); - if (slotIndex == SLOT_QUEEN) { - handleQueenChange(); - } - } - - private void handleQueenChange() { - if (!Proxies.common.isSimulating(worldObj)) { - TileAlvearyPlain master = (TileAlvearyPlain) getCentralTE(); - if (master != null) { - ItemStack itemStack = getStackInSlot(SLOT_QUEEN); - master.displayQueen = BeeManager.beeRoot.getMember(itemStack); - } - } - } - - @Override - public void setDrone(ItemStack itemstack) { - setInventorySlotContents(SLOT_DRONE, itemstack); - } - - @Override - public BiomeGenBase getBiome() { - return biome; - } - - @Override - public EnumTemperature getTemperature() { - if (isHellish() && tempChange >= 0) { - return EnumTemperature.HELLISH; - } - - return EnumTemperature.getFromValue(getExactTemperature()); - } - - @Override - public EnumHumidity getHumidity() { - return EnumHumidity.getFromValue(getExactHumidity()); - } - - @Override - public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { - float mod = 2.0f; - for (IBeeModifier modifier : modifiers) { - mod *= modifier.getTerritoryModifier(genome, mod); - } - return mod; - } - - @Override - public float getProductionModifier(IBeeGenome genome, float currentModifier) { - float mod = 1.0f; - for (IBeeModifier modifier : modifiers) { - mod *= modifier.getProductionModifier(genome, mod); - } - return mod; - } - - @Override - public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - float mod = 1.0f; - for (IBeeModifier modifier : modifiers) { - mod *= modifier.getMutationModifier(genome, mate, mod); - } - return mod; - } - - @Override - public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - float mod = 1.0f; - for (IBeeModifier modifier : modifiers) { - mod *= modifier.getLifespanModifier(genome, mate, mod); - } - return mod; - } - - @Override - public float getFloweringModifier(IBeeGenome genome, float currentModifier) { - float mod = 1.0f; - for (IBeeModifier modifier : modifiers) { - mod *= modifier.getFloweringModifier(genome, mod); - } - return mod; - } - - @Override - public float getGeneticDecay(IBeeGenome genome, float currentModifier) { - float mod = 1.0f; - for (IBeeModifier modifier : modifiers) { - mod *= modifier.getGeneticDecay(genome, mod); - } - return mod; - } - - @Override - public World getWorld() { - return worldObj; - } - - @Override - public boolean canBreed() { - return true; - } - - @Override - public boolean addProduct(ItemStack product, boolean all) { - IInventoryAdapter inventory = getStructureInventory(); - if (inventory == null) { - return false; - } - - return InvTools.tryAddStack(inventory, product, SLOT_PRODUCT_1, SLOT_PRODUCT_COUNT, all); - } - - @Deprecated - @Override - public void setErrorState(IErrorState state) { - removeErrorStates(); - if (state != EnumErrorCode.OK) { - addErrorState(state); - } - } - - @Override - public void wearOutEquipment(int amount) { - for (IBeeListener eventHandler : eventHandlers) { - eventHandler.wearOutEquipment(amount); - } - } - - @Override - public void onQueenChange(ItemStack queenStack) { - if (!Proxies.common.isSimulating(worldObj)) { - return; - } - - for (IBeeListener eventHandler : eventHandlers) { - eventHandler.onQueenChange(queenStack); - } - } - - @Override - public void onQueenDeath(IBee queen) { - for (IBeeListener eventHandler : eventHandlers) { - eventHandler.onQueenDeath(queen); - } - } - - @Override - public void onPostQueenDeath(IBee queen) { - for (IBeeListener eventHandler : eventHandlers) { - eventHandler.onPostQueenDeath(queen); - } - } - - @Override - public boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled) { - - for (IBeeListener eventHandler : eventHandlers) { - if (eventHandler.onPollenRetrieved(queen, pollen, isHandled)) { - isHandled = true; - } - } - - return isHandled; - } - - @Override - public boolean onEggLaid(IBee queen) { - for (IBeeListener eventHandler : eventHandlers) { - if (eventHandler.onEggLaid(queen)) { - return true; - } - } - - return false; - } - - @Override - public boolean isSealed() { - for (IBeeModifier modifier : modifiers) { - if (modifier.isSealed()) { - return true; - } - } - return false; - } - - @Override - public boolean isSelfLighted() { - for (IBeeModifier modifier : modifiers) { - if (modifier.isSelfLighted()) { - return true; - } - } - return false; - } - - @Override - public boolean isSunlightSimulated() { - for (IBeeModifier modifier : modifiers) { - if (modifier.isSunlightSimulated()) { - return true; - } - } - return false; - } - - @Override - public boolean isHellish() { - if (BiomeHelper.isBiomeHellish(biome)) { - return true; - } - - for (IBeeModifier modifier : modifiers) { - if (modifier.isHellish()) { - return true; - } - } - return false; - } - - /* IINVENTORY */ - @Override - public IInventoryAdapter getInternalInventory() { - IInventoryAdapter inventory = super.getInternalInventory(); - if (isMaster()) { - return inventory; - } else if (hasMaster()) { - ITileStructure central = getCentralTE(); - if (central instanceof TileAlveary) { - return ((TileAlveary) central).getInternalInventory(); - } - } - return inventory; - } - - /* SMP GUI */ - public void getGUINetworkData(int i, int j) { - switch (i) { - case 0: - displayHealth = j; - break; - case 1: - displayHealthMax = j; - break; - case 4: - this.tempChange = (float) j / 100; - break; - case 5: - this.humidChange = (float) j / 100; - break; - case 6: { - this.biome = BiomeGenBase.getBiome(j); - break; - } - } - - } - - public void sendGUINetworkData(ContainerAlveary container, ICrafting iCrafting) { - if (beekeepingLogic == null) { - return; - } - - iCrafting.sendProgressBarUpdate(container, 0, beekeepingLogic.getBreedingTime()); - iCrafting.sendProgressBarUpdate(container, 1, beekeepingLogic.getTotalBreedingTime()); - iCrafting.sendProgressBarUpdate(container, 4, Math.round(tempChange * 100)); - iCrafting.sendProgressBarUpdate(container, 5, Math.round(humidChange * 100)); - iCrafting.sendProgressBarUpdate(container, 6, biome.biomeID); - } - - /* IERRORSOURCE */ - @Deprecated - @Override - public IErrorState getErrorState() { - Set errorStates = null; - if (hasMaster()) { - ITileStructure tile = getCentralTE(); - if (tile != null) { - errorStates = ((IErrorSource) tile).getErrorStates(); - } - } - - if (errorStates == null) { - errorStates = this.getErrorStates(); - } - - if (errorStates.size() == 0) { - return EnumErrorCode.OK; - } else { - return getErrorStates().iterator().next(); - } - } - - /* ICLIMATISED */ - @Override - public boolean isClimatized() { - return true; - } - - @Override - public float getExactTemperature() { - return biome.getFloatTemperature(xCoord, yCoord, zCoord) + this.tempChange; - } - - @Override - public float getExactHumidity() { - return biome.rainfall + this.humidChange; - } - - /* IHINTSOURCE */ - @Override - public boolean hasHints() { - return Config.hints.get("alveary").length > 0; - } - - @Override - public String[] getHints() { - return Config.hints.get("alveary"); - } - - /* IHousing */ - @Override - public GameProfile getOwnerName() { - return this.getOwner(); - } - - private static class AlvearyInventoryAdapter extends TileInventoryAdapter { - public AlvearyInventoryAdapter(TileAlvearyPlain tileAlvearyPlain) { - super(tileAlvearyPlain, 9, "Items"); - } - - @Override - public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { - if (slotIndex == SLOT_QUEEN) { - return BeeManager.beeRoot.isMember(itemStack) && !BeeManager.beeRoot.isDrone(itemStack); - } else if (slotIndex == SLOT_DRONE) { - return BeeManager.beeRoot.isDrone(itemStack); - } - return false; - } - - @Override - public boolean canExtractItem(int slotIndex, ItemStack itemstack, int side) { - return slotIndex != SLOT_QUEEN && slotIndex != SLOT_DRONE; - } - } -} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearySieve.java b/src/main/java/forestry/apiculture/gadgets/TileAlvearySieve.java deleted file mode 100755 index 79a8d3222..000000000 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearySieve.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; - -import forestry.api.apiculture.IAlvearyComponent; -import forestry.api.apiculture.IBee; -import forestry.api.apiculture.IBeeListener; -import forestry.api.arboriculture.EnumGermlingType; -import forestry.api.core.ForestryAPI; -import forestry.api.genetics.AlleleManager; -import forestry.api.genetics.IIndividual; -import forestry.core.config.ForestryItem; -import forestry.core.interfaces.ICrafter; -import forestry.core.inventory.IInventoryAdapter; -import forestry.core.inventory.TileInventoryAdapter; -import forestry.core.network.GuiId; -import forestry.core.proxy.Proxies; -import forestry.core.utils.StackUtils; - -public class TileAlvearySieve extends TileAlveary implements ICrafter, IBeeListener { - - /* CONSTANTS */ - public static final int BLOCK_META = 7; - - public static final int SLOT_POLLEN_1 = 0; - public static final int SLOTS_POLLEN_COUNT = 4; - public static final int SLOT_SIEVE = 4; - - public TileAlvearySieve() { - super(BLOCK_META); - setInternalInventory(new AlvearySieveInventoryAdapter(this)); - } - - @Override - public void openGui(EntityPlayer player) { - player.openGui(ForestryAPI.instance, GuiId.AlvearySieveGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); - } - - @Override - public boolean hasFunction() { - return true; - } - - /* UPDATING */ - @Override - public void initialize() { - super.initialize(); - - if (!hasMaster() || !isIntegratedIntoStructure() || !Proxies.common.isSimulating(worldObj)) { - return; - } - - ((IAlvearyComponent) getCentralTE()).registerBeeListener(this); - } - - @Override - protected void updateServerSide() { - super.updateServerSide(); - if (!updateOnInterval(200)) { - return; - } - - if (!hasMaster() || !isIntegratedIntoStructure()) { - return; - } - - ((IAlvearyComponent) getCentralTE()).registerBeeListener(this); - } - - /* TEXTURES & INTERNAL */ - @Override - public int getIcon(int side, int metadata) { - if (side == 0 || side == 1) { - return BlockAlveary.BOTTOM; - } - return BlockAlveary.SIEVE; - } - - private void destroySieve() { - IInventoryAdapter inventory = getInternalInventory(); - inventory.setInventorySlotContents(SLOT_SIEVE, null); - } - - private void destroyPollen() { - IInventoryAdapter inventory = getInternalInventory(); - for (int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { - inventory.setInventorySlotContents(i, null); - } - } - - private boolean canStorePollen() { - IInventoryAdapter inventory = getInternalInventory(); - if (inventory.getStackInSlot(SLOT_SIEVE) == null) { - return false; - } - - for (int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - return true; - } - } - - return false; - } - - private void storePollenStack(ItemStack itemstack) { - IInventoryAdapter inventory = getInternalInventory(); - for (int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - inventory.setInventorySlotContents(i, itemstack); - return; - } - } - } - - /* ICRAFTER */ - @Override - public boolean canTakeStack(int slotIndex) { - return true; - } - - @Override - public ItemStack takenFromSlot(int slotIndex, EntityPlayer player) { - IInventoryAdapter inventory = getInternalInventory(); - if (slotIndex == SLOT_SIEVE) { - destroyPollen(); - return inventory.getStackInSlot(SLOT_SIEVE); - } else { - destroySieve(); - return inventory.getStackInSlot(slotIndex); - } - } - - @Override - public ItemStack getResult() { - return null; - } - - /* IBEELISTENER */ - @Override - public void onQueenChange(ItemStack queen) { - } - - @Override - public void wearOutEquipment(int amount) { - } - - @Override - public void onQueenDeath(IBee queen) { - } - - @Override - public void onPostQueenDeath(IBee queen) { - } - - @Override - public boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled) { - - if (isHandled) { - return true; - } - if (!canStorePollen()) { - return false; - } - - storePollenStack(AlleleManager.alleleRegistry.getSpeciesRoot(pollen.getClass()).getMemberStack(pollen, EnumGermlingType.POLLEN.ordinal())); - return true; - } - - @Override - public boolean onEggLaid(IBee queen) { - return false; - } - - private static class AlvearySieveInventoryAdapter extends TileInventoryAdapter { - public AlvearySieveInventoryAdapter(TileAlvearySieve alvearySieve) { - super(alvearySieve, 5, "Items", 1); - } - - @Override - public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { - return StackUtils.isIdenticalItem(ForestryItem.craftingMaterial.getItemStack(1, 3), itemStack); - } - } -} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearyStabiliser.java b/src/main/java/forestry/apiculture/gadgets/TileAlvearyStabiliser.java deleted file mode 100755 index 79166e165..000000000 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearyStabiliser.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -import forestry.api.apiculture.IAlvearyComponent; -import forestry.api.apiculture.IBeeGenome; -import forestry.api.apiculture.IBeeModifier; -import forestry.core.proxy.Proxies; - -public class TileAlvearyStabiliser extends TileAlveary implements IBeeModifier { - - public static final int BLOCK_META = 6; - - public TileAlvearyStabiliser() { - super(BLOCK_META); - } - - /* UPDATING */ - @Override - public void initialize() { - super.initialize(); - - if (!hasMaster() || !isIntegratedIntoStructure() || !Proxies.common.isSimulating(worldObj)) { - return; - } - - ((IAlvearyComponent) getCentralTE()).registerBeeModifier(this); - - } - - @Override - protected void updateServerSide() { - super.updateServerSide(); - if (!updateOnInterval(200)) { - return; - } - - if (!hasMaster() || !isIntegratedIntoStructure()) { - return; - } - - ((IAlvearyComponent) getCentralTE()).registerBeeModifier(this); - } - - - @Override - public boolean hasFunction() { - return true; - } - - /* TEXTURES */ - @Override - public int getIcon(int side, int metadata) { - if (side == 0 || side == 1) { - return BlockAlveary.BOTTOM; - } - - return BlockAlveary.STABILISER; - } - - /* IBEEMODIFIER */ - @Override - public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return 0.0f; - } - - @Override - public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return 1.0f; - } - - @Override - public float getProductionModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public float getFloweringModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public float getGeneticDecay(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public boolean isSealed() { - return false; - } - - @Override - public boolean isSelfLighted() { - return false; - } - - @Override - public boolean isSunlightSimulated() { - return false; - } - - @Override - public boolean isHellish() { - return false; - } - -} diff --git a/src/main/java/forestry/apiculture/gadgets/TileApiary.java b/src/main/java/forestry/apiculture/gadgets/TileApiary.java index 28fe61c05..4b1c9e7a9 100755 --- a/src/main/java/forestry/apiculture/gadgets/TileApiary.java +++ b/src/main/java/forestry/apiculture/gadgets/TileApiary.java @@ -10,10 +10,16 @@ ******************************************************************************/ package forestry.apiculture.gadgets; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; +import java.util.List; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; @@ -21,20 +27,41 @@ import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.common.Optional; import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.DefaultBeeListener; +import forestry.api.apiculture.DefaultBeeModifier; +import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; +import forestry.api.apiculture.IBeekeepingMode; import forestry.api.apiculture.IHiveFrame; import forestry.api.core.ForestryAPI; import forestry.apiculture.trigger.ApicultureTriggers; import forestry.core.gadgets.TileBase; -import forestry.core.inventory.IInventoryAdapter; +import forestry.core.inventory.wrappers.InventoryMapper; import forestry.core.network.GuiId; +import forestry.core.utils.GuiUtil; import buildcraft.api.statements.ITriggerExternal; -public class TileApiary extends TileBeehouse { +public class TileApiary extends TileBeeHousing { + private static final IBeeModifier beeModifier = new ApiaryBeeModifier(); + + private final IBeeListener beeListener; + private final ApiaryInventory inventory; public TileApiary() { - setInternalInventory(new BeehouseInventoryAdapter(this, 12, "Items")); + this.beeListener = new ApiaryBeeListener(this); + + ApiaryInventory apiaryInventory = new ApiaryInventory(this, 12, "Items"); + this.inventory = apiaryInventory; + setInternalInventory(apiaryInventory); + } + + @Override + public IBeeHousingInventory getBeeInventory() { + return inventory; } @Override @@ -42,209 +69,105 @@ public class TileApiary extends TileBeehouse { player.openGui(ForestryAPI.instance, GuiId.ApiaryGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); } - /* IBEEHOUSING */ @Override - public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { - IInventoryAdapter inventory = getInternalInventory(); - float mod = 1.0f; - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) { - mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getTerritoryModifier(genome, mod); - } + public Collection getBeeModifiers() { + List beeModifiers = new ArrayList(); + + beeModifiers.add(beeModifier); + + for (IHiveFrame frame : inventory.getFrames()) { + beeModifiers.add(frame.getBeeModifier()); } - return mod; + + return beeModifiers; } @Override - public float getProductionModifier(IBeeGenome genome, float currentModifier) { - IInventoryAdapter inventory = getInternalInventory(); - float mod = 0.1f; - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) { - mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getProductionModifier(genome, mod); - } - } - return mod; + public Iterable getBeeListeners() { + return Collections.singleton(beeListener); } - @Override - public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - IInventoryAdapter inventory = getInternalInventory(); - float mod = 1.0f; - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) { - mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getMutationModifier(genome, mate, mod); - } - } - return mod; - } - - @Override - public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - IInventoryAdapter inventory = getInternalInventory(); - float mod = 1.0f; - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) { - mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getLifespanModifier(genome, mate, mod); - } - } - return mod; - } - - @Override - public float getFloweringModifier(IBeeGenome genome, float currentModifier) { - IInventoryAdapter inventory = getInternalInventory(); - float mod = 1f; - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) { - mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getFloweringModifier(genome, mod); - } - } - return mod; - } - - @Override - public float getGeneticDecay(IBeeGenome genome, float currentModifier) { - IInventoryAdapter inventory = getInternalInventory(); - float mod = 1f; - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) { - mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getGeneticDecay(genome, mod); - } - } - return mod; - } - - @Override - public void wearOutEquipment(int amount) { - IInventoryAdapter inventory = getInternalInventory(); - int wear = Math.round(amount * BeeManager.beeRoot.getBeekeepingMode(worldObj).getWearModifier()); - - for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (!(inventory.getStackInSlot(i).getItem() instanceof IHiveFrame)) { - continue; - } - - inventory.setInventorySlotContents( - i, - ((IHiveFrame) inventory.getStackInSlot(i).getItem()).frameUsed(this, inventory.getStackInSlot(i), - BeeManager.beeRoot.getMember(inventory.getStackInSlot(SLOT_QUEEN)), wear)); + private static class ApiaryBeeModifier extends DefaultBeeModifier { + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return 0.1f; } } - /* ISPECIALINVENTORY */ - // @Override - // public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { - // ItemStack product = null; - // - // for (int i = SLOT_PRODUCT_1; i < SLOT_PRODUCT_1 + SLOT_PRODUCT_COUNT; i++) { - // if (inventory.getStackInSlot(i) == null) - // continue; - // - // // Princesses can only be extracted from top. - // if (ForestryItem.beePrincessGE.isItemEqual(inventory.getStackInSlot(i))) { - // if (PluginApiculture.apiarySideSensitive && from != ForgeDirection.UP) - // continue; - // - // product = inventory.getStackInSlot(i).copy(); - // if (doRemove) { - // inventory.getStackInSlot(i).stackSize = 0; - // inventory.setInventorySlotContents(i, null); - // } - // break; - // - // // Drones can only be extracted from the bottom. - // } else if (ForestryItem.beeDroneGE.isItemEqual(inventory.getStackInSlot(i))) { - // if (PluginApiculture.apiarySideSensitive && from != ForgeDirection.DOWN) - // continue; - // - // product = StackUtils.createSplitStack(inventory.getStackInSlot(i), 1); - // product.stackSize = 1; - // if (doRemove) { - // inventory.getStackInSlot(i).stackSize--; - // if (inventory.getStackInSlot(i).stackSize <= 0) - // inventory.setInventorySlotContents(i, null); - // } - // break; - // - // // Everything else to be extracted from the sides - // } else { - // if (PluginApiculture.apiarySideSensitive && (from == ForgeDirection.UP || from == ForgeDirection.DOWN)) - // continue; - // - // product = StackUtils.createSplitStack(inventory.getStackInSlot(i), 1); - // if (doRemove) { - // inventory.getStackInSlot(i).stackSize--; - // if (inventory.getStackInSlot(i).stackSize <= 0) - // inventory.setInventorySlotContents(i, null); - // } - // break; - // } - // } - // - // return new ItemStack[] { product }; - // } - // - // @Override - // public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { - // // Princesses && Queens - // if (ForestryItem.beePrincessGE.isItemEqual(stack) || ForestryItem.beeQueenGE.isItemEqual(stack)) - // if (inventory.getStackInSlot(SLOT_QUEEN) == null) { - // if (doAdd) { - // inventory.setInventorySlotContents(SLOT_QUEEN, stack.copy()); - // inventory.getStackInSlot(SLOT_QUEEN).stackSize = 1; - // } - // - // return 1; - // } - // - // // Drones - // if (ForestryItem.beeDroneGE.isItemEqual(stack)) { - // - // ItemStack droneStack = inventory.getStackInSlot(SLOT_DRONE); - // if (droneStack == null) { - // if (doAdd) - // inventory.setInventorySlotContents(SLOT_DRONE, stack.copy()); - // return stack.stackSize; - // } else { - // if (!droneStack.isItemEqual(stack)) - // return 0; - // if (!ItemStack.areItemStackTagsEqual(droneStack, stack)) - // return 0; - // int space = droneStack.getMaxStackSize() - droneStack.stackSize; - // if (space <= 0) - // return 0; - // - // int added = space > stack.stackSize ? stack.stackSize : space; - // if (doAdd) - // droneStack.stackSize += added; - // return added; - // } - // } - // - // return 0; - // } + private static class ApiaryBeeListener extends DefaultBeeListener { + private final TileApiary apiary; + + public ApiaryBeeListener(TileApiary apiary) { + this.apiary = apiary; + } + + @Override + public void wearOutEquipment(int amount) { + IBeekeepingMode beekeepingMode = BeeManager.beeRoot.getBeekeepingMode(apiary.getWorldObj()); + int wear = Math.round(amount * beekeepingMode.getWearModifier()); + + IInventory framesInventory = apiary.inventory.getFrameInventory(); + for (int i = 0; i < framesInventory.getSizeInventory(); i++) { + ItemStack hiveFrameStack = framesInventory.getStackInSlot(i); + if (hiveFrameStack == null) { + continue; + } + + Item hiveFrameItem = hiveFrameStack.getItem(); + if (!(hiveFrameItem instanceof IHiveFrame)) { + continue; + } + + IHiveFrame hiveFrame = (IHiveFrame) hiveFrameItem; + + ItemStack queenStack = apiary.getBeeInventory().getQueen(); + IBee queen = BeeManager.beeRoot.getMember(queenStack); + ItemStack usedFrame = hiveFrame.frameUsed(apiary, hiveFrameStack, queen, wear); + + framesInventory.setInventorySlotContents(i, usedFrame); + } + } + } + + public static class ApiaryInventory extends TileBeeHousingInventory { + public static final int SLOT_FRAMES_1 = 9; + public static final int SLOT_FRAMES_COUNT = 3; + + public ApiaryInventory(TileApiary tile, int size, String name) { + super(tile, size, name); + } + + @Override + public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { + if (GuiUtil.isIndexInRange(slotIndex, SLOT_FRAMES_1, SLOT_FRAMES_COUNT)) { + return itemStack.getItem() instanceof IHiveFrame; + } + + return super.canSlotAccept(slotIndex, itemStack); + } + + public IInventory getFrameInventory() { + return new InventoryMapper(this, SLOT_FRAMES_1, SLOT_FRAMES_COUNT); + } + + public Collection getFrames() { + Collection hiveFrames = new ArrayList(SLOT_FRAMES_COUNT); + + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + ItemStack stackInSlot = getStackInSlot(i); + if (stackInSlot == null) { + continue; + } + + Item itemInSlot = stackInSlot.getItem(); + if (itemInSlot instanceof IHiveFrame) { + hiveFrames.add((IHiveFrame) itemInSlot); + } + } + + return hiveFrames; + } + } /* ITRIGGERPROVIDER */ @Optional.Method(modid = "BuildCraftAPI|statements") diff --git a/src/main/java/forestry/apiculture/gadgets/TileBeeHousing.java b/src/main/java/forestry/apiculture/gadgets/TileBeeHousing.java new file mode 100644 index 000000000..2bf75382f --- /dev/null +++ b/src/main/java/forestry/apiculture/gadgets/TileBeeHousing.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import com.mojang.authlib.GameProfile; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.apiculture.BeeHousingInventory; +import forestry.core.config.Config; +import forestry.core.gadgets.TileBase; +import forestry.core.interfaces.IClimatised; +import forestry.core.proxy.Proxies; + +public abstract class TileBeeHousing extends TileBase implements IBeeHousing, IClimatised { + private final IBeekeepingLogic beeLogic; + private BiomeGenBase cachedBiome; + + // CLIENT + private int breedingProgressPercent = 0; + + public TileBeeHousing() { + setHints(Config.hints.get("apiary")); + this.beeLogic = BeeManager.beeRoot.createBeekeepingLogic(this); + } + + @Override + public IBeekeepingLogic getBeekeepingLogic() { + return beeLogic; + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + beeLogic.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + beeLogic.readFromNBT(nbttagcompound); + } + + /* ICLIMATISED */ + @Override + public EnumTemperature getTemperature() { + return EnumTemperature.getFromBiome(getBiome(), xCoord, yCoord, zCoord); + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.getFromValue(getExactHumidity()); + } + + @Override + public float getExactTemperature() { + return getBiome().getFloatTemperature(xCoord, yCoord, zCoord); + } + + @Override + public float getExactHumidity() { + return getBiome().rainfall; + } + + /* UPDATING */ + @Override + public void updateClientSide() { + if (beeLogic.canDoBeeFX() && updateOnInterval(4)) { + beeLogic.doBeeFX(); + + if (updateOnInterval(50)) { + float fxX = xCoord + 0.5F; + float fxY = yCoord + 0.25F; + float fxZ = zCoord + 0.5F; + float distanceFromCenter = 0.6F; + float leftRightSpreadFromCenter = distanceFromCenter * (worldObj.rand.nextFloat() - 0.5F); + float upSpread = (worldObj.rand.nextFloat() * 6F) / 16F; + fxY += upSpread; + + Proxies.common.addEntitySwarmFX(worldObj, (fxX - distanceFromCenter), fxY, (fxZ + leftRightSpreadFromCenter), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (fxX + distanceFromCenter), fxY, (fxZ + leftRightSpreadFromCenter), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (fxX + leftRightSpreadFromCenter), fxY, (fxZ - distanceFromCenter), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (fxX + leftRightSpreadFromCenter), fxY, (fxZ + distanceFromCenter), 0F, 0F, 0F); + } + } + } + + @Override + public void updateServerSide() { + if (beeLogic.canWork()) { + beeLogic.doWork(); + } + } + + /** + * Returns scaled queen health or breeding progress + */ + public int getHealthScaled(int i) { + return (breedingProgressPercent * i) / 100; + } + + /* SMP */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + breedingProgressPercent = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, beeLogic.getBeeProgressPercent()); + } + + // / IBEEHOUSING + @Override + public BiomeGenBase getBiome() { + if (cachedBiome == null) { + cachedBiome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); + } + return cachedBiome; + } + + @Override + public int getBlockLightValue() { + return worldObj.getBlockLightValue(xCoord, yCoord + 1, zCoord); + } + + @Override + public boolean canBlockSeeTheSky() { + return worldObj.canBlockSeeTheSky(xCoord, yCoord + 1, zCoord); + } + + @Override + public GameProfile getOwner() { + return getAccessHandler().getOwner(); + } + + @Override + public World getWorld() { + return worldObj; + } + + public static class TileBeeHousingInventory extends BeeHousingInventory { + private final TileBeeHousing tile; + + public TileBeeHousingInventory(TileBeeHousing tile, int size, String name) { + super(size, name, tile.getAccessHandler()); + this.tile = tile; + } + + @Override + public void markDirty() { + super.markDirty(); + tile.markDirty(); + } + } + +} diff --git a/src/main/java/forestry/apiculture/gadgets/TileBeehouse.java b/src/main/java/forestry/apiculture/gadgets/TileBeehouse.java index a864f50e9..c28cd3ff9 100755 --- a/src/main/java/forestry/apiculture/gadgets/TileBeehouse.java +++ b/src/main/java/forestry/apiculture/gadgets/TileBeehouse.java @@ -10,66 +10,39 @@ ******************************************************************************/ package forestry.apiculture.gadgets; -import java.io.IOException; -import java.util.Set; +import java.util.Collections; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.ICrafting; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import com.mojang.authlib.GameProfile; - -import forestry.api.apiculture.BeeManager; -import forestry.api.apiculture.IBee; +import forestry.api.apiculture.DefaultBeeListener; +import forestry.api.apiculture.DefaultBeeModifier; import forestry.api.apiculture.IBeeGenome; -import forestry.api.apiculture.IBeeHousing; -import forestry.api.apiculture.IBeekeepingLogic; -import forestry.api.apiculture.IHiveFrame; -import forestry.api.core.EnumHumidity; -import forestry.api.core.EnumTemperature; +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; import forestry.api.core.ForestryAPI; -import forestry.api.core.IErrorState; -import forestry.api.genetics.IIndividual; -import forestry.apiculture.network.PacketActiveUpdate; -import forestry.core.EnumErrorCode; -import forestry.core.config.Config; import forestry.core.gadgets.TileBase; -import forestry.core.interfaces.IActivatable; -import forestry.core.interfaces.IClimatised; -import forestry.core.inventory.InvTools; -import forestry.core.inventory.TileInventoryAdapter; -import forestry.core.network.DataInputStreamForestry; -import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; -import forestry.core.proxy.Proxies; -import forestry.core.utils.GuiUtil; -public class TileBeehouse extends TileBase implements IBeeHousing, IClimatised, IActivatable { - // CONSTANTS - public static final int SLOT_QUEEN = 0; - public static final int SLOT_DRONE = 1; - public static final int SLOT_PRODUCT_1 = 2; - public static final int SLOT_PRODUCT_COUNT = 7; - public static final int SLOT_FRAMES_1 = 9; - public static final int SLOT_FRAMES_COUNT = 3; +public class TileBeehouse extends TileBeeHousing { + private static final IBeeModifier beeModifier = new BeehouseBeeModifier(); - private final IBeekeepingLogic logic; - private BiomeGenBase biome; - - // CLIENT - private boolean active; - private int displayHealthMax = 0; - private int displayHealth = 0; - private IBee displayQueen; + private final IBeeListener beeListener; + private final IBeeHousingInventory beeInventory; public TileBeehouse() { - setHints(Config.hints.get("apiary")); - logic = BeeManager.beeRoot.createBeekeepingLogic(this); - setInternalInventory(new BeehouseInventoryAdapter(this, 12, "Items").disableAutomation()); + this.beeListener = new DefaultBeeListener(); + + TileBeeHousingInventory beeHousingInventory = new TileBeeHousingInventory(this, 12, "Items"); + beeHousingInventory.disableAutomation(); + + this.beeInventory = beeHousingInventory; + setInternalInventory(beeHousingInventory); + } + + @Override + public IBeeHousingInventory getBeeInventory() { + return beeInventory; } @Override @@ -77,410 +50,45 @@ public class TileBeehouse extends TileBase implements IBeeHousing, IClimatised, player.openGui(ForestryAPI.instance, GuiId.BeehouseGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); } - /* LOADING & SAVING */ @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - - nbttagcompound.setInteger("BiomeId", biome.biomeID); - if (logic != null) { - logic.writeToNBT(nbttagcompound); - } + public Iterable getBeeModifiers() { + return Collections.singleton(beeModifier); } @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - super.readFromNBT(nbttagcompound); - - int biomeId = nbttagcompound.getInteger("BiomeId"); - biome = BiomeGenBase.getBiome(biomeId); - logic.readFromNBT(nbttagcompound); + public Iterable getBeeListeners() { + return Collections.singleton(beeListener); } - @Override - public void writeData(DataOutputStreamForestry data) throws IOException { - super.writeData(data); - data.writeBoolean(active); - if (active) { - ItemStack queen = getStackInSlot(SLOT_QUEEN); - data.writeItemStack(queen); - } - } - - @Override - public void readData(DataInputStreamForestry data) throws IOException { - super.readData(data); - active = data.readBoolean(); - if (active) { - ItemStack queen = data.readItemStack(); - setInventorySlotContents(SLOT_QUEEN, queen); - } - } - - @Override - public void initialize() { - super.initialize(); - updateBiome(); - } - - @Override - public void validate() { - updateBiome(); - } - - /* ICLIMATISED */ - @Override - public boolean isClimatized() { - return true; - } - - @Override - public EnumTemperature getTemperature() { - return EnumTemperature.getFromBiome(biome, xCoord, yCoord, zCoord); - } - - @Override - public EnumHumidity getHumidity() { - return EnumHumidity.getFromValue(getExactHumidity()); - } - - @Deprecated - @Override - public void setErrorState(IErrorState state) { - removeErrorStates(); - if (state != EnumErrorCode.OK) { - addErrorState(state); - } - } - - @Deprecated - @Override - public IErrorState getErrorState() { - Set errorStates = getErrorStates(); - if (errorStates.size() == 0) { - return EnumErrorCode.OK; - } else { - return getErrorStates().iterator().next(); - } - } - - @Override - public float getExactTemperature() { - return biome.getFloatTemperature(xCoord, yCoord, zCoord); - } - - @Override - public float getExactHumidity() { - return biome.rainfall; - } - - /* UPDATING */ - @Override - public void updateClientSide() { - if (isActive() && (displayQueen != null) && updateOnInterval(4)) { - displayQueen.doFX(logic.getEffectData(), this); - - if (updateOnInterval(50)) { - float fxX = xCoord + 0.5F; - float fxY = yCoord + 0.25F + (worldObj.rand.nextFloat() * 6F) / 16F; - float fxZ = zCoord + 0.5F; - float f3 = 0.6F; - float f4 = worldObj.rand.nextFloat() * f3 - 0.5F; - - Proxies.common.addEntitySwarmFX(worldObj, (fxX - f3), fxY, (fxZ + f4), 0F, 0F, 0F); - Proxies.common.addEntitySwarmFX(worldObj, (fxX + f3), fxY, (fxZ + f4), 0F, 0F, 0F); - Proxies.common.addEntitySwarmFX(worldObj, (fxX + f4), fxY, (fxZ - f3), 0F, 0F, 0F); - Proxies.common.addEntitySwarmFX(worldObj, (fxX + f4), fxY, (fxZ + f3), 0F, 0F, 0F); - } - } - } - - @Override - public void updateServerSide() { - boolean canWork = logic.canWork(); - setActive(canWork); - if (canWork) { - logic.doWork(); - } - } - - // @Override - public boolean isWorking() { - return !hasErrorState(); - } - - @Override - public boolean addProduct(ItemStack product, boolean all) { - return InvTools.tryAddStack(getInternalInventory(), product, SLOT_PRODUCT_1, SLOT_PRODUCT_COUNT, all, true); - } - - /* NETWORK SYNCH */ - @Override - public void onQueenChange(ItemStack queenStack) { - } - - /* STATE INFORMATION */ - private int getHealthDisplay() { - if (displayQueen == null) { - return 0; - } - - if (displayQueen.getMate() != null) { - return displayQueen.getHealth(); - } else { - return displayHealth; - } - } - - private int getMaxHealthDisplay() { - if (displayQueen == null) { - return 0; - } - - if (displayQueen.getMate() != null) { - return displayQueen.getMaxHealth(); - } else { - return displayHealthMax; - } - } - - /** - * Returns scaled queen health or breeding progress - */ - public int getHealthScaled(int i) { - if (getMaxHealthDisplay() == 0) { - return 0; - } - - return (getHealthDisplay() * i) / getMaxHealthDisplay(); - } - - public void updateBiome() { - if (worldObj != null) { - BiomeGenBase biome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); - if (biome != null) { - this.biome = biome; - } - } - } - - /* SMP */ - // @Override - public void getGUINetworkData(int i, int j) { - if (logic == null) { - return; - } - - switch (i) { - case 0: - displayHealth = j; - break; - case 1: - displayHealthMax = j; - break; - } - } - - // @Override - public void sendGUINetworkData(Container container, ICrafting iCrafting) { - if (logic == null) { - return; - } - - iCrafting.sendProgressBarUpdate(container, 0, logic.getBreedingTime()); - iCrafting.sendProgressBarUpdate(container, 1, logic.getTotalBreedingTime()); - } - - // / IBEEHOUSING - @Override - public int getXCoord() { - return xCoord; - } - - @Override - public int getYCoord() { - return yCoord; - } - - @Override - public int getZCoord() { - return zCoord; - } - - @Override - public BiomeGenBase getBiome() { - return biome; - } - - @Override - public ItemStack getQueen() { - return getStackInSlot(SLOT_QUEEN); - } - - @Override - public ItemStack getDrone() { - return getStackInSlot(SLOT_DRONE); - } - - @Override - public void setQueen(ItemStack itemstack) { - setInventorySlotContents(SLOT_QUEEN, itemstack); - } - - @Override - public ItemStack decrStackSize(int slotIndex, int amount) { - ItemStack itemStack = super.decrStackSize(slotIndex, amount); - if (slotIndex == SLOT_QUEEN) { - handleQueenChange(); - } - return itemStack; - } - - @Override - public void setInventorySlotContents(int slotIndex, ItemStack itemStack) { - super.setInventorySlotContents(slotIndex, itemStack); - if (slotIndex == SLOT_QUEEN) { - handleQueenChange(); - } - } - - private void handleQueenChange() { - if (!Proxies.common.isSimulating(worldObj)) { - ItemStack itemStack = getStackInSlot(SLOT_QUEEN); - displayQueen = BeeManager.beeRoot.getMember(itemStack); - } - } - - @Override - public void setDrone(ItemStack itemstack) { - setInventorySlotContents(SLOT_DRONE, itemstack); - } - - @Override - public World getWorld() { - return worldObj; - } - - @Override - public boolean canBreed() { - return true; - } - - @Override - public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public float getProductionModifier(IBeeGenome genome, float currentModifier) { - return 0.25f; - } - - @Override - public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return 0.0f; - } - - @Override - public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return 3.0f; - } - - @Override - public float getFloweringModifier(IBeeGenome genome, float currentModifier) { - return 3.0f; - } - - @Override - public float getGeneticDecay(IBeeGenome genome, float currentModifier) { - return 0.0f; - } - - @Override - public void wearOutEquipment(int amount) { - } - - @Override - public boolean isSealed() { - return false; - } - - @Override - public boolean isSelfLighted() { - return false; - } - - @Override - public boolean isSunlightSimulated() { - return false; - } - - @Override - public boolean isHellish() { - return false; - } - - @Override - public void onQueenDeath(IBee queen) { - } - - @Override - public void onPostQueenDeath(IBee queen) { - } - - @Override - public boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled) { - return false; - } - - @Override - public boolean onEggLaid(IBee queen) { - return false; - } - - /* IHousing */ - @Override - public GameProfile getOwnerName() { - return this.getOwner(); - } - - @Override - public boolean isActive() { - return active; - } - - @Override - public void setActive(boolean active) { - if (this.active == active) { - return; - } - this.active = active; - - if (!worldObj.isRemote) { - Proxies.net.sendNetworkPacket(new PacketActiveUpdate(this)); - } - } - - protected static class BeehouseInventoryAdapter extends TileInventoryAdapter { - public BeehouseInventoryAdapter(TileBeehouse tile, int size, String name) { - super(tile, size, name); + public static class BeehouseBeeModifier extends DefaultBeeModifier { + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; } @Override - public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { - if (slotIndex == SLOT_QUEEN) { - return BeeManager.beeRoot.isMember(itemStack) && !BeeManager.beeRoot.isDrone(itemStack); - } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_FRAMES_1, SLOT_FRAMES_COUNT)) { - return itemStack.getItem() instanceof IHiveFrame; - } else if (slotIndex == SLOT_DRONE) { - return BeeManager.beeRoot.isDrone(itemStack); - } - return false; + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return 0.25f; } @Override - public boolean canExtractItem(int slotIndex, ItemStack itemstack, int side) { - return GuiUtil.isIndexInRange(slotIndex, SLOT_PRODUCT_1, SLOT_PRODUCT_COUNT); + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 0.0f; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 3.0f; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + return 3.0f; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + return 0.0f; } } } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleBeeSpecies.java b/src/main/java/forestry/apiculture/genetics/AlleleBeeSpecies.java index d15f5c448..9508de3ce 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleBeeSpecies.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleBeeSpecies.java @@ -45,12 +45,6 @@ import forestry.core.render.TextureManager; import forestry.core.utils.StackUtils; public class AlleleBeeSpecies extends AlleleSpecies implements IAlleleBeeSpeciesCustom { - - @Deprecated - private final Map products = new HashMap(); - @Deprecated - private final Map specialty = new HashMap(); - private final Map productChances = new HashMap(); private final Map specialtyChances = new HashMap(); @@ -85,8 +79,6 @@ public class AlleleBeeSpecies extends AlleleSpecies implements IAlleleBeeSpecies throw new IllegalArgumentException("chance must be in the range (0, 1]"); } this.productChances.put(product, chance); - int intChance = Math.max(1, Math.round(chance * 100)); - this.products.put(product, intChance); return this; } @@ -99,8 +91,6 @@ public class AlleleBeeSpecies extends AlleleSpecies implements IAlleleBeeSpecies throw new IllegalArgumentException("chance must be in the range (0, 1]"); } this.specialtyChances.put(specialty, chance); - int intChance = Math.max(1, Math.round(chance * 100)); - this.specialty.put(specialty, intChance); return this; } @@ -194,21 +184,11 @@ public class AlleleBeeSpecies extends AlleleSpecies implements IAlleleBeeSpecies return nocturnal; } - @Override - public Map getProducts() { - return products; - } - @Override public Map getProductChances() { return productChances; } - @Override - public Map getSpecialty() { - return specialty; - } - @Override public Map getSpecialtyChances() { return specialtyChances; diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectCreeper.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectCreeper.java index 7b85dfb41..b13dc5b92 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectCreeper.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectCreeper.java @@ -14,6 +14,7 @@ import java.util.List; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import forestry.api.apiculture.IBeeGenome; @@ -26,8 +27,8 @@ public class AlleleEffectCreeper extends AlleleEffectThrottled { private static final int explosionChance = 50; private static final byte defaultForce = 12; - private final byte indexExplosionTimer = 1; - private final byte indexExplosionForce = 2; + private static final byte indexExplosionTimer = 1; + private static final byte indexExplosionForce = 2; public AlleleEffectCreeper() { super("creeper", true, 20, false, true); @@ -50,6 +51,7 @@ public class AlleleEffectCreeper extends AlleleEffectThrottled { public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { World world = housing.getWorld(); + ChunkCoordinates housingCoords = housing.getCoordinates(); if (isHalted(storedData, housing)) { return storedData; @@ -57,7 +59,7 @@ public class AlleleEffectCreeper extends AlleleEffectThrottled { // If we are already triggered, we continue the explosion sequence. if (storedData.getInteger(indexExplosionTimer) > 0) { - progressExplosion(storedData, world, housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + progressExplosion(storedData, world, housingCoords.posX, housingCoords.posY, housingCoords.posZ); return storedData; } @@ -94,7 +96,7 @@ public class AlleleEffectCreeper extends AlleleEffectThrottled { continue; } - world.playSoundEffect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord(), "mob.creeper", 4F, + world.playSoundEffect(housingCoords.posX, housingCoords.posY, housingCoords.posZ, "mob.creeper", 4F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F); storedData.setInteger(indexExplosionTimer, 2); // Set explosion // timer @@ -103,7 +105,7 @@ public class AlleleEffectCreeper extends AlleleEffectThrottled { return storedData; } - private void progressExplosion(IEffectData storedData, World world, int x, int y, int z) { + private static void progressExplosion(IEffectData storedData, World world, int x, int y, int z) { int explosionTimer = storedData.getInteger(indexExplosionTimer); explosionTimer--; diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectFertile.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectFertile.java index 97180b748..5770acb0f 100644 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectFertile.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectFertile.java @@ -3,11 +3,13 @@ package forestry.apiculture.genetics; import java.util.Random; import net.minecraft.block.Block; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; import forestry.api.genetics.IEffectData; +import forestry.core.vect.IVect; public class AlleleEffectFertile extends AlleleEffectThrottled { @@ -25,29 +27,30 @@ public class AlleleEffectFertile extends AlleleEffectThrottled { } World world = housing.getWorld(); - int territorySize[] = getModifiedArea(genome, housing); + ChunkCoordinates housingCoordinates = housing.getCoordinates(); + IVect area = getModifiedArea(genome, housing); - int blockX = getRandomOffset(world.rand, housing.getXCoord(), territorySize[0]); - int blockZ = getRandomOffset(world.rand, housing.getZCoord(), territorySize[2]); - int blockMaxY = housing.getYCoord() + territorySize[1] / 2 + 1; - int blockMinY = housing.getYCoord() - (territorySize[1] / 2) - 1; + int blockX = getRandomOffset(world.rand, housingCoordinates.posX, area.getX()); + int blockZ = getRandomOffset(world.rand, housingCoordinates.posZ, area.getZ()); + int blockMaxY = housingCoordinates.posY + (area.getY() / 2) + 1; + int blockMinY = housingCoordinates.posY - (area.getY() / 2) - 1; for (int attempt = 0; attempt < MAX_BLOCK_FIND_TRIES; ++attempt) { if (tryTickColumn(world, blockX, blockZ, blockMaxY, blockMinY)) { break; } - blockX = getRandomOffset(world.rand, housing.getXCoord(), territorySize[0]); - blockZ = getRandomOffset(world.rand, housing.getZCoord(), territorySize[2]); + blockX = getRandomOffset(world.rand, housingCoordinates.posX, area.getX()); + blockZ = getRandomOffset(world.rand, housingCoordinates.posZ, area.getZ()); } return storedData; } - private int getRandomOffset(Random random, int centrePos, int offset) { + private static int getRandomOffset(Random random, int centrePos, int offset) { return centrePos + random.nextInt(offset) - (offset / 2); } - private boolean tryTickColumn(World world, int x, int z, int maxY, int minY) { + private static boolean tryTickColumn(World world, int x, int z, int maxY, int minY) { for (int y = maxY; y >= minY; --y) { if (!world.isAirBlock(x, y, z)) { Block block = world.getBlock(x, y, z); diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectFungification.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectFungification.java index 31a109e37..e1f0bf4dd 100644 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectFungification.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectFungification.java @@ -8,6 +8,7 @@ import net.minecraft.entity.passive.EntityCow; import net.minecraft.entity.passive.EntityMooshroom; import net.minecraft.init.Blocks; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenBigMushroom; @@ -15,6 +16,7 @@ import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; import forestry.api.genetics.IEffectData; import forestry.core.genetics.EffectData; +import forestry.core.vect.IVect; public class AlleleEffectFungification extends AlleleEffectThrottled { @@ -56,11 +58,12 @@ public class AlleleEffectFungification extends AlleleEffectThrottled { private void doBlockEffect(IBeeGenome genome, IBeeHousing housing) { World world = housing.getWorld(); - int territorySize[] = getModifiedArea(genome, housing); + ChunkCoordinates housingCoordinates = housing.getCoordinates(); + IVect area = getModifiedArea(genome, housing); - int blockX = getRandomOffset(world.rand, housing.getXCoord(), territorySize[0]); - int blockY = getRandomOffset(world.rand, housing.getYCoord(), territorySize[1]); - int blockZ = getRandomOffset(world.rand, housing.getZCoord(), territorySize[2]); + int blockX = getRandomOffset(world.rand, housingCoordinates.posX, area.getX()); + int blockY = getRandomOffset(world.rand, housingCoordinates.posY, area.getY()); + int blockZ = getRandomOffset(world.rand, housingCoordinates.posZ, area.getZ()); for (int attempt = 0; attempt < MAX_BLOCK_FIND_TRIES; ++attempt) { Block block = world.getBlock(blockX, blockY, blockZ); @@ -71,9 +74,9 @@ public class AlleleEffectFungification extends AlleleEffectThrottled { doMushroomGrowth(block, world, blockX, blockY, blockZ); break; } - blockX = getRandomOffset(world.rand, housing.getXCoord(), territorySize[0]); - blockY = getRandomOffset(world.rand, housing.getYCoord(), territorySize[1]); - blockZ = getRandomOffset(world.rand, housing.getZCoord(), territorySize[2]); + blockX = getRandomOffset(world.rand, housingCoordinates.posX, area.getX()); + blockY = getRandomOffset(world.rand, housingCoordinates.posY, area.getY()); + blockZ = getRandomOffset(world.rand, housingCoordinates.posZ, area.getZ()); } } @@ -91,15 +94,15 @@ public class AlleleEffectFungification extends AlleleEffectThrottled { } } - private int getRandomOffset(Random random, int centrePos, int offset) { + private static int getRandomOffset(Random random, int centrePos, int offset) { return centrePos + random.nextInt(offset) - (offset / 2); } - private boolean isSuitableForMycelium(World world, Block block, int blockX, int blockY, int blockZ) { + private static boolean isSuitableForMycelium(World world, Block block, int blockX, int blockY, int blockZ) { return block == Blocks.grass || (block == Blocks.dirt && world.canBlockSeeTheSky(blockX, blockY, blockZ)); } - private boolean isSuitableForGrowth(Block block) { + private static boolean isSuitableForGrowth(Block block) { return block == Blocks.red_mushroom || block == Blocks.brown_mushroom; } @@ -114,7 +117,7 @@ public class AlleleEffectFungification extends AlleleEffectThrottled { worldObj.spawnParticle("largeexplode", cow.posX, cow.posY + (double) (cow.height / 2.0F), cow.posZ, 0.0D, 0.0D, 0.0D); } - private void doMushroomGrowth(Block block, World world, int blockX, int blockY, int blockZ) { + private static void doMushroomGrowth(Block block, World world, int blockX, int blockY, int blockZ) { WorldGenBigMushroom giantMushroomGenerator; if (block == Blocks.brown_mushroom) { diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectGlacial.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectGlacial.java index 2430c3e7f..ab75a573f 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectGlacial.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectGlacial.java @@ -13,7 +13,6 @@ package forestry.apiculture.genetics; import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; @@ -50,13 +49,12 @@ public class AlleleEffectGlacial extends AlleleEffectThrottled { int[] areaAr = genome.getTerritory(); Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]); Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + Vect housingCoords = new Vect(housing.getCoordinates()); for (int i = 0; i < 10; i++) { - Vect randomPos = new Vect(world.rand.nextInt(area.x), world.rand.nextInt(area.y), world.rand.nextInt(area.z)); - - Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); - posBlock = posBlock.add(offset); + Vect randomPos = Vect.getRandomPositionInArea(world.rand, area); + Vect posBlock = Vect.add(randomPos, housingCoords, offset); // Freeze water Block block = world.getBlock(posBlock.x, posBlock.y, posBlock.z); diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectIgnition.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectIgnition.java index 4720a542e..ae3ddd2fe 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectIgnition.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectIgnition.java @@ -21,6 +21,7 @@ import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; import forestry.api.genetics.IEffectData; import forestry.apiculture.items.ItemArmorApiarist; +import forestry.core.vect.IVect; import forestry.plugins.PluginApiculture; public class AlleleEffectIgnition extends AlleleEffectThrottled { @@ -83,14 +84,12 @@ public class AlleleEffectIgnition extends AlleleEffectThrottled { @Override public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { - int[] area = getModifiedArea(genome, housing); + IVect area = getModifiedArea(genome, housing); if (housing.getWorld().rand.nextBoolean()) { - PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), - housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getCoordinates(), genome.getPrimary().getIconColour(0), area); } else { - PluginApiculture.proxy.addBeeHiveFX("particles/ember", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), - housing.getZCoord(), 0xffffff, area[0], area[1], area[2]); + PluginApiculture.proxy.addBeeHiveFX("particles/ember", housing.getWorld(), housing.getCoordinates(), 0xffffff, area); } return storedData; } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectMiasmic.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectMiasmic.java index 0874591a2..785c54f06 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectMiasmic.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectMiasmic.java @@ -22,6 +22,7 @@ import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; import forestry.api.genetics.IEffectData; import forestry.apiculture.items.ItemArmorApiarist; +import forestry.core.vect.IVect; import forestry.plugins.PluginApiculture; public class AlleleEffectMiasmic extends AlleleEffectThrottled { @@ -78,14 +79,12 @@ public class AlleleEffectMiasmic extends AlleleEffectThrottled { @Override public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { - int[] area = getModifiedArea(genome, housing); + IVect area = getModifiedArea(genome, housing); if (housing.getWorld().rand.nextBoolean()) { - PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), - housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getCoordinates(), genome.getPrimary().getIconColour(0), area); } else { - PluginApiculture.proxy.addBeeHiveFX("particles/poison", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), - housing.getZCoord(), 0xffffff, area[0], area[1], area[2]); + PluginApiculture.proxy.addBeeHiveFX("particles/poison", housing.getWorld(), housing.getCoordinates(), 0xffffff, area); } return storedData; } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectNone.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectNone.java index 7efa581c3..f8700500e 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectNone.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectNone.java @@ -13,8 +13,11 @@ package forestry.apiculture.genetics; import forestry.api.apiculture.IAlleleBeeEffect; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.genetics.IEffectData; +import forestry.apiculture.BeeHousingModifier; import forestry.core.genetics.alleles.AlleleCategorized; +import forestry.core.vect.MutableVect; import forestry.plugins.PluginApiculture; public class AlleleEffectNone extends AlleleCategorized implements IAlleleBeeEffect { @@ -41,23 +44,23 @@ public class AlleleEffectNone extends AlleleCategorized implements IAlleleBeeEff @Override public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { - int[] area = genome.getTerritory(); - area[0] *= housing.getTerritoryModifier(genome, 1f); - area[1] *= housing.getTerritoryModifier(genome, 1f); - area[2] *= housing.getTerritoryModifier(genome, 1f); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + float territoryModifier = beeModifier.getTerritoryModifier(genome, 1f); - if (area[0] < 1) { - area[0] = 1; + MutableVect area = new MutableVect(genome.getTerritory()); + area.multiply(territoryModifier); + + if (area.x < 1) { + area.x = 1; } - if (area[1] < 1) { - area[1] = 1; + if (area.y < 1) { + area.y = 1; } - if (area[2] < 1) { - area[2] = 1; + if (area.z < 1) { + area.z = 1; } - PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), - housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getCoordinates(), genome.getPrimary().getIconColour(0), area); return storedData; } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectRadioactive.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectRadioactive.java index 36f6f6fa0..34fe841f4 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectRadioactive.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectRadioactive.java @@ -25,8 +25,8 @@ import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; import forestry.api.genetics.IEffectData; import forestry.apiculture.gadgets.BlockAlveary; -import forestry.apiculture.gadgets.TileAlveary; import forestry.apiculture.items.ItemArmorApiarist; +import forestry.apiculture.multiblock.TileAlveary; import forestry.core.utils.DamageSourceForestry; import forestry.core.vect.Vect; @@ -52,8 +52,8 @@ public class AlleleEffectRadioactive extends AlleleEffectThrottled { Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); // Radioactivity hurts players and mobs - Vect min = new Vect(housing.getXCoord() + offset.x, housing.getYCoord() + offset.y, housing.getZCoord() + offset.z); - Vect max = new Vect(housing.getXCoord() + offset.x + area.x, housing.getYCoord() + offset.y + area.y, housing.getZCoord() + offset.z + area.z); + Vect min = new Vect(housing.getCoordinates()).add(offset); + Vect max = min.add(area); AxisAlignedBB hurtBox = AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z); @@ -91,15 +91,16 @@ public class AlleleEffectRadioactive extends AlleleEffectThrottled { Vect randomPos = new Vect(rand.nextInt(area.x), rand.nextInt(area.y), rand.nextInt(area.z)); - Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + Vect posHousing = new Vect(housing.getCoordinates()); + Vect posBlock = randomPos.add(posHousing); posBlock = posBlock.add(offset); if (posBlock.y <= 1 || posBlock.y >= housing.getWorld().getActualHeight()) { continue; } - // Don't destroy ourself and blocks below us. - if (posBlock.x == housing.getXCoord() && posBlock.z == housing.getZCoord() && posBlock.y <= housing.getYCoord()) { + // Don't destroy ourselves or blocks below us. + if (posBlock.x == posHousing.x && posBlock.z == posHousing.z && posBlock.y <= posHousing.y) { continue; } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectRepulsion.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectRepulsion.java index 2eda66f0c..1ce2c757a 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectRepulsion.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectRepulsion.java @@ -32,7 +32,7 @@ public class AlleleEffectRepulsion extends AlleleEffectThrottled { return storedData; } - if (housing.getOwnerName() == null) { + if (housing.getOwner() == null) { return storedData; } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectSnowing.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectSnowing.java index 224cd9a90..1e862a55a 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectSnowing.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectSnowing.java @@ -11,8 +11,8 @@ package forestry.apiculture.genetics; import net.minecraft.init.Blocks; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; import net.minecraftforge.common.util.ForgeDirection; @@ -21,6 +21,7 @@ import forestry.api.apiculture.IBeeHousing; import forestry.api.core.EnumTemperature; import forestry.api.genetics.IEffectData; import forestry.core.proxy.Proxies; +import forestry.core.vect.IVect; import forestry.core.vect.Vect; public class AlleleEffectSnowing extends AlleleEffectThrottled { @@ -56,7 +57,7 @@ public class AlleleEffectSnowing extends AlleleEffectThrottled { Vect randomPos = new Vect(world.rand.nextInt(area.x), world.rand.nextInt(area.y), world.rand.nextInt(area.z)); - Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + Vect posBlock = randomPos.add(new Vect(housing.getCoordinates())); posBlock = posBlock.add(offset); // Put snow on the ground @@ -77,9 +78,18 @@ public class AlleleEffectSnowing extends AlleleEffectThrottled { @Override public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { if (housing.getWorld().rand.nextInt(3) == 0) { - int[] area = getModifiedArea(genome, housing); - Proxies.render.addSnowFX(housing.getWorld(), housing.getXCoord(), housing.getYCoord(), housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + IVect area = getModifiedArea(genome, housing); + + ChunkCoordinates coordinates = housing.getCoordinates(); + World world = housing.getWorld(); + + double spawnX = coordinates.posX + world.rand.nextInt(area.getX() * 2) - area.getX(); + double spawnY = coordinates.posY + world.rand.nextInt(area.getY()); + double spawnZ = coordinates.posZ + world.rand.nextInt(area.getZ() * 2) - area.getZ(); + + Proxies.common.addEntitySnowFX(world, spawnX, spawnY, spawnZ, 0F, 0F, 0F); } + return storedData; } } diff --git a/src/main/java/forestry/apiculture/genetics/AlleleEffectThrottled.java b/src/main/java/forestry/apiculture/genetics/AlleleEffectThrottled.java index 87f185f99..e53a62490 100755 --- a/src/main/java/forestry/apiculture/genetics/AlleleEffectThrottled.java +++ b/src/main/java/forestry/apiculture/genetics/AlleleEffectThrottled.java @@ -15,10 +15,13 @@ import net.minecraft.util.AxisAlignedBB; import forestry.api.apiculture.IAlleleBeeEffect; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.genetics.IEffectData; -import forestry.core.EnumErrorCode; +import forestry.apiculture.BeeHousingModifier; import forestry.core.genetics.EffectData; import forestry.core.genetics.alleles.AlleleCategorized; +import forestry.core.vect.IVect; +import forestry.core.vect.MutableVect; import forestry.core.vect.Vect; import forestry.plugins.PluginApiculture; @@ -55,7 +58,7 @@ public abstract class AlleleEffectThrottled extends AlleleCategorized implements public boolean isHalted(IEffectData storedData, IBeeHousing housing) { - if (requiresWorkingQueen && housing.getErrorState() != EnumErrorCode.OK) { + if (requiresWorkingQueen && housing.getErrorLogic().hasErrors()) { return true; } @@ -75,27 +78,27 @@ public abstract class AlleleEffectThrottled extends AlleleCategorized implements @Override public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { - int[] area = getModifiedArea(genome, housing); + IVect area = getModifiedArea(genome, housing); - PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), - housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getCoordinates(), genome.getPrimary().getIconColour(0), area); return storedData; } - protected int[] getModifiedArea(IBeeGenome genome, IBeeHousing housing) { - int[] area = genome.getTerritory(); - area[0] *= housing.getTerritoryModifier(genome, 1f) * 3; - area[1] *= housing.getTerritoryModifier(genome, 1f) * 3; - area[2] *= housing.getTerritoryModifier(genome, 1f) * 3; + protected IVect getModifiedArea(IBeeGenome genome, IBeeHousing housing) { + IBeeModifier beeModifier = new BeeHousingModifier(housing); + float territoryModifier = beeModifier.getTerritoryModifier(genome, 1f); - if (area[0] < 1) { - area[0] = 1; + MutableVect area = new MutableVect(genome.getTerritory()); + area.multiply(territoryModifier * 3); + + if (area.x < 1) { + area.x = 1; } - if (area[1] < 1) { - area[1] = 1; + if (area.y < 1) { + area.y = 1; } - if (area[2] < 1) { - area[2] = 1; + if (area.z < 1) { + area.z = 1; } return area; @@ -106,9 +109,8 @@ public abstract class AlleleEffectThrottled extends AlleleCategorized implements Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(modifier); Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); - // Radioactivity hurts players and mobs - Vect min = new Vect(housing.getXCoord() + offset.x, housing.getYCoord() + offset.y, housing.getZCoord() + offset.z); - Vect max = new Vect(housing.getXCoord() + offset.x + area.x, housing.getYCoord() + offset.y + area.y, housing.getZCoord() + offset.z + area.z); + Vect min = new Vect(housing.getCoordinates()).add(offset); + Vect max = min.add(area); return AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z); } diff --git a/src/main/java/forestry/apiculture/genetics/Bee.java b/src/main/java/forestry/apiculture/genetics/Bee.java old mode 100755 new mode 100644 index 9e163cb0b..df657491c --- a/src/main/java/forestry/apiculture/genetics/Bee.java +++ b/src/main/java/forestry/apiculture/genetics/Bee.java @@ -10,6 +10,11 @@ ******************************************************************************/ package forestry.apiculture.genetics; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -21,6 +26,7 @@ import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; @@ -35,6 +41,7 @@ import forestry.api.apiculture.IApiaristTracker; import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.apiculture.IBeeMutation; import forestry.api.apiculture.IBeekeepingMode; import forestry.api.core.BiomeHelper; @@ -43,7 +50,6 @@ import forestry.api.core.EnumTemperature; import forestry.api.core.IErrorState; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAllele; -import forestry.api.genetics.IAlleleSpecies; import forestry.api.genetics.IAlleleTolerance; import forestry.api.genetics.IChromosome; import forestry.api.genetics.IEffectData; @@ -51,6 +57,7 @@ import forestry.api.genetics.IFlowerProvider; import forestry.api.genetics.IIndividual; import forestry.api.genetics.IMutation; import forestry.api.genetics.IPollinatable; +import forestry.apiculture.BeeHousingModifier; import forestry.arboriculture.genetics.FakePollinatable; import forestry.arboriculture.genetics.ICheckPollinatable; import forestry.core.EnumErrorCode; @@ -62,7 +69,6 @@ import forestry.core.genetics.IndividualLiving; import forestry.core.proxy.Proxies; import forestry.core.utils.GeneticsUtil; import forestry.core.utils.StringUtil; -import forestry.core.vect.MutableVect; import forestry.core.vect.Vect; public class Bee extends IndividualLiving implements IBee { @@ -73,8 +79,24 @@ public class Bee extends IndividualLiving implements IBee { public IBeeGenome genome; public IBeeGenome mate; + private static final LoadingCache getBeeCache = CacheBuilder.newBuilder() + .maximumSize(128) + .build(new CacheLoader() { + @Override + public Bee load(@Nonnull NBTTagCompound tagCompound) { + return new Bee(tagCompound); + } + }); + /* CONSTRUCTOR */ - public Bee(NBTTagCompound nbttagcompound) { + public static Bee fromNBT(NBTTagCompound nbtTagCompound) { + if (nbtTagCompound == null) { + return null; + } + return getBeeCache.getUnchecked(nbtTagCompound); + } + + private Bee(NBTTagCompound nbttagcompound) { readFromNBT(nbttagcompound); } @@ -252,8 +274,10 @@ public class Bee extends IndividualLiving implements IBee { Set errorStates = new HashSet(); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + // / Rain needs tolerant flyers - if (world.isRaining() && !genome.getTolerantFlyer() && BiomeHelper.canRainOrSnow(biome) && !housing.isSealed()) { + if (world.isRaining() && !genome.getTolerantFlyer() && BiomeHelper.canRainOrSnow(biome) && !beeModifier.isSealed()) { errorStates.add(EnumErrorCode.ISRAINING); } @@ -262,21 +286,20 @@ public class Bee extends IndividualLiving implements IBee { if (!canWorkDuringDay()) { errorStates.add(EnumErrorCode.NOTNIGHT); } - } else if (!canWorkAtNight() && !housing.isSelfLighted()) { + } else if (!canWorkAtNight() && !beeModifier.isSelfLighted()) { errorStates.add(EnumErrorCode.NOTDAY); } - if (world.getBlockLightValue(housing.getXCoord(), housing.getYCoord() + 2, housing.getZCoord()) > Defaults.APIARY_MIN_LEVEL_LIGHT) { + if (housing.getBlockLightValue() > Defaults.APIARY_MIN_LEVEL_LIGHT) { if (!canWorkDuringDay()) { errorStates.add(EnumErrorCode.NOTGLOOMY); } - } else if (!canWorkAtNight() && !housing.isSelfLighted()) { + } else if (!canWorkAtNight() && !beeModifier.isSelfLighted()) { errorStates.add(EnumErrorCode.NOTLUCID); } // / No sky, except if in hell - if (biome != null && !BiomeHelper.isBiomeHellish(biome) && !world.canBlockSeeTheSky(housing.getXCoord(), housing.getYCoord() + 3, housing.getZCoord()) - && !genome.getCaveDwelling() && !housing.isSunlightSimulated()) { + if (biome != null && !BiomeHelper.isBiomeHellish(biome) && !housing.canBlockSeeTheSky() && !genome.getCaveDwelling() && !beeModifier.isSunlightSimulated()) { errorStates.add(EnumErrorCode.NOSKY); } @@ -288,16 +311,6 @@ public class Bee extends IndividualLiving implements IBee { return errorStates; } - @Override - public IErrorState canWork(IBeeHousing housing) { - Set errorStates = getCanWork(housing); - if (errorStates.size() == 0) { - return EnumErrorCode.OK; - } else { - return errorStates.iterator().next(); - } - } - private boolean canWorkAtNight() { return genome.getPrimary().isNocturnal() || genome.getNocturnal(); } @@ -322,32 +335,6 @@ public class Bee extends IndividualLiving implements IBee { genome.getPrimary().getHumidity(), genome.getToleranceHumid()); } - @Override - public boolean hasFlower(IBeeHousing housing) { - - IFlowerProvider provider = genome.getFlowerProvider(); - - Vect housingPos = new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); - Vect area = getArea(genome, housing); - Vect offset = new Vect(-area.x / 2, -area.y / 2, -area.z / 2); - - boolean hasFlower = false; - - MutableVect posCurrent = new MutableVect(0, 0, 0); - while (posCurrent.advancePositionInArea(area)) { - - Vect posBlock = Vect.add(housingPos, posCurrent, offset); - - if (provider.isAcceptedFlower(housing.getWorld(), this, posBlock.x, posBlock.y, posBlock.z)) { - hasFlower = true; - break; - } - - } - - return hasFlower; - } - @Override public ArrayList getSuitableBiomes() { ArrayList suitableBiomes = new ArrayList(); @@ -427,7 +414,8 @@ public class Bee extends IndividualLiving implements IBee { @Override public void age(World world, float housingLifespanModifier) { IBeekeepingMode mode = BeeManager.beeRoot.getBeekeepingMode(world); - float finalModifier = housingLifespanModifier * mode.getLifespanModifier(genome, mate, housingLifespanModifier); + IBeeModifier beeModifier = mode.getBeeModifier(); + float finalModifier = housingLifespanModifier * beeModifier.getLifespanModifier(genome, mate, housingLifespanModifier); super.age(world, finalModifier); } @@ -440,9 +428,9 @@ public class Bee extends IndividualLiving implements IBee { IAlleleBeeSpecies primary = genome.getPrimary(); IAlleleBeeSpecies secondary = genome.getSecondary(); - products.addAll(primary.getProducts().keySet()); + products.addAll(primary.getProductChances().keySet()); - Set secondaryProducts = secondary.getProducts().keySet(); + Set secondaryProducts = secondary.getProductChances().keySet(); // Remove duplicates for (ItemStack second : secondaryProducts) { boolean skip = false; @@ -465,7 +453,7 @@ public class Bee extends IndividualLiving implements IBee { @Override public ItemStack[] getSpecialtyList() { - Set specialties = genome.getPrimary().getSpecialty().keySet(); + Set specialties = genome.getPrimary().getSpecialtyChances().keySet(); return specialties.toArray(new ItemStack[specialties.size()]); } @@ -491,33 +479,37 @@ public class Bee extends IndividualLiving implements IBee { setIsNatural(false); } + IBeeModifier beeHousingModifier = new BeeHousingModifier(housing); + IBeeModifier beeModeModifier = mode.getBeeModifier(); + // Bee genetic speed * beehousing * beekeeping mode - float speed = genome.getSpeed() * housing.getProductionModifier(genome, 1f) * mode.getProductionModifier(genome, 1f); + float speed = genome.getSpeed() * beeHousingModifier.getProductionModifier(genome, 1f) * beeModeModifier.getProductionModifier(genome, 1f); // / Primary Products - for (Map.Entry entry : primary.getProducts().entrySet()) { - if (housing.getWorld().rand.nextInt(100) < entry.getValue() * speed) { + for (Map.Entry entry : primary.getProductChances().entrySet()) { + if (housing.getWorld().rand.nextFloat() < entry.getValue() * speed) { products.add(entry.getKey().copy()); } } // / Secondary Products - for (Map.Entry entry : secondary.getProducts().entrySet()) { - if (housing.getWorld().rand.nextInt(100) < Math.round(entry.getValue() / 2) * speed) { + for (Map.Entry entry : secondary.getProductChances().entrySet()) { + if (housing.getWorld().rand.nextFloat() < Math.round(entry.getValue() / 2) * speed) { products.add(entry.getKey().copy()); } } // / Specialty products if (primary.isJubilant(genome, housing) && secondary.isJubilant(genome, housing)) { - for (Map.Entry entry : primary.getSpecialty().entrySet()) { - if (housing.getWorld().rand.nextInt(100) < entry.getValue() * speed) { + for (Map.Entry entry : primary.getSpecialtyChances().entrySet()) { + if (housing.getWorld().rand.nextFloat() < entry.getValue() * speed) { products.add(entry.getKey().copy()); } } } ItemStack[] productsArray = products.toArray(new ItemStack[products.size()]); - return genome.getFlowerProvider().affectProducts(housing.getWorld(), this, housing.getXCoord(), housing.getYCoord(), housing.getZCoord(), productsArray); + ChunkCoordinates housingCoordinates = housing.getCoordinates(); + return genome.getFlowerProvider().affectProducts(housing.getWorld(), this, housingCoordinates.posX, housingCoordinates.posY, housingCoordinates.posZ, productsArray); } /* REPRODUCTION */ @@ -547,10 +539,10 @@ public class Bee extends IndividualLiving implements IBee { return null; } - ArrayList bees = new ArrayList(); + List bees = new ArrayList(); - int toCreate = BeeManager.beeRoot.getBeekeepingMode(world).getFinalFertility(this, world, housing.getXCoord(), housing.getYCoord(), - housing.getZCoord()); + ChunkCoordinates housingCoordinates = housing.getCoordinates(); + int toCreate = BeeManager.beeRoot.getBeekeepingMode(world).getFinalFertility(this, world, housingCoordinates.posX, housingCoordinates.posY, housingCoordinates.posZ); if (toCreate <= 0) { toCreate = 1; @@ -609,8 +601,9 @@ public class Bee extends IndividualLiving implements IBee { IBeeGenome genome0; IBeeGenome genome1; - IAlleleSpecies allele0; - IAlleleSpecies allele1; + + IAlleleBeeSpecies allele0; + IAlleleBeeSpecies allele1; if (world.rand.nextBoolean()) { allele0 = (IAlleleBeeSpecies) parent1[EnumBeeChromosome.SPECIES.ordinal()].getPrimaryAllele(); @@ -626,7 +619,7 @@ public class Bee extends IndividualLiving implements IBee { genome1 = genomeOne; } - GameProfile playerProfile = housing.getOwnerName(); + GameProfile playerProfile = housing.getOwner(); IApiaristTracker breedingTracker = BeeManager.beeRoot.getBreedingTracker(world, playerProfile); List combinations = BeeManager.beeRoot.getCombinations(allele0, allele1, true); @@ -646,8 +639,8 @@ public class Bee extends IndividualLiving implements IBee { } if (chance > world.rand.nextFloat() * 100) { - breedingTracker.registerMutation(beeMutation); - return BeeManager.beeRoot.templateAsChromosomes(beeMutation.getTemplate()); + breedingTracker.registerMutation(mutation); + return BeeManager.beeRoot.templateAsChromosomes(mutation.getTemplate()); } } @@ -658,7 +651,9 @@ public class Bee extends IndividualLiving implements IBee { @Override public IIndividual retrievePollen(IBeeHousing housing) { - int chance = Math.round(genome.getFlowering() * housing.getFloweringModifier(getGenome(), 1f)); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + + int chance = Math.round(genome.getFlowering() * beeModifier.getFloweringModifier(getGenome(), 1f)); World world = housing.getWorld(); Random random = world.rand; @@ -668,9 +663,9 @@ public class Bee extends IndividualLiving implements IBee { return null; } - Vect area = getArea(genome, housing); + Vect area = getArea(genome, beeModifier); Vect offset = new Vect(-area.x / 2, -area.y / 4, -area.z / 2); - Vect housingPos = new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + Vect housingPos = new Vect(housing.getCoordinates()); IIndividual pollen = null; @@ -699,7 +694,9 @@ public class Bee extends IndividualLiving implements IBee { @Override public boolean pollinateRandom(IBeeHousing housing, IIndividual pollen) { - int chance = (int) (genome.getFlowering() * housing.getFloweringModifier(getGenome(), 1f)); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + + int chance = (int) (genome.getFlowering() * beeModifier.getFloweringModifier(getGenome(), 1f)); World world = housing.getWorld(); Random random = world.rand; @@ -709,9 +706,9 @@ public class Bee extends IndividualLiving implements IBee { return false; } - Vect area = getArea(genome, housing); + Vect area = getArea(genome, beeModifier); Vect offset = new Vect(-area.x / 2, -area.y / 4, -area.z / 2); - Vect housingPos = new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + Vect housingPos = new Vect(housing.getCoordinates()); for (int i = 0; i < 30; i++) { @@ -730,7 +727,7 @@ public class Bee extends IndividualLiving implements IBee { continue; } - IPollinatable realPollinatable = GeneticsUtil.getOrCreatePollinatable(housing.getOwnerName(), world, posBlock.x, posBlock.y, posBlock.z); + IPollinatable realPollinatable = GeneticsUtil.getOrCreatePollinatable(housing.getOwner(), world, posBlock.x, posBlock.y, posBlock.z); if (realPollinatable != null) { realPollinatable.mateWith(pollen); @@ -744,7 +741,9 @@ public class Bee extends IndividualLiving implements IBee { @Override public void plantFlowerRandom(IBeeHousing housing) { - int chance = Math.round(genome.getFlowering() * housing.getFloweringModifier(getGenome(), 1f)); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + + int chance = Math.round(genome.getFlowering() * beeModifier.getFloweringModifier(getGenome(), 1f)); World world = housing.getWorld(); Random random = world.rand; @@ -756,9 +755,9 @@ public class Bee extends IndividualLiving implements IBee { // Gather required info IFlowerProvider provider = genome.getFlowerProvider(); - Vect area = getArea(genome, housing); + Vect area = getArea(genome, beeModifier); Vect offset = new Vect(-area.x / 2, -area.y / 4, -area.z / 2); - Vect housingPos = new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + Vect housingPos = new Vect(housing.getCoordinates()); for (int i = 0; i < 10; i++) { Vect randomPos = Vect.getRandomPositionInArea(random, area); @@ -770,9 +769,9 @@ public class Bee extends IndividualLiving implements IBee { } } - private static Vect getArea(IBeeGenome genome, IBeeHousing housing) { + private static Vect getArea(IBeeGenome genome, IBeeModifier beeModifier) { int[] genomeTerritory = genome.getTerritory(); - float housingModifier = housing.getTerritoryModifier(genome, 1f); + float housingModifier = beeModifier.getTerritoryModifier(genome, 1f); return new Vect(genomeTerritory).multiply(housingModifier * 3.0f); } } diff --git a/src/main/java/forestry/apiculture/genetics/BeeBranchDefinition.java b/src/main/java/forestry/apiculture/genetics/BeeBranchDefinition.java index b3da39b4b..c75630d87 100644 --- a/src/main/java/forestry/apiculture/genetics/BeeBranchDefinition.java +++ b/src/main/java/forestry/apiculture/genetics/BeeBranchDefinition.java @@ -108,8 +108,7 @@ public enum BeeBranchDefinition { Allele.helper.set(alleles, EnumBeeChromosome.CAVE_DWELLING, true); Allele.helper.set(alleles, EnumBeeChromosome.FLOWER_PROVIDER, EnumAllele.Flowers.WHEAT); } - } - ; + }; private final IClassification branch; diff --git a/src/main/java/forestry/apiculture/genetics/BeeDefinition.java b/src/main/java/forestry/apiculture/genetics/BeeDefinition.java index 511bc2b81..65e2c8e44 100644 --- a/src/main/java/forestry/apiculture/genetics/BeeDefinition.java +++ b/src/main/java/forestry/apiculture/genetics/BeeDefinition.java @@ -505,7 +505,6 @@ public enum BeeDefinition implements IBeeDefinition { } }, SPECTRAL(BeeBranchDefinition.END, "idolum", true, new Color(0xa98bed), new Color(0xd9de9e)) { - @Override protected void setSpeciesProperties(IAlleleBeeSpeciesCustom beeSpecies) { beeSpecies.addProduct(ForestryItem.beeComb.getItemStack(1, 8), 0.50f) @@ -523,7 +522,6 @@ public enum BeeDefinition implements IBeeDefinition { } }, PHANTASMAL(BeeBranchDefinition.END, "lemur", false, new Color(0xcc00fa), new Color(0xd9de9e)) { - @Override protected void setSpeciesProperties(IAlleleBeeSpeciesCustom beeSpecies) { beeSpecies.addProduct(ForestryItem.beeComb.getItemStack(1, 8), 0.40f) diff --git a/src/main/java/forestry/apiculture/genetics/BeeGenome.java b/src/main/java/forestry/apiculture/genetics/BeeGenome.java index c4b61e455..2a55cc356 100755 --- a/src/main/java/forestry/apiculture/genetics/BeeGenome.java +++ b/src/main/java/forestry/apiculture/genetics/BeeGenome.java @@ -12,16 +12,13 @@ package forestry.apiculture.genetics; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; import forestry.api.apiculture.BeeManager; import forestry.api.apiculture.EnumBeeChromosome; import forestry.api.apiculture.IAlleleBeeEffect; import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.apiculture.IBeeGenome; -import forestry.api.genetics.AlleleManager; import forestry.api.genetics.EnumTolerance; -import forestry.api.genetics.IAllele; import forestry.api.genetics.IAlleleFloat; import forestry.api.genetics.IAlleleFlowers; import forestry.api.genetics.IAlleleInteger; @@ -29,7 +26,6 @@ import forestry.api.genetics.IAlleleSpecies; import forestry.api.genetics.IChromosome; import forestry.api.genetics.IFlowerProvider; import forestry.api.genetics.ISpeciesRoot; -import forestry.core.genetics.Chromosome; import forestry.core.genetics.Genome; import forestry.core.genetics.alleles.AlleleArea; import forestry.core.genetics.alleles.AlleleBoolean; diff --git a/src/main/java/forestry/apiculture/genetics/BeeHelper.java b/src/main/java/forestry/apiculture/genetics/BeeHelper.java index 43ca7cdd7..df2ecbdc2 100755 --- a/src/main/java/forestry/apiculture/genetics/BeeHelper.java +++ b/src/main/java/forestry/apiculture/genetics/BeeHelper.java @@ -29,7 +29,6 @@ import forestry.api.apiculture.BeeManager; import forestry.api.apiculture.EnumBeeChromosome; import forestry.api.apiculture.EnumBeeType; import forestry.api.apiculture.IAlleleBeeSpecies; -import forestry.api.apiculture.IAlvearyComponent; import forestry.api.apiculture.IApiaristTracker; import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeGenome; @@ -38,14 +37,12 @@ import forestry.api.apiculture.IBeeMutation; import forestry.api.apiculture.IBeeRoot; import forestry.api.apiculture.IBeekeepingLogic; import forestry.api.apiculture.IBeekeepingMode; -import forestry.api.core.IStructureLogic; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAllele; import forestry.api.genetics.IChromosomeType; import forestry.api.genetics.IIndividual; import forestry.api.genetics.IMutation; import forestry.apiculture.BeekeepingLogic; -import forestry.apiculture.gadgets.StructureLogicAlveary; import forestry.core.config.ForestryItem; import forestry.core.genetics.SpeciesRoot; import forestry.plugins.PluginApiculture; @@ -167,12 +164,12 @@ public class BeeHelper extends SpeciesRoot implements IBeeRoot { return null; } - return new Bee(stack.getTagCompound()); + return Bee.fromNBT(stack.getTagCompound()); } @Override public IBee getMember(NBTTagCompound compound) { - return new Bee(compound); + return Bee.fromNBT(compound); } @Override @@ -255,8 +252,8 @@ public class BeeHelper extends SpeciesRoot implements IBeeRoot { } /* BREEDING MODES */ - final ArrayList beekeepingModes = new ArrayList(); - public static IBeekeepingMode activeBeekeepingMode; + private final ArrayList beekeepingModes = new ArrayList(); + private static IBeekeepingMode activeBeekeepingMode; @Override public void resetBeekeepingMode() { @@ -329,11 +326,6 @@ public class BeeHelper extends SpeciesRoot implements IBeeRoot { return new BeekeepingLogic(housing); } - @Override - public IStructureLogic createAlvearyStructureLogic(IAlvearyComponent structure) { - return new StructureLogicAlveary(structure); - } - @Override public IChromosomeType[] getKaryotype() { return EnumBeeChromosome.values(); diff --git a/src/main/java/forestry/apiculture/genetics/BeeMutation.java b/src/main/java/forestry/apiculture/genetics/BeeMutation.java old mode 100755 new mode 100644 index e15a99c9c..706013fb6 --- a/src/main/java/forestry/apiculture/genetics/BeeMutation.java +++ b/src/main/java/forestry/apiculture/genetics/BeeMutation.java @@ -10,16 +10,18 @@ ******************************************************************************/ package forestry.apiculture.genetics; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import forestry.api.apiculture.BeeManager; import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.apiculture.IBeeMutationCustom; import forestry.api.apiculture.IBeeRoot; import forestry.api.genetics.IAllele; -import forestry.api.genetics.IGenome; +import forestry.apiculture.BeeHousingModifier; import forestry.core.genetics.Mutation; public class BeeMutation extends Mutation implements IBeeMutationCustom { @@ -33,25 +35,24 @@ public class BeeMutation extends Mutation implements IBeeMutationCustom { return BeeManager.beeRoot; } - @Override - public float getChance(IBeeHousing housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { - return getChance(housing, (IAlleleBeeSpecies) allele0, (IAlleleBeeSpecies) allele1, (IBeeGenome) genome0, (IBeeGenome) genome1); - } - @Override public float getChance(IBeeHousing housing, IAlleleBeeSpecies allele0, IAlleleBeeSpecies allele1, IBeeGenome genome0, IBeeGenome genome1) { World world = housing.getWorld(); - int x = housing.getXCoord(); - int y = housing.getYCoord(); - int z = housing.getZCoord(); + ChunkCoordinates housingCoordinates = housing.getCoordinates(); + int x = housingCoordinates.posX; + int y = housingCoordinates.posY; + int z = housingCoordinates.posZ; float processedChance = super.getChance(world, x, y, z, allele0, allele1, genome0, genome1); if (processedChance <= 0) { return 0; } - processedChance *= housing.getMutationModifier(genome0, genome1, 1f); - processedChance *= BeeManager.beeRoot.getBeekeepingMode(world).getMutationModifier(genome0, genome1, 1f); + IBeeModifier beeHousingModifier = new BeeHousingModifier(housing); + IBeeModifier beeModeModifier = BeeManager.beeRoot.getBeekeepingMode(world).getBeeModifier(); + + processedChance *= beeHousingModifier.getMutationModifier(genome0, genome1, processedChance); + processedChance *= beeModeModifier.getMutationModifier(genome0, genome1, processedChance); return processedChance; } diff --git a/src/main/java/forestry/apiculture/genetics/BeekeepingMode.java b/src/main/java/forestry/apiculture/genetics/BeekeepingMode.java index a7f6e6c29..0294d7c39 100755 --- a/src/main/java/forestry/apiculture/genetics/BeekeepingMode.java +++ b/src/main/java/forestry/apiculture/genetics/BeekeepingMode.java @@ -16,10 +16,13 @@ import java.util.Random; import net.minecraft.world.World; +import forestry.api.apiculture.DefaultBeeModifier; import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.apiculture.IBeekeepingMode; +import forestry.apiculture.BeeHousingModifier; public class BeekeepingMode implements IBeekeepingMode { @@ -29,22 +32,18 @@ public class BeekeepingMode implements IBeekeepingMode { public static final IBeekeepingMode hardcore = new BeekeepingMode("HARDCORE", 0.5f, 5.0f, 0.8f, true, true); public static final IBeekeepingMode insane = new BeekeepingMode("INSANE", 0.2f, 10.0f, 0.6f, true, true); - final Random rand; - final String name; - final float mutationModifier; - final float lifespanModifier; - final float speedModifier; - final boolean reducesFertility; - final boolean canFatigue; + private final Random rand; + private final String name; + private final boolean reducesFertility; + private final boolean canFatigue; + private final IBeeModifier beeModifier; public BeekeepingMode(String name, float mutationModifier, float lifespanModifier, float speedModifier, boolean reducesFertility, boolean canFatigue) { this.rand = new Random(); this.name = name; - this.mutationModifier = mutationModifier; - this.lifespanModifier = lifespanModifier; - this.speedModifier = speedModifier; this.reducesFertility = reducesFertility; this.canFatigue = canFatigue; + this.beeModifier = new BeekeepingModeBeeModifier(mutationModifier, lifespanModifier, speedModifier); } @Override @@ -64,36 +63,6 @@ public class BeekeepingMode implements IBeekeepingMode { return 1.0f; } - @Override - public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return this.mutationModifier; - } - - @Override - public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return this.lifespanModifier; - } - - @Override - public float getProductionModifier(IBeeGenome genome, float currentModifier) { - return this.speedModifier; - } - - @Override - public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public float getFloweringModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - - @Override - public float getGeneticDecay(IBeeGenome genome, float currentModifier) { - return 1.0f; - } - @Override public int getFinalFertility(IBee queen, World world, int x, int y, int z) { int toCreate = queen.getGenome().getFertility(); @@ -115,17 +84,17 @@ public class BeekeepingMode implements IBeekeepingMode { return false; } - if (queen.getGeneration() > 96 + rand.nextInt(6) + rand.nextInt(6) && - rand.nextFloat() < 0.02f * housing.getGeneticDecay(queen.getGenome(), 1f)) { - return true; - } + IBeeModifier beeModifier = new BeeHousingModifier(housing); - return false; + return queen.getGeneration() > 96 + rand.nextInt(6) + rand.nextInt(6) && + rand.nextFloat() < 0.02f * beeModifier.getGeneticDecay(queen.getGenome(), 1f); } @Override public boolean isOverworked(IBee queen, IBeeHousing housing) { - float productionModifier = housing.getProductionModifier(queen.getGenome(), 1f); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + + float productionModifier = beeModifier.getProductionModifier(queen.getGenome(), 1f); if (productionModifier > 16) { if (housing.getWorld().rand.nextFloat() * 100 < 0.01 * ((productionModifier * productionModifier) - 100)) { return true; @@ -137,7 +106,9 @@ public class BeekeepingMode implements IBeekeepingMode { @Override public boolean isDegenerating(IBee queen, IBee offspring, IBeeHousing housing) { - float mutationModifier = housing.getMutationModifier(queen.getGenome(), queen.getMate(), 1.0f); + IBeeModifier beeModifier = new BeeHousingModifier(housing); + + float mutationModifier = beeModifier.getMutationModifier(queen.getGenome(), queen.getMate(), 1.0f); if (mutationModifier > 10) { if (housing.getWorld().rand.nextFloat() * 100 < 0.4 * ((mutationModifier * mutationModifier) - 100)) { return true; @@ -158,23 +129,34 @@ public class BeekeepingMode implements IBeekeepingMode { } @Override - public boolean isSealed() { - return false; + public IBeeModifier getBeeModifier() { + return beeModifier; } - @Override - public boolean isSelfLighted() { - return false; - } + private static class BeekeepingModeBeeModifier extends DefaultBeeModifier { + private final float mutationModifier; + private final float lifespanModifier; + private final float speedModifier; - @Override - public boolean isSunlightSimulated() { - return false; - } + public BeekeepingModeBeeModifier(float mutationModifier, float lifespanModifier, float speedModifier) { + this.mutationModifier = mutationModifier; + this.lifespanModifier = lifespanModifier; + this.speedModifier = speedModifier; + } - @Override - public boolean isHellish() { - return false; - } + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return this.mutationModifier; + } + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return this.lifespanModifier; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return this.speedModifier; + } + } } diff --git a/src/main/java/forestry/apiculture/genetics/JubilanceProviderHermit.java b/src/main/java/forestry/apiculture/genetics/JubilanceProviderHermit.java index e0b80efdf..3e62a63e6 100755 --- a/src/main/java/forestry/apiculture/genetics/JubilanceProviderHermit.java +++ b/src/main/java/forestry/apiculture/genetics/JubilanceProviderHermit.java @@ -14,6 +14,7 @@ import java.util.List; import net.minecraft.entity.EntityLiving; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChunkCoordinates; import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.apiculture.IBeeGenome; @@ -38,9 +39,11 @@ public class JubilanceProviderHermit extends JubilanceDefault { int[] areaAr = genome.getTerritory(); Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(modifier); Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); - - Vect min = new Vect(housing.getXCoord() + offset.x, housing.getYCoord() + offset.y, housing.getZCoord() + offset.z); - Vect max = new Vect(housing.getXCoord() + offset.x + area.x, housing.getYCoord() + offset.y + area.y, housing.getZCoord() + offset.z + area.z); + + ChunkCoordinates housingCoordinates = housing.getCoordinates(); + + Vect min = new Vect(housingCoordinates).add(offset); + Vect max = min.add(area); return AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z); } diff --git a/src/main/java/forestry/apiculture/genetics/JubilanceRequiresResource.java b/src/main/java/forestry/apiculture/genetics/JubilanceRequiresResource.java index fe9363ab4..bd1bbcd99 100644 --- a/src/main/java/forestry/apiculture/genetics/JubilanceRequiresResource.java +++ b/src/main/java/forestry/apiculture/genetics/JubilanceRequiresResource.java @@ -12,6 +12,7 @@ package forestry.apiculture.genetics; import net.minecraft.block.Block; import net.minecraft.item.ItemStack; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import forestry.api.apiculture.IAlleleBeeSpecies; @@ -31,9 +32,10 @@ public class JubilanceRequiresResource implements IJubilanceProvider { @Override public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { World world = housing.getWorld(); + ChunkCoordinates housingCoords = housing.getCoordinates(); - Block block = world.getBlock(housing.getXCoord(), housing.getYCoord() - 1, housing.getZCoord()); - int meta = world.getBlockMetadata(housing.getXCoord(), housing.getYCoord() - 1, housing.getZCoord()); + Block block = world.getBlock(housingCoords.posX, housingCoords.posY - 1, housingCoords.posZ); + int meta = world.getBlockMetadata(housingCoords.posX, housingCoords.posY - 1, housingCoords.posZ); return StackUtils.equals(block, meta, blockRequired); } diff --git a/src/main/java/forestry/apiculture/gui/ContainerAlveary.java b/src/main/java/forestry/apiculture/gui/ContainerAlveary.java index 6f35b3a98..8b0740e69 100755 --- a/src/main/java/forestry/apiculture/gui/ContainerAlveary.java +++ b/src/main/java/forestry/apiculture/gui/ContainerAlveary.java @@ -11,12 +11,13 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.inventory.ICrafting; -import forestry.apiculture.gadgets.TileAlvearyPlain; +import forestry.apiculture.BeeHousingInventory; +import forestry.apiculture.multiblock.TileAlvearyPlain; import forestry.core.gui.ContainerTile; import forestry.core.gui.slots.SlotFiltered; import forestry.core.gui.slots.SlotOutput; +import forestry.core.network.PacketGuiUpdate; public class ContainerAlveary extends ContainerTile { @@ -24,10 +25,10 @@ public class ContainerAlveary extends ContainerTile { super(tile, player, 8, 108); // Queen/Princess - this.addSlotToContainer(new SlotFiltered(tile, TileAlvearyPlain.SLOT_QUEEN, 29, 39)); + this.addSlotToContainer(new SlotFiltered(tile, BeeHousingInventory.SLOT_QUEEN, 29, 39)); // Drone - this.addSlotToContainer(new SlotFiltered(tile, TileAlvearyPlain.SLOT_DRONE, 29, 65)); + this.addSlotToContainer(new SlotFiltered(tile, BeeHousingInventory.SLOT_DRONE, 29, 65)); // Product Inventory this.addSlotToContainer(new SlotOutput(tile, 2, 116, 52)); @@ -39,16 +40,10 @@ public class ContainerAlveary extends ContainerTile { this.addSlotToContainer(new SlotOutput(tile, 8, 116, 26)); } - @Override - public void updateProgressBar(int i, int j) { - tile.getGUINetworkData(i, j); - } - @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - for (Object crafter : crafters) { - tile.sendGUINetworkData(this, (ICrafting) crafter); - } + PacketGuiUpdate packet = new PacketGuiUpdate(tile); + sendPacketToCrafters(packet); } } diff --git a/src/main/java/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java b/src/main/java/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java index e7a0e9072..8687f0874 100755 --- a/src/main/java/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java +++ b/src/main/java/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java @@ -12,7 +12,7 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; -import forestry.apiculture.gadgets.TileAlvearyHygroregulator; +import forestry.apiculture.multiblock.TileAlvearyHygroregulator; import forestry.core.gui.ContainerLiquidTanks; import forestry.core.gui.slots.SlotFiltered; @@ -21,7 +21,7 @@ public class ContainerAlvearyHygroregulator extends ContainerLiquidTanks { addSlotToContainer(new SlotOutput(tile, 2, 73, 39).setCrafter(tile)); addSlotToContainer(new SlotOutput(tile, 3, 94, 26).setCrafter(tile)); - addSlotToContainer(new SlotFiltered(tile, TileAlvearySieve.SLOT_SIEVE, 43, 39).setCrafter(tile)); + addSlotToContainer(new SlotFiltered(tile, TileAlvearySieve.AlvearySieveInventory.SLOT_SIEVE, 43, 39).setCrafter(tile)); } } diff --git a/src/main/java/forestry/apiculture/gui/ContainerAlvearySwarmer.java b/src/main/java/forestry/apiculture/gui/ContainerAlvearySwarmer.java index 1ea937839..469256b11 100755 --- a/src/main/java/forestry/apiculture/gui/ContainerAlvearySwarmer.java +++ b/src/main/java/forestry/apiculture/gui/ContainerAlvearySwarmer.java @@ -12,7 +12,7 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; -import forestry.apiculture.gadgets.TileAlvearySwarmer; +import forestry.apiculture.multiblock.TileAlvearySwarmer; import forestry.core.gui.ContainerTile; import forestry.core.gui.slots.SlotFiltered; diff --git a/src/main/java/forestry/apiculture/gui/ContainerApiary.java b/src/main/java/forestry/apiculture/gui/ContainerBeeHousing.java old mode 100755 new mode 100644 similarity index 67% rename from src/main/java/forestry/apiculture/gui/ContainerApiary.java rename to src/main/java/forestry/apiculture/gui/ContainerBeeHousing.java index 637b37293..527b0a5a2 --- a/src/main/java/forestry/apiculture/gui/ContainerApiary.java +++ b/src/main/java/forestry/apiculture/gui/ContainerBeeHousing.java @@ -13,27 +13,30 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ICrafting; -import forestry.apiculture.gadgets.TileBeehouse; +import forestry.apiculture.BeeHousingInventory; +import forestry.apiculture.gadgets.TileApiary; +import forestry.apiculture.gadgets.TileBeeHousing; import forestry.core.gui.ContainerTile; import forestry.core.gui.slots.SlotFiltered; import forestry.core.gui.slots.SlotOutput; -public class ContainerApiary extends ContainerTile { +public class ContainerBeeHousing extends ContainerTile { - public ContainerApiary(InventoryPlayer player, TileBeehouse tile, boolean hasFrames) { + public ContainerBeeHousing(InventoryPlayer player, TileBeeHousing tile, boolean hasFrames) { super(tile, player, 8, 108); // Queen/Princess - this.addSlotToContainer(new SlotFiltered(tile, TileBeehouse.SLOT_QUEEN, 29, 39)); + this.addSlotToContainer(new SlotFiltered(tile, BeeHousingInventory.SLOT_QUEEN, 29, 39)); // Drone - this.addSlotToContainer(new SlotFiltered(tile, TileBeehouse.SLOT_DRONE, 29, 65)); + this.addSlotToContainer(new SlotFiltered(tile, BeeHousingInventory.SLOT_DRONE, 29, 65)); // Frames if (hasFrames) { - this.addSlotToContainer(new SlotFiltered(tile, TileBeehouse.SLOT_FRAMES_1, 66, 23)); - this.addSlotToContainer(new SlotFiltered(tile, TileBeehouse.SLOT_FRAMES_1 + 1, 66, 52)); - this.addSlotToContainer(new SlotFiltered(tile, TileBeehouse.SLOT_FRAMES_1 + 2, 66, 81)); + final int slotFrames1 = TileApiary.ApiaryInventory.SLOT_FRAMES_1; + this.addSlotToContainer(new SlotFiltered(tile, slotFrames1, 66, 23)); + this.addSlotToContainer(new SlotFiltered(tile, slotFrames1 + 1, 66, 52)); + this.addSlotToContainer(new SlotFiltered(tile, slotFrames1 + 2, 66, 81)); } // Product Inventory diff --git a/src/main/java/forestry/apiculture/gui/GuiAlveary.java b/src/main/java/forestry/apiculture/gui/GuiAlveary.java index b383ca48c..7f0dd8cf6 100755 --- a/src/main/java/forestry/apiculture/gui/GuiAlveary.java +++ b/src/main/java/forestry/apiculture/gui/GuiAlveary.java @@ -12,9 +12,11 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; -import forestry.apiculture.gadgets.TileAlvearyPlain; +import forestry.apiculture.multiblock.IAlvearyController; +import forestry.apiculture.multiblock.TileAlvearyPlain; import forestry.core.config.Defaults; import forestry.core.gui.GuiForestryTitled; +import forestry.core.gui.OwnerLedger; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.Utils; @@ -30,8 +32,8 @@ public class GuiAlveary extends GuiForestryTitled { +public class GuiAlvearySieve extends GuiForestryTitled { public GuiAlvearySieve(InventoryPlayer inventory, TileAlvearySieve tile) { super(Defaults.TEXTURE_PATH_GUI + "/sieve.png", new ContainerAlvearySieve(inventory, tile), tile); diff --git a/src/main/java/forestry/apiculture/gui/GuiAlvearySwarmer.java b/src/main/java/forestry/apiculture/gui/GuiAlvearySwarmer.java index 8dd2dca36..a52cb8f8d 100755 --- a/src/main/java/forestry/apiculture/gui/GuiAlvearySwarmer.java +++ b/src/main/java/forestry/apiculture/gui/GuiAlvearySwarmer.java @@ -12,11 +12,11 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; -import forestry.apiculture.gadgets.TileAlvearySwarmer; +import forestry.apiculture.multiblock.TileAlvearySwarmer; import forestry.core.config.Defaults; -import forestry.core.gui.GuiForestry; +import forestry.core.gui.GuiForestryTitled; -public class GuiAlvearySwarmer extends GuiForestry { +public class GuiAlvearySwarmer extends GuiForestryTitled { public GuiAlvearySwarmer(InventoryPlayer inventory, TileAlvearySwarmer tile) { super(Defaults.TEXTURE_PATH_GUI + "/swarmer.png", new ContainerAlvearySwarmer(inventory, tile), tile); diff --git a/src/main/java/forestry/apiculture/gui/GuiApiary.java b/src/main/java/forestry/apiculture/gui/GuiBeeHousing.java old mode 100755 new mode 100644 similarity index 76% rename from src/main/java/forestry/apiculture/gui/GuiApiary.java rename to src/main/java/forestry/apiculture/gui/GuiBeeHousing.java index fce9ef829..7fb523857 --- a/src/main/java/forestry/apiculture/gui/GuiApiary.java +++ b/src/main/java/forestry/apiculture/gui/GuiBeeHousing.java @@ -13,22 +13,23 @@ package forestry.apiculture.gui; import net.minecraft.entity.player.InventoryPlayer; import forestry.apiculture.gadgets.TileApiary; +import forestry.apiculture.gadgets.TileBeeHousing; import forestry.apiculture.gadgets.TileBeehouse; import forestry.core.config.Defaults; import forestry.core.gui.GuiForestryTitled; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.Utils; -public class GuiApiary extends GuiForestryTitled { +public class GuiBeeHousing extends GuiForestryTitled { - public GuiApiary(InventoryPlayer inventory, TileApiary tile) { - super(Defaults.TEXTURE_PATH_GUI + "/apiary.png", new ContainerApiary(inventory, tile, true), tile); + public GuiBeeHousing(InventoryPlayer inventory, TileApiary tile) { + super(Defaults.TEXTURE_PATH_GUI + "/apiary.png", new ContainerBeeHousing(inventory, tile, true), tile); ySize = 190; } - public GuiApiary(InventoryPlayer inventory, TileBeehouse tile) { - super(Defaults.TEXTURE_PATH_GUI + "/alveary.png", new ContainerApiary(inventory, tile, false), tile); + public GuiBeeHousing(InventoryPlayer inventory, TileBeehouse tile) { + super(Defaults.TEXTURE_PATH_GUI + "/alveary.png", new ContainerBeeHousing(inventory, tile, false), tile); ySize = 190; } @@ -37,8 +38,7 @@ public class GuiApiary extends GuiForestryTitled protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); - TileBeehouse machine = inventory; - drawHealthMeter(guiLeft + 20, guiTop + 37, machine.getHealthScaled(46), Utils.rateTankLevel(machine.getHealthScaled(100))); + drawHealthMeter(guiLeft + 20, guiTop + 37, inventory.getHealthScaled(46), Utils.rateTankLevel(inventory.getHealthScaled(100))); } private void drawHealthMeter(int x, int y, int height, EnumTankLevel rated) { diff --git a/src/main/java/forestry/apiculture/items/ItemBeeGE.java b/src/main/java/forestry/apiculture/items/ItemBeeGE.java index 152b58843..f5f584021 100755 --- a/src/main/java/forestry/apiculture/items/ItemBeeGE.java +++ b/src/main/java/forestry/apiculture/items/ItemBeeGE.java @@ -34,7 +34,6 @@ import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAllele; import forestry.api.genetics.IAlleleSpecies; import forestry.api.genetics.IIndividual; -import forestry.apiculture.genetics.Bee; import forestry.apiculture.genetics.BeeGenome; import forestry.core.config.Config; import forestry.core.genetics.ItemGE; @@ -55,7 +54,7 @@ public class ItemBeeGE extends ItemGE { @Override public IBee getIndividual(ItemStack itemstack) { - return new Bee(itemstack.getTagCompound()); + return BeeManager.beeRoot.getMember(itemstack); } @Override @@ -80,7 +79,7 @@ public class ItemBeeGE extends ItemGE { return super.getItemStackDisplayName(itemstack); } - IBee individual = new Bee(itemstack.getTagCompound()); + IBee individual = BeeManager.beeRoot.getMember(itemstack); String customBeeKey = "bees.custom." + type.getName() + "." + individual.getGenome().getPrimary().getUnlocalizedName().replace("bees.species.", ""); if (StringUtil.canTranslate(customBeeKey)) { return StringUtil.localize(customBeeKey); @@ -99,7 +98,7 @@ public class ItemBeeGE extends ItemGE { } if (type != EnumBeeType.DRONE) { - IBee individual = new Bee(itemstack.getTagCompound()); + IBee individual = BeeManager.beeRoot.getMember(itemstack); if (individual.isNatural()) { list.add(EnumChatFormatting.YELLOW + EnumChatFormatting.ITALIC.toString() + StringUtil.localize("bees.stock.pristine")); } else { diff --git a/src/main/java/forestry/apiculture/items/ItemHabitatLocator.java b/src/main/java/forestry/apiculture/items/ItemHabitatLocator.java index 71060c789..505a3ad3f 100644 --- a/src/main/java/forestry/apiculture/items/ItemHabitatLocator.java +++ b/src/main/java/forestry/apiculture/items/ItemHabitatLocator.java @@ -39,6 +39,7 @@ import forestry.api.apiculture.IBee; import forestry.api.core.EnumHumidity; import forestry.api.core.EnumTemperature; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorSource; import forestry.api.core.IErrorState; import forestry.api.core.Tabs; import forestry.api.genetics.AlleleManager; @@ -46,7 +47,6 @@ import forestry.apiculture.render.TextureHabitatLocator; import forestry.core.EnumErrorCode; import forestry.core.config.Config; import forestry.core.config.ForestryItem; -import forestry.core.interfaces.IErrorSource; import forestry.core.interfaces.IHintSource; import forestry.core.inventory.ItemInventory; import forestry.core.items.ItemInventoried; diff --git a/src/main/java/forestry/apiculture/items/ItemHiveFrame.java b/src/main/java/forestry/apiculture/items/ItemHiveFrame.java index 23c1249c0..8898afa57 100755 --- a/src/main/java/forestry/apiculture/items/ItemHiveFrame.java +++ b/src/main/java/forestry/apiculture/items/ItemHiveFrame.java @@ -12,23 +12,25 @@ package forestry.apiculture.items; import net.minecraft.item.ItemStack; +import forestry.api.apiculture.DefaultBeeModifier; import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeGenome; import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeModifier; import forestry.api.apiculture.IHiveFrame; import forestry.api.core.Tabs; import forestry.core.items.ItemForestry; public class ItemHiveFrame extends ItemForestry implements IHiveFrame { - private final float geneticDecay; + private final IBeeModifier beeModifier; public ItemHiveFrame(int maxDamage, float geneticDecay) { - super(); setMaxStackSize(1); setMaxDamage(maxDamage); - this.geneticDecay = geneticDecay; setCreativeTab(Tabs.tabApiculture); + + this.beeModifier = new HiveFrameBeeModifier(geneticDecay); } @Override @@ -42,58 +44,25 @@ public class ItemHiveFrame extends ItemForestry implements IHiveFrame { } @Override - public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; + public IBeeModifier getBeeModifier() { + return beeModifier; } - @Override - public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return 1.0f; - } + private static class HiveFrameBeeModifier extends DefaultBeeModifier { + private final float geneticDecay; - @Override - public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { - return 1.0f; - } + public HiveFrameBeeModifier(float geneticDecay) { + this.geneticDecay = geneticDecay; + } - @Override - public float getProductionModifier(IBeeGenome genome, float currentModifier) { - return currentModifier < 10f ? 2.0f : 1f; - } + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return (currentModifier < 10f) ? 2f : 1f; + } - @Override - public float getFloweringModifier(IBeeGenome genome, float currentModifier) { - return 1.0f; + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + return this.geneticDecay; + } } - - @Override - public float getGeneticDecay(IBeeGenome genome, float currentModifier) { - return this.geneticDecay; - } - - @Override - public boolean isSealed() { - return false; - } - - @Override - public boolean isSelfLighted() { - return false; - } - - @Override - public boolean isSunlightSimulated() { - return false; - } - - @Override - public boolean isHellish() { - return false; - } - - @Override - public boolean isBookEnchantable(ItemStack itemstack1, ItemStack itemstack2) { - return false; - } - } diff --git a/src/main/java/forestry/apiculture/multiblock/AlvearyController.java b/src/main/java/forestry/apiculture/multiblock/AlvearyController.java new file mode 100644 index 000000000..a475f2b99 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/AlvearyController.java @@ -0,0 +1,466 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import com.mojang.authlib.GameProfile; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.DefaultBeeModifier; +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.IClimateControlled; +import forestry.apiculture.BeeHousingInventory; +import forestry.apiculture.BeeHousingModifier; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.multiblock.CoordTriplet; +import forestry.core.multiblock.IMultiblockPart; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockTileEntityBase; +import forestry.core.multiblock.MultiblockValidationException; +import forestry.core.multiblock.rectangular.RectangularMultiblockControllerBase; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.PacketGuiUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; +import forestry.core.utils.Utils; + +public class AlvearyController extends RectangularMultiblockControllerBase implements IAlvearyController, IClimateControlled { + + private final BeeHousingInventory inventory; + private final IBeekeepingLogic beekeepingLogic; + + private BiomeGenBase cachedBiome; + private float tempChange = 0.0f; + private float humidChange = 0.0f; + + // PARTS + private final Set beeModifiers = new HashSet(); + private final Set beeListeners = new HashSet(); + private final Set climatisers = new HashSet(); + private final Set activeComponents = new HashSet(); + + // CLIENT + private int breedingProgressPercent = 0; + + public AlvearyController(World world) { + super(world); + this.inventory = new BeeHousingInventory(9, "Items", getAccessHandler()); + this.beekeepingLogic = BeeManager.beeRoot.createBeekeepingLogic(this); + + this.beeModifiers.add(new AlvearyBeeModifier()); + } + + @Override + public IBeeHousingInventory getBeeInventory() { + return inventory; + } + + @Override + public IBeekeepingLogic getBeekeepingLogic() { + return beekeepingLogic; + } + + @Override + public IInventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + public Iterable getBeeListeners() { + return beeListeners; + } + + @Override + public Iterable getBeeModifiers() { + return beeModifiers; + } + + @Override + public void onAttachedPartWithMultiblockData(IMultiblockPart part, NBTTagCompound data) { + this.readFromNBT(data); + } + + @Override + protected void onBlockAdded(IMultiblockPart newPart) { + if (newPart instanceof IAlvearyComponent.BeeModifier) { + IAlvearyComponent.BeeModifier alvearyBeeModifier = (IAlvearyComponent.BeeModifier) newPart; + IBeeModifier beeModifier = alvearyBeeModifier.getBeeModifier(); + beeModifiers.add(beeModifier); + } + + if (newPart instanceof IAlvearyComponent.BeeListener) { + IAlvearyComponent.BeeListener beeListenerSource = (IAlvearyComponent.BeeListener) newPart; + IBeeListener beeListener = beeListenerSource.getBeeListener(); + beeListeners.add(beeListener); + } + + if (newPart instanceof IAlvearyComponent.Climatiser) { + climatisers.add((IAlvearyComponent.Climatiser) newPart); + } + + if (newPart instanceof IAlvearyComponent.Active) { + activeComponents.add((IAlvearyComponent.Active) newPart); + } + } + + @Override + protected void onBlockRemoved(IMultiblockPart oldPart) { + if (oldPart instanceof IAlvearyComponent.BeeModifier) { + IAlvearyComponent.BeeModifier alvearyBeeModifier = (IAlvearyComponent.BeeModifier) oldPart; + IBeeModifier beeModifier = alvearyBeeModifier.getBeeModifier(); + beeModifiers.remove(beeModifier); + } + + if (oldPart instanceof IAlvearyComponent.BeeListener) { + IAlvearyComponent.BeeListener beeListenerSource = (IAlvearyComponent.BeeListener) oldPart; + IBeeListener beeListener = beeListenerSource.getBeeListener(); + beeListeners.remove(beeListener); + } + + if (oldPart instanceof IAlvearyComponent.Climatiser) { + climatisers.remove(oldPart); + } + + if (oldPart instanceof IAlvearyComponent.Active) { + activeComponents.remove(oldPart); + } + } + + @Override + protected void isMachineWhole() throws MultiblockValidationException { + super.isMachineWhole(); + + final CoordTriplet maximumCoord = getMaximumCoord(); + final CoordTriplet minimumCoord = getMinimumCoord(); + + // check that the top is covered in wood slabs + + final int slabY = maximumCoord.y + 1; + for (int slabX = minimumCoord.x; slabX <= maximumCoord.x; slabX++) { + for (int slabZ = minimumCoord.z; slabZ <= maximumCoord.z; slabZ++) { + Block block = worldObj.getBlock(slabX, slabY, slabZ); + if (!Utils.isWoodSlabBlock(block)) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.alveary.error.needSlabs")); + } + + int meta = worldObj.getBlockMetadata(slabX, slabY, slabZ); + if ((meta & 8) != 0) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.alveary.error.needSlabs")); + } + } + } + + // check that there is space all around the alveary entrances + + int airY = maximumCoord.y; + for (int airX = minimumCoord.x - 1; airX <= maximumCoord.x + 1; airX++) { + for (int airZ = minimumCoord.z - 1; airZ <= maximumCoord.z + 1; airZ++) { + if (isCoordInMultiblock(airX, airY, airZ)) { + continue; + } + Block block = worldObj.getBlock(airX, airY, airZ); + if (block.isOpaqueCube()) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.alveary.error.needSpace")); + } + } + } + } + + @Override + protected int getMinimumNumberOfBlocksForAssembledMachine() { + return 27; + } + + @Override + protected int getMaximumXSize() { + return 3; + } + + @Override + protected int getMaximumZSize() { + return 3; + } + + @Override + protected int getMaximumYSize() { + return 3; + } + + @Override + protected int getMinimumXSize() { + return 3; + } + + @Override + protected int getMinimumYSize() { + return 3; + } + + @Override + protected int getMinimumZSize() { + return 3; + } + + @Override + protected void onAssimilate(MultiblockControllerBase assimilated) { + + } + + @Override + protected void onAssimilated(MultiblockControllerBase assimilator) { + + } + + @Override + protected boolean updateServer(int tickCount) { + for (IAlvearyComponent.Active activeComponent : activeComponents) { + activeComponent.updateServer(tickCount); + } + + final boolean canWork = beekeepingLogic.canWork(); + if (canWork) { + beekeepingLogic.doWork(); + } + + for (IAlvearyComponent.Climatiser climatiser : climatisers) { + climatiser.changeClimate(tickCount, this); + } + + tempChange = equalizeChange(tempChange); + humidChange = equalizeChange(humidChange); + + return canWork; + } + + private static float equalizeChange(float change) { + if (change == 0) { + return 0; + } + + change *= 0.95f; + if (change <= 0.001f && change >= -0.001f) { + change = 0; + } + return change; + } + + @Override + protected void updateClient(int tickCount) { + for (IAlvearyComponent.Active activeComponent : activeComponents) { + activeComponent.updateClient(tickCount); + } + + if (beekeepingLogic.canDoBeeFX() && updateOnInterval(2)) { + beekeepingLogic.doBeeFX(); + + if (updateOnInterval(50)) { + CoordTriplet center = getCenterCoord(); + float fxX = center.x + 0.5F; + float fxY = center.y + 1.0F; + float fxZ = center.z + 0.5F; + float distanceFromCenter = 1.6F; + + float leftRightSpreadFromCenter = distanceFromCenter * (worldObj.rand.nextFloat() - 0.5F); + float upSpread = worldObj.rand.nextFloat() * 0.8F; + fxY += upSpread; + + // display fx on all 4 sides + Proxies.common.addEntitySwarmFX(worldObj, (fxX - distanceFromCenter), fxY, (fxZ + leftRightSpreadFromCenter), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (fxX + distanceFromCenter), fxY, (fxZ + leftRightSpreadFromCenter), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (fxX + leftRightSpreadFromCenter), fxY, (fxZ - distanceFromCenter), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (fxX + leftRightSpreadFromCenter), fxY, (fxZ + distanceFromCenter), 0F, 0F, 0F); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + + data.setFloat("TempChange", tempChange); + data.setFloat("HumidChange", humidChange); + + beekeepingLogic.writeToNBT(data); + inventory.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + + tempChange = data.getFloat("TempChange"); + humidChange = data.getFloat("HumidChange"); + + beekeepingLogic.readFromNBT(data); + inventory.readFromNBT(data); + } + + @Override + public void formatDescriptionPacket(NBTTagCompound data) { + writeToNBT(data); + } + + @Override + public void decodeDescriptionPacket(NBTTagCompound data) { + readFromNBT(data); + } + + /* IActivatable */ + + @Override + public ChunkCoordinates getCoordinates() { + CoordTriplet coord = getCenterCoord(); + return new ChunkCoordinates(coord.x, coord.y + 1, coord.z); + } + + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + PacketGuiUpdate packet = new PacketGuiUpdate(this); + Proxies.net.sendNetworkPacket(packet); + + if (oldAccess == EnumAccess.SHARED || newAccess == EnumAccess.SHARED) { + // pipes connected to this need to update + for (IMultiblockPart part : connectedParts) { + if (part instanceof MultiblockTileEntityBase) { + MultiblockTileEntityBase tile = (MultiblockTileEntityBase) part; + tile.notifyNeighborsOfBlockChange(); + } + } + markDirty(); + } + } + + @Override + public float getExactTemperature() { + CoordTriplet coords = getReferenceCoord(); + return getBiome().getFloatTemperature(coords.x, coords.y, coords.z) + tempChange; + } + + @Override + public float getExactHumidity() { + return getBiome().rainfall + humidChange; + } + + @Override + public GameProfile getOwner() { + return getAccessHandler().getOwner(); + } + + @Override + public World getWorld() { + return worldObj; + } + + @Override + public BiomeGenBase getBiome() { + if (cachedBiome == null) { + CoordTriplet coords = getReferenceCoord(); + cachedBiome = worldObj.getBiomeGenForCoords(coords.x, coords.z); + } + return cachedBiome; + } + + @Override + public EnumTemperature getTemperature() { + IBeeModifier beeModifier = new BeeHousingModifier(this); + if (beeModifier.isHellish() && tempChange >= 0) { + return EnumTemperature.HELLISH; + } + + CoordTriplet coords = getReferenceCoord(); + return EnumTemperature.getFromBiome(getBiome(), coords.x, coords.y, coords.z); + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.getFromValue(getExactHumidity()); + } + + @Override + public int getBlockLightValue() { + CoordTriplet topCenter = getTopCenterCoord(); + return worldObj.getBlockLightValue(topCenter.x, topCenter.y + 1, topCenter.z); + } + + @Override + public boolean canBlockSeeTheSky() { + CoordTriplet topCenter = getTopCenterCoord(); + return worldObj.canBlockSeeTheSky(topCenter.x, topCenter.y + 2, topCenter.z); + } + + @Override + public void addTemperatureChange(float change, float boundaryDown, float boundaryUp) { + ChunkCoordinates coordinates = getCoordinates(); + + float temperature = getBiome().getFloatTemperature(coordinates.posX, coordinates.posY, coordinates.posZ); + + tempChange += change; + tempChange = Math.max(boundaryDown - temperature, tempChange); + tempChange = Math.min(boundaryUp - temperature, tempChange); + } + + @Override + public void addHumidityChange(float change, float boundaryDown, float boundaryUp) { + float humidity = getBiome().rainfall; + + humidChange += change; + humidChange = Math.max(boundaryDown - humidity, humidChange); + humidChange = Math.min(boundaryUp - humidity, humidChange); + } + + /* GUI */ + @Override + public int getHealthScaled(int i) { + return (breedingProgressPercent * i) / 100; + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + super.writeGuiData(data); + data.writeVarInt(beekeepingLogic.getBeeProgressPercent()); + data.writeVarInt(Math.round(tempChange * 100)); + data.writeVarInt(Math.round(humidChange * 100)); + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + super.readGuiData(data); + breedingProgressPercent = data.readVarInt(); + tempChange = data.readVarInt() / 100.0F; + humidChange = data.readVarInt() / 100.0F; + } + + private static class AlvearyBeeModifier extends DefaultBeeModifier { + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + return 2.0f; + } + } + +} diff --git a/src/main/java/forestry/apiculture/multiblock/FakeAlvearyController.java b/src/main/java/forestry/apiculture/multiblock/FakeAlvearyController.java new file mode 100644 index 000000000..318292bea --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/FakeAlvearyController.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import java.io.IOException; +import java.util.Collections; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import com.mojang.authlib.GameProfile; + +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.IErrorLogic; +import forestry.apiculture.FakeBeekeepingLogic; +import forestry.core.delegates.FakeAccessHandler; +import forestry.core.delegates.FakeErrorLogic; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.inventory.FakeInventoryAdapter; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.utils.EnumAccess; + +public class FakeAlvearyController implements IAlvearyController { + public static final FakeAlvearyController instance = new FakeAlvearyController(); + + private FakeAlvearyController() { + + } + + @Override + public Iterable getBeeModifiers() { + return Collections.emptyList(); + } + + @Override + public Iterable getBeeListeners() { + return Collections.emptyList(); + } + + @Override + public IBeeHousingInventory getBeeInventory() { + return FakeBeeHousingInventory.instance; + } + + @Override + public IBeekeepingLogic getBeekeepingLogic() { + return FakeBeekeepingLogic.instance; + } + + @Override + public EnumTemperature getTemperature() { + return EnumTemperature.NORMAL; + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.NORMAL; + } + + @Override + public int getBlockLightValue() { + return 0; + } + + @Override + public boolean canBlockSeeTheSky() { + return false; + } + + @Override + public float getExactTemperature() { + return 0.5f; + } + + @Override + public float getExactHumidity() { + return 0.5f; + } + + @Override + public GameProfile getOwner() { + return null; + } + + @Override + public IErrorLogic getErrorLogic() { + return FakeErrorLogic.instance; + } + + @Override + public World getWorld() { + return null; + } + + @Override + public ChunkCoordinates getCoordinates() { + return null; + } + + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + + } + + @Override + public BiomeGenBase getBiome() { + return null; + } + + @Override + public IAccessHandler getAccessHandler() { + return FakeAccessHandler.getInstance(); + } + + @Override + public IInventoryAdapter getInternalInventory() { + return FakeInventoryAdapter.instance(); + } + + @Override + public int getHealthScaled(int i) { + return 0; + } + + private static class FakeBeeHousingInventory implements IBeeHousingInventory { + public static final FakeBeeHousingInventory instance = new FakeBeeHousingInventory(); + + private FakeBeeHousingInventory() { + + } + + @Override + public ItemStack getQueen() { + return null; + } + + @Override + public ItemStack getDrone() { + return null; + } + + @Override + public void setQueen(ItemStack itemstack) { + + } + + @Override + public void setDrone(ItemStack itemstack) { + + } + + @Override + public boolean addProduct(ItemStack product, boolean all) { + return false; + } + } +} diff --git a/src/main/java/forestry/apiculture/multiblock/IAlvearyController.java b/src/main/java/forestry/apiculture/multiblock/IAlvearyController.java new file mode 100644 index 000000000..d0c9bc599 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/IAlvearyController.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import forestry.api.apiculture.IBeeHousing; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.network.IStreamableGui; + + +public interface IAlvearyController extends IBeeHousing, IClimatised, IRestrictedAccessTile, IStreamableGui { + IInventoryAdapter getInternalInventory(); + + int getHealthScaled(int i); +} diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlveary.java b/src/main/java/forestry/apiculture/multiblock/TileAlveary.java new file mode 100644 index 000000000..14ca61c5a --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlveary.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import net.minecraft.util.StatCollector; + +import forestry.apiculture.gadgets.BlockAlveary; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockValidationException; +import forestry.core.multiblock.rectangular.RectangularMultiblockTileEntityBase; + +public abstract class TileAlveary extends RectangularMultiblockTileEntityBase { + + public static final int PLAIN_META = 0; + public static final int ENTRANCE_META = 1; + public static final int SWARMER_META = 2; + public static final int FAN_META = 3; + public static final int HEATER_META = 4; + public static final int HYGRO_META = 5; + public static final int STABILIZER_META = 6; + public static final int SIEVE_META = 7; + + /* TEXTURES */ + public int getIcon(int side, int metadata) { + return BlockAlveary.PLAIN; + } + + @Override + public void isGoodForExteriorLevel(int level) throws MultiblockValidationException { + if (level == 2 && !(this instanceof TileAlvearyPlain)) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.alveary.error.needPlainOnTop")); + } + } + + @Override + public void isGoodForInterior() throws MultiblockValidationException { + if (!(this instanceof TileAlvearyPlain)) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.alveary.error.needPlainInterior")); + } + } + + @Override + public void onMachineActivated() { + + } + + @Override + public void onMachineDeactivated() { + + } + + @Override + public MultiblockControllerBase createNewMultiblock() { + return new AlvearyController(worldObj); + } + + @Override + public Class getMultiblockControllerType() { + return AlvearyController.class; + } + + public IAlvearyController getAlvearyController() { + if (isConnected()) { + return (IAlvearyController) getMultiblockController(); + } else { + return FakeAlvearyController.instance; + } + } + + @Override + public void onMachineAssembled(MultiblockControllerBase controller) { + super.onMachineAssembled(controller); + + // Re-render this block on the client + if (worldObj.isRemote) { + this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + } + + @Override + public void onMachineBroken() { + super.onMachineBroken(); + + // Re-render this block on the client + if (worldObj.isRemote) { + this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + } + +} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearyClimatiser.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyClimatiser.java old mode 100755 new mode 100644 similarity index 63% rename from src/main/java/forestry/apiculture/gadgets/TileAlvearyClimatiser.java rename to src/main/java/forestry/apiculture/multiblock/TileAlvearyClimatiser.java index acdc58178..561a7f6d8 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearyClimatiser.java +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyClimatiser.java @@ -8,66 +8,54 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.apiculture.gadgets; - -import java.io.IOException; +package forestry.apiculture.multiblock; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; import net.minecraftforge.common.util.ForgeDirection; import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.core.IClimateControlled; import forestry.apiculture.network.PacketActiveUpdate; import forestry.core.interfaces.IActivatable; -import forestry.core.network.DataInputStreamForestry; -import forestry.core.network.DataOutputStreamForestry; import forestry.core.proxy.Proxies; import forestry.energy.EnergyManager; import cofh.api.energy.IEnergyHandler; -public abstract class TileAlvearyClimatiser extends TileAlveary implements IEnergyHandler, IActivatable { +public abstract class TileAlvearyClimatiser extends TileAlveary implements IEnergyHandler, IActivatable, IAlvearyComponent.Climatiser { - public static class ClimateControl { + protected interface IClimitiserDefinition { + float getChangePerTransfer(); - final float changePerTransfer; - final float boundaryUp; - final float boundaryDown; + float getBoundaryUp(); - public ClimateControl(float changePerTransfer, float boundaryDown, float boundaryUp) { - this.changePerTransfer = changePerTransfer; - this.boundaryDown = boundaryDown; - this.boundaryUp = boundaryUp; - } + float getBoundaryDown(); + + int getIconOff(); + + int getIconOn(); } - protected final EnergyManager energyManager; - private final ClimateControl climateControl; + private final EnergyManager energyManager; + private final IClimitiserDefinition definition; + private int workingTime = 0; - private final int textureOff; - private final int textureOn; // CLIENT private boolean active; - public TileAlvearyClimatiser(ClimateControl control, int textureOff, int textureOn, int componentBlockMeta) { - super(componentBlockMeta); - this.climateControl = control; - energyManager = new EnergyManager(1000, 50, 2000); - energyManager.setReceiveOnly(); - this.textureOff = textureOff; - this.textureOn = textureOn; + public TileAlvearyClimatiser(IClimitiserDefinition definition) { + this.definition = definition; + + this.energyManager = new EnergyManager(1000, 50, 2000); + this.energyManager.setReceiveOnly(); } /* UPDATING */ @Override - protected void updateServerSide() { - super.updateServerSide(); - - if (!this.hasMaster()) { - return; - } - + public void changeClimate(int tick, IClimateControlled climateControlled) { if (workingTime < 20 && energyManager.consumeEnergyToDoWork()) { // consume 10 RF per tick of work workingTime += energyManager.getEnergyPerWork() / 10; @@ -75,27 +63,19 @@ public abstract class TileAlvearyClimatiser extends TileAlveary implements IEner if (workingTime > 0) { workingTime--; - IAlvearyComponent component = (IAlvearyComponent) this.getCentralTE(); - if (component != null) { - component.addTemperatureChange(climateControl.changePerTransfer, climateControl.boundaryDown, climateControl.boundaryUp); - } + climateControlled.addTemperatureChange(definition.getChangePerTransfer(), definition.getBoundaryDown(), definition.getBoundaryUp()); } setActive(workingTime > 0); } - @Override - public boolean hasFunction() { - return true; - } - /* TEXTURES */ @Override public int getIcon(int side, int metadata) { if (active) { - return textureOn; + return definition.getIconOn(); } else { - return textureOff; + return definition.getIconOff(); } } @@ -115,19 +95,20 @@ public abstract class TileAlvearyClimatiser extends TileAlveary implements IEner nbttagcompound.setInteger("Heating", workingTime); } - /* NETWORK */ + /* Network */ @Override - public void writeData(DataOutputStreamForestry data) throws IOException { - super.writeData(data); - data.writeBoolean(active); + protected void encodeDescriptionPacket(NBTTagCompound packetData) { + super.encodeDescriptionPacket(packetData); + packetData.setBoolean("Active", active); } @Override - public void readData(DataInputStreamForestry data) throws IOException { - super.readData(data); - setActive(data.readBoolean()); + protected void decodeDescriptionPacket(NBTTagCompound packetData) { + super.decodeDescriptionPacket(packetData); + setActive(packetData.getBoolean("Active")); } + /* IActivatable */ @Override public boolean isActive() { return active; @@ -148,6 +129,11 @@ public abstract class TileAlvearyClimatiser extends TileAlveary implements IEner } } + @Override + public ChunkCoordinates getCoordinates() { + return new ChunkCoordinates(xCoord, yCoord, zCoord); + } + /* IEnergyHandler */ @Override public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) { @@ -173,4 +159,5 @@ public abstract class TileAlvearyClimatiser extends TileAlveary implements IEner public boolean canConnectEnergy(ForgeDirection from) { return energyManager.canConnectEnergy(from); } + } diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlvearyFan.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyFan.java new file mode 100644 index 000000000..664e35a60 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyFan.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import forestry.apiculture.gadgets.BlockAlveary; + +public class TileAlvearyFan extends TileAlvearyClimatiser { + + private static final FanDefinition definition = new FanDefinition(); + + public TileAlvearyFan() { + super(definition); + } + + private static class FanDefinition implements IClimitiserDefinition { + + @Override + public float getChangePerTransfer() { + return -0.01f; + } + + @Override + public float getBoundaryUp() { + return 2.5f; + } + + @Override + public float getBoundaryDown() { + return 0.05f; + } + + @Override + public int getIconOff() { + return BlockAlveary.ALVEARY_FAN_OFF; + } + + @Override + public int getIconOn() { + return BlockAlveary.ALVEARY_FAN_ON; + } + } +} diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlvearyHeater.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyHeater.java new file mode 100644 index 000000000..b869fd676 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyHeater.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import forestry.apiculture.gadgets.BlockAlveary; + +public class TileAlvearyHeater extends TileAlvearyClimatiser { + + private static final HeaterDefinition definition = new HeaterDefinition(); + + public TileAlvearyHeater() { + super(definition); + } + + private static class HeaterDefinition implements IClimitiserDefinition { + + @Override + public float getChangePerTransfer() { + return 0.01f; + } + + @Override + public float getBoundaryUp() { + return 2.5f; + } + + @Override + public float getBoundaryDown() { + return 0.0f; + } + + @Override + public int getIconOff() { + return BlockAlveary.ALVEARY_HEATER_OFF; + } + + @Override + public int getIconOn() { + return BlockAlveary.ALVEARY_HEATER_ON; + } + } +} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearyHygroregulator.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyHygroregulator.java old mode 100755 new mode 100644 similarity index 80% rename from src/main/java/forestry/apiculture/gadgets/TileAlvearyHygroregulator.java rename to src/main/java/forestry/apiculture/multiblock/TileAlvearyHygroregulator.java index 3d7632994..d5b0c9807 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearyHygroregulator.java +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyHygroregulator.java @@ -8,9 +8,8 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.apiculture.gadgets; +package forestry.apiculture.multiblock; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.IInventory; @@ -23,7 +22,8 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.apiculture.IAlvearyComponent; -import forestry.api.core.ForestryAPI; +import forestry.api.core.IClimateControlled; +import forestry.apiculture.gadgets.BlockAlveary; import forestry.core.config.Defaults; import forestry.core.fluids.FluidHelper; import forestry.core.fluids.Fluids; @@ -34,58 +34,43 @@ import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; import forestry.core.network.GuiId; -public class TileAlvearyHygroregulator extends TileAlveary implements IInventory, ILiquidTankContainer { - - /* CONSTANTS */ - public static final int BLOCK_META = 5; - - /* RECIPE MANAGMENT */ - private static class HygroregulatorRecipe { - - public final FluidStack liquid; - public final int transferTime; - public final float humidChange; - public final float tempChange; - - public HygroregulatorRecipe(FluidStack liquid, int transferTime, float humidChange, float tempChange) { - this.liquid = liquid; - this.transferTime = transferTime; - this.humidChange = humidChange; - this.tempChange = tempChange; - } - } - - public static final short SLOT_INPUT = 0; +public class TileAlvearyHygroregulator extends TileAlvearyWithGui implements IInventory, ILiquidTankContainer, IAlvearyComponent.Climatiser { private final HygroregulatorRecipe[] recipes; /* MEMBERS */ private final TankManager tankManager; private final FilteredTank liquidTank; + private final IInventoryAdapter inventory; private HygroregulatorRecipe currentRecipe; private int transferTime; public TileAlvearyHygroregulator() { - super(BLOCK_META); + super(TileAlveary.HYGRO_META, GuiId.HygroregulatorGUI); - setInternalInventory(new HygroInventoryAdapter(this)); + this.inventory = new HygroInventory(this); Fluid water = Fluids.WATER.getFluid(); Fluid lava = Fluids.LAVA.getFluid(); Fluid liquidIce = Fluids.ICE.getFluid(); - liquidTank = new FilteredTank(Defaults.PROCESSOR_TANK_CAPACITY, water, lava, liquidIce); - tankManager = new TankManager(liquidTank); + this.liquidTank = new FilteredTank(Defaults.PROCESSOR_TANK_CAPACITY, water, lava, liquidIce); + this.tankManager = new TankManager(liquidTank); - recipes = new HygroregulatorRecipe[]{new HygroregulatorRecipe(new FluidStack(water, 1), 1, 0.01f, -0.005f), + this.recipes = new HygroregulatorRecipe[]{new HygroregulatorRecipe(new FluidStack(water, 1), 1, 0.01f, -0.005f), new HygroregulatorRecipe(new FluidStack(lava, 1), 10, -0.01f, +0.005f), new HygroregulatorRecipe(new FluidStack(liquidIce, 1), 10, 0.02f, -0.01f)}; } @Override - public void openGui(EntityPlayer player) { - player.openGui(ForestryAPI.instance, GuiId.HygroregulatorGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + public IInventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + public boolean allowsAutomation() { + return true; } /* UPDATING */ @@ -101,9 +86,7 @@ public class TileAlvearyHygroregulator extends TileAlveary implements IInventory } @Override - protected void updateServerSide() { - super.updateServerSide(); - + public void changeClimate(int tickCount, IClimateControlled climateControlled) { if (transferTime <= 0 && liquidTank.getFluidAmount() > 0) { currentRecipe = getRecipe(liquidTank.getFluid()); @@ -117,17 +100,14 @@ public class TileAlvearyHygroregulator extends TileAlveary implements IInventory transferTime--; if (currentRecipe != null) { - IAlvearyComponent component = (IAlvearyComponent) this.getCentralTE(); - if (component != null) { - component.addHumidityChange(currentRecipe.humidChange, 0.0f, 1.0f); - component.addTemperatureChange(currentRecipe.tempChange, 0.0f, 2.0f); - } + climateControlled.addHumidityChange(currentRecipe.humidChange, 0.0f, 1.0f); + climateControlled.addTemperatureChange(currentRecipe.tempChange, 0.0f, 2.0f); } else { transferTime = 0; } } - if (updateOnInterval(20)) { + if (tickCount % 20 == 0) { IInventoryAdapter canInventory = getInternalInventory(); // Check if we have suitable items waiting in the item slot @@ -137,11 +117,6 @@ public class TileAlvearyHygroregulator extends TileAlveary implements IInventory } } - @Override - public boolean hasFunction() { - return true; - } - /* SAVING & LOADING */ @Override public void readFromNBT(NBTTagCompound nbttagcompound) { @@ -167,7 +142,6 @@ public class TileAlvearyHygroregulator extends TileAlveary implements IInventory currentRecipe.liquid.writeToNBT(subcompound); nbttagcompound.setTag("CurrentLiquid", subcompound); } - } /* TEXTURES */ @@ -220,8 +194,26 @@ public class TileAlvearyHygroregulator extends TileAlveary implements IInventory public void sendGUINetworkData(Container container, ICrafting iCrafting) { } - private static class HygroInventoryAdapter extends TileInventoryAdapter { - public HygroInventoryAdapter(TileAlvearyHygroregulator alvearyHygroregulator) { + /* RECIPE MANAGMENT */ + private static class HygroregulatorRecipe { + + public final FluidStack liquid; + public final int transferTime; + public final float humidChange; + public final float tempChange; + + public HygroregulatorRecipe(FluidStack liquid, int transferTime, float humidChange, float tempChange) { + this.liquid = liquid; + this.transferTime = transferTime; + this.humidChange = humidChange; + this.tempChange = tempChange; + } + } + + public static class HygroInventory extends TileInventoryAdapter { + public static final short SLOT_INPUT = 0; + + public HygroInventory(TileAlvearyHygroregulator alvearyHygroregulator) { super(alvearyHygroregulator, 1, "CanInv"); } diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlvearyPlain.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyPlain.java new file mode 100644 index 000000000..065168a89 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyPlain.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.util.ForgeDirection; + +import cpw.mods.fml.common.Optional; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeHousingInventory; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; +import forestry.apiculture.trigger.ApicultureTriggers; +import forestry.core.config.Config; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IHintSource; +import forestry.core.interfaces.ITitled; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.rectangular.PartPosition; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.GuiId; +import forestry.core.network.IStreamableGui; + +import buildcraft.api.statements.IStatementContainer; +import buildcraft.api.statements.ITriggerExternal; +import buildcraft.api.statements.ITriggerInternal; +import buildcraft.api.statements.ITriggerProvider; + +@Optional.Interface(iface = "buildcraft.api.statements.ITriggerProvider", modid = "BuildCraftAPI|statements") +public class TileAlvearyPlain extends TileAlveary implements IBeeHousing, IClimatised, IHintSource, IStreamableGui, ITitled, ITriggerProvider { + + @Override + public void onMachineAssembled(MultiblockControllerBase controller) { + super.onMachineAssembled(controller); + + // set alveary entrance block meta + if (getPartPosition() == PartPosition.Frame) { + if (worldObj.getTileEntity(xCoord, yCoord + 1, zCoord) == null) { + this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, TileAlveary.ENTRANCE_META, 2); + } + } + } + + @Override + public void onMachineBroken() { + super.onMachineBroken(); + + // set alveary entrance block meta back to normal + this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, TileAlveary.PLAIN_META, 2); + } + + @Override + public IInventoryAdapter getInternalInventory() { + return getAlvearyController().getInternalInventory(); + } + + @Override + public boolean allowsAutomation() { + return true; + } + + /* GUI */ + @Override + public void openGui(EntityPlayer player) { + if (isConnected()) { + player.openGui(ForestryAPI.instance, GuiId.AlvearyGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + getAlvearyController().writeGuiData(data); + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + getAlvearyController().readGuiData(data); + } + + @Override + public String getUnlocalizedTitle() { + return "alveary.0.name"; + } + + /* IHintSource */ + @Override + public boolean hasHints() { + return Config.hints.get("apiary").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("apiary"); + } + + /* ITRIGGERPROVIDER */ + @Optional.Method(modid = "BuildCraftAPI|statements") + @Override + public Collection getInternalTriggers(IStatementContainer container) { + return null; + } + + @Optional.Method(modid = "BuildCraftAPI|statements") + @Override + public Collection getExternalTriggers(ForgeDirection side, TileEntity tile) { + Collection res = new ArrayList(); + res.add(ApicultureTriggers.missingQueen); + res.add(ApicultureTriggers.missingDrone); + return res; + } + + /* IHousing */ + @Override + public World getWorld() { + return getAlvearyController().getWorld(); + } + + @Override + public ChunkCoordinates getCoordinates() { + return getAlvearyController().getCoordinates(); + } + + @Override + public BiomeGenBase getBiome() { + return getAlvearyController().getBiome(); + } + + /* IBeeHousing */ + @Override + public Iterable getBeeModifiers() { + return getAlvearyController().getBeeModifiers(); + } + + @Override + public Iterable getBeeListeners() { + return getAlvearyController().getBeeListeners(); + } + + @Override + public IBeeHousingInventory getBeeInventory() { + return getAlvearyController().getBeeInventory(); + } + + @Override + public IBeekeepingLogic getBeekeepingLogic() { + return getAlvearyController().getBeekeepingLogic(); + } + + /* IClimatised */ + @Override + public EnumTemperature getTemperature() { + return getAlvearyController().getTemperature(); + } + + @Override + public EnumHumidity getHumidity() { + return getAlvearyController().getHumidity(); + } + + @Override + public int getBlockLightValue() { + return getAlvearyController().getBlockLightValue(); + } + + @Override + public boolean canBlockSeeTheSky() { + return getAlvearyController().canBlockSeeTheSky(); + } + + @Override + public float getExactTemperature() { + return getAlvearyController().getExactTemperature(); + } + + @Override + public float getExactHumidity() { + return getAlvearyController().getExactHumidity(); + } + + @Override + public IErrorLogic getErrorLogic() { + return getAlvearyController().getErrorLogic(); + } + +} diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlvearySieve.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearySieve.java new file mode 100644 index 000000000..21caa6576 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearySieve.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.DefaultBeeListener; +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBeeListener; +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.ISpeciesRoot; +import forestry.apiculture.gadgets.BlockAlveary; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.ICrafter; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.GuiId; +import forestry.core.utils.StackUtils; + +public class TileAlvearySieve extends TileAlvearyWithGui implements ICrafter, IAlvearyComponent.BeeListener { + + private final IBeeListener beeListener; + private final AlvearySieveInventory inventory; + + public TileAlvearySieve() { + super(TileAlveary.SIEVE_META, GuiId.AlvearySieveGUI); + this.inventory = new AlvearySieveInventory(this); + this.beeListener = new AlvearySieveBeeListener(this); + } + + @Override + public IInventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + public IBeeListener getBeeListener() { + return beeListener; + } + + /* TEXTURES & INTERNAL */ + @Override + public int getIcon(int side, int metadata) { + if (side == 0 || side == 1) { + return BlockAlveary.BOTTOM; + } + return BlockAlveary.SIEVE; + } + + /* ICRAFTER */ + @Override + public boolean canTakeStack(int slotIndex) { + return true; + } + + @Override + public ItemStack takenFromSlot(int slotIndex, EntityPlayer player) { + return inventory.takenFromSlot(slotIndex); + } + + @Override + public ItemStack getResult() { + return null; + } + + private static class AlvearySieveBeeListener extends DefaultBeeListener { + private final TileAlvearySieve tile; + + public AlvearySieveBeeListener(TileAlvearySieve tile) { + this.tile = tile; + } + + @Override + public boolean onPollenRetrieved(IIndividual pollen) { + if (!tile.inventory.canStorePollen()) { + return false; + } + + ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot(pollen.getClass()); + + ItemStack pollenStack = speciesRoot.getMemberStack(pollen, EnumGermlingType.POLLEN.ordinal()); + if (pollenStack != null) { + tile.inventory.storePollenStack(pollenStack); + return true; + } + return false; + } + } + + public static class AlvearySieveInventory extends TileInventoryAdapter { + public static final int SLOT_POLLEN_1 = 0; + public static final int SLOTS_POLLEN_COUNT = 4; + public static final int SLOT_SIEVE = 4; + + public AlvearySieveInventory(TileAlvearySieve alvearySieve) { + super(alvearySieve, 5, "Items", 1); + } + + @Override + public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { + return StackUtils.isIdenticalItem(ForestryItem.craftingMaterial.getItemStack(1, 3), itemStack); + } + + private boolean canStorePollen() { + if (getStackInSlot(SLOT_SIEVE) == null) { + return false; + } + + for (int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { + if (getStackInSlot(i) == null) { + return true; + } + } + + return false; + } + + private void storePollenStack(ItemStack itemstack) { + for (int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { + if (getStackInSlot(i) == null) { + setInventorySlotContents(i, itemstack); + return; + } + } + } + + public ItemStack takenFromSlot(int slotIndex) { + if (slotIndex == SLOT_SIEVE) { + for (int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { + setInventorySlotContents(i, null); + } + return getStackInSlot(SLOT_SIEVE); + } else { + setInventorySlotContents(SLOT_SIEVE, null); + return getStackInSlot(slotIndex); + } + } + } + +} diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlvearyStabiliser.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyStabiliser.java new file mode 100644 index 000000000..8790d2462 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyStabiliser.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import forestry.api.apiculture.DefaultBeeModifier; +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeModifier; +import forestry.apiculture.gadgets.BlockAlveary; + +public class TileAlvearyStabiliser extends TileAlveary implements IAlvearyComponent.BeeModifier { + + private static final IBeeModifier beeModifier = new AlvearyStabiliserBeeModifier(); + + /* TEXTURES */ + @Override + public int getIcon(int side, int metadata) { + if (side == 0 || side == 1) { + return BlockAlveary.BOTTOM; + } + + return BlockAlveary.STABILISER; + } + + @Override + public IBeeModifier getBeeModifier() { + return beeModifier; + } + + private static class AlvearyStabiliserBeeModifier extends DefaultBeeModifier { + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 0.0f; + } + } +} diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearySwarmer.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearySwarmer.java old mode 100755 new mode 100644 similarity index 74% rename from src/main/java/forestry/apiculture/gadgets/TileAlvearySwarmer.java rename to src/main/java/forestry/apiculture/multiblock/TileAlvearySwarmer.java index 9ae809e2d..ecd72752b --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearySwarmer.java +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearySwarmer.java @@ -8,13 +8,11 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.apiculture.gadgets; +package forestry.apiculture.multiblock; -import java.io.IOException; import java.util.Map.Entry; import java.util.Stack; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -24,55 +22,55 @@ import forestry.api.apiculture.BeeManager; import forestry.api.apiculture.EnumBeeType; import forestry.api.apiculture.IAlvearyComponent; import forestry.api.apiculture.IBee; -import forestry.api.apiculture.IBeeHousing; -import forestry.api.core.ForestryAPI; +import forestry.apiculture.gadgets.BlockAlveary; import forestry.apiculture.network.PacketActiveUpdate; import forestry.apiculture.worldgen.Hive; import forestry.apiculture.worldgen.HiveDecorator; import forestry.apiculture.worldgen.HiveDescriptionSwarmer; import forestry.core.interfaces.IActivatable; +import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; import forestry.core.inventory.wrappers.IInvSlot; import forestry.core.inventory.wrappers.InventoryIterator; -import forestry.core.network.DataInputStreamForestry; -import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; import forestry.core.utils.StackUtils; -public class TileAlvearySwarmer extends TileAlveary implements ISidedInventory, IActivatable { - - /* CONSTANTS */ - public static final int BLOCK_META = 2; +public class TileAlvearySwarmer extends TileAlvearyWithGui implements ISidedInventory, IActivatable, IAlvearyComponent.Active { + private final SwarmerInventory inventory; private final Stack pendingSpawns = new Stack(); private boolean active; public TileAlvearySwarmer() { - super(BLOCK_META); - setInternalInventory(new SwarmerInventoryAdapter(this)); + super(TileAlveary.SWARMER_META, GuiId.AlvearySwarmerGUI); + this.inventory = new SwarmerInventory(this); } @Override - public void openGui(EntityPlayer player) { - player.openGui(ForestryAPI.instance, GuiId.AlvearySwarmerGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + public IInventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + public boolean allowsAutomation() { + return true; } /* UPDATING */ @Override - protected void updateServerSide() { - super.updateServerSide(); - + public void updateServer(int tickCount) { if (pendingSpawns.size() > 0) { setActive(true); - if (updateOnInterval(1000)) { + if (tickCount % 1000 == 0) { trySpawnSwarm(); } } else { setActive(false); } - if (!updateOnInterval(500)) { + if (tickCount % 500 != 0) { return; } @@ -97,23 +95,19 @@ public class TileAlvearySwarmer extends TileAlveary implements ISidedInventory, pendingSpawns.push(BeeManager.beeRoot.getMemberStack(princess, EnumBeeType.PRINCESS.ordinal())); } + @Override + public void updateClient(int tickCount) { + + } + private ItemStack getPrincessStack() { - if (!this.hasMaster()) { - return null; + ItemStack princessStack = getAlvearyController().getBeeInventory().getQueen(); + + if (BeeManager.beeRoot.isMated(princessStack)) { + return princessStack; } - IAlvearyComponent master = (IAlvearyComponent) this.getCentralTE(); - if (!(master instanceof IBeeHousing)) { - return null; - } - - IBeeHousing housing = (IBeeHousing) master; - ItemStack princessStack = housing.getQueen(); - if (princessStack == null || !BeeManager.beeRoot.isMated(princessStack)) { - return null; - } - - return princessStack; + return null; } private int consumeInducerAndGetChance() { @@ -151,24 +145,15 @@ public class TileAlvearySwarmer extends TileAlveary implements ISidedInventory, /* NETWORK */ @Override - public void writeData(DataOutputStreamForestry data) throws IOException { - super.writeData(data); - data.writeBoolean(active); + protected void encodeDescriptionPacket(NBTTagCompound packetData) { + super.encodeDescriptionPacket(packetData); + packetData.setBoolean("Active", active); } @Override - public void readData(DataInputStreamForestry data) throws IOException { - super.readData(data); - boolean active = data.readBoolean(); - if (this.active != active) { - this.active = active; - worldObj.func_147479_m(xCoord, yCoord, zCoord); - } - } - - @Override - public boolean hasFunction() { - return true; + protected void decodeDescriptionPacket(NBTTagCompound packetData) { + super.decodeDescriptionPacket(packetData); + setActive(packetData.getBoolean("Active")); } /* TEXTURES */ @@ -189,18 +174,19 @@ public class TileAlvearySwarmer extends TileAlveary implements ISidedInventory, @Override public void readFromNBT(NBTTagCompound nbttagcompound) { super.readFromNBT(nbttagcompound); + setActive(nbttagcompound.getBoolean("Active")); NBTTagList nbttaglist = nbttagcompound.getTagList("PendingSpawns", 10); for (int i = 0; i < nbttaglist.tagCount(); i++) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); pendingSpawns.add(ItemStack.loadItemStackFromNBT(nbttagcompound1)); } - } @Override public void writeToNBT(NBTTagCompound nbttagcompound) { super.writeToNBT(nbttagcompound); + nbttagcompound.setBoolean("Active", active); NBTTagList nbttaglist = new NBTTagList(); ItemStack[] offspring = pendingSpawns.toArray(new ItemStack[pendingSpawns.size()]); @@ -213,7 +199,15 @@ public class TileAlvearySwarmer extends TileAlveary implements ISidedInventory, } } nbttagcompound.setTag("PendingSpawns", nbttaglist); + } + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + if (oldAccess == EnumAccess.SHARED || newAccess == EnumAccess.SHARED) { + // pipes connected to this need to update + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, blockType); + markDirty(); + } } @Override @@ -234,8 +228,8 @@ public class TileAlvearySwarmer extends TileAlveary implements ISidedInventory, } } - private static class SwarmerInventoryAdapter extends TileInventoryAdapter { - public SwarmerInventoryAdapter(TileAlvearySwarmer alvearySwarmer) { + private static class SwarmerInventory extends TileInventoryAdapter { + public SwarmerInventory(TileAlvearySwarmer alvearySwarmer) { super(alvearySwarmer, 4, "SwarmInv"); } diff --git a/src/main/java/forestry/apiculture/multiblock/TileAlvearyWithGui.java b/src/main/java/forestry/apiculture/multiblock/TileAlvearyWithGui.java new file mode 100644 index 000000000..29b014345 --- /dev/null +++ b/src/main/java/forestry/apiculture/multiblock/TileAlvearyWithGui.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.multiblock; + +import java.io.IOException; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; + +import forestry.api.core.ForestryAPI; +import forestry.core.delegates.AccessHandler; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.interfaces.ITitled; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.GuiId; +import forestry.core.network.IStreamableGui; +import forestry.core.utils.EnumAccess; + +public abstract class TileAlvearyWithGui extends TileAlveary implements IStreamableGui, ITitled, IRestrictedAccessTile { + + private final AccessHandler accessHandler; + private final String unlocalizedTitle; + private final GuiId guiId; + + public TileAlvearyWithGui(int meta, GuiId guiId) { + this.accessHandler = new AccessHandler(this); + this.unlocalizedTitle = "alveary." + meta + ".name"; + this.guiId = guiId; + } + + @Override + public final IAccessHandler getAccessHandler() { + return accessHandler; + } + + @Override + public final ChunkCoordinates getCoordinates() { + return new ChunkCoordinates(xCoord, yCoord, zCoord); + } + + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + if (oldAccess == EnumAccess.SHARED || newAccess == EnumAccess.SHARED) { + // pipes connected to this need to update + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, blockType); + markDirty(); + } + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + accessHandler.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + accessHandler.readFromNBT(data); + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + accessHandler.writeData(data); + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + accessHandler.readData(data); + } + + @Override + public final String getUnlocalizedTitle() { + return unlocalizedTitle; + } + + @Override + public final void openGui(EntityPlayer player) { + player.openGui(ForestryAPI.instance, guiId.ordinal(), worldObj, xCoord, yCoord, zCoord); + } +} diff --git a/src/main/java/forestry/apiculture/network/PacketActiveUpdate.java b/src/main/java/forestry/apiculture/network/PacketActiveUpdate.java index cfbf8d6a7..625d16bf3 100644 --- a/src/main/java/forestry/apiculture/network/PacketActiveUpdate.java +++ b/src/main/java/forestry/apiculture/network/PacketActiveUpdate.java @@ -14,7 +14,6 @@ import java.io.IOException; import net.minecraft.tileentity.TileEntity; -import forestry.core.gadgets.TileForestry; import forestry.core.interfaces.IActivatable; import forestry.core.network.DataInputStreamForestry; import forestry.core.network.DataOutputStreamForestry; @@ -24,7 +23,7 @@ import forestry.core.proxy.Proxies; public class PacketActiveUpdate extends PacketCoordinates { - private IActivatable activatable; + private boolean active; public static void onPacketData(DataInputStreamForestry data) throws IOException { new PacketActiveUpdate(data); @@ -34,22 +33,22 @@ public class PacketActiveUpdate extends PacketCoordinates { super(data); } - public PacketActiveUpdate(T tile) { - super(PacketId.TILE_FORESTRY_ACTIVE, tile); - this.activatable = tile; + public PacketActiveUpdate(IActivatable tile) { + super(PacketId.TILE_FORESTRY_ACTIVE, tile.getCoordinates()); + this.active = tile.isActive(); } @Override protected void writeData(DataOutputStreamForestry data) throws IOException { super.writeData(data); - data.writeBoolean(activatable.isActive()); + data.writeBoolean(active); } @Override protected void readData(DataInputStreamForestry data) throws IOException { super.readData(data); - boolean active = data.readBoolean(); + active = data.readBoolean(); TileEntity tile = getTarget(Proxies.common.getRenderWorld()); if (tile instanceof IActivatable) { diff --git a/src/main/java/forestry/apiculture/network/PacketBeekeepingLogicActive.java b/src/main/java/forestry/apiculture/network/PacketBeekeepingLogicActive.java new file mode 100644 index 000000000..d851b948f --- /dev/null +++ b/src/main/java/forestry/apiculture/network/PacketBeekeepingLogicActive.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.apiculture.network; + +import java.io.IOException; + +import net.minecraft.tileentity.TileEntity; + +import forestry.api.apiculture.IBeeHousing; +import forestry.apiculture.BeekeepingLogic; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketId; +import forestry.core.proxy.Proxies; + +public class PacketBeekeepingLogicActive extends PacketCoordinates { + private BeekeepingLogic beekeepingLogic; + + public static void onPacketData(DataInputStreamForestry data) throws IOException { + new PacketBeekeepingLogicActive(data); + } + + private PacketBeekeepingLogicActive(DataInputStreamForestry data) throws IOException { + super(data); + } + + public PacketBeekeepingLogicActive(IBeeHousing tile) { + super(PacketId.BEE_LOGIC_ACTIVE, tile.getCoordinates()); + this.beekeepingLogic = (BeekeepingLogic) tile.getBeekeepingLogic(); + } + + @Override + protected void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + beekeepingLogic.writeData(data); + } + + @Override + protected void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + + TileEntity tile = getTarget(Proxies.common.getRenderWorld()); + if (tile instanceof IBeeHousing) { + IBeeHousing beeHousing = (IBeeHousing) tile; + BeekeepingLogic beekeepingLogic = (BeekeepingLogic) beeHousing.getBeekeepingLogic(); + beekeepingLogic.readData(data); + } + } +} diff --git a/src/main/java/forestry/apiculture/network/PacketHandlerApiculture.java b/src/main/java/forestry/apiculture/network/PacketHandlerApiculture.java index babf10cc5..9173ddfb5 100644 --- a/src/main/java/forestry/apiculture/network/PacketHandlerApiculture.java +++ b/src/main/java/forestry/apiculture/network/PacketHandlerApiculture.java @@ -43,6 +43,10 @@ public class PacketHandlerApiculture implements IPacketHandler { onCandleUpdate(updateCandle); return true; } + case BEE_LOGIC_ACTIVE: { + PacketBeekeepingLogicActive.onPacketData(data); + return true; + } } return false; diff --git a/src/main/java/forestry/apiculture/proxy/ClientProxyApiculture.java b/src/main/java/forestry/apiculture/proxy/ClientProxyApiculture.java index 5fda06750..ec50202ad 100755 --- a/src/main/java/forestry/apiculture/proxy/ClientProxyApiculture.java +++ b/src/main/java/forestry/apiculture/proxy/ClientProxyApiculture.java @@ -11,6 +11,7 @@ package forestry.apiculture.proxy; import net.minecraft.client.particle.EntityFX; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import net.minecraftforge.client.MinecraftForgeClient; @@ -27,6 +28,7 @@ import forestry.core.interfaces.IBlockRenderer; import forestry.core.proxy.ClientProxyRender; import forestry.core.render.RenderAnalyzer; import forestry.core.render.TextureManager; +import forestry.core.vect.IVect; import forestry.plugins.PluginApiculture; public class ClientProxyApiculture extends ProxyApiculture { @@ -43,7 +45,7 @@ public class ClientProxyApiculture extends ProxyApiculture { } @Override - public void addBeeHiveFX(String icon, World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { + public void addBeeHiveFX(String icon, World world, ChunkCoordinates coordinates, int color, IVect area) { if (!ClientProxyRender.shouldSpawnParticle(world)) { return; } @@ -51,11 +53,11 @@ public class ClientProxyApiculture extends ProxyApiculture { EntityFX fx; if (world.rand.nextBoolean()) { - fx = new EntityBeeFX(world, xCoord + 0.5D, yCoord + 0.75D, zCoord + 0.5D, 0.0f, 0.0f, 0.0f, color); + fx = new EntityBeeFX(world, coordinates.posX + 0.5D, coordinates.posY + 0.75D, coordinates.posZ + 0.5D, 0.0f, 0.0f, 0.0f, color); } else { - double spawnX = xCoord + world.rand.nextInt(areaX * 2) - areaX; - double spawnY = yCoord + world.rand.nextInt(areaY); - double spawnZ = zCoord + world.rand.nextInt(areaZ * 2) - areaZ; + double spawnX = coordinates.posX + world.rand.nextInt(area.getX() * 2) - area.getX(); + double spawnY = coordinates.posY + world.rand.nextInt(area.getY()); + double spawnZ = coordinates.posZ + world.rand.nextInt(area.getZ() * 2) - area.getZ(); fx = new EntityBeeFX(world, spawnX, spawnY, spawnZ, 0.0f, 0.0f, 0.0f, color); } diff --git a/src/main/java/forestry/apiculture/proxy/ProxyApiculture.java b/src/main/java/forestry/apiculture/proxy/ProxyApiculture.java index 132042669..5b4264fee 100755 --- a/src/main/java/forestry/apiculture/proxy/ProxyApiculture.java +++ b/src/main/java/forestry/apiculture/proxy/ProxyApiculture.java @@ -10,12 +10,14 @@ ******************************************************************************/ package forestry.apiculture.proxy; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import forestry.core.interfaces.IBlockRenderer; +import forestry.core.vect.IVect; public class ProxyApiculture { - public void addBeeHiveFX(String texture, World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { + public void addBeeHiveFX(String texture, World world, ChunkCoordinates coordinates, int color, IVect area) { } public void addBeeSwarmFX(String texture, World world, double xCoord, double yCoord, double zCoord, int color) { diff --git a/src/main/java/forestry/apiculture/trigger/TriggerMissingDrone.java b/src/main/java/forestry/apiculture/trigger/TriggerMissingDrone.java index c3d1d21a5..51265a2fd 100644 --- a/src/main/java/forestry/apiculture/trigger/TriggerMissingDrone.java +++ b/src/main/java/forestry/apiculture/trigger/TriggerMissingDrone.java @@ -14,9 +14,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; -import forestry.apiculture.gadgets.TileAlveary; +import forestry.api.core.IErrorLogicSource; import forestry.core.EnumErrorCode; -import forestry.core.interfaces.IErrorSource; import forestry.core.triggers.Trigger; import buildcraft.api.statements.IStatementContainer; @@ -34,14 +33,12 @@ public class TriggerMissingDrone extends Trigger { @Override public boolean isTriggerActive(TileEntity tile, ForgeDirection side, IStatementContainer source, IStatementParameter[] parameters) { - if (!(tile instanceof IErrorSource)) { + if (!(tile instanceof IErrorLogicSource)) { return false; } - if (tile instanceof TileAlveary) { - tile = (TileAlveary) ((TileAlveary) tile).getCentralTE(); - } - - return ((IErrorSource) tile).getErrorStates().contains(EnumErrorCode.NODRONE); + + IErrorLogicSource apiary = (IErrorLogicSource) tile; + return apiary.getErrorLogic().contains(EnumErrorCode.NODRONE); } } diff --git a/src/main/java/forestry/apiculture/trigger/TriggerMissingQueen.java b/src/main/java/forestry/apiculture/trigger/TriggerMissingQueen.java index 9f8bc5cad..f45f49d22 100644 --- a/src/main/java/forestry/apiculture/trigger/TriggerMissingQueen.java +++ b/src/main/java/forestry/apiculture/trigger/TriggerMissingQueen.java @@ -14,9 +14,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; -import forestry.apiculture.gadgets.TileAlveary; +import forestry.api.core.IErrorLogicSource; import forestry.core.EnumErrorCode; -import forestry.core.interfaces.IErrorSource; import forestry.core.triggers.Trigger; import buildcraft.api.statements.IStatementContainer; @@ -34,13 +33,11 @@ public class TriggerMissingQueen extends Trigger { @Override public boolean isTriggerActive(TileEntity tile, ForgeDirection side, IStatementContainer source, IStatementParameter[] parameters) { - if (!(tile instanceof IErrorSource)) { + if (!(tile instanceof IErrorLogicSource)) { return false; } - if (tile instanceof TileAlveary) { - tile = (TileAlveary) ((TileAlveary) tile).getCentralTE(); - } - return ((IErrorSource) tile).getErrorStates().contains(EnumErrorCode.NOQUEEN); + IErrorLogicSource apiary = (IErrorLogicSource) tile; + return apiary.getErrorLogic().contains(EnumErrorCode.NOQUEEN); } } diff --git a/src/main/java/forestry/apiculture/trigger/TriggerNoFrames.java b/src/main/java/forestry/apiculture/trigger/TriggerNoFrames.java index 7f4e6cdac..adb31bbb4 100755 --- a/src/main/java/forestry/apiculture/trigger/TriggerNoFrames.java +++ b/src/main/java/forestry/apiculture/trigger/TriggerNoFrames.java @@ -36,14 +36,11 @@ public class TriggerNoFrames extends Trigger { return false; } - for (int i = TileApiary.SLOT_FRAMES_1; i < TileApiary.SLOT_FRAMES_1 + TileApiary.SLOT_FRAMES_COUNT; i++) { - if (((TileApiary) tile).getStackInSlot(i) != null) { - return false; - } - } + TileApiary apiary = (TileApiary) tile; - return true; + TileApiary.ApiaryInventory inventory = (TileApiary.ApiaryInventory) apiary.getInternalInventory(); + return inventory.getFrames().size() == 0; } } diff --git a/src/main/java/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java b/src/main/java/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java index 24d2a12d6..a0c98ea22 100755 --- a/src/main/java/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java +++ b/src/main/java/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java @@ -11,7 +11,6 @@ package forestry.apiculture.worldgen; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Random; @@ -36,9 +35,8 @@ import forestry.api.apiculture.IBeeGenome; import forestry.api.core.EnumHumidity; import forestry.api.core.EnumTemperature; import forestry.api.genetics.AlleleManager; -import forestry.api.genetics.EnumTolerance; import forestry.api.genetics.IFlower; -import forestry.apiculture.gadgets.TileBeehouse; +import forestry.apiculture.gadgets.TileApiary; import forestry.arboriculture.gadgets.BlockFireproofLog; import forestry.arboriculture.gadgets.BlockFireproofPlanks; import forestry.arboriculture.gadgets.BlockLog; @@ -298,38 +296,52 @@ public class ComponentVillageBeeHouse extends StructureVillagePieces.House1 { int yCoord = this.getYWithOffset(y); int zCoord = this.getZWithOffset(x, z); - if (box.isVecInside(xCoord, yCoord, zCoord) && !ForestryBlock.apiculture.isBlockEqual(world, xCoord, yCoord, zCoord) - && world.blockExists(xCoord, yCoord - 1, zCoord)) { + if (!box.isVecInside(xCoord, yCoord, zCoord) || ForestryBlock.apiculture.isBlockEqual(world, xCoord, yCoord, zCoord) + || !world.blockExists(xCoord, yCoord - 1, zCoord)) { + return; + } - world.setBlock(xCoord, yCoord, zCoord, ForestryBlock.apiculture.block(), Defaults.DEFINITION_APIARY_META, - Defaults.FLAG_BLOCK_SYNCH); - ForestryBlock.apiculture.block().onBlockAdded(world, xCoord, yCoord, zCoord); + world.setBlock(xCoord, yCoord, zCoord, ForestryBlock.apiculture.block(), Defaults.DEFINITION_APIARY_META, Defaults.FLAG_BLOCK_SYNCH); + ForestryBlock.apiculture.block().onBlockAdded(world, xCoord, yCoord, zCoord); - TileEntity tile = world.getTileEntity(xCoord, yCoord, zCoord); - if (tile instanceof TileBeehouse) { - TileBeehouse apiary = ((TileBeehouse) tile); - apiary.initialize(); - apiary.setInventorySlotContents(TileBeehouse.SLOT_QUEEN, - BeeManager.beeRoot.getMemberStack(getVillageBee(world, xCoord, yCoord, zCoord), EnumBeeType.PRINCESS.ordinal())); - apiary.setInventorySlotContents(TileBeehouse.SLOT_DRONE, - BeeManager.beeRoot.getMemberStack(getVillageBee(world, xCoord, yCoord, zCoord), EnumBeeType.DRONE.ordinal())); + TileEntity tile = world.getTileEntity(xCoord, yCoord, zCoord); + if (!(tile instanceof TileApiary)) { + return; + } - for (int i = TileBeehouse.SLOT_FRAMES_1; i < TileBeehouse.SLOT_FRAMES_1 + TileBeehouse.SLOT_FRAMES_COUNT; i++) { - float roll = world.rand.nextFloat(); - if (roll < 0.2f) { - apiary.setInventorySlotContents(i, ForestryItem.frameUntreated.getItemStack()); - } else if (roll < 0.4f) { - apiary.setInventorySlotContents(i, ForestryItem.frameImpregnated.getItemStack()); - } else if (roll < 0.6) { - apiary.setInventorySlotContents(i, ForestryItem.frameProven.getItemStack()); - } - } + TileApiary apiary = (TileApiary) tile; - } + ItemStack randomVillagePrincess = getRandomVillageBeeStack(world, xCoord, yCoord, zCoord, EnumBeeType.PRINCESS); + apiary.getBeeInventory().setQueen(randomVillagePrincess); + + ItemStack randomVillageDrone = getRandomVillageBeeStack(world, xCoord, yCoord, zCoord, EnumBeeType.DRONE); + apiary.getBeeInventory().setDrone(randomVillageDrone); + + for (int i = TileApiary.ApiaryInventory.SLOT_FRAMES_1; i < TileApiary.ApiaryInventory.SLOT_FRAMES_1 + TileApiary.ApiaryInventory.SLOT_FRAMES_COUNT; i++) { + ItemStack randomFrame = getRandomFrame(world.rand); + apiary.setInventorySlotContents(i, randomFrame); } } - private static IBee getVillageBee(World world, int xCoord, int yCoord, int zCoord) { + private static ItemStack getRandomFrame(Random random) { + float roll = random.nextFloat(); + if (roll < 0.2f) { + return ForestryItem.frameUntreated.getItemStack(); + } else if (roll < 0.4f) { + return ForestryItem.frameImpregnated.getItemStack(); + } else if (roll < 0.6) { + return ForestryItem.frameProven.getItemStack(); + } else { + return null; + } + } + + private static ItemStack getRandomVillageBeeStack(World world, int xCoord, int yCoord, int zCoord, EnumBeeType beeType) { + IBee randomVillageBee = getRandomVillageBee(world, xCoord, yCoord, zCoord); + return BeeManager.beeRoot.getMemberStack(randomVillageBee, beeType.ordinal()); + } + + private static IBee getRandomVillageBee(World world, int xCoord, int yCoord, int zCoord) { // Get current biome BiomeGenBase biome = world.getBiomeGenForCoords(xCoord, zCoord); diff --git a/src/main/java/forestry/arboriculture/gadgets/ForestryBlockLeaves.java b/src/main/java/forestry/arboriculture/gadgets/ForestryBlockLeaves.java index 536321ab1..e67258ccb 100644 --- a/src/main/java/forestry/arboriculture/gadgets/ForestryBlockLeaves.java +++ b/src/main/java/forestry/arboriculture/gadgets/ForestryBlockLeaves.java @@ -154,13 +154,7 @@ public class ForestryBlockLeaves extends BlockNewLeaf implements ITileEntityProv } // Add saplings - ITree[] saplings; - try { - saplings = tile.getTree().getSaplings(world, playerProfile, x, y, z, saplingModifier); - } catch (Throwable ignored) { - // legacy - saplings = tile.getTree().getSaplings(world, x, y, z, saplingModifier); - } + ITree[] saplings = tile.getTree().getSaplings(world, playerProfile, x, y, z, saplingModifier); for (ITree sapling : saplings) { if (sapling != null) { diff --git a/src/main/java/forestry/arboriculture/gadgets/TileLeaves.java b/src/main/java/forestry/arboriculture/gadgets/TileLeaves.java index a2bcc20b7..2fa243253 100755 --- a/src/main/java/forestry/arboriculture/gadgets/TileLeaves.java +++ b/src/main/java/forestry/arboriculture/gadgets/TileLeaves.java @@ -10,8 +10,6 @@ ******************************************************************************/ package forestry.arboriculture.gadgets; -import com.google.common.collect.ImmutableSet; - import java.io.IOException; import java.util.Arrays; import java.util.Collection; @@ -23,11 +21,9 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.Packet; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; - -import com.mojang.authlib.GameProfile; import net.minecraftforge.common.EnumPlantType; @@ -41,9 +37,6 @@ import forestry.api.arboriculture.ILeafTickHandler; import forestry.api.arboriculture.ITree; import forestry.api.arboriculture.ITreeGenome; import forestry.api.arboriculture.ITreekeepingMode; -import forestry.api.core.EnumHumidity; -import forestry.api.core.EnumTemperature; -import forestry.api.core.IErrorState; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAllele; import forestry.api.genetics.IEffectData; @@ -56,7 +49,6 @@ import forestry.api.lepidopterology.IButterflyGenome; import forestry.api.lepidopterology.IButterflyNursery; import forestry.api.lepidopterology.IButterflyRoot; import forestry.arboriculture.network.PacketRipeningUpdate; -import forestry.core.EnumErrorCode; import forestry.core.genetics.alleles.Allele; import forestry.core.network.DataInputStreamForestry; import forestry.core.network.DataOutputStreamForestry; @@ -87,17 +79,8 @@ public class TileLeaves extends TileTreeContainer implements IPollinatable, IFru private int maturationTime; private int damage; - private BiomeGenBase biome; - private IEffectData effectData[] = new IEffectData[2]; - private void updateBiome() { - if (worldObj == null) { - return; - } - biome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); - } - /* SAVING & LOADING */ @Override public void readFromNBT(NBTTagCompound nbttagcompound) { @@ -142,10 +125,6 @@ public class TileLeaves extends TileTreeContainer implements IPollinatable, IFru @Override public void onBlockTick() { - if (biome == null) { - updateBiome(); - } - ITree tree = getTree(); if (isDecorative || tree == null) { return; @@ -155,7 +134,7 @@ public class TileLeaves extends TileTreeContainer implements IPollinatable, IFru boolean isDestroyed = isDestroyed(tree, damage); for (ILeafTickHandler tickHandler : genome.getPrimary().getRoot().getLeafTickHandlers()) { - if (tickHandler.onRandomLeafTick(tree, worldObj, biome.biomeID, xCoord, yCoord, zCoord, isDestroyed)) { + if (tickHandler.onRandomLeafTick(tree, worldObj, xCoord, yCoord, zCoord, isDestroyed)) { return; } } @@ -183,7 +162,7 @@ public class TileLeaves extends TileTreeContainer implements IPollinatable, IFru matureCaterpillar(); } - effectData = tree.doEffect(effectData, worldObj, biome.biomeID, xCoord, yCoord, zCoord); + effectData = tree.doEffect(effectData, worldObj, xCoord, yCoord, zCoord); } @Override @@ -523,62 +502,8 @@ public class TileLeaves extends TileTreeContainer implements IPollinatable, IFru } @Override - public World getWorld() { - return worldObj; - } - - @Override - public int getXCoord() { - return xCoord; - } - - @Override - public int getYCoord() { - return yCoord; - } - - @Override - public int getZCoord() { - return zCoord; - } - - @Override - public BiomeGenBase getBiome() { - return biome; - } - - @Override - public EnumTemperature getTemperature() { - return null; - } - - @Override - public EnumHumidity getHumidity() { - return null; - } - - @Override - public boolean setErrorCondition(boolean condition, IErrorState errorState) { - return condition; - } - - @Override - public ImmutableSet getErrorStates() { - return ImmutableSet.of(); - } - - @Override - public void setErrorState(IErrorState state) { - } - - @Override - public EnumErrorCode getErrorState() { - return null; - } - - @Override - public boolean addProduct(ItemStack product, boolean all) { - return false; + public ChunkCoordinates getCoordinates() { + return new ChunkCoordinates(xCoord, yCoord, zCoord); } @Override @@ -607,9 +532,4 @@ public class TileLeaves extends TileTreeContainer implements IPollinatable, IFru return !isDecorative && !isDestroyed(tree, damage) && caterpillar == null; } - /* IHousing */ - @Override - public GameProfile getOwnerName() { - return this.getOwner(); - } } diff --git a/src/main/java/forestry/arboriculture/gadgets/TileTreeContainer.java b/src/main/java/forestry/arboriculture/gadgets/TileTreeContainer.java index 019424df7..168cb3c07 100755 --- a/src/main/java/forestry/arboriculture/gadgets/TileTreeContainer.java +++ b/src/main/java/forestry/arboriculture/gadgets/TileTreeContainer.java @@ -12,7 +12,6 @@ package forestry.arboriculture.gadgets; import java.io.IOException; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTUtil; import net.minecraft.network.Packet; @@ -23,11 +22,9 @@ import com.mojang.authlib.GameProfile; import forestry.api.arboriculture.ITree; import forestry.api.genetics.IAllele; import forestry.arboriculture.genetics.Tree; -import forestry.core.interfaces.IOwnable; import forestry.core.network.DataInputStreamForestry; import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.IStreamable; -import forestry.core.utils.PlayerUtil; import forestry.plugins.PluginArboriculture; /** @@ -35,9 +32,10 @@ import forestry.plugins.PluginArboriculture; * * @author SirSengir */ -public abstract class TileTreeContainer extends TileEntity implements IStreamable, IOwnable { +public abstract class TileTreeContainer extends TileEntity implements IStreamable { private ITree containedTree; + private GameProfile owner; /* SAVING & LOADING */ @Override @@ -104,6 +102,15 @@ public abstract class TileTreeContainer extends TileEntity implements IStreamabl return this.containedTree; } + /* Owner */ + public GameProfile getOwner() { + return owner; + } + + public void setOwner(GameProfile owner) { + this.owner = owner; + } + /* UPDATING */ /** @@ -123,36 +130,4 @@ public abstract class TileTreeContainer extends TileEntity implements IStreamabl @Override public abstract Packet getDescriptionPacket(); - /* IOWNABLE */ - public GameProfile owner = null; - - @Override - public boolean allowsRemoval(EntityPlayer player) { - return true; - } - - @Override - public boolean isOwned() { - return owner != null; - } - - @Override - public GameProfile getOwner() { - return owner; - } - - @Override - public void setOwner(EntityPlayer player) { - this.owner = player.getGameProfile(); - } - - public void setOwner(GameProfile playername) { - this.owner = playername; - } - - @Override - public boolean isOwner(EntityPlayer player) { - return PlayerUtil.isSameGameProfile(owner, player.getGameProfile()); - } - } diff --git a/src/main/java/forestry/arboriculture/genetics/AlleleTreeSpecies.java b/src/main/java/forestry/arboriculture/genetics/AlleleTreeSpecies.java index 463604318..c97de7033 100755 --- a/src/main/java/forestry/arboriculture/genetics/AlleleTreeSpecies.java +++ b/src/main/java/forestry/arboriculture/genetics/AlleleTreeSpecies.java @@ -93,7 +93,7 @@ public class AlleleTreeSpecies extends AlleleSpecies implements IAlleleTreeSpeci public AlleleTreeSpecies(String uid, boolean isDominant, String speciesName, IClassification branch, String binomial, int primaryColor, int secondaryColor, Class generator, ItemStack wood) { - super("forestry." + uid, "for.trees.species." + speciesName, "Sengir", "for.description." + uid, isDominant, branch, binomial, true); + super("forestry." + uid, "for.trees.species." + speciesName, "Sengir", "for.description." + uid, isDominant, branch, binomial, true); this.root = (ITreeRoot) AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees"); this.generatorClass = generator; diff --git a/src/main/java/forestry/arboriculture/genetics/Tree.java b/src/main/java/forestry/arboriculture/genetics/Tree.java index 2cea8087d..9df7dbd6e 100755 --- a/src/main/java/forestry/arboriculture/genetics/Tree.java +++ b/src/main/java/forestry/arboriculture/genetics/Tree.java @@ -42,11 +42,9 @@ import forestry.api.arboriculture.ITreeGenome; import forestry.api.arboriculture.ITreeMutation; import forestry.api.genetics.IAllele; import forestry.api.genetics.IAlleleBoolean; -import forestry.api.genetics.IAlleleSpecies; import forestry.api.genetics.IChromosome; import forestry.api.genetics.IEffectData; import forestry.api.genetics.IFruitFamily; -import forestry.api.genetics.IGenome; import forestry.api.genetics.IMutation; import forestry.arboriculture.gadgets.ForestryBlockLeaves; import forestry.arboriculture.gadgets.TileLeaves; @@ -120,14 +118,14 @@ public class Tree extends Individual implements ITree, IPlantable { /* EFFECTS */ @Override - public IEffectData[] doEffect(IEffectData[] storedData, World world, int biomeid, int x, int y, int z) { + public IEffectData[] doEffect(IEffectData[] storedData, World world, int x, int y, int z) { IAlleleLeafEffect effect = (IAlleleLeafEffect) getGenome().getActiveAllele(EnumTreeChromosome.EFFECT); if (effect == null) { return null; } - storedData[0] = doEffect(effect, storedData[0], world, biomeid, x, y, z); + storedData[0] = doEffect(effect, storedData[0], world, x, y, z); // Return here if the primary can already not be combined if (!effect.isCombinable()) { @@ -139,18 +137,18 @@ public class Tree extends Individual implements ITree, IPlantable { return storedData; } - storedData[1] = doEffect(secondary, storedData[1], world, biomeid, x, y, z); + storedData[1] = doEffect(secondary, storedData[1], world, x, y, z); return storedData; } - private IEffectData doEffect(IAlleleLeafEffect effect, IEffectData storedData, World world, int biomeid, int x, int y, int z) { + private IEffectData doEffect(IAlleleLeafEffect effect, IEffectData storedData, World world, int x, int y, int z) { storedData = effect.validateStorage(storedData); return effect.doEffect(getGenome(), storedData, world, x, y, z); } @Override - public IEffectData[] doFX(IEffectData[] storedData, World world, int biomeid, int x, int y, int z) { + public IEffectData[] doFX(IEffectData[] storedData, World world, int x, int y, int z) { return null; } @@ -358,11 +356,6 @@ public class Tree extends Individual implements ITree, IPlantable { } /* REPRODUCTION */ - @Override - public ITree[] getSaplings(World world, int x, int y, int z, float modifier) { - return getSaplings(world, null, x, y, z, modifier); - } - @Override public ITree[] getSaplings(World world, GameProfile playerProfile, int x, int y, int z, float modifier) { ArrayList prod = new ArrayList(); @@ -406,15 +399,15 @@ public class Tree extends Individual implements ITree, IPlantable { return new Tree(new TreeGenome(chromosomes)); } - private static IChromosome[] mutateSpecies(World world, @Nullable GameProfile playerProfile, int x, int y, int z, IGenome genomeOne, IGenome genomeTwo) { + private static IChromosome[] mutateSpecies(World world, @Nullable GameProfile playerProfile, int x, int y, int z, ITreeGenome genomeOne, ITreeGenome genomeTwo) { IChromosome[] parent1 = genomeOne.getChromosomes(); IChromosome[] parent2 = genomeTwo.getChromosomes(); - IGenome genome0; - IGenome genome1; - IAlleleSpecies allele0; - IAlleleSpecies allele1; + ITreeGenome genome0; + ITreeGenome genome1; + IAlleleTreeSpecies allele0; + IAlleleTreeSpecies allele1; if (world.rand.nextBoolean()) { allele0 = (IAlleleTreeSpecies) parent1[EnumTreeChromosome.SPECIES.ordinal()].getPrimaryAllele(); diff --git a/src/main/java/forestry/arboriculture/genetics/TreeHelper.java b/src/main/java/forestry/arboriculture/genetics/TreeHelper.java index 336cf2268..1e73ece6e 100755 --- a/src/main/java/forestry/arboriculture/genetics/TreeHelper.java +++ b/src/main/java/forestry/arboriculture/genetics/TreeHelper.java @@ -45,9 +45,7 @@ import forestry.api.genetics.IChromosomeType; import forestry.api.genetics.IIndividual; import forestry.api.genetics.IMutation; import forestry.arboriculture.gadgets.BlockFruitPod; -import forestry.arboriculture.gadgets.ForestryBlockLeaves; import forestry.arboriculture.gadgets.TileFruitPod; -import forestry.arboriculture.gadgets.TileLeaves; import forestry.arboriculture.gadgets.TileSapling; import forestry.core.config.Defaults; import forestry.core.config.ForestryBlock; @@ -160,6 +158,9 @@ public class TreeHelper extends SpeciesRoot implements ITreeRoot { @Override public ItemStack getMemberStack(IIndividual tree, int type) { + if (!isMember(tree)) { + return null; + } Item germlingItem; switch (EnumGermlingType.VALUES[type]) { @@ -209,33 +210,6 @@ public class TreeHelper extends SpeciesRoot implements ITreeRoot { return true; } - @Override - public boolean setLeaves(World world, IIndividual tree, GameProfile owner, int x, int y, int z) { - return setLeaves(world, tree, owner, x, y, z, false); - } - - @Override - public boolean setLeaves(World world, IIndividual tree, GameProfile owner, int x, int y, int z, boolean decorative) { - - if (decorative) { - ((ITree) tree).setLeavesDecorative(world, owner, x, y, z); - } else { - ((ITree) tree).setLeaves(world, owner, x, y, z); - } - - if (!ForestryBlock.leaves.isBlockEqual(world, x, y, z)) { - return false; - } - - TileLeaves tileLeaves = ForestryBlockLeaves.getLeafTile(world, x, y, z); - if (tileLeaves == null) { - world.setBlockToAir(x, y, z); - return false; - } - - return true; - } - @Override public boolean setFruitBlock(World world, IAlleleFruit allele, float sappiness, short[] indices, int x, int y, int z) { diff --git a/src/main/java/forestry/arboriculture/genetics/TreeMutation.java b/src/main/java/forestry/arboriculture/genetics/TreeMutation.java index dfa4c4127..8d2c56a90 100755 --- a/src/main/java/forestry/arboriculture/genetics/TreeMutation.java +++ b/src/main/java/forestry/arboriculture/genetics/TreeMutation.java @@ -19,7 +19,6 @@ import forestry.api.arboriculture.ITreeRoot; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAllele; import forestry.api.genetics.IAlleleSpecies; -import forestry.api.genetics.IGenome; import forestry.core.genetics.Mutation; import forestry.plugins.PluginArboriculture; @@ -38,11 +37,6 @@ public class TreeMutation extends Mutation implements ITreeMutation { public ITreeRoot getRoot() { return root; } - - @Override - public float getChance(World world, int x, int y, int z, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { - return getChance(world, x, y, z, (IAlleleTreeSpecies) allele0, (IAlleleTreeSpecies) allele1, (ITreeGenome) genome0, (ITreeGenome) genome1); - } @Override public float getChance(World world, int x, int y, int z, IAlleleTreeSpecies allele0, IAlleleTreeSpecies allele1, ITreeGenome genome0, ITreeGenome genome1) { diff --git a/src/main/java/forestry/core/EnumErrorCode.java b/src/main/java/forestry/core/EnumErrorCode.java index 7ae1dcb8f..ae2c9bb07 100644 --- a/src/main/java/forestry/core/EnumErrorCode.java +++ b/src/main/java/forestry/core/EnumErrorCode.java @@ -11,15 +11,13 @@ import net.minecraft.util.IIcon; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import forestry.api.core.ErrorStateRegistry; +import forestry.api.core.ForestryAPI; import forestry.api.core.IErrorState; import forestry.core.config.Defaults; public enum EnumErrorCode implements IErrorState { UNKNOWN("unknown"), - @Deprecated // use no error code - OK("ok"), INVALIDBIOME("invalidBiome"), ISRAINING("isRaining"), NOTRAINING("notRaining"), @@ -49,15 +47,12 @@ public enum EnumErrorCode implements IErrorState { NOSTAMPS("noStamps"), NOCIRCUITBOARD("noCircuitBoard"), NOCIRCUITLAYOUT("noCircuitLayout"), - @Deprecated // wrong stack size is prevented in code WRONGSTACKSIZE("wrongStacksize"), NOFERTILIZER("noFertilizer"), NOFARMLAND("noFarmland"), CIRCUITMISMATCH("circuitMismatch"), NOLIQUID("noLiquid"), NOPAPER("noPaper"), - @Deprecated // use two error codes instead: NOSTAMPS and NOPAPER - NOSTAMPSNOPAPER("noStampsNoPaper", "noStamps"), NOSUPPLIES("noSupplies", "noResource"), NOTRADE("noTrade", "noResource"), NOPOWER("noPower"), @@ -113,7 +108,7 @@ public enum EnumErrorCode implements IErrorState { public static void init() { for (IErrorState code : values()) { - ErrorStateRegistry.registerErrorState(code); + ForestryAPI.errorStateRegistry.registerErrorState(code); } } } diff --git a/src/main/java/forestry/core/ErrorStateRegistry.java b/src/main/java/forestry/core/ErrorStateRegistry.java new file mode 100644 index 000000000..14e258ea0 --- /dev/null +++ b/src/main/java/forestry/core/ErrorStateRegistry.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import net.minecraft.client.renderer.texture.IIconRegister; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorState; +import forestry.api.core.IErrorStateRegistry; +import forestry.core.delegates.ErrorLogic; + +/** + * + * @author CovertJaguar + */ +public class ErrorStateRegistry implements IErrorStateRegistry { + + private static final BiMap states = HashBiMap.create(); + private static final Map stateNames = new HashMap(); + private static final Set stateView = Collections.unmodifiableSet(states.inverse().keySet()); + + @Override + public void registerErrorState(IErrorState state) { + if (states.containsKey(state.getID())) { + throw new RuntimeException("Forestry Error State does not possess a unique id."); + } + + states.put(state.getID(), state); + addStateName(state, state.getUniqueName()); + } + + @Override + public void addAlias(IErrorState state, String name) { + if (!states.values().contains(state)) { + throw new RuntimeException("Forestry Error State did not exist while trying to register alias."); + } + + addStateName(state, name); + } + + private static void addStateName(IErrorState state, String name) { + if (!name.contains(":")) { + throw new RuntimeException("Forestry Error State name must be in the format :."); + } + + if (stateNames.containsKey(name)) { + throw new RuntimeException("Forestry Error State does not possess a unique name."); + } + + stateNames.put(name, state); + } + + @Override + public IErrorState getErrorState(short id) { + return states.get(id); + } + + @Override + public IErrorState getErrorState(String name) { + return stateNames.get(name); + } + + @Override + public Set getErrorStates() { + return stateView; + } + + @Override + public IErrorLogic createErrorLogic() { + return new ErrorLogic(); + } + + @SideOnly(Side.CLIENT) + public static void initIcons(IIconRegister register) { + for (IErrorState code : states.values()) { + code.registerIcons(register); + } + } +} diff --git a/src/main/java/forestry/core/EventHandlerCore.java b/src/main/java/forestry/core/EventHandlerCore.java index 20dc42a3c..8bf372989 100755 --- a/src/main/java/forestry/core/EventHandlerCore.java +++ b/src/main/java/forestry/core/EventHandlerCore.java @@ -19,7 +19,6 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import forestry.api.core.ErrorStateRegistry; import forestry.core.interfaces.IPickupHandler; import forestry.core.interfaces.ISaveEventHandler; import forestry.core.render.TextureManager; @@ -65,7 +64,7 @@ public class EventHandlerCore { handler.onWorldUnload(event.world); } } - + @SubscribeEvent @SideOnly(Side.CLIENT) public void handleTextureRemap(TextureStitchEvent.Pre event) { diff --git a/src/main/java/forestry/core/ForestryCore.java b/src/main/java/forestry/core/ForestryCore.java index bf3b3ea6c..b3546bed2 100755 --- a/src/main/java/forestry/core/ForestryCore.java +++ b/src/main/java/forestry/core/ForestryCore.java @@ -35,8 +35,8 @@ import forestry.api.fuels.RainSubstrate; import forestry.core.config.Config; import forestry.core.config.Defaults; import forestry.core.config.ForestryItem; -import forestry.core.config.Version; import forestry.core.fluids.Fluids; +import forestry.core.multiblock.MultiblockEventHandler; import forestry.core.proxy.Proxies; import forestry.plugins.PluginManager; @@ -45,12 +45,14 @@ public class ForestryCore { public void preInit(File modLocation, Object basemod) { ForestryAPI.instance = basemod; ForestryAPI.forestryConstants = new ForestryConstants(); + ForestryAPI.errorStateRegistry = new ErrorStateRegistry(); // Register event handler MinecraftForge.EVENT_BUS.register(new EventHandlerCore()); + MinecraftForge.EVENT_BUS.register(new MultiblockEventHandler()); Config.load(); - + EnumErrorCode.init(); PluginManager.runSetup(); diff --git a/src/main/java/forestry/core/GuiHandler.java b/src/main/java/forestry/core/GuiHandler.java index 9f9a013a5..c74810080 100755 --- a/src/main/java/forestry/core/GuiHandler.java +++ b/src/main/java/forestry/core/GuiHandler.java @@ -38,10 +38,10 @@ public class GuiHandler extends GuiHandlerBase { switch (GuiId.values()[cleanId]) { case AnalyzerGUI: - return new GuiAnalyzer(player.inventory, getTileForestry(world, x, y, z, player, TileAnalyzer.class)); + return new GuiAnalyzer(player.inventory, getTile(world, x, y, z, player, TileAnalyzer.class)); case NaturalistBenchGUI: - return new GuiEscritoire(player, getTileForestry(world, x, y, z, player, TileEscritoire.class)); + return new GuiEscritoire(player, getTile(world, x, y, z, player, TileEscritoire.class)); case SolderingIronGUI: ItemStack equipped = player.getCurrentEquippedItem(); @@ -73,10 +73,10 @@ public class GuiHandler extends GuiHandlerBase { switch (GuiId.values()[cleanId]) { case AnalyzerGUI: - return new ContainerAnalyzer(player.inventory, getTileForestry(world, x, y, z, player, TileAnalyzer.class)); + return new ContainerAnalyzer(player.inventory, getTile(world, x, y, z, player, TileAnalyzer.class)); case NaturalistBenchGUI: - return new ContainerEscritoire(player, getTileForestry(world, x, y, z, player, TileEscritoire.class)); + return new ContainerEscritoire(player, getTile(world, x, y, z, player, TileEscritoire.class)); case SolderingIronGUI: ItemStack equipped = player.getCurrentEquippedItem(); diff --git a/src/main/java/forestry/core/GuiHandlerBase.java b/src/main/java/forestry/core/GuiHandlerBase.java index 465537173..fceec1170 100755 --- a/src/main/java/forestry/core/GuiHandlerBase.java +++ b/src/main/java/forestry/core/GuiHandlerBase.java @@ -11,37 +11,36 @@ package forestry.core; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import cpw.mods.fml.common.network.IGuiHandler; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.ISpeciesRoot; -import forestry.core.gadgets.TileForestry; import forestry.core.gadgets.TileNaturalistChest; import forestry.core.gui.ContainerNaturalistInventory; import forestry.core.gui.GuiNaturalistInventory; +import forestry.core.network.IStreamableGui; +import forestry.core.network.PacketGuiUpdate; import forestry.core.proxy.Proxies; +import forestry.core.utils.Utils; public abstract class GuiHandlerBase implements IGuiHandler { - public T getTileForestry(World world, int x, int y, int z, EntityPlayer player, Class tileClass) { - T tileForestry = null; - try { - tileForestry = tileClass.cast(world.getTileEntity(x, y, z)); - } catch (ClassCastException ex) { - Proxies.log.warning("Failed to cast a tile entity to a TileForestry at " + x + '/' + y + '/' + z); - } + public static T getTile(World world, int x, int y, int z, EntityPlayer player, Class tileClass) { + T tileForestry = Utils.getTile(world, x, y, z, tileClass); - if (tileForestry != null && !world.isRemote) { - tileForestry.sendGuiOpened(player); + if (tileForestry instanceof IStreamableGui && !world.isRemote) { + PacketGuiUpdate packet = new PacketGuiUpdate((IStreamableGui) tileForestry); + Proxies.net.sendToPlayer(packet, player); } return tileForestry; } public GuiNaturalistInventory getNaturalistChestGui(String rootUID, EntityPlayer player, World world, int x, int y, int z, int page) { - TileNaturalistChest tile = getTileForestry(world, x, y, z, player, TileNaturalistChest.class); + TileNaturalistChest tile = getTile(world, x, y, z, player, TileNaturalistChest.class); ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot(rootUID); return new GuiNaturalistInventory(speciesRoot, player, new ContainerNaturalistInventory(player.inventory, tile, page, 25), tile, page, 5); } @@ -49,7 +48,7 @@ public abstract class GuiHandlerBase implements IGuiHandler { public ContainerNaturalistInventory getNaturalistChestContainer(String rootUID, EntityPlayer player, World world, int x, int y, int z, int page) { ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot(rootUID); speciesRoot.getBreedingTracker(world, player.getGameProfile()).synchToPlayer(player); - return new ContainerNaturalistInventory(player.inventory, getTileForestry(world, x, y, z, player, TileNaturalistChest.class), page, 25); + return new ContainerNaturalistInventory(player.inventory, getTile(world, x, y, z, player, TileNaturalistChest.class), page, 25); } public static int encodeGuiData(int guiId, int data) { diff --git a/src/main/java/forestry/core/WorldGenerator.java b/src/main/java/forestry/core/WorldGenerator.java index b174acee0..9e7a1c47f 100755 --- a/src/main/java/forestry/core/WorldGenerator.java +++ b/src/main/java/forestry/core/WorldGenerator.java @@ -23,7 +23,6 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import forestry.core.config.Config; import forestry.core.config.ForestryBlock; -import forestry.core.proxy.Proxies; import forestry.core.worldgen.WorldGenMinableMeta; import forestry.plugins.PluginManager; diff --git a/src/main/java/forestry/core/circuits/CircuitBoard.java b/src/main/java/forestry/core/circuits/CircuitBoard.java index 8d62d5681..562b200f0 100755 --- a/src/main/java/forestry/core/circuits/CircuitBoard.java +++ b/src/main/java/forestry/core/circuits/CircuitBoard.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.List; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumChatFormatting; import forestry.api.circuits.ChipsetManager; @@ -24,7 +23,7 @@ import forestry.api.circuits.ICircuitLayout; import forestry.core.proxy.Proxies; import forestry.core.utils.StringUtil; -public class CircuitBoard implements ICircuitBoard { +public class CircuitBoard implements ICircuitBoard { private EnumCircuitBoardType type; private ICircuitLayout layout; @@ -83,7 +82,7 @@ public class CircuitBoard implements ICircuitBoard { ChipsetManager.circuitRegistry.getDefaultLayout(); } - ArrayList readcircuits = new ArrayList(); + List readcircuits = new ArrayList(); if (circuits != null) { return; @@ -124,42 +123,46 @@ public class CircuitBoard implements ICircuitBoard { } @Override - public void onInsertion(TileEntity tile) { + public void onInsertion(Object tile) { for (int i = 0; i < circuits.length; i++) { - if (circuits[i] == null) { + ICircuit circuit = circuits[i]; + if (circuit == null) { continue; } - circuits[i].onInsertion(i, tile); + circuit.onInsertion(i, tile); } } @Override - public void onLoad(TileEntity tile) { + public void onLoad(Object tile) { for (int i = 0; i < circuits.length; i++) { - if (circuits[i] == null) { + ICircuit circuit = circuits[i]; + if (circuit == null) { continue; } - circuits[i].onLoad(i, tile); + circuit.onLoad(i, tile); } } @Override - public void onRemoval(TileEntity tile) { + public void onRemoval(Object tile) { for (int i = 0; i < circuits.length; i++) { - if (circuits[i] == null) { + ICircuit circuit = circuits[i]; + if (circuit == null) { continue; } - circuits[i].onRemoval(i, tile); + circuit.onRemoval(i, tile); } } @Override - public void onTick(TileEntity tile) { + public void onTick(Object tile) { for (int i = 0; i < circuits.length; i++) { - if (circuits[i] == null) { + ICircuit circuit = circuits[i]; + if (circuit == null) { continue; } - circuits[i].onTick(i, tile); + circuit.onTick(i, tile); } } diff --git a/src/main/java/forestry/core/circuits/ItemSolderingIron.java b/src/main/java/forestry/core/circuits/ItemSolderingIron.java index f8dba2629..e9e990a5b 100755 --- a/src/main/java/forestry/core/circuits/ItemSolderingIron.java +++ b/src/main/java/forestry/core/circuits/ItemSolderingIron.java @@ -25,9 +25,9 @@ import forestry.api.circuits.ICircuit; import forestry.api.circuits.ICircuitLayout; import forestry.api.circuits.ISolderManager; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorSource; import forestry.api.core.IErrorState; import forestry.core.EnumErrorCode; -import forestry.core.interfaces.IErrorSource; import forestry.core.inventory.ItemInventory; import forestry.core.items.ItemForestry; import forestry.core.network.GuiId; diff --git a/src/main/java/forestry/core/config/Config.java b/src/main/java/forestry/core/config/Config.java index 7a280c030..14f6bddb9 100755 --- a/src/main/java/forestry/core/config/Config.java +++ b/src/main/java/forestry/core/config/Config.java @@ -86,6 +86,7 @@ public class Config { public static boolean craftingStampsEnabled = true; public static final ArrayList collectorStamps = new ArrayList(); + public static int farmSize = 2; public static boolean squareFarms = false; public static boolean enableExUtilEnderLily = true; public static boolean enableMagicalCropsSupport = true; @@ -263,6 +264,7 @@ public class Config { enablePermissions = configCommon.getBooleanLocalized("tweaks", "permissions", enablePermissions); + farmSize = configCommon.getIntLocalized("tweaks.farms", "size", farmSize, 1, 3); squareFarms = configCommon.getBooleanLocalized("tweaks.farms", "square", squareFarms); enableExUtilEnderLily = configCommon.getBooleanLocalized("tweaks.farms", "enderlily", enableExUtilEnderLily); enableMagicalCropsSupport = configCommon.getBooleanLocalized("tweaks.farms", "magicalcrops", enableMagicalCropsSupport); diff --git a/src/main/java/forestry/core/delegates/AccessHandler.java b/src/main/java/forestry/core/delegates/AccessHandler.java new file mode 100644 index 000000000..be077c575 --- /dev/null +++ b/src/main/java/forestry/core/delegates/AccessHandler.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.delegates; + +import java.io.IOException; +import java.util.UUID; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; + +import com.mojang.authlib.GameProfile; + +import forestry.api.core.INBTTagable; +import forestry.core.config.Config; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.IStreamable; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; +import forestry.core.utils.PlayerUtil; + +public final class AccessHandler implements IAccessHandler, IStreamable, INBTTagable { + private final IRestrictedAccessTile tile; + + private GameProfile owner = null; + private EnumAccess access = EnumAccess.SHARED; + + public AccessHandler(IRestrictedAccessTile tile) { + this.tile = tile; + } + + @Override + public final boolean allowsRemoval(EntityPlayer player) { + return !Config.enablePermissions || getAccessType() == EnumAccess.SHARED || !isOwned() || isOwner(player) || Proxies.common.isOp(player); + } + + @Override + public final boolean allowsAlteration(EntityPlayer player) { + return allowsRemoval(player); + } + + @Override + public final boolean allowsViewing(EntityPlayer player) { + return allowsAlteration(player) || getAccessType() == EnumAccess.VIEWABLE; + } + + @Override + public final boolean allowsPipeConnections() { + return access == EnumAccess.SHARED; + } + + @Override + public EnumAccess getAccessType() { + return access; + } + + @Override + public boolean isOwned() { + return owner != null; + } + + @Override + public GameProfile getOwner() { + return owner; + } + + @Override + public void setOwner(GameProfile owner) { + this.owner = owner; + } + + @Override + public boolean isOwner(EntityPlayer player) { + return PlayerUtil.isSameGameProfile(owner, player.getGameProfile()); + } + + @Override + public boolean switchAccessRule(EntityPlayer player) { + if (!isOwner(player)) { + return false; + } + + EnumAccess oldAccess = access; + int ordinal = (access.ordinal() + 1) % EnumAccess.values().length; + access = EnumAccess.values()[ordinal]; + + if (player.worldObj.isRemote) { + Proxies.net.sendToServer(new PacketCoordinates(PacketId.ACCESS_SWITCH, tile.getCoordinates())); + } else { + tile.onSwitchAccess(oldAccess, access); + } + + return true; + } + + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + if (owner == null) { + data.writeByte(-1); + } else { + data.writeByte(access.ordinal()); + data.writeLong(owner.getId().getMostSignificantBits()); + data.writeLong(owner.getId().getLeastSignificantBits()); + data.writeUTF(owner.getName()); + } + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + byte accessOrdinal = data.readByte(); + if (accessOrdinal >= 0) { + access = EnumAccess.values()[accessOrdinal]; + owner = new GameProfile(new UUID(data.readLong(), data.readLong()), data.readUTF()); + } + } + + @Override + public void readFromNBT(NBTTagCompound data) { + access = EnumAccess.values()[data.getInteger("Access")]; + + if (data.hasKey("owner")) { + owner = NBTUtil.func_152459_a(data.getCompoundTag("owner")); + } + } + + @Override + public void writeToNBT(NBTTagCompound data) { + data.setInteger("Access", access.ordinal()); + + if (this.owner != null) { + NBTTagCompound nbt = new NBTTagCompound(); + NBTUtil.func_152460_a(nbt, owner); + data.setTag("owner", nbt); + } + } +} diff --git a/src/main/java/forestry/core/delegates/ErrorLogic.java b/src/main/java/forestry/core/delegates/ErrorLogic.java new file mode 100644 index 000000000..4c8256d80 --- /dev/null +++ b/src/main/java/forestry/core/delegates/ErrorLogic.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.delegates; + +import com.google.common.collect.ImmutableSet; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorState; + +public class ErrorLogic implements IErrorLogic { + private final Set errorStates = new HashSet(); + + @Override + public final boolean setCondition(boolean condition, IErrorState errorState) { + if (condition) { + errorStates.add(errorState); + } else { + errorStates.remove(errorState); + } + return condition; + } + + public final boolean contains(IErrorState state) { + return errorStates.contains(state); + } + + public final boolean hasErrors() { + return errorStates.size() > 0; + } + + @Override + public final ImmutableSet getErrorStates() { + return ImmutableSet.copyOf(errorStates); + } + + @Override + public void clearErrors() { + errorStates.clear(); + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + data.writeShort(errorStates.size()); + for (IErrorState errorState : errorStates) { + data.writeShort(errorState.getID()); + } + } + + @Override + public void readData(DataInputStream data) throws IOException { + clearErrors(); + + short errorStateCount = data.readShort(); + for (int i = 0; i < errorStateCount; i++) { + short errorStateId = data.readShort(); + IErrorState errorState = ForestryAPI.errorStateRegistry.getErrorState(errorStateId); + errorStates.add(errorState); + } + } +} diff --git a/src/main/java/forestry/core/delegates/FakeAccessHandler.java b/src/main/java/forestry/core/delegates/FakeAccessHandler.java new file mode 100644 index 000000000..4f1609a7d --- /dev/null +++ b/src/main/java/forestry/core/delegates/FakeAccessHandler.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.delegates; + +import net.minecraft.entity.player.EntityPlayer; + +import com.mojang.authlib.GameProfile; + +import forestry.core.interfaces.IAccessHandler; +import forestry.core.utils.EnumAccess; + +public class FakeAccessHandler implements IAccessHandler { + private static FakeAccessHandler instance; + + public static FakeAccessHandler getInstance() { + if (instance == null) { + instance = new FakeAccessHandler(); + } + return instance; + } + + private FakeAccessHandler() { + + } + + @Override + public boolean switchAccessRule(EntityPlayer player) { + return false; + } + + @Override + public EnumAccess getAccessType() { + return EnumAccess.SHARED; + } + + @Override + public boolean allowsRemoval(EntityPlayer player) { + return true; + } + + @Override + public boolean allowsAlteration(EntityPlayer player) { + return true; + } + + @Override + public boolean allowsViewing(EntityPlayer player) { + return true; + } + + @Override + public boolean allowsPipeConnections() { + return true; + } + + @Override + public boolean isOwned() { + return false; + } + + @Override + public GameProfile getOwner() { + return null; + } + + @Override + public void setOwner(GameProfile owner) { + + } + + @Override + public boolean isOwner(EntityPlayer player) { + return true; + } +} diff --git a/src/main/java/forestry/core/delegates/FakeErrorLogic.java b/src/main/java/forestry/core/delegates/FakeErrorLogic.java new file mode 100644 index 000000000..afd76aff8 --- /dev/null +++ b/src/main/java/forestry/core/delegates/FakeErrorLogic.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.delegates; + +import com.google.common.collect.ImmutableSet; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorState; + +public class FakeErrorLogic implements IErrorLogic { + + public static final FakeErrorLogic instance = new FakeErrorLogic(); + + private FakeErrorLogic() { + + } + + @Override + public boolean setCondition(boolean condition, IErrorState errorState) { + return false; + } + + @Override + public boolean contains(IErrorState state) { + return false; + } + + @Override + public boolean hasErrors() { + return true; + } + + @Override + public void clearErrors() { + + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + + } + + @Override + public void readData(DataInputStream data) throws IOException { + + } + + @Override + public ImmutableSet getErrorStates() { + return ImmutableSet.of(); + } +} diff --git a/src/main/java/forestry/core/utils/DelayTimer.java b/src/main/java/forestry/core/delegates/FakeErrorSource.java old mode 100755 new mode 100644 similarity index 57% rename from src/main/java/forestry/core/utils/DelayTimer.java rename to src/main/java/forestry/core/delegates/FakeErrorSource.java index 0883a0cd8..ba8618081 --- a/src/main/java/forestry/core/utils/DelayTimer.java +++ b/src/main/java/forestry/core/delegates/FakeErrorSource.java @@ -1,31 +1,29 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.core.utils; - -import net.minecraft.world.World; - -public class DelayTimer { - private long markedTime; - - public boolean delayPassed(World world, long delay) { - long currentTime = world.getTotalWorldTime(); - - if (currentTime < markedTime) { - markedTime = currentTime; - return false; - } else if (markedTime + delay <= currentTime) { - markedTime = currentTime; - return true; - } else { - return false; - } - } -} +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.delegates; + +import com.google.common.collect.ImmutableSet; + +import forestry.api.core.IErrorSource; +import forestry.api.core.IErrorState; + +public class FakeErrorSource implements IErrorSource { + public static final FakeErrorSource instance = new FakeErrorSource(); + + private FakeErrorSource() { + + } + + @Override + public ImmutableSet getErrorStates() { + return ImmutableSet.of(); + } +} diff --git a/src/main/java/forestry/core/fluids/FakeTankManager.java b/src/main/java/forestry/core/fluids/FakeTankManager.java new file mode 100644 index 000000000..49b9e9657 --- /dev/null +++ b/src/main/java/forestry/core/fluids/FakeTankManager.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.fluids; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; + +import forestry.core.fluids.tanks.FakeTank; + +public class FakeTankManager implements ITankManager { + public static final FakeTankManager instance = new FakeTankManager(); + + private FakeTankManager() { + + } + + @Override + public void initGuiData(Container container, ICrafting player) { + + } + + @Override + public void updateGuiData(Container container, List crafters) { + + } + + @Override + public void processGuiUpdate(int messageId, int data) { + + } + + @Override + public IFluidTank getTank(int tankIndex) { + return FakeTank.INSTANCE; + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return FakeTank.INSTANCE.fill(resource, doFill); + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + return FakeTank.INSTANCE.drain(resource.amount, doDrain); + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + return FakeTank.INSTANCE.drain(maxDrain, doDrain); + } + + @Override + public boolean canFill(ForgeDirection from, Fluid fluid) { + return false; + } + + @Override + public boolean canDrain(ForgeDirection from, Fluid fluid) { + return false; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + return FakeTank.INFO; + } +} diff --git a/src/main/java/forestry/core/fluids/ITankManager.java b/src/main/java/forestry/core/fluids/ITankManager.java new file mode 100644 index 000000000..1e211619f --- /dev/null +++ b/src/main/java/forestry/core/fluids/ITankManager.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.fluids; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; + +import net.minecraftforge.fluids.IFluidHandler; +import net.minecraftforge.fluids.IFluidTank; + +public interface ITankManager extends IFluidHandler { + void initGuiData(Container container, ICrafting player); + + void updateGuiData(Container container, List crafters); + + void processGuiUpdate(int messageId, int data); + + IFluidTank getTank(int tankIndex); +} + diff --git a/src/main/java/forestry/core/fluids/TankManager.java b/src/main/java/forestry/core/fluids/TankManager.java index b1aa35a3d..7aa2457ae 100644 --- a/src/main/java/forestry/core/fluids/TankManager.java +++ b/src/main/java/forestry/core/fluids/TankManager.java @@ -33,6 +33,7 @@ import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; +import net.minecraftforge.fluids.IFluidTank; import forestry.core.fluids.tanks.FakeTank; import forestry.core.fluids.tanks.StandardTank; @@ -45,7 +46,7 @@ import forestry.core.utils.NBTUtil.NBTList; /** * @author CovertJaguar */ -public class TankManager extends ForwardingList implements IFluidHandler, List { +public class TankManager extends ForwardingList implements ITankManager, List { public static final ITileFilter TANK_FILTER = new ITileFilter() { @Override @@ -158,13 +159,14 @@ public class TankManager extends ForwardingList implements IFluidH } } + @Override public void initGuiData(Container container, ICrafting player) { for (StandardTank tank : tanks) { initGuiData(container, player, tank.getTankIndex()); } } - public void initGuiData(Container container, ICrafting player, int tankIndex) { + private void initGuiData(Container container, ICrafting player, int tankIndex) { if (tankIndex >= tanks.size()) { return; } @@ -181,13 +183,14 @@ public class TankManager extends ForwardingList implements IFluidH Proxies.net.sendToPlayer(packet, (EntityPlayerMP) player); } + @Override public void updateGuiData(Container container, List crafters) { for (StandardTank tank : tanks) { updateGuiData(container, crafters, tank.getTankIndex()); } } - public void updateGuiData(Container container, List crafters, int tankIndex) { + private void updateGuiData(Container container, List crafters, int tankIndex) { StandardTank tank = tanks.get(tankIndex); FluidStack fluidStack = tank.getFluid(); FluidStack prev = prevFluidStacks.get(tankIndex); @@ -224,6 +227,7 @@ public class TankManager extends ForwardingList implements IFluidH prevColor.set(tankIndex, color); } + @Override public void processGuiUpdate(int messageId, int data) { int tankIndex = messageId / NETWORK_DATA; @@ -255,6 +259,11 @@ public class TankManager extends ForwardingList implements IFluidH } } + @Override + public IFluidTank getTank(int tankIndex) { + return get(tankIndex); + } + @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { for (StandardTank tank : tanks) { diff --git a/src/main/java/forestry/core/gadgets/BlockBase.java b/src/main/java/forestry/core/gadgets/BlockBase.java index 664b40c25..6d2e90712 100755 --- a/src/main/java/forestry/core/gadgets/BlockBase.java +++ b/src/main/java/forestry/core/gadgets/BlockBase.java @@ -13,12 +13,14 @@ package forestry.core.gadgets; import java.util.ArrayList; import java.util.List; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -34,7 +36,8 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import forestry.core.fluids.FluidHelper; -import forestry.core.interfaces.IOwnable; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.interfaces.IRestrictedAccessTile; import forestry.core.items.ItemNBTTile; import forestry.core.proxy.Proxies; import forestry.core.utils.PlayerUtil; @@ -178,8 +181,10 @@ public class BlockBase extends BlockForestry { return false; } + IAccessHandler access = tile.getAccessHandler(); + ItemStack current = player.getCurrentEquippedItem(); - if (current != null && current.getItem() != Items.bucket && tile instanceof IFluidHandler && tile.allowsAlteration(player)) { + if (current != null && current.getItem() != Items.bucket && tile instanceof IFluidHandler && access.allowsAlteration(player)) { if (FluidHelper.handleRightClick((IFluidHandler) tile, ForgeDirection.getOrientation(side), player, true, tile.canDrainWithBucket())) { return true; } @@ -189,10 +194,10 @@ public class BlockBase extends BlockForestry { return true; } - if (tile.allowsViewing(player)) { + if (access.allowsViewing(player)) { tile.openGui(player, tile); } else { - player.addChatMessage(new ChatComponentTranslation("for.chat.accesslocked", PlayerUtil.getOwnerName(tile))); + player.addChatMessage(new ChatComponentTranslation("for.chat.accesslocked", PlayerUtil.getOwnerName(access))); } return true; } @@ -211,12 +216,14 @@ public class BlockBase extends BlockForestry { @Override public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { - IOwnable tile = (IOwnable) world.getTileEntity(x, y, z); + IRestrictedAccessTile tile = (IRestrictedAccessTile) world.getTileEntity(x, y, z); if (tile == null) { return world.setBlockToAir(x, y, z); } - if (tile.isOwned() && !tile.allowsRemoval(player)) { + IAccessHandler accessHandler = tile.getAccessHandler(); + + if (accessHandler.isOwned() && !accessHandler.allowsRemoval(player)) { return false; } @@ -227,6 +234,24 @@ public class BlockBase extends BlockForestry { } } + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + + if (!Proxies.common.isSimulating(world)) { + return; + } + + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof IInventory) { + IInventory inventory = (IInventory) tile; + Utils.dropInventory(inventory, world, x, y, z); + if (tile instanceof TileForestry) { + ((TileForestry) tile).onRemoval(); + } + } + super.breakBlock(world, x, y, z, block, meta); + } + @Override public boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int side) { int metadata = world.getBlockMetadata(x, y, z); diff --git a/src/main/java/forestry/core/gadgets/BlockForestry.java b/src/main/java/forestry/core/gadgets/BlockForestry.java index 67a6a5c47..aecff9e20 100755 --- a/src/main/java/forestry/core/gadgets/BlockForestry.java +++ b/src/main/java/forestry/core/gadgets/BlockForestry.java @@ -21,10 +21,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; +import com.mojang.authlib.GameProfile; + import forestry.core.CreativeTabForestry; import forestry.core.interfaces.IOwnable; +import forestry.core.interfaces.IRestrictedAccessTile; import forestry.core.proxy.Proxies; -import forestry.core.utils.Utils; public abstract class BlockForestry extends BlockContainer { @@ -36,28 +38,16 @@ public abstract class BlockForestry extends BlockContainer { @Override public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { - IOwnable tile = (IOwnable) world.getTileEntity(x, y, z); - if (!tile.isOwned() || tile.allowsRemoval(player)) { - return super.removedByPlayer(world, player, x, y, z); - } else { - return false; - } - } - - @Override - public void breakBlock(World world, int x, int y, int z, Block block, int meta) { - - if (!Proxies.common.isSimulating(world)) { - return; - } - TileEntity tile = world.getTileEntity(x, y, z); - if (tile instanceof TileForestry) { - TileForestry tileForestry = (TileForestry) tile; - Utils.dropInventory(tileForestry, world, x, y, z); - tileForestry.onRemoval(); + + if (tile instanceof IRestrictedAccessTile) { + IRestrictedAccessTile restrictedAccessTile = (IRestrictedAccessTile) tile; + if (!restrictedAccessTile.getAccessHandler().allowsRemoval(player)) { + return false; + } } - super.breakBlock(world, x, y, z, block, meta); + + return super.removedByPlayer(world, player, x, y, z); } @Override @@ -67,9 +57,22 @@ public abstract class BlockForestry extends BlockContainer { return; } - TileForestry tile = (TileForestry) world.getTileEntity(i, j, k); if (entityliving instanceof EntityPlayer) { - tile.setOwner(((EntityPlayer) entityliving)); + TileEntity tile = world.getTileEntity(i, j, k); + + IOwnable ownable; + + if (tile instanceof IRestrictedAccessTile) { + ownable = ((IRestrictedAccessTile) tile).getAccessHandler(); + } else if (tile instanceof IOwnable) { + ownable = (IOwnable) tile; + } else { + return; + } + + EntityPlayer player = (EntityPlayer) entityliving; + GameProfile gameProfile = player.getGameProfile(); + ownable.setOwner(gameProfile); } } diff --git a/src/main/java/forestry/core/gadgets/BlockStructure.java b/src/main/java/forestry/core/gadgets/BlockStructure.java index a6c9ee58a..def0b9671 100755 --- a/src/main/java/forestry/core/gadgets/BlockStructure.java +++ b/src/main/java/forestry/core/gadgets/BlockStructure.java @@ -14,20 +14,17 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import forestry.api.core.ITileStructure; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockTileEntityBase; import forestry.core.proxy.Proxies; -import forestry.core.utils.PlayerUtil; import forestry.core.utils.Utils; public abstract class BlockStructure extends BlockForestry { - public enum EnumStructureState { - VALID, INVALID, INDETERMINATE - } - public BlockStructure(Material material) { super(material); setHardness(1.0f); @@ -38,64 +35,72 @@ public abstract class BlockStructure extends BlockForestry { return false; } - @Override - public void breakBlock(World world, int x, int y, int z, Block block, int meta) { - TileEntity tile = world.getTileEntity(x, y, z); - - super.breakBlock(world, x, y, z, block, meta); - - if (tile instanceof ITileStructure) { - ITileStructure structure = (ITileStructure) tile; - if (structure.isIntegratedIntoStructure() && !structure.isMaster()) { - ITileStructure central = structure.getCentralTE(); - if (central != null) { - central.validateStructure(); - } - } - } - } + private long previousMessageTick = 0; @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int par6, float par7, float par8, float par9) { - if (player.isSneaking()) { return false; } - TileForestry tile = (TileForestry) world.getTileEntity(x, y, z); - if (!Utils.isUseableByPlayer(player, tile)) { + MultiblockTileEntityBase part; + MultiblockControllerBase controller; + + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof MultiblockTileEntityBase) { + part = (MultiblockTileEntityBase) tile; + controller = part.getMultiblockController(); + } else { return false; } - // GUIs can only be opened on integrated structure blocks. - if (tile instanceof ITileStructure) { - if (!((ITileStructure) tile).isIntegratedIntoStructure()) { - return false; + // If the player's hands are empty and they right-click on a multiblock, they get a + // multiblock-debugging message if the machine is not assembled. + if (player.getCurrentEquippedItem() == null) { + if (controller != null) { + Exception e = controller.getLastValidationException(); + if (e != null) { + long tick = world.getTotalWorldTime(); + if (tick > previousMessageTick + 20) { + player.addChatMessage(new ChatComponentText(e.getMessage())); + previousMessageTick = tick; + } + return true; + } + } else { + player.addChatMessage(new ChatComponentText(StatCollector.translateToLocal("for.multiblock.error.notConnected"))); + return true; } } - if (Proxies.common.isSimulating(world)) { - if (tile.allowsViewing(player)) { - tile.openGui(player); - } else { - player.addChatMessage(new ChatComponentTranslation("for.chat.accesslocked", PlayerUtil.getOwnerName(tile))); - } + // Don't open the GUI if the multiblock isn't assembled + if (controller == null || !controller.isAssembled()) { + return false; + } + + if (!world.isRemote) { + part.openGui(player); } return true; } @Override - public void onNeighborBlockChange(World world, int x, int y, int z, Block neighbor) { - super.onNeighborBlockChange(world, x, y, z, neighbor); + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + if (!Proxies.common.isSimulating(world)) { return; } TileEntity tile = world.getTileEntity(x, y, z); - if (!(tile instanceof ITileStructure)) { - return; - } + if (tile instanceof MultiblockTileEntityBase) { + MultiblockTileEntityBase part = (MultiblockTileEntityBase) tile; - ((ITileStructure) tile).validateStructure(); + // drop inventory if we're the last part remaining + if (part.getNeighboringParts().length == 0) { + Utils.dropInventory(part, world, x, y, z); + } + } + super.breakBlock(world, x, y, z, block, meta); } + } diff --git a/src/main/java/forestry/core/gadgets/Engine.java b/src/main/java/forestry/core/gadgets/Engine.java index 4e58e9e71..1174e93cc 100755 --- a/src/main/java/forestry/core/gadgets/Engine.java +++ b/src/main/java/forestry/core/gadgets/Engine.java @@ -22,6 +22,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; +import forestry.api.core.IErrorLogic; import forestry.apiculture.network.PacketActiveUpdate; import forestry.core.EnumErrorCode; import forestry.core.TemperatureState; @@ -112,10 +113,11 @@ public abstract class Engine extends TileBase implements IEnergyConnection, IAct forceCooldown = false; } - setErrorCondition(forceCooldown, EnumErrorCode.FORCEDCOOLDOWN); + IErrorLogic errorLogic = getErrorLogic(); + errorLogic.setCondition(forceCooldown, EnumErrorCode.FORCEDCOOLDOWN); boolean enabledRedstone = isRedstoneActivated(); - setErrorCondition(!enabledRedstone, EnumErrorCode.NOREDSTONE); + errorLogic.setCondition(!enabledRedstone, EnumErrorCode.NOREDSTONE); // Determine targeted tile TileEntity tile = worldObj.getTileEntity(xCoord + getOrientation().offsetX, yCoord + getOrientation().offsetY, zCoord + getOrientation().offsetZ); diff --git a/src/main/java/forestry/core/gadgets/StructureLogic.java b/src/main/java/forestry/core/gadgets/StructureLogic.java deleted file mode 100755 index 5254f28aa..000000000 --- a/src/main/java/forestry/core/gadgets/StructureLogic.java +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.core.gadgets; - -import java.util.EnumMap; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; - -import forestry.api.core.IStructureLogic; -import forestry.api.core.ITileStructure; -import forestry.core.config.Defaults; -import forestry.core.gadgets.BlockStructure.EnumStructureState; -import forestry.core.utils.Schemata; -import forestry.core.utils.Schemata.EnumStructureBlock; -import forestry.core.vect.Vect; - -public abstract class StructureLogic implements IStructureLogic { - - protected final ITileStructure structure; - protected final TileEntity structureTile; - - protected final String uid; - protected Schemata[] schematas; - protected short activeSchemata = -1; - protected boolean isRotated = false; - protected EnumMap metaOnValid = new EnumMap(EnumStructureBlock.class); - - public StructureLogic(String uid, ITileStructure structure) { - this.uid = uid; - this.structure = structure; - this.structureTile = (TileEntity) structure; - } - - @Override - public String getTypeUID() { - return uid; - } - - @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - if (nbttagcompound.hasKey("SchemataOrdinal")) { - activeSchemata = nbttagcompound.getShort("SchemataOrdinal"); - } - isRotated = nbttagcompound.getBoolean("Rotated"); - } - - @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - if (activeSchemata >= 0) { - nbttagcompound.setShort("SchemataOrdinal", activeSchemata); - } - nbttagcompound.setBoolean("Rotated", isRotated); - } - - @Override - public void validateStructure() { - - ITileStructure master = structure.getCentralTE(); - if (!structure.isMaster() && master != null) { - master.validateStructure(); - return; - } - - EnumStructureState state = EnumStructureState.INDETERMINATE; - - boolean rotate; - for (int i = 0; i < schematas.length; i++) { - if (!schematas[i].isEnabled()) { - continue; - } - - state = determineMasterState(schematas[i], false); - rotate = false; - if (state == EnumStructureState.INVALID && schematas[i].getWidth() != schematas[i].getDepth()) { - state = determineMasterState(schematas[i], true); - rotate = true; - } - - if (state == EnumStructureState.VALID) { - activeSchemata = (short) i; - isRotated = rotate; - break; - } - } - - // Structure state is indeterminate, possibly caused by chunkloading. Remain calm, do nothing. - if (state == EnumStructureState.INDETERMINATE) { - return; - } - - if (state == EnumStructureState.VALID) { - // Structure is valid and this block is master, set all other blocks - // System.out.println(String.format("Structure is valid at %s/%s/%s", ((TileEntity)structure).xCoord, ((TileEntity)structure).yCoord, - // ((TileEntity)structure).zCoord)); - if (!structure.isMaster()) { - structure.makeMaster(); - markStructureBlocks(schematas[activeSchemata]); - } - - /* - * int offsetX = schematas[activeSchemata].getxOffset(); int offsetZ = schematas[activeSchemata].getzOffset(); if(isRotated) { offsetX = - * schematas[activeSchemata].getzOffset(); offsetZ = schematas[activeSchemata].getxOffset(); - * - * } - */ - // System.out.println(String.format("Offsets: %s and %s.", offsetX, offsetZ)); - - } else if (structure.isMaster()) - // Structure is invalid, break it up. - { - resetStructureBlocks(schematas[activeSchemata]); - } - } - - protected void resetStructureBlocks(Schemata schemata) { - - Vect dimensions = schemata.getDimensions(isRotated); - int offsetX = schemata.getxOffset(); - int offsetZ = schemata.getzOffset(); - if (isRotated) { - offsetX = schemata.getzOffset(); - offsetZ = schemata.getxOffset(); - } - - for (int i = 0; i < dimensions.x; i++) { - for (int j = 0; j < schemata.getHeight(); j++) { - for (int k = 0; k < dimensions.z; k++) { - int x = structureTile.xCoord + i + offsetX; - int y = structureTile.yCoord + j + schemata.getyOffset(); - int z = structureTile.zCoord + k + offsetZ; - - TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); - if (!(tile instanceof ITileStructure)) { - continue; - } - - ITileStructure part = (ITileStructure) tile; - if (!part.getTypeUID().equals(getTypeUID())) { - continue; - } - - part.onStructureReset(); - } - } - } - } - - protected void markStructureBlocks(Schemata schemata) { - - Vect dimensions = schemata.getDimensions(isRotated); - int offsetX = schemata.getxOffset(); - int offsetZ = schemata.getzOffset(); - if (isRotated) { - offsetX = schemata.getzOffset(); - offsetZ = schemata.getxOffset(); - } - - for (int i = 0; i < dimensions.x; i++) { - for (int j = 0; j < schemata.getHeight(); j++) { - for (int k = 0; k < dimensions.z; k++) { - int x = structureTile.xCoord + i + offsetX; - int y = structureTile.yCoord + j + schemata.getyOffset(); - int z = structureTile.zCoord + k + offsetZ; - - TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); - if (!(tile instanceof ITileStructure)) { - continue; - } - - ITileStructure part = (ITileStructure) tile; - if (!part.getTypeUID().equals(getTypeUID())) { - continue; - } - - part.setCentralTE((TileEntity) structure); - EnumStructureBlock type = schemata.getAt(i, j, k, isRotated); - if (metaOnValid.containsKey(type)) { - structureTile.getWorldObj().setBlockMetadataWithNotify(x, y, z, metaOnValid.get(type), Defaults.FLAG_BLOCK_SYNCH); - structureTile.getWorldObj().markBlockForUpdate(x, y, z); - } - } - } - } - } - - protected abstract EnumStructureState determineMasterState(Schemata schemata, boolean rotate); - -} diff --git a/src/main/java/forestry/core/gadgets/TileAnalyzer.java b/src/main/java/forestry/core/gadgets/TileAnalyzer.java index e07c9844f..9a4e01214 100755 --- a/src/main/java/forestry/core/gadgets/TileAnalyzer.java +++ b/src/main/java/forestry/core/gadgets/TileAnalyzer.java @@ -153,7 +153,7 @@ public class TileAnalyzer extends TilePowered implements ISidedInventory, ILiqui Proxies.net.sendNetworkPacket(packet); } - setErrorCondition(!added, EnumErrorCode.NOSPACE); + getErrorLogic().setCondition(!added, EnumErrorCode.NOSPACE); return added; } @@ -163,7 +163,7 @@ public class TileAnalyzer extends TilePowered implements ISidedInventory, ILiqui IInvSlot slot = getInputSlot(); boolean noInput = (slot == null); - setErrorCondition(noInput, EnumErrorCode.NOTHINGANALYZE); + getErrorLogic().setCondition(noInput, EnumErrorCode.NOTHINGANALYZE); if (noInput) { return false; } @@ -176,7 +176,7 @@ public class TileAnalyzer extends TilePowered implements ISidedInventory, ILiqui IIndividual individual = AlleleManager.alleleRegistry.getIndividual(inputStack); if (!individual.isAnalyzed()) { boolean hasHoney = resourceTank.getFluidAmount() >= HONEY_REQUIRED; - setErrorCondition(!hasHoney, EnumErrorCode.NORESOURCE); + getErrorLogic().setCondition(!hasHoney, EnumErrorCode.NORESOURCE); if (!hasHoney) { return false; } @@ -206,12 +206,14 @@ public class TileAnalyzer extends TilePowered implements ISidedInventory, ILiqui super.writeData(data); ItemStack displayStack = getIndividualOnDisplay(); data.writeItemStack(displayStack); + tankManager.writePacketData(data); } @Override public void readData(DataInputStreamForestry data) throws IOException { super.readData(data); individualOnDisplayClient = data.readItemStack(); + tankManager.readPacketData(data); } @Override @@ -231,7 +233,7 @@ public class TileAnalyzer extends TilePowered implements ISidedInventory, ILiqui @Override public boolean hasWork() { - Set errors = new HashSet(getErrorStates()); + Set errors = new HashSet(getErrorLogic().getErrorStates()); errors.remove(EnumErrorCode.NOPOWER); return errors.size() == 0; } diff --git a/src/main/java/forestry/core/gadgets/TileBase.java b/src/main/java/forestry/core/gadgets/TileBase.java index 76e01aaf0..8f83c2a66 100755 --- a/src/main/java/forestry/core/gadgets/TileBase.java +++ b/src/main/java/forestry/core/gadgets/TileBase.java @@ -16,11 +16,6 @@ import forestry.core.interfaces.IHintSource; public abstract class TileBase extends TileForestry implements IHintSource { - /* UPDATING */ - @Override - public void initialize() { - } - /* INTERACTION */ public abstract void openGui(EntityPlayer player, TileBase tile); diff --git a/src/main/java/forestry/core/gadgets/TileForestry.java b/src/main/java/forestry/core/gadgets/TileForestry.java index e5a3f1950..bfa5b01b0 100755 --- a/src/main/java/forestry/core/gadgets/TileForestry.java +++ b/src/main/java/forestry/core/gadgets/TileForestry.java @@ -10,14 +10,9 @@ ******************************************************************************/ package forestry.core.gadgets; -import com.google.common.collect.ImmutableSet; - import java.io.IOException; import java.util.Collection; -import java.util.HashSet; import java.util.Random; -import java.util.Set; -import java.util.UUID; import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; @@ -25,39 +20,34 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTUtil; import net.minecraft.network.Packet; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import com.mojang.authlib.GameProfile; - import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.common.Optional; -import forestry.api.core.ErrorStateRegistry; -import forestry.api.core.IErrorState; -import forestry.core.config.Config; -import forestry.core.config.Defaults; -import forestry.core.fluids.TankManager; -import forestry.core.interfaces.IErrorSource; +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorLogicSource; +import forestry.core.delegates.AccessHandler; +import forestry.core.delegates.ErrorLogic; +import forestry.core.interfaces.IAccessHandler; import forestry.core.interfaces.IFilterSlotDelegate; -import forestry.core.interfaces.ILiquidTankContainer; -import forestry.core.interfaces.IRestrictedAccess; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.interfaces.ITitled; import forestry.core.inventory.FakeInventoryAdapter; import forestry.core.inventory.IInventoryAdapter; import forestry.core.network.DataInputStreamForestry; import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.IStreamable; -import forestry.core.network.PacketTileGuiOpened; +import forestry.core.network.IStreamableGui; import forestry.core.network.PacketTileStream; import forestry.core.proxy.Proxies; import forestry.core.utils.AdjacentTileCache; import forestry.core.utils.EnumAccess; -import forestry.core.utils.PlayerUtil; -import forestry.core.utils.Utils; import buildcraft.api.statements.IStatementContainer; import buildcraft.api.statements.ITriggerExternal; @@ -65,19 +55,20 @@ import buildcraft.api.statements.ITriggerInternal; import buildcraft.api.statements.ITriggerProvider; @Optional.Interface(iface = "buildcraft.api.statements.ITriggerProvider", modid = "BuildCraftAPI|statements") -public abstract class TileForestry extends TileEntity implements IStreamable, IRestrictedAccess, IErrorSource, ITriggerProvider, ISidedInventory, IFilterSlotDelegate { +public abstract class TileForestry extends TileEntity implements IStreamable, IErrorLogicSource, ITriggerProvider, ISidedInventory, IFilterSlotDelegate, IRestrictedAccessTile, IStreamableGui, ITitled { private static final Random rand = new Random(); + private final AccessHandler accessHandler = new AccessHandler(this); + private final ErrorLogic errorHandler = new ErrorLogic(); + private final AdjacentTileCache tileCache = new AdjacentTileCache(this); private IInventoryAdapter inventory = FakeInventoryAdapter.instance(); + private int tickCount = rand.nextInt(256); private boolean needsNetworkUpdate = false; private ForgeDirection orientation = ForgeDirection.WEST; - protected final AdjacentTileCache tileCache = new AdjacentTileCache(this); - protected boolean isInited = false; - - public AdjacentTileCache getTileCache() { + protected AdjacentTileCache getTileCache() { return tileCache; } @@ -97,9 +88,6 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR super.validate(); } - public void openGui(EntityPlayer player) { - } - public void rotateAfterPlacement(World world, int x, int y, int z, EntityLivingBase entityliving, ItemStack stack) { int l = MathHelper.floor_double(((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3; @@ -123,11 +111,6 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR public final void updateEntity() { tickCount++; - if (!isInited) { - initialize(); - isInited = true; - } - if (Proxies.common.isSimulating(worldObj)) { updateServerSide(); } else { @@ -150,49 +133,31 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR return tickCount % tickInterval == 0; } - public abstract void initialize(); - // / SAVING & LOADING @Override public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); inventory.readFromNBT(data); - - if (data.hasKey("Access")) { - access = EnumAccess.values()[data.getInteger("Access")]; - } else { - access = EnumAccess.SHARED; - } - if (data.hasKey("owner")) { - owner = NBTUtil.func_152459_a(data.getCompoundTag("owner")); - } + accessHandler.readFromNBT(data); if (data.hasKey("Orientation")) { orientation = ForgeDirection.values()[data.getInteger("Orientation")]; } else { orientation = ForgeDirection.WEST; } - } @Override public void writeToNBT(NBTTagCompound data) { super.writeToNBT(data); inventory.writeToNBT(data); - data.setInteger("Access", access.ordinal()); - if (this.owner != null) { - NBTTagCompound nbt = new NBTTagCompound(); - NBTUtil.func_152460_a(nbt, owner); - data.setTag("owner", nbt); - } - if (orientation != null) { - data.setInteger("Orientation", orientation.ordinal()); - } + accessHandler.writeToNBT(data); + data.setInteger("Orientation", orientation.ordinal()); } @Override - public final Packet getDescriptionPacket() { + public Packet getDescriptionPacket() { PacketTileStream packet = new PacketTileStream(this); return packet.getPacket(); } @@ -203,72 +168,26 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR Proxies.net.sendNetworkPacket(packet); } + @Override public void writeData(DataOutputStreamForestry data) throws IOException { data.writeByte(orientation.ordinal()); - - if (this instanceof ILiquidTankContainer) { - TankManager tankManager = ((ILiquidTankContainer) this).getTankManager(); - if (tankManager != null) { - tankManager.writePacketData(data); - } - } } + @Override public void readData(DataInputStreamForestry data) throws IOException { orientation = ForgeDirection.getOrientation(data.readByte()); - - if (this instanceof ILiquidTankContainer) { - TankManager tankManager = ((ILiquidTankContainer) this).getTankManager(); - if (tankManager != null) { - tankManager.readPacketData(data); - } - } - } - - public final void writeErrorData(DataOutputStreamForestry data) throws IOException { - data.writeShort(errorStates.size()); - for (IErrorState errorState : errorStates) { - data.writeShort(errorState.getID()); - } - } - - public final void readErrorData(DataInputStreamForestry data) throws IOException { - errorStates.clear(); - - short errorStateCount = data.readShort(); - for (int i = 0; i < errorStateCount; i++) { - short errorStateId = data.readShort(); - IErrorState errorState = ErrorStateRegistry.getErrorState(errorStateId); - errorStates.add(errorState); - } - } - - public final void sendGuiOpened(EntityPlayer player) { - PacketTileGuiOpened packet = new PacketTileGuiOpened(this); - Proxies.net.sendToPlayer(packet, player); } + @Override public void writeGuiData(DataOutputStreamForestry data) throws IOException { - writeErrorData(data); - - if (owner == null) { - data.writeByte(-1); - } else { - data.writeByte(access.ordinal()); - data.writeLong(owner.getId().getMostSignificantBits()); - data.writeLong(owner.getId().getLeastSignificantBits()); - data.writeUTF(owner.getName()); - } + accessHandler.writeData(data); + errorHandler.writeData(data); } + @Override public void readGuiData(DataInputStreamForestry data) throws IOException { - readErrorData(data); - - byte accessOrdinal = data.readByte(); - if (accessOrdinal >= 0) { - access = EnumAccess.values()[accessOrdinal]; - owner = new GameProfile(new UUID(data.readLong(), data.readLong()), data.readUTF()); - } + accessHandler.readData(data); + errorHandler.readData(data); } public void onRemoval() { @@ -298,6 +217,9 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR } public void setOrientation(ForgeDirection orientation) { + if (orientation == null) { + throw new NullPointerException("Orientation cannot be null"); + } if (this.orientation == orientation) { return; } @@ -309,114 +231,23 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR needsNetworkUpdate = true; } - // / ERROR HANDLING - private final Set errorStates = new HashSet(); + @Override + public final IErrorLogic getErrorLogic() { + return errorHandler; + } - public final boolean setErrorCondition(boolean condition, IErrorState errorState) { - if (condition) { - errorStates.add(errorState); - } else { - errorStates.remove(errorState); + @Override + public final IAccessHandler getAccessHandler() { + return accessHandler; + } + + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + if (oldAccess == EnumAccess.SHARED || newAccess == EnumAccess.SHARED) { + // pipes connected to this need to update + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, blockType); + markDirty(); } - return condition; - } - - @Deprecated - protected final void addErrorState(IErrorState state) { - errorStates.add(state); - } - - @Deprecated - protected final void removeErrorStates() { - errorStates.clear(); - } - - public final boolean hasErrorState(IErrorState state) { - return errorStates.contains(state); - } - - public final boolean hasErrorState() { - return errorStates.size() > 0; - } - - @Override - public ImmutableSet getErrorStates() { - return ImmutableSet.copyOf(errorStates); - } - - // / OWNERSHIP - private GameProfile owner = null; - private EnumAccess access = EnumAccess.SHARED; - - @Override - public final boolean allowsRemoval(EntityPlayer player) { - return !Config.enablePermissions || getAccess() == EnumAccess.SHARED || !isOwned() || isOwner(player) || Proxies.common.isOp(player); - } - - @Override - public final boolean allowsAlteration(EntityPlayer player) { - return allowsRemoval(player); - } - - @Override - public final boolean allowsViewing(EntityPlayer player) { - return allowsAlteration(player) || getAccess() == EnumAccess.VIEWABLE; - } - - private boolean allowsPipeConnections() { - return access == EnumAccess.SHARED; - } - - @Override - public EnumAccess getAccess() { - return access; - } - - @Override - public boolean isOwned() { - return owner != null; - } - - @Override - public GameProfile getOwner() { - return owner; - } - - @Override - public void setOwner(EntityPlayer player) { - this.owner = player.getGameProfile(); - } - - @Override - public boolean isOwner(EntityPlayer player) { - if (owner != null && player != null) { - return PlayerUtil.isSameGameProfile(owner, player.getGameProfile()); - } - return false; - } - - @Override - public boolean switchAccessRule(EntityPlayer player) { - if (!isOwner(player)) { - return false; - } - - boolean couldPipesConnect = allowsPipeConnections(); - - int ordinal = (access.ordinal() + 1) % EnumAccess.values().length; - access = EnumAccess.values()[ordinal]; - if (!this.worldObj.isRemote) { - sendGuiOpened(player); - - boolean canPipesConnect = allowsPipeConnections(); - if (couldPipesConnect != canPipesConnect) { - // pipes connected to this need to update - worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, blockType); - markDirty(); - } - } - - return true; } /* NAME */ @@ -424,7 +255,8 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR /** * Gets the tile's unlocalized name, based on the block at the location of this entity (client-only). */ - public String getUnlocalizedName() { + @Override + public String getUnlocalizedTitle() { String blockUnlocalizedName = getBlockType().getUnlocalizedName().replace("tile.for.", ""); return blockUnlocalizedName + '.' + getBlockMetadata() + ".name"; } @@ -484,14 +316,11 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR @Override public final String getInventoryName() { - return getUnlocalizedName(); + return getUnlocalizedTitle(); } @Override public final boolean isUseableByPlayer(EntityPlayer player) { - if (!Utils.isUseableByPlayer(player, this) || !allowsViewing(player)) { - return false; - } return getInternalInventory().isUseableByPlayer(player); } @@ -502,14 +331,6 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR @Override public final boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) { - if (itemStack == null || !allowsPipeConnections()) { - return false; - } - - if (!canSlotAccept(slotIndex, itemStack)) { - return false; - } - return getInternalInventory().isItemValidForSlot(slotIndex, itemStack); } @@ -525,25 +346,21 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IR @Override public final int[] getAccessibleSlotsFromSide(int side) { - if (!allowsPipeConnections()) { - return Defaults.SLOTS_NONE; - } return getInternalInventory().getAccessibleSlotsFromSide(side); } @Override public final boolean canInsertItem(int slotIndex, ItemStack itemStack, int side) { - if (itemStack == null || !allowsPipeConnections()) { - return false; - } - return isItemValidForSlot(slotIndex, itemStack); + return getInternalInventory().canInsertItem(slotIndex, itemStack, side); } @Override public final boolean canExtractItem(int slotIndex, ItemStack itemStack, int side) { - if (itemStack == null || !allowsPipeConnections()) { - return false; - } return getInternalInventory().canExtractItem(slotIndex, itemStack, side); } + + @Override + public final ChunkCoordinates getCoordinates() { + return new ChunkCoordinates(xCoord, yCoord, zCoord); + } } diff --git a/src/main/java/forestry/core/gadgets/TileNaturalistChest.java b/src/main/java/forestry/core/gadgets/TileNaturalistChest.java index 59b2e927d..6c2bae320 100755 --- a/src/main/java/forestry/core/gadgets/TileNaturalistChest.java +++ b/src/main/java/forestry/core/gadgets/TileNaturalistChest.java @@ -53,6 +53,8 @@ public abstract class TileNaturalistChest extends TileBase implements IPagedInve } @Override - public boolean canExtractItem(int slotIndex, ItemStack stack, int side) { return true; } + public boolean canExtractItem(int slotIndex, ItemStack stack, int side) { + return true; + } } } diff --git a/src/main/java/forestry/core/gadgets/TilePowered.java b/src/main/java/forestry/core/gadgets/TilePowered.java index 534bfe704..e6c04050d 100644 --- a/src/main/java/forestry/core/gadgets/TilePowered.java +++ b/src/main/java/forestry/core/gadgets/TilePowered.java @@ -18,6 +18,7 @@ import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.common.Optional; +import forestry.api.core.IErrorLogic; import forestry.core.EnumErrorCode; import forestry.core.interfaces.IPowerHandler; import forestry.core.interfaces.IRenderableMachine; @@ -59,15 +60,17 @@ public abstract class TilePowered extends TileBase implements IRenderableMachine protected void updateServerSide() { super.updateServerSide(); + IErrorLogic errorLogic = getErrorLogic(); + boolean disabled = isRedstoneActivated(); - setErrorCondition(disabled, EnumErrorCode.DISABLED); + errorLogic.setCondition(disabled, EnumErrorCode.DISABLED); if (disabled) { return; } if (updateOnInterval(20)) { boolean hasEnergy = energyManager.hasEnergyToDoWork(); - setErrorCondition(!hasEnergy, EnumErrorCode.NOPOWER); + errorLogic.setCondition(!hasEnergy, EnumErrorCode.NOPOWER); } if (workCounter < WORK_CYCLES) { diff --git a/src/main/java/forestry/core/genetics/Genome.java b/src/main/java/forestry/core/genetics/Genome.java index 11c81fc51..bbfb19c3b 100755 --- a/src/main/java/forestry/core/genetics/Genome.java +++ b/src/main/java/forestry/core/genetics/Genome.java @@ -51,6 +51,7 @@ public abstract class Genome implements IGenome { } // NBT RETRIEVAL + /** * Quickly gets the species without loading the whole genome. * We need this because the client uses the species for rendering. diff --git a/src/main/java/forestry/core/genetics/IGeneticDefinition.java b/src/main/java/forestry/core/genetics/IGeneticDefinition.java index 4e58b374f..73b9ff29f 100644 --- a/src/main/java/forestry/core/genetics/IGeneticDefinition.java +++ b/src/main/java/forestry/core/genetics/IGeneticDefinition.java @@ -1,7 +1,6 @@ package forestry.core.genetics; import forestry.api.genetics.IAllele; -import forestry.api.genetics.IAlleleSpecies; import forestry.api.genetics.IGenome; import forestry.api.genetics.IIndividual; diff --git a/src/main/java/forestry/core/genetics/IndividualLiving.java b/src/main/java/forestry/core/genetics/IndividualLiving.java index 96524db90..5f8e75ac2 100755 --- a/src/main/java/forestry/core/genetics/IndividualLiving.java +++ b/src/main/java/forestry/core/genetics/IndividualLiving.java @@ -95,7 +95,6 @@ public abstract class IndividualLiving extends Individual implements IIndividual if (world.rand.nextFloat() < ageModifier) { decreaseHealth(); } - } public void decreaseHealth() { @@ -104,5 +103,4 @@ public abstract class IndividualLiving extends Individual implements IIndividual } } - } diff --git a/src/main/java/forestry/core/gui/ContainerLiquidTanks.java b/src/main/java/forestry/core/gui/ContainerLiquidTanks.java index d09bf55fb..78c1ddef2 100755 --- a/src/main/java/forestry/core/gui/ContainerLiquidTanks.java +++ b/src/main/java/forestry/core/gui/ContainerLiquidTanks.java @@ -16,21 +16,22 @@ import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ICrafting; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import forestry.api.core.IToolPipette; -import forestry.core.fluids.tanks.StandardTank; -import forestry.core.gadgets.TileForestry; import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.IStreamableGui; import forestry.core.network.PacketId; import forestry.core.network.PacketSlotClick; import forestry.core.proxy.Proxies; -public class ContainerLiquidTanks extends ContainerTile { +public class ContainerLiquidTanks extends ContainerTile { public ContainerLiquidTanks(T tile, InventoryPlayer playerInventory, int xInv, int yInv) { super(tile, playerInventory, xInv, yInv); @@ -59,7 +60,7 @@ public class ContainerLiquidTanks } IToolPipette pipette = (IToolPipette) held; - StandardTank tank = tile.getTankManager().get(slot); + IFluidTank tank = tile.getTankManager().getTank(slot); int liquidAmount = tank.getFluidAmount(); if (pipette.canPipette(itemstack) && liquidAmount > 0) { @@ -102,7 +103,7 @@ public class ContainerLiquidTanks tile.getTankManager().initGuiData(this, icrafting); } - public StandardTank getTank(int slot) { - return tile.getTankManager().get(slot); + public IFluidTank getTank(int slot) { + return tile.getTankManager().getTank(slot); } } diff --git a/src/main/java/forestry/core/gui/ContainerSocketed.java b/src/main/java/forestry/core/gui/ContainerSocketed.java index a2606dd3b..e59ff7985 100755 --- a/src/main/java/forestry/core/gui/ContainerSocketed.java +++ b/src/main/java/forestry/core/gui/ContainerSocketed.java @@ -13,16 +13,17 @@ package forestry.core.gui; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; -import forestry.core.gadgets.TileForestry; import forestry.core.interfaces.ISocketable; +import forestry.core.network.IStreamableGui; import forestry.core.network.PacketId; import forestry.core.network.PacketSlotClick; import forestry.core.network.PacketSocketUpdate; import forestry.core.proxy.Proxies; import forestry.core.utils.StackUtils; -public class ContainerSocketed extends ContainerTile { +public class ContainerSocketed extends ContainerTile { public ContainerSocketed(T tile, InventoryPlayer playerInventory, int xInv, int yInv) { super(tile, playerInventory, xInv, yInv); diff --git a/src/main/java/forestry/core/gui/ContainerTile.java b/src/main/java/forestry/core/gui/ContainerTile.java index abaa92ca9..7192d4c84 100644 --- a/src/main/java/forestry/core/gui/ContainerTile.java +++ b/src/main/java/forestry/core/gui/ContainerTile.java @@ -14,54 +14,73 @@ import com.google.common.collect.ImmutableSet; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.tileentity.TileEntity; +import forestry.api.core.IErrorLogicSource; import forestry.api.core.IErrorState; -import forestry.core.gadgets.TileForestry; +import forestry.core.delegates.FakeAccessHandler; +import forestry.core.interfaces.IAccessHandler; import forestry.core.interfaces.IPowerHandler; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.network.IStreamableGui; import forestry.core.network.PacketErrorUpdate; import forestry.core.network.PacketGuiEnergy; +import forestry.core.network.PacketGuiUpdate; +import forestry.core.utils.EnumAccess; +import forestry.core.utils.Utils; import forestry.energy.EnergyManager; -public class ContainerTile extends ContainerForestry { +public class ContainerTile extends ContainerForestry { protected final T tile; + protected final IAccessHandler accessHandler; - public ContainerTile(T tileForestry) { - this.tile = tileForestry; + public ContainerTile(T tile) { + this.tile = tile; + + if (tile instanceof IRestrictedAccessTile) { + accessHandler = ((IRestrictedAccessTile) tile).getAccessHandler(); + } else { + accessHandler = FakeAccessHandler.getInstance(); + } } public ContainerTile(T tileForestry, InventoryPlayer playerInventory, int xInv, int yInv) { - this.tile = tileForestry; + this(tileForestry); addPlayerInventory(playerInventory, xInv, yInv); } @Override protected final boolean canAccess(EntityPlayer player) { - return player != null && tile.allowsAlteration(player); + return player != null && accessHandler.allowsAlteration(player); } @Override public final boolean canInteractWith(EntityPlayer entityplayer) { - return tile.isUseableByPlayer(entityplayer); + return Utils.isUseableByPlayer(entityplayer, tile) && accessHandler.allowsViewing(entityplayer); } private ImmutableSet previousErrorStates; private int previousEnergyManagerData = 0; + private EnumAccess previousAccess; @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - ImmutableSet errorStates = tile.getErrorStates(); + if (tile instanceof IErrorLogicSource) { + IErrorLogicSource errorLogicSource = (IErrorLogicSource) tile; + ImmutableSet errorStates = errorLogicSource.getErrorLogic().getErrorStates(); - if ((previousErrorStates != null) && !errorStates.equals(previousErrorStates)) { - PacketErrorUpdate packet = new PacketErrorUpdate(tile); - sendPacketToCrafters(packet); + if ((previousErrorStates != null) && !errorStates.equals(previousErrorStates)) { + PacketErrorUpdate packet = new PacketErrorUpdate(tile, errorLogicSource); + sendPacketToCrafters(packet); + } + + previousErrorStates = errorStates; } - previousErrorStates = errorStates; - if (tile instanceof IPowerHandler) { EnergyManager energyManager = ((IPowerHandler) tile).getEnergyManager(); int energyManagerData = energyManager.toGuiInt(); @@ -72,6 +91,18 @@ public class ContainerTile extends ContainerForestry { previousEnergyManagerData = energyManagerData; } } + + if (tile instanceof IRestrictedAccessTile) { + IRestrictedAccessTile restrictedAccessTile = (IRestrictedAccessTile) tile; + IAccessHandler accessHandler = restrictedAccessTile.getAccessHandler(); + EnumAccess access = accessHandler.getAccessType(); + if (access != previousAccess) { + PacketGuiUpdate packet = new PacketGuiUpdate(tile); + sendPacketToCrafters(packet); + + previousAccess = access; + } + } } public void onGuiEnergy(int energyStored) { diff --git a/src/main/java/forestry/core/gui/ErrorLedger.java b/src/main/java/forestry/core/gui/ErrorLedger.java index 9aac5bd06..7fe92a5d4 100755 --- a/src/main/java/forestry/core/gui/ErrorLedger.java +++ b/src/main/java/forestry/core/gui/ErrorLedger.java @@ -12,9 +12,11 @@ package forestry.core.gui; import javax.annotation.Nullable; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import forestry.api.core.IErrorState; +import forestry.core.proxy.Proxies; import forestry.core.utils.StringUtil; /** @@ -34,7 +36,8 @@ public class ErrorLedger extends Ledger { this.state = state; if (state != null) { String helpString = StringUtil.localize(state.getHelp()); - FontRenderer fontRenderer = manager.minecraft.fontRenderer; + Minecraft minecraft = Proxies.common.getClientInstance(); + FontRenderer fontRenderer = minecraft.fontRenderer; int lineCount = fontRenderer.listFormattedStringToWidth(helpString, maxWidth - 28).size(); maxHeight = (lineCount + 1) * fontRenderer.FONT_HEIGHT + 20; } diff --git a/src/main/java/forestry/core/gui/GuiForestry.java b/src/main/java/forestry/core/gui/GuiForestry.java index 953768c89..57e71ce8f 100755 --- a/src/main/java/forestry/core/gui/GuiForestry.java +++ b/src/main/java/forestry/core/gui/GuiForestry.java @@ -33,15 +33,16 @@ import cpw.mods.fml.common.Optional; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; +import forestry.api.core.IErrorLogicSource; +import forestry.api.core.IErrorSource; import forestry.core.config.Config; +import forestry.core.gadgets.TileForestry; import forestry.core.gui.tooltips.IToolTipProvider; import forestry.core.gui.tooltips.ToolTip; import forestry.core.gui.tooltips.ToolTipLine; import forestry.core.gui.widgets.Widget; import forestry.core.interfaces.IClimatised; -import forestry.core.interfaces.IErrorSource; import forestry.core.interfaces.IHintSource; -import forestry.core.interfaces.IOwnable; import forestry.core.interfaces.IPowerHandler; import forestry.core.proxy.Proxies; import forestry.core.utils.FontColour; @@ -85,7 +86,12 @@ public abstract class GuiForestry ext ledgerManager.add((IErrorSource) inventory); } - if (inventory instanceof IClimatised && ((IClimatised) inventory).isClimatized()) { + if (inventory instanceof IErrorLogicSource) { + IErrorLogicSource errorLogicSource = (IErrorLogicSource) inventory; + ledgerManager.add(errorLogicSource.getErrorLogic()); + } + + if (inventory instanceof IClimatised) { ledgerManager.add(new ClimateLedger(ledgerManager, (IClimatised) inventory)); } @@ -97,8 +103,8 @@ public abstract class GuiForestry ext ledgerManager.add(new HintLedger(ledgerManager, (IHintSource) inventory)); } - if (inventory instanceof IOwnable) { - ledgerManager.add(new OwnerLedger(ledgerManager, (IOwnable) inventory)); + if (inventory instanceof TileForestry) { + ledgerManager.add(new OwnerLedger(ledgerManager, (TileForestry) inventory)); } } diff --git a/src/main/java/forestry/core/gui/GuiForestryTitled.java b/src/main/java/forestry/core/gui/GuiForestryTitled.java index 65fbb709f..eabd4d4a1 100644 --- a/src/main/java/forestry/core/gui/GuiForestryTitled.java +++ b/src/main/java/forestry/core/gui/GuiForestryTitled.java @@ -11,24 +11,20 @@ package forestry.core.gui; import net.minecraft.inventory.Container; -import net.minecraft.util.ResourceLocation; +import net.minecraft.inventory.IInventory; -import forestry.core.gadgets.TileForestry; +import forestry.core.interfaces.ITitled; import forestry.core.utils.StringUtil; -public abstract class GuiForestryTitled extends GuiForestry { +public abstract class GuiForestryTitled extends GuiForestry { public GuiForestryTitled(String texture, C container, I inventory) { super(texture, container, inventory); } - public GuiForestryTitled(ResourceLocation texture, C container, I inventory) { - super(texture, container, inventory); - } - @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { - String name = StringUtil.localizeTile(inventory.getUnlocalizedName()); + String name = StringUtil.localizeTile(inventory.getUnlocalizedTitle()); this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); super.drawGuiContainerForegroundLayer(mouseX, mouseY); } diff --git a/src/main/java/forestry/core/gui/HintLedger.java b/src/main/java/forestry/core/gui/HintLedger.java index 7c2bc1fd8..8960ce64d 100755 --- a/src/main/java/forestry/core/gui/HintLedger.java +++ b/src/main/java/forestry/core/gui/HintLedger.java @@ -12,9 +12,11 @@ package forestry.core.gui; import java.util.Random; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import forestry.core.interfaces.IHintSource; +import forestry.core.proxy.Proxies; import forestry.core.render.TextureManager; import forestry.core.utils.StringUtil; @@ -31,7 +33,8 @@ public class HintLedger extends Ledger { hintString = StringUtil.localize("hints." + hints[position] + ".desc"); hintTooltip = StringUtil.localize("hints." + hints[position] + ".tag"); - FontRenderer fontRenderer = manager.minecraft.fontRenderer; + Minecraft minecraft = Proxies.common.getClientInstance(); + FontRenderer fontRenderer = minecraft.fontRenderer; int lineCount = fontRenderer.listFormattedStringToWidth(hintString, maxWidth - 28).size(); maxHeight = (lineCount + 1) * fontRenderer.FONT_HEIGHT + 20; } diff --git a/src/main/java/forestry/core/gui/Ledger.java b/src/main/java/forestry/core/gui/Ledger.java index 09a61dd05..2c0dd94fc 100755 --- a/src/main/java/forestry/core/gui/Ledger.java +++ b/src/main/java/forestry/core/gui/Ledger.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.core.gui; +import net.minecraft.client.Minecraft; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; @@ -197,18 +198,22 @@ public abstract class Ledger { } protected void drawHeader(String string, int x, int y) { - manager.minecraft.fontRenderer.drawStringWithShadow(string, x, y, fontColorHeader); + Minecraft minecraft = Proxies.common.getClientInstance(); + minecraft.fontRenderer.drawStringWithShadow(string, x, y, fontColorHeader); } protected void drawSubheader(String string, int x, int y) { - manager.minecraft.fontRenderer.drawStringWithShadow(string, x, y, fontColorSubheader); + Minecraft minecraft = Proxies.common.getClientInstance(); + minecraft.fontRenderer.drawStringWithShadow(string, x, y, fontColorSubheader); } protected void drawText(String string, int x, int y) { - manager.minecraft.fontRenderer.drawString(string, x, y, fontColorText); + Minecraft minecraft = Proxies.common.getClientInstance(); + minecraft.fontRenderer.drawString(string, x, y, fontColorText); } protected void drawSplitText(String string, int x, int y, int width) { - manager.minecraft.fontRenderer.drawSplitString(string, x, y, width, fontColorText); + Minecraft minecraft = Proxies.common.getClientInstance(); + minecraft.fontRenderer.drawSplitString(string, x, y, width, fontColorText); } } diff --git a/src/main/java/forestry/core/gui/LedgerManager.java b/src/main/java/forestry/core/gui/LedgerManager.java index 09e000be6..0c058845d 100755 --- a/src/main/java/forestry/core/gui/LedgerManager.java +++ b/src/main/java/forestry/core/gui/LedgerManager.java @@ -10,7 +10,8 @@ ******************************************************************************/ package forestry.core.gui; -import javax.annotation.Nullable; +import com.google.common.collect.ImmutableSet; + import java.util.ArrayList; import java.util.List; @@ -18,16 +19,15 @@ import net.minecraft.client.Minecraft; import org.lwjgl.opengl.GL11; +import forestry.api.core.IErrorSource; import forestry.api.core.IErrorState; import forestry.core.config.SessionVars; -import forestry.core.interfaces.IErrorSource; +import forestry.core.delegates.FakeErrorSource; import forestry.core.proxy.Proxies; public class LedgerManager { public final GuiForestry gui; - public final Minecraft minecraft; - @Nullable public IErrorSource errorSource; protected final List ledgers = new ArrayList(); @@ -35,10 +35,14 @@ public class LedgerManager { public LedgerManager(GuiForestry gui) { this.gui = gui; - this.minecraft = Proxies.common.getClientInstance(); + this.errorSource = FakeErrorSource.instance; } public void add(IErrorSource errorSource) { + if (errorSource == null) { + return; + } + this.errorSource = errorSource; int maxErrorLedgerCount = (gui.getSizeY() - 10) / Ledger.minHeight; for (int i = 0; i < maxErrorLedgerCount; i++) { @@ -81,23 +85,21 @@ public class LedgerManager { } } - if (errorSource != null) { - final int xShiftError = ((gui.width - gui.getSizeX()) / 2); - int yShiftError = ((gui.height - gui.getSizeY()) / 2) + 8; + final int xShiftError = ((gui.width - gui.getSizeX()) / 2); + int yShiftError = ((gui.height - gui.getSizeY()) / 2) + 8; - for (ErrorLedger errorLedger : errorLedgers) { - if (!errorLedger.isVisible()) { - continue; - } - - errorLedger.currentShiftX = xShiftError - errorLedger.getWidth(); - errorLedger.currentShiftY = yShiftError; - if (errorLedger.intersectsWith(mX, mY)) { - return errorLedger; - } - - yShiftError += errorLedger.getHeight(); + for (ErrorLedger errorLedger : errorLedgers) { + if (!errorLedger.isVisible()) { + continue; } + + errorLedger.currentShiftX = xShiftError - errorLedger.getWidth(); + errorLedger.currentShiftY = yShiftError; + if (errorLedger.intersectsWith(mX, mY)) { + return errorLedger; + } + + yShiftError += errorLedger.getHeight(); } return null; @@ -118,26 +120,25 @@ public class LedgerManager { yPos += ledger.getHeight(); } - if (errorSource != null) { - yPos = 8; + ImmutableSet errorStates = errorSource.getErrorStates(); - int index = 0; - for (IErrorState errorState : errorSource.getErrorStates()) { - if (index >= errorLedgers.size()) { - break; - } - ErrorLedger errorLedger = errorLedgers.get(index++); - errorLedger.setState(errorState); - - errorLedger.update(); - if (!errorLedger.isVisible()) { - continue; - } - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - errorLedger.draw(-errorLedger.getWidth(), yPos); - yPos += errorLedger.getHeight(); + yPos = 8; + int index = 0; + for (IErrorState errorState : errorStates) { + if (index >= errorLedgers.size()) { + break; } + ErrorLedger errorLedger = errorLedgers.get(index++); + errorLedger.setState(errorState); + + errorLedger.update(); + if (!errorLedger.isVisible()) { + continue; + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + errorLedger.draw(-errorLedger.getWidth(), yPos); + yPos += errorLedger.getHeight(); } } @@ -149,6 +150,7 @@ public class LedgerManager { int startY = mouseY - ((gui.height - gui.getSizeY()) / 2) - 12; String tooltip = ledger.getTooltip(); + Minecraft minecraft = Proxies.common.getClientInstance(); int textWidth = minecraft.fontRenderer.getStringWidth(tooltip); gui.drawGradientRect(startX - 3, startY - 3, startX + textWidth + 3, startY + 8 + 3, 0xc0000000, 0xc0000000); minecraft.fontRenderer.drawStringWithShadow(tooltip, startX, startY, -1); diff --git a/src/main/java/forestry/core/gui/OwnerLedger.java b/src/main/java/forestry/core/gui/OwnerLedger.java index 46400a969..2cb82dc58 100755 --- a/src/main/java/forestry/core/gui/OwnerLedger.java +++ b/src/main/java/forestry/core/gui/OwnerLedger.java @@ -12,13 +12,12 @@ package forestry.core.gui; import java.util.Locale; -import net.minecraft.tileentity.TileEntity; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.IIcon; -import forestry.core.interfaces.IOwnable; -import forestry.core.interfaces.IRestrictedAccess; -import forestry.core.network.PacketCoordinates; -import forestry.core.network.PacketId; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.interfaces.IRestrictedAccessTile; import forestry.core.proxy.Proxies; import forestry.core.render.TextureManager; import forestry.core.utils.EnumAccess; @@ -30,13 +29,15 @@ import forestry.core.utils.StringUtil; */ public class OwnerLedger extends Ledger { - private final IOwnable tile; + private final IAccessHandler accessHandler; - public OwnerLedger(LedgerManager manager, IOwnable tile) { + public OwnerLedger(LedgerManager manager, IRestrictedAccessTile tile) { super(manager, "owner"); - this.tile = tile; - boolean playerIsOwner = tile.isOwner(manager.minecraft.thePlayer); + this.accessHandler = tile.getAccessHandler(); + + Minecraft minecraft = Proxies.common.getClientInstance(); + boolean playerIsOwner = accessHandler.isOwner(minecraft.thePlayer); if (playerIsOwner) { maxHeight = 60; @@ -55,7 +56,7 @@ public class OwnerLedger extends Ledger { @Override public boolean isVisible() { - return tile.isOwned(); + return accessHandler.isOwned(); } @Override @@ -64,13 +65,8 @@ public class OwnerLedger extends Ledger { drawBackground(x, y); // Draw icon - EnumAccess access; - if (tile instanceof IRestrictedAccess) { - access = ((IRestrictedAccess) tile).getAccess(); - } else { - access = EnumAccess.SHARED; - } - IIcon accessIcon = TextureManager.getInstance().getDefault("misc/access." + access.toString().toLowerCase(Locale.ENGLISH)); + EnumAccess accessType = accessHandler.getAccessType(); + IIcon accessIcon = TextureManager.getInstance().getDefault("misc/access." + accessType.toString().toLowerCase(Locale.ENGLISH)); drawIcon(accessIcon, x + 3, y + 4); // Draw description @@ -80,33 +76,31 @@ public class OwnerLedger extends Ledger { drawHeader(StringUtil.localize("gui.owner"), x + 22, y + 8); - drawText(PlayerUtil.getOwnerName(tile), x + 22, y + 20); + drawText(PlayerUtil.getOwnerName(accessHandler), x + 22, y + 20); - boolean playerIsOwner = tile.isOwner(manager.minecraft.thePlayer); - if (playerIsOwner && tile instanceof IRestrictedAccess) { + Minecraft minecraft = Proxies.common.getClientInstance(); + boolean playerIsOwner = accessHandler.isOwner(minecraft.thePlayer); + if (playerIsOwner) { drawSubheader(StringUtil.localize("gui.access") + ':', x + 22, y + 32); // Access rules drawIcon(accessIcon, x + 20, y + 40); - drawText(StringUtil.localize(access.getName()), x + 38, y + 44); + drawText(StringUtil.localize(accessType.getName()), x + 38, y + 44); } } @Override public String getTooltip() { - return StringUtil.localize("gui.owner") + ": " + PlayerUtil.getOwnerName(tile); + return StringUtil.localize("gui.owner") + ": " + PlayerUtil.getOwnerName(accessHandler); } @Override public boolean handleMouseClicked(int x, int y, int mouseButton) { - if (isAccessButton(x, y) && tile instanceof IRestrictedAccess) { - if (!Proxies.common.isSimulating(((TileEntity) tile).getWorldObj())) { - TileEntity te = (TileEntity) tile; - Proxies.net.sendToServer(new PacketCoordinates(PacketId.ACCESS_SWITCH, te)); - } + if (isAccessButton(x, y)) { + Minecraft minecraft = Proxies.common.getClientInstance(); + EntityPlayer player = minecraft.thePlayer; - ((IRestrictedAccess) tile).switchAccessRule(manager.minecraft.thePlayer); - return true; + return accessHandler.switchAccessRule(player); } return false; diff --git a/src/main/java/forestry/core/gui/widgets/TankWidget.java b/src/main/java/forestry/core/gui/widgets/TankWidget.java index 7165a8a9c..e9af7d7ed 100755 --- a/src/main/java/forestry/core/gui/widgets/TankWidget.java +++ b/src/main/java/forestry/core/gui/widgets/TankWidget.java @@ -16,6 +16,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; import org.lwjgl.opengl.GL11; @@ -49,7 +50,7 @@ public class TankWidget extends Widget { return this; } - public StandardTank getTank() { + public IFluidTank getTank() { Container container = manager.gui.inventorySlots; if (container instanceof ContainerLiquidTanks) { return ((ContainerLiquidTanks) container).getTank(slot); @@ -61,7 +62,7 @@ public class TankWidget extends Widget { @Override public void draw(int startX, int startY) { - StandardTank tank = getTank(); + IFluidTank tank = getTank(); if (tank == null) { return; } @@ -108,11 +109,11 @@ public class TankWidget extends Widget { @Override public ToolTip getToolTip() { - StandardTank tank = getTank(); - if (tank == null) { + IFluidTank tank = getTank(); + if (!(tank instanceof StandardTank)) { return null; } - return tank.getToolTip(); + return ((StandardTank) tank).getToolTip(); } @Override diff --git a/src/main/java/forestry/core/interfaces/IRestrictedAccess.java b/src/main/java/forestry/core/interfaces/IAccessHandler.java similarity index 81% rename from src/main/java/forestry/core/interfaces/IRestrictedAccess.java rename to src/main/java/forestry/core/interfaces/IAccessHandler.java index 3a941b7ee..0e2c8e17b 100644 --- a/src/main/java/forestry/core/interfaces/IRestrictedAccess.java +++ b/src/main/java/forestry/core/interfaces/IAccessHandler.java @@ -14,14 +14,18 @@ import net.minecraft.entity.player.EntityPlayer; import forestry.core.utils.EnumAccess; -public interface IRestrictedAccess extends IOwnable { +public interface IAccessHandler extends IOwnable { boolean switchAccessRule(EntityPlayer player); - EnumAccess getAccess(); + EnumAccess getAccessType(); + + boolean allowsRemoval(EntityPlayer player); boolean allowsAlteration(EntityPlayer player); boolean allowsViewing(EntityPlayer player); + boolean allowsPipeConnections(); + } diff --git a/src/main/java/forestry/core/interfaces/IActivatable.java b/src/main/java/forestry/core/interfaces/IActivatable.java index 0d8da1e77..9e5d3b6b8 100644 --- a/src/main/java/forestry/core/interfaces/IActivatable.java +++ b/src/main/java/forestry/core/interfaces/IActivatable.java @@ -10,8 +10,13 @@ ******************************************************************************/ package forestry.core.interfaces; +import net.minecraft.util.ChunkCoordinates; + /* Networked tile entities that have a client side "active" flag */ public interface IActivatable { + + ChunkCoordinates getCoordinates(); + boolean isActive(); void setActive(boolean active); diff --git a/src/main/java/forestry/core/interfaces/IClimatised.java b/src/main/java/forestry/core/interfaces/IClimatised.java index 4d1a2ba6f..4eafc10ff 100755 --- a/src/main/java/forestry/core/interfaces/IClimatised.java +++ b/src/main/java/forestry/core/interfaces/IClimatised.java @@ -14,7 +14,6 @@ import forestry.api.core.EnumHumidity; import forestry.api.core.EnumTemperature; public interface IClimatised { - boolean isClimatized(); EnumTemperature getTemperature(); diff --git a/src/main/java/forestry/core/interfaces/ILiquidTankContainer.java b/src/main/java/forestry/core/interfaces/ILiquidTankContainer.java index e752580cd..ba345a11a 100755 --- a/src/main/java/forestry/core/interfaces/ILiquidTankContainer.java +++ b/src/main/java/forestry/core/interfaces/ILiquidTankContainer.java @@ -15,11 +15,11 @@ import net.minecraft.inventory.ICrafting; import net.minecraftforge.fluids.IFluidHandler; -import forestry.core.fluids.TankManager; +import forestry.core.fluids.ITankManager; public interface ILiquidTankContainer extends IFluidHandler { - TankManager getTankManager(); + ITankManager getTankManager(); void getGUINetworkData(int messageId, int data); diff --git a/src/main/java/forestry/core/interfaces/IOwnable.java b/src/main/java/forestry/core/interfaces/IOwnable.java index 159cd43d2..ab7870f8f 100755 --- a/src/main/java/forestry/core/interfaces/IOwnable.java +++ b/src/main/java/forestry/core/interfaces/IOwnable.java @@ -20,10 +20,8 @@ public interface IOwnable { GameProfile getOwner(); - void setOwner(EntityPlayer player); + void setOwner(GameProfile owner); boolean isOwner(EntityPlayer player); - boolean allowsRemoval(EntityPlayer player); - } diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearyHeater.java b/src/main/java/forestry/core/interfaces/IRestrictedAccessTile.java old mode 100755 new mode 100644 similarity index 64% rename from src/main/java/forestry/apiculture/gadgets/TileAlvearyHeater.java rename to src/main/java/forestry/core/interfaces/IRestrictedAccessTile.java index 3b102843c..ef0678342 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearyHeater.java +++ b/src/main/java/forestry/core/interfaces/IRestrictedAccessTile.java @@ -1,22 +1,23 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -public class TileAlvearyHeater extends TileAlvearyClimatiser { - - /* CONSTANTS */ - public static final int BLOCK_META = 4; - - public TileAlvearyHeater() { - super(new ClimateControl(0.01f, 0.0f, 2.5f), BlockAlveary.ALVEARY_HEATER_OFF, BlockAlveary.ALVEARY_HEATER_ON, BLOCK_META); - } - -} +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.util.ChunkCoordinates; + +import forestry.core.utils.EnumAccess; + +public interface IRestrictedAccessTile { + IAccessHandler getAccessHandler(); + + ChunkCoordinates getCoordinates(); + + void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess); +} diff --git a/src/main/java/forestry/core/interfaces/ITitled.java b/src/main/java/forestry/core/interfaces/ITitled.java new file mode 100644 index 000000000..b1f333d24 --- /dev/null +++ b/src/main/java/forestry/core/interfaces/ITitled.java @@ -0,0 +1,5 @@ +package forestry.core.interfaces; + +public interface ITitled { + String getUnlocalizedTitle(); +} diff --git a/src/main/java/forestry/core/inventory/AdjacentInventoryCache.java b/src/main/java/forestry/core/inventory/AdjacentInventoryCache.java index 4890041f0..291b9af87 100644 --- a/src/main/java/forestry/core/inventory/AdjacentInventoryCache.java +++ b/src/main/java/forestry/core/inventory/AdjacentInventoryCache.java @@ -40,6 +40,10 @@ public final class AdjacentInventoryCache implements AdjacentTileCache.ICacheLis this(tile, cache, null, null); } + public AdjacentInventoryCache(TileEntity tile, AdjacentTileCache cache, ITileFilter filter) { + this(tile, cache, filter, null); + } + public AdjacentInventoryCache(TileEntity tile, AdjacentTileCache cache, ITileFilter filter, Comparator sorter) { this.cache = cache; this.filter = filter; diff --git a/src/main/java/forestry/core/inventory/AlyzerInventory.java b/src/main/java/forestry/core/inventory/AlyzerInventory.java index c1a9c3d95..88ede7e0c 100644 --- a/src/main/java/forestry/core/inventory/AlyzerInventory.java +++ b/src/main/java/forestry/core/inventory/AlyzerInventory.java @@ -5,10 +5,10 @@ import com.google.common.collect.ImmutableSet; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import forestry.api.core.IErrorSource; import forestry.api.core.IErrorState; import forestry.core.EnumErrorCode; import forestry.core.config.ForestryItem; -import forestry.core.interfaces.IErrorSource; public abstract class AlyzerInventory extends ItemInventory implements IErrorSource { diff --git a/src/main/java/forestry/core/inventory/InvTools.java b/src/main/java/forestry/core/inventory/InvTools.java index 795888845..f82538fdc 100755 --- a/src/main/java/forestry/core/inventory/InvTools.java +++ b/src/main/java/forestry/core/inventory/InvTools.java @@ -36,7 +36,6 @@ import net.minecraftforge.oredict.OreDictionary; import cpw.mods.fml.common.Optional; -import forestry.core.config.Defaults; import forestry.core.inventory.filters.ArrayStackFilter; import forestry.core.inventory.filters.IStackFilter; import forestry.core.inventory.filters.InvertedStackFilter; @@ -308,7 +307,7 @@ public abstract class InvTools { /** * Counts the number of items that match the filter. Ignores - * ISpecialInventory and ISidedInventory, and bypasses InventoryMapper to + * ISidedInventory, and bypasses InventoryMapper to * count from the base IInventory. */ public static int countItems(IInventory inv, ItemStack... filters) { @@ -886,30 +885,6 @@ public abstract class InvTools { stack.writeToNBT(data); } - public static IInventoryAdapter configureSidedUp(IInventoryAdapter inventory, int startSlot, int count) { - return configureSided(inventory, Defaults.FACING_UP, startSlot, count); - } - - public static IInventoryAdapter configureSidedDown(IInventoryAdapter inventory, int startSlot, int count) { - return configureSided(inventory, Defaults.FACING_DOWN, startSlot, count); - } - - public static IInventoryAdapter configureSidedNorthSouth(IInventoryAdapter inventory, int startSlot, int count) { - return configureSided(inventory, Defaults.FACING_NORTHSOUTH, startSlot, count); - } - - public static IInventoryAdapter configureSidedWestEast(IInventoryAdapter inventory, int startSlot, int count) { - return configureSided(inventory, Defaults.FACING_WESTEAST, startSlot, count); - } - - public static IInventoryAdapter configureSidedSides(IInventoryAdapter inventory, int startSlot, int count) { - return configureSided(inventory, Defaults.FACING_SIDES, startSlot, count); - } - - public static IInventoryAdapter configureSided(IInventoryAdapter inventory, int side, int startSlot, int count) { - return configureSided(inventory, new int[]{side}, startSlot, count); - } - public static IInventoryAdapter configureSided(IInventoryAdapter inventory, int[] sides, int startSlot, int count) { int[] slots = new int[count]; for (int i = 0; i < count; i++) { @@ -919,7 +894,7 @@ public abstract class InvTools { return inventory.configureSided(sides, slots); } - /* REMOVAL */ + /* REMOVAL */ /** * Removes a set of items from an inventory. @@ -927,6 +902,10 @@ public abstract class InvTools { * If the inventory doesn't have all the required items, returns false without removing anything. * If stowContainer is true, items with containers will have their container stowed. */ + public static boolean removeSets(IInventory inventory, int count, ItemStack[] set, EntityPlayer player, boolean stowContainer, boolean oreDictionary, boolean craftingTools) { + return removeSets(inventory, count, set, 0, inventory.getSizeInventory(), player, stowContainer, oreDictionary, craftingTools); + } + public static boolean removeSets(IInventory inventory, int count, ItemStack[] set, int firstSlotIndex, int slotCount, EntityPlayer player, boolean stowContainer, boolean oreDictionary, boolean craftingTools) { ItemStack[] condensedSet = StackUtils.condenseStacks(set, -1, false); @@ -983,11 +962,19 @@ public abstract class InvTools { return contains(inventory, queryArray, startSlot, slots); } + public static boolean contains(IInventory inventory, ItemStack[] query) { + return contains(inventory, query, 0, inventory.getSizeInventory()); + } + public static boolean contains(IInventory inventory, ItemStack[] query, int startSlot, int slots) { ItemStack[] stock = getStacks(inventory, startSlot, slots); return StackUtils.containsSets(query, stock) > 0; } + public static boolean containsPercent(IInventory inventory, float percent) { + return containsPercent(inventory, percent, 0, inventory.getSizeInventory()); + } + public static boolean containsPercent(IInventory inventory, float percent, int slot1, int length) { int amount = 0; int stackMax = 0; diff --git a/src/main/java/forestry/core/inventory/InventoryAdapter.java b/src/main/java/forestry/core/inventory/InventoryAdapter.java index 233c83de6..e5ec2d667 100755 --- a/src/main/java/forestry/core/inventory/InventoryAdapter.java +++ b/src/main/java/forestry/core/inventory/InventoryAdapter.java @@ -29,7 +29,7 @@ import forestry.core.utils.PlainInventory; */ public class InventoryAdapter implements IInventoryAdapter, IStreamable { - protected final IInventory inventory; + private final IInventory inventory; private boolean allowAutomation = true; //private boolean debug = false; diff --git a/src/main/java/forestry/core/inventory/InventoryAdapterRestricted.java b/src/main/java/forestry/core/inventory/InventoryAdapterRestricted.java new file mode 100644 index 000000000..4bbca1512 --- /dev/null +++ b/src/main/java/forestry/core/inventory/InventoryAdapterRestricted.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.inventory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.core.config.Defaults; +import forestry.core.interfaces.IAccessHandler; + +public class InventoryAdapterRestricted extends InventoryAdapter { + private final IAccessHandler accessHandler; + + public InventoryAdapterRestricted(int size, String name, IAccessHandler accessHandler) { + super(size, name); + this.accessHandler = accessHandler; + } + + public InventoryAdapterRestricted(int size, String name, int stackLimit, IAccessHandler accessHandler) { + super(size, name, stackLimit); + this.accessHandler = accessHandler; + } + + @Override + public final boolean isUseableByPlayer(EntityPlayer player) { + return accessHandler.allowsViewing(player); + } + + @Override + public final boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) { + if (itemStack == null || !accessHandler.allowsPipeConnections()) { + return false; + } + + return canSlotAccept(slotIndex, itemStack); + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + if (!accessHandler.allowsPipeConnections()) { + return Defaults.SLOTS_NONE; + } + return super.getAccessibleSlotsFromSide(side); + } + + @Override + public final boolean canInsertItem(int slotIndex, ItemStack itemStack, int side) { + if (itemStack == null || !accessHandler.allowsPipeConnections()) { + return false; + } + return isItemValidForSlot(slotIndex, itemStack); + } + + @Override + public boolean canExtractItem(int slotIndex, ItemStack itemStack, int side) { + return itemStack != null && accessHandler.allowsPipeConnections(); + } +} diff --git a/src/main/java/forestry/core/inventory/TileInventoryAdapter.java b/src/main/java/forestry/core/inventory/TileInventoryAdapter.java index 27905b3da..b086e1c47 100755 --- a/src/main/java/forestry/core/inventory/TileInventoryAdapter.java +++ b/src/main/java/forestry/core/inventory/TileInventoryAdapter.java @@ -11,10 +11,11 @@ package forestry.core.inventory; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; -import forestry.core.gadgets.TileForestry; +import forestry.core.interfaces.IRestrictedAccessTile; -public class TileInventoryAdapter extends InventoryAdapter { +public class TileInventoryAdapter extends InventoryAdapterRestricted { protected final T tile; @@ -23,7 +24,7 @@ public class TileInventoryAdapter extends InventoryAdapt } public TileInventoryAdapter(T tile, int size, String name, int stackLimit) { - super(size, name, stackLimit); + super(size, name, stackLimit, tile.getAccessHandler()); this.tile = tile; } diff --git a/src/main/java/forestry/core/multiblock/BlockMultiblockBase.java b/src/main/java/forestry/core/multiblock/BlockMultiblockBase.java new file mode 100644 index 000000000..1ff8f06f8 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/BlockMultiblockBase.java @@ -0,0 +1,15 @@ +package forestry.core.multiblock; + +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; + +/* + * Base class for multiblock-capable blocks. This is only a reference implementation + * and can be safely ignored. + */ +public abstract class BlockMultiblockBase extends BlockContainer { + + protected BlockMultiblockBase(Material material) { + super(material); + } +} diff --git a/src/main/java/forestry/core/multiblock/CoordTriplet.java b/src/main/java/forestry/core/multiblock/CoordTriplet.java new file mode 100644 index 000000000..30e6b7ca5 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/CoordTriplet.java @@ -0,0 +1,168 @@ +package forestry.core.multiblock; + +import net.minecraft.world.ChunkCoordIntPair; + +import net.minecraftforge.common.util.ForgeDirection; + +/* + * Simple wrapper class for XYZ coordinates. + */ +public class CoordTriplet implements Comparable { + public int x, y, z; + + public CoordTriplet(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public int getChunkX() { + return x >> 4; + } + + public int getChunkZ() { + return z >> 4; + } + + public long getChunkXZHash() { + return ChunkCoordIntPair.chunkXZ2Int(x >> 4, z >> 4); + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } else if (other instanceof CoordTriplet) { + CoordTriplet otherTriplet = (CoordTriplet) other; + return this.x == otherTriplet.x && this.y == otherTriplet.y && this.z == otherTriplet.z; + } else { + return false; + } + } + + public void translate(ForgeDirection dir) { + this.x += dir.offsetX; + this.y += dir.offsetY; + this.z += dir.offsetZ; + } + + public boolean equals(int x, int y, int z) { + return this.x == x && this.y == y && this.z == z; + } + + // Suggested implementation from NetBeans 7.1 + public int hashCode() { + int hash = 7; + hash = 71 * hash + this.x; + hash = 71 * hash + this.y; + hash = 71 * hash + this.z; + return hash; + } + + public CoordTriplet copy() { + return new CoordTriplet(x, y, z); + } + + public void copy(CoordTriplet other) { + this.x = other.x; + this.y = other.y; + this.z = other.z; + } + + public CoordTriplet[] getNeighbors() { + return new CoordTriplet[]{ + new CoordTriplet(x + 1, y, z), + new CoordTriplet(x - 1, y, z), + new CoordTriplet(x, y + 1, z), + new CoordTriplet(x, y - 1, z), + new CoordTriplet(x, y, z + 1), + new CoordTriplet(x, y, z - 1) + }; + } + + ///// IComparable + + @Override + public int compareTo(Object o) { + if (o instanceof CoordTriplet) { + CoordTriplet other = (CoordTriplet) o; + if (this.x < other.x) { + return -1; + } else if (this.x > other.x) { + return 1; + } else if (this.y < other.y) { + return -1; + } else if (this.y > other.y) { + return 1; + } else if (this.z < other.z) { + return -1; + } else if (this.z > other.z) { + return 1; + } else { + return 0; + } + } + return 0; + } + + ///// Really confusing code that should be cleaned up + + public ForgeDirection getDirectionFromSourceCoords(int x, int y, int z) { + if (this.x < x) { + return ForgeDirection.WEST; + } else if (this.x > x) { + return ForgeDirection.EAST; + } else if (this.y < y) { + return ForgeDirection.DOWN; + } else if (this.y > y) { + return ForgeDirection.UP; + } else if (this.z < z) { + return ForgeDirection.SOUTH; + } else if (this.z > z) { + return ForgeDirection.NORTH; + } else { + return ForgeDirection.UNKNOWN; + } + } + + public ForgeDirection getOppositeDirectionFromSourceCoords(int x, int y, int z) { + if (this.x < x) { + return ForgeDirection.EAST; + } else if (this.x > x) { + return ForgeDirection.WEST; + } else if (this.y < y) { + return ForgeDirection.UP; + } else if (this.y > y) { + return ForgeDirection.DOWN; + } else if (this.z < z) { + return ForgeDirection.NORTH; + } else if (this.z > z) { + return ForgeDirection.SOUTH; + } else { + return ForgeDirection.UNKNOWN; + } + } + + @Override + public String toString() { + return String.format("(%d, %d, %d)", this.x, this.y, this.z); + } + + public int compareTo(int xCoord, int yCoord, int zCoord) { + if (this.x < xCoord) { + return -1; + } else if (this.x > xCoord) { + return 1; + } else if (this.y < yCoord) { + return -1; + } else if (this.y > yCoord) { + return 1; + } else if (this.z < zCoord) { + return -1; + } else if (this.z > zCoord) { + return 1; + } else { + return 0; + } + } +} diff --git a/src/main/java/forestry/core/multiblock/IMultiblockPart.java b/src/main/java/forestry/core/multiblock/IMultiblockPart.java new file mode 100644 index 000000000..e73c51079 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/IMultiblockPart.java @@ -0,0 +1,193 @@ +package forestry.core.multiblock; + +import java.util.Set; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +/** + * Basic interface for a multiblock machine part. This is defined as an abstract class + * as we need the basic functionality of a TileEntity as well. + * Preferably, you should derive from MultiblockTileEntityBase, + * which does all the hard work for you. + * + * {@link forestry.core.multiblock.MultiblockTileEntityBase} + */ +public abstract class IMultiblockPart extends TileEntity { + public static final int INVALID_DISTANCE = Integer.MAX_VALUE; + + /** + * @return True if this block is connected to a multiblock controller. False otherwise. + */ + public abstract boolean isConnected(); + + /** + * @return The attached multiblock controller for this tile entity. + */ + public abstract MultiblockControllerBase getMultiblockController(); + + /** + * Returns the location of this tile entity in the world, in CoordTriplet form. + * @return A CoordTriplet with its x,y,z members set to the location of this tile entity in the world. + */ + public abstract CoordTriplet getWorldLocation(); + + // Multiblock connection-logic callbacks + + /** + * Called after this block has been attached to a new multiblock controller. + * @param newController The new multiblock controller to which this tile entity is attached. + */ + public abstract void onAttached(MultiblockControllerBase newController); + + /** + * Called after this block has been detached from a multiblock controller. + * @param multiblockController The multiblock controller that no longer controls this tile entity. + */ + public abstract void onDetached(MultiblockControllerBase multiblockController); + + /** + * Called when this block is being orphaned. Use this to copy game-data values that + * should persist despite a machine being broken. + * This should NOT mark the part as disconnected. onDetached will be called immediately afterwards. + * @see #onDetached(MultiblockControllerBase) + * @param oldController The controller which is orphaning this block. + * @param oldControllerSize The number of connected blocks in the controller prior to shedding orphans. + * @param newControllerSize The number of connected blocks in the controller after shedding orphans. + */ + public abstract void onOrphaned(MultiblockControllerBase oldController, int oldControllerSize, int newControllerSize); + + // Multiblock fuse/split helper methods. Here there be dragons. + + /** + * Factory method. Creates a new multiblock controller and returns it. + * Does not attach this tile entity to it. + * Override this in your game code! + * @return A new Multiblock Controller, derived from MultiblockControllerBase. + */ + public abstract MultiblockControllerBase createNewMultiblock(); + + /** + * Retrieve the type of multiblock controller which governs this part. + * Used to ensure that incompatible multiblocks are not merged. + * @return The class/type of the multiblock controller which governs this type of part. + */ + public abstract Class getMultiblockControllerType(); + + /** + * Called when this block is moved from its current controller into a new controller. + * A special case of attach/detach, done here for efficiency to avoid triggering + * lots of recalculation logic. + * @param newController The new controller into which this tile entity is being merged. + */ + public abstract void onAssimilated(MultiblockControllerBase newController); + + // Multiblock connection data access. + // You generally shouldn't toy with these! + // They're for use by Multiblock Controllers. + + /** + * Set that this block has been visited by your validation algorithms. + */ + public abstract void setVisited(); + + /** + * Set that this block has not been visited by your validation algorithms; + */ + public abstract void setUnvisited(); + + /** + * @return True if this block has been visited by your validation algorithms since the last reset. + */ + public abstract boolean isVisited(); + + /** + * Called when this block becomes the designated block for saving data and + * transmitting data across the wire. + */ + public abstract void becomeMultiblockSaveDelegate(); + + /** + * Called when this block is no longer the designated block for saving data + * and transmitting data across the wire. + */ + public abstract void forfeitMultiblockSaveDelegate(); + + /** + * Is this block the designated save/load & network delegate? + */ + public abstract boolean isMultiblockSaveDelegate(); + + /** + * Returns an array containing references to neighboring IMultiblockPart tile entities. + * Primarily a utility method. Only works after tileentity construction, so it cannot be used in + * MultiblockControllerBase::attachBlock. + * + * This method is chunk-safe on the server; it will not query for parts in chunks that are unloaded. + * Note that no method is chunk-safe on the client, because ChunkProviderClient is stupid. + * @return An array of references to neighboring IMultiblockPart tile entities. + */ + public abstract IMultiblockPart[] getNeighboringParts(); + + // Multiblock business-logic callbacks - implement these! + + /** + * Called when a machine is fully assembled from the disassembled state, meaning + * it was broken by a player/entity action, not by chunk unloads. + * Note that, for non-square machines, the min/max coordinates may not actually be part + * of the machine! They form an outer bounding box for the whole machine itself. + * @param multiblockControllerBase The controller to which this part is being assembled. + */ + public abstract void onMachineAssembled(MultiblockControllerBase multiblockControllerBase); + + /** + * Called when the machine is broken for game reasons, e.g. a player removed a block + * or an explosion occurred. + */ + public abstract void onMachineBroken(); + + /** + * Called when the user activates the machine. This is not called by default, but is included + * as most machines have this game-logical concept. + */ + public abstract void onMachineActivated(); + + /** + * Called when the user deactivates the machine. This is not called by default, but is included + * as most machines have this game-logical concept. + */ + public abstract void onMachineDeactivated(); + + // Block events + + /** + * Called when this part should check its neighbors. + * This method MUST NOT cause additional chunks to load. + * ALWAYS check to see if a chunk is loaded before querying for its tile entity + * This part should inform the controller that it is attaching at this time. + * @return A Set of multiblock controllers to which this object would like to attach. It should have attached to one of the controllers in this list. Return null if there are no compatible controllers nearby. + */ + public abstract Set attachToNeighbors(); + + /** + * Assert that this part is detached. If not, log a warning and set the part's controller to null. + * Do NOT fire the full disconnection logic. + */ + public abstract void assertDetached(); + + /** + * @return True if a part has multiblock game-data saved inside it. + */ + public abstract boolean hasMultiblockSaveData(); + + /** + * @return The part's saved multiblock game-data in NBT format, or null if there isn't any. + */ + public abstract NBTTagCompound getMultiblockSaveData(); + + /** + * Called after a block is added and the controller has incorporated the part's saved + * multiblock game-data into itself. Generally, you should clear the saved data here. + */ + public abstract void onMultiblockDataAssimilated(); +} diff --git a/src/main/java/forestry/core/multiblock/LICENSE.txt b/src/main/java/forestry/core/multiblock/LICENSE.txt new file mode 100644 index 000000000..b3c0fa6fb --- /dev/null +++ b/src/main/java/forestry/core/multiblock/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 "Erogenous Beef" + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/main/java/forestry/core/multiblock/MultiblockClientTickHandler.java b/src/main/java/forestry/core/multiblock/MultiblockClientTickHandler.java new file mode 100644 index 000000000..df3a4b6eb --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockClientTickHandler.java @@ -0,0 +1,16 @@ +package forestry.core.multiblock; + +import net.minecraft.client.Minecraft; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; + +public class MultiblockClientTickHandler { + + @SubscribeEvent + public void onClientTick(TickEvent.ClientTickEvent event) { + if (event.phase == TickEvent.Phase.START) { + MultiblockRegistry.tickStart(Minecraft.getMinecraft().theWorld); + } + } +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockControllerBase.java b/src/main/java/forestry/core/multiblock/MultiblockControllerBase.java new file mode 100644 index 000000000..81dca9b66 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockControllerBase.java @@ -0,0 +1,1132 @@ +package forestry.core.multiblock; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; + +import java.io.IOException; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Random; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkProvider; + +import com.mojang.authlib.GameProfile; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorLogicSource; +import forestry.core.delegates.AccessHandler; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.interfaces.IOwnable; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.inventory.FakeInventoryAdapter; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.IStreamableGui; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; + +/** + * This class contains the base logic for "multiblock controllers". Conceptually, they are + * meta-TileEntities. They govern the logic for an associated group of TileEntities. + * + * Subordinate TileEntities implement the IMultiblockPart class and, generally, should not have an update() loop. + */ +public abstract class MultiblockControllerBase implements ISidedInventory, IRestrictedAccessTile, IStreamableGui, IErrorLogicSource { + public static final short DIMENSION_UNBOUNDED = -1; + + // Multiblock stuff - do not mess with + protected World worldObj; + + // Disassembled -> Assembled; Assembled -> Disassembled OR Paused; Paused -> Assembled + protected enum AssemblyState { + Disassembled, Assembled, Paused + } + + protected AssemblyState assemblyState; + + protected HashSet connectedParts; + + /** This is a deterministically-picked coordinate that identifies this + * multiblock uniquely in its dimension. + * Currently, this is the coord with the lowest X, Y and Z coordinates, in that order of evaluation. + * i.e. If something has a lower X but higher Y/Z coordinates, it will still be the reference. + * If something has the same X but a lower Y coordinate, it will be the reference. Etc. + */ + private CoordTriplet referenceCoord; + + /** + * Minimum bounding box coordinate. Blocks do not necessarily exist at this coord if your machine + * is not a cube/rectangular prism. + */ + private CoordTriplet minimumCoord; + + /** + * Maximum bounding box coordinate. Blocks do not necessarily exist at this coord if your machine + * is not a cube/rectangular prism. + */ + private CoordTriplet maximumCoord; + + /** + * Set to true whenever a part is removed from this controller. + */ + private boolean shouldCheckForDisconnections; + + /** + * Set whenever we validate the multiblock + */ + private MultiblockValidationException lastValidationException; + + // Ticks + private static final Random rand = new Random(); + private int tickCount = rand.nextInt(256); + + private final AccessHandler accessHandler; + private final IErrorLogic errorLogic; + + protected boolean debugMode; + + protected MultiblockControllerBase(World world) { + // Multiblock stuff + worldObj = world; + connectedParts = new HashSet(); + + referenceCoord = null; + assemblyState = AssemblyState.Disassembled; + + minimumCoord = null; + maximumCoord = null; + + shouldCheckForDisconnections = true; + lastValidationException = null; + + accessHandler = new AccessHandler(this); + errorLogic = ForestryAPI.errorStateRegistry.createErrorLogic(); + + debugMode = false; + } + + @Override + public IAccessHandler getAccessHandler() { + return accessHandler; + } + + @Override + public IErrorLogic getErrorLogic() { + return errorLogic; + } + + public void setDebugMode(boolean active) { + debugMode = active; + } + + public boolean isDebugMode() { + return debugMode; + } + + /** + * Call when a block with cached save-delegate data is added to the multiblock. + * The part will be notified that the data has been used after this call completes. + * @param part The NBT tag containing this controller's data. + */ + public abstract void onAttachedPartWithMultiblockData(IMultiblockPart part, NBTTagCompound data); + + /** + * Attach a new part to this machine. + * @param part The part to add. + */ + public void attachBlock(IMultiblockPart part) { + CoordTriplet coord = part.getWorldLocation(); + + if (!connectedParts.add(part)) { + Proxies.log.warning("[%s] Controller %s is double-adding part %d @ %s. This is unusual. If you encounter odd behavior, please tear down the machine and rebuild it.", (worldObj.isRemote ? "CLIENT" : "SERVER"), hashCode(), part.hashCode(), coord); + } + + part.onAttached(this); + this.onBlockAdded(part); + + if (part.hasMultiblockSaveData()) { + NBTTagCompound savedData = part.getMultiblockSaveData(); + onAttachedPartWithMultiblockData(part, savedData); + part.onMultiblockDataAssimilated(); + } + + if (this.referenceCoord == null) { + referenceCoord = coord; + part.becomeMultiblockSaveDelegate(); + } else if (coord.compareTo(referenceCoord) < 0) { + TileEntity te = this.worldObj.getTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z); + ((IMultiblockPart) te).forfeitMultiblockSaveDelegate(); + + referenceCoord = coord; + part.becomeMultiblockSaveDelegate(); + } else { + part.forfeitMultiblockSaveDelegate(); + } + + if (minimumCoord != null) { + if (part.xCoord < minimumCoord.x) { + minimumCoord.x = part.xCoord; + } + if (part.yCoord < minimumCoord.y) { + minimumCoord.y = part.yCoord; + } + if (part.zCoord < minimumCoord.z) { + minimumCoord.z = part.zCoord; + } + } + + if (maximumCoord != null) { + if (part.xCoord > maximumCoord.x) { + maximumCoord.x = part.xCoord; + } + if (part.yCoord > maximumCoord.y) { + maximumCoord.y = part.yCoord; + } + if (part.zCoord > maximumCoord.z) { + maximumCoord.z = part.zCoord; + } + } + + MultiblockRegistry.addDirtyController(worldObj, this); + } + + /** + * Called when a new part is added to the machine. Good time to register things into lists. + * @param newPart The part being added. + */ + protected abstract void onBlockAdded(IMultiblockPart newPart); + + /** + * Called when a part is removed from the machine. Good time to clean up lists. + * @param oldPart The part being removed. + */ + protected abstract void onBlockRemoved(IMultiblockPart oldPart); + + /** + * Called when a machine is assembled from a disassembled state. + */ + protected void onMachineAssembled() { + if (worldObj.isRemote) { + return; + } + + // Figure out who owns the multiblock, by majority + + Multiset owners = HashMultiset.create(); + for (IMultiblockPart part : connectedParts) { + if (part instanceof IRestrictedAccessTile) { + IAccessHandler accessHandler = ((IRestrictedAccessTile) part).getAccessHandler(); + GameProfile owner = accessHandler.getOwner(); + if (owner != null) { + owners.add(owner); + } + } else if (part instanceof IOwnable) { + IOwnable ownable = (IOwnable) part; + GameProfile owner = ownable.getOwner(); + if (owner != null) { + owners.add(owner); + } + } + } + + GameProfile owner = null; + int max = 0; + for (Multiset.Entry entry : owners.entrySet()) { + int count = entry.getCount(); + if (count > max) { + max = count; + owner = entry.getElement(); + } + } + + getAccessHandler().setOwner(owner); + } + + /** + * Called when a machine is restored to the assembled state from a paused state. + */ + protected void onMachineRestored() { + + } + + /** + * Called when a machine is paused from an assembled state + * This generally only happens due to chunk-loads and other "system" events. + */ + protected void onMachinePaused() { + + } + + /** + * Called when a machine is disassembled from an assembled state. + * This happens due to user or in-game actions (e.g. explosions) + */ + protected void onMachineDisassembled() { + + } + + /** + * Callback whenever a part is removed (or will very shortly be removed) from a controller. + * Do housekeeping/callbacks, also nulls min/max coords. + * @param part The part being removed. + */ + private void onDetachBlock(IMultiblockPart part) { + // Strip out this part + part.onDetached(this); + this.onBlockRemoved(part); + part.forfeitMultiblockSaveDelegate(); + + minimumCoord = maximumCoord = null; + + if (referenceCoord != null && referenceCoord.equals(part.xCoord, part.yCoord, part.zCoord)) { + referenceCoord = null; + } + + shouldCheckForDisconnections = true; + } + + /** + * Call to detach a block from this machine. Generally, this should be called + * when the tile entity is being released, e.g. on block destruction. + * @param part The part to detach from this machine. + * @param chunkUnloading Is this entity detaching due to the chunk unloading? If true, the multiblock will be paused instead of broken. + */ + public void detachBlock(IMultiblockPart part, boolean chunkUnloading) { + if (chunkUnloading && this.assemblyState == AssemblyState.Assembled) { + this.assemblyState = AssemblyState.Paused; + this.onMachinePaused(); + } + + // Strip out this part + onDetachBlock(part); + if (!connectedParts.remove(part)) { + Proxies.log.warning("[%s] Double-removing part (%d) @ %d, %d, %d, this is unexpected and may cause problems. If you encounter anomalies, please tear down the reactor and rebuild it.", worldObj.isRemote ? "CLIENT" : "SERVER", part.hashCode(), part.xCoord, part.yCoord, part.zCoord); + } + + if (connectedParts.isEmpty()) { + // Destroy/unregister + MultiblockRegistry.addDeadController(this.worldObj, this); + return; + } + + MultiblockRegistry.addDirtyController(this.worldObj, this); + + // Find new save delegate if we need to. + if (referenceCoord == null) { + selectNewReferenceCoord(); + } + } + + /** + * Helper method so we don't check for a whole machine until we have enough blocks + * to actually assemble it. This isn't as simple as xmax*ymax*zmax for non-cubic machines + * or for machines with hollow/complex interiors. + * @return The minimum number of blocks connected to the machine for it to be assembled. + */ + protected abstract int getMinimumNumberOfBlocksForAssembledMachine(); + + /** + * Returns the maximum X dimension size of the machine, or -1 (DIMENSION_UNBOUNDED) to disable + * dimension checking in X. (This is not recommended.) + * @return The maximum X dimension size of the machine, or -1 + */ + protected abstract int getMaximumXSize(); + + /** + * Returns the maximum Z dimension size of the machine, or -1 (DIMENSION_UNBOUNDED) to disable + * dimension checking in X. (This is not recommended.) + * @return The maximum Z dimension size of the machine, or -1 + */ + protected abstract int getMaximumZSize(); + + /** + * Returns the maximum Y dimension size of the machine, or -1 (DIMENSION_UNBOUNDED) to disable + * dimension checking in X. (This is not recommended.) + * @return The maximum Y dimension size of the machine, or -1 + */ + protected abstract int getMaximumYSize(); + + /** + * Returns the minimum X dimension size of the machine. Must be at least 1, because nothing else makes sense. + * @return The minimum X dimension size of the machine + */ + protected int getMinimumXSize() { + return 1; + } + + /** + * Returns the minimum Y dimension size of the machine. Must be at least 1, because nothing else makes sense. + * @return The minimum Y dimension size of the machine + */ + protected int getMinimumYSize() { + return 1; + } + + /** + * Returns the minimum Z dimension size of the machine. Must be at least 1, because nothing else makes sense. + * @return The minimum Z dimension size of the machine + */ + protected int getMinimumZSize() { + return 1; + } + + + /** + * @return An exception representing the last error encountered when trying to assemble this + * multiblock, or null if there is no error. + */ + public MultiblockValidationException getLastValidationException() { + return lastValidationException; + } + + /** + * Checks if a machine is whole. If not, throws an exception with the reason why. + */ + protected abstract void isMachineWhole() throws MultiblockValidationException; + + /** + * Check if the machine is whole or not. + * If the machine was not whole, but now is, assemble the machine. + * If the machine was whole, but no longer is, disassemble the machine. + * @return + */ + public void checkIfMachineIsWhole() { + AssemblyState oldState = this.assemblyState; + boolean isWhole; + lastValidationException = null; + try { + isMachineWhole(); + isWhole = true; + } catch (MultiblockValidationException e) { + lastValidationException = e; + isWhole = false; + } + + if (isWhole) { + // This will alter assembly state + assembleMachine(oldState); + } else if (oldState == AssemblyState.Assembled) { + // This will alter assembly state + disassembleMachine(); + } + // Else Paused, do nothing + } + + /** + * Called when a machine becomes "whole" and should begin + * functioning as a game-logically finished machine. + * Calls onMachineAssembled on all attached parts. + */ + private void assembleMachine(AssemblyState oldState) { + for (IMultiblockPart part : connectedParts) { + part.onMachineAssembled(this); + } + + this.assemblyState = AssemblyState.Assembled; + if (oldState == AssemblyState.Paused) { + onMachineRestored(); + } else { + onMachineAssembled(); + } + } + + /** + * Called when the machine needs to be disassembled. + * It is not longer "whole" and should not be functional, usually + * as a result of a block being removed. + * Calls onMachineBroken on all attached parts. + */ + private void disassembleMachine() { + for (IMultiblockPart part : connectedParts) { + part.onMachineBroken(); + } + + this.assemblyState = AssemblyState.Disassembled; + onMachineDisassembled(); + } + + /** + * Assimilate another controller into this controller. + * Acquire all of the other controller's blocks and attach them + * to this one. + * + * @param other The controller to merge into this one. + */ + public void assimilate(MultiblockControllerBase other) { + CoordTriplet otherReferenceCoord = other.getReferenceCoord(); + if (otherReferenceCoord != null && getReferenceCoord().compareTo(otherReferenceCoord) >= 0) { + throw new IllegalArgumentException("The controller with the lowest minimum-coord value must consume the one with the higher coords"); + } + + TileEntity te; + Set partsToAcquire = new HashSet(other.connectedParts); + + // releases all blocks and references gently so they can be incorporated into another multiblock + other._onAssimilated(this); + + for (IMultiblockPart acquiredPart : partsToAcquire) { + // By definition, none of these can be the minimum block. + if (acquiredPart.isInvalid()) { + continue; + } + + connectedParts.add(acquiredPart); + acquiredPart.onAssimilated(this); + this.onBlockAdded(acquiredPart); + } + + this.onAssimilate(other); + other.onAssimilated(this); + } + + /** + * Called when this machine is consumed by another controller. + * Essentially, forcibly tear down this object. + * @param otherController The controller consuming this controller. + */ + private void _onAssimilated(MultiblockControllerBase otherController) { + if (referenceCoord != null) { + if (worldObj.getChunkProvider().chunkExists(referenceCoord.getChunkX(), referenceCoord.getChunkZ())) { + TileEntity te = this.worldObj.getTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z); + if (te instanceof IMultiblockPart) { + ((IMultiblockPart) te).forfeitMultiblockSaveDelegate(); + } + } + this.referenceCoord = null; + } + + connectedParts.clear(); + } + + /** + * Callback. Called after this controller assimilates all the blocks + * from another controller. + * Use this to absorb that controller's game data. + * @param assimilated The controller whose uniqueness was added to our own. + */ + protected abstract void onAssimilate(MultiblockControllerBase assimilated); + + /** + * Callback. Called after this controller is assimilated into another controller. + * All blocks have been stripped out of this object and handed over to the + * other controller. + * This is intended primarily for cleanup. + * @param assimilator The controller which has assimilated this controller. + */ + protected abstract void onAssimilated(MultiblockControllerBase assimilator); + + /** + * Driver for the update loop. If the machine is assembled, runs + * the game logic update method. + */ + public final void updateMultiblockEntity() { + tickCount++; + + if (connectedParts.isEmpty()) { + // This shouldn't happen, but just in case... + MultiblockRegistry.addDeadController(this.worldObj, this); + return; + } + + if (this.assemblyState != AssemblyState.Assembled) { + // Not assembled - don't run game logic + return; + } + + if (worldObj.isRemote) { + updateClient(tickCount); + } else if (updateServer(tickCount)) { + // If this returns true, the server has changed its internal data. + // If our chunks are loaded (they should be), we must mark our chunks as dirty. + if (minimumCoord != null && maximumCoord != null && + this.worldObj.checkChunksExist(minimumCoord.x, minimumCoord.y, minimumCoord.z, + maximumCoord.x, maximumCoord.y, maximumCoord.z)) { + int minChunkX = minimumCoord.x >> 4; + int minChunkZ = minimumCoord.z >> 4; + int maxChunkX = maximumCoord.x >> 4; + int maxChunkZ = maximumCoord.z >> 4; + + for (int x = minChunkX; x <= maxChunkX; x++) { + for (int z = minChunkZ; z <= maxChunkZ; z++) { + // Ensure that we save our data, even if the our save delegate is in has no TEs. + Chunk chunkToSave = this.worldObj.getChunkFromChunkCoords(x, z); + chunkToSave.setChunkModified(); + } + } + } + } + // Else: Server, but no need to save data. + } + + /** + * The server-side update loop! Use this similarly to a TileEntity's update loop. + * You do not need to call your superclass' update() if you're directly + * derived from MultiblockControllerBase. This is a callback. + * Note that this will only be called when the machine is assembled. + * @return True if the multiblock should save data, i.e. its internal game state has changed. False otherwise. + */ + protected abstract boolean updateServer(int tickCount); + + /** + * Client-side update loop. Generally, this shouldn't do anything, but if you want + * to do some interpolation or something, do it here. + */ + protected abstract void updateClient(int tickCount); + + protected final boolean updateOnInterval(int tickInterval) { + return tickCount % tickInterval == 0; + } + + // Validation helpers + + /** + * @param level the level of the block on the multiblock, starting at 0 for the bottom. + * @param world World object for the world in which this controller is located. + * @param x X coordinate of the block being tested + * @param y Y coordinate of the block being tested + * @param z Z coordinate of the block being tested + * @throws MultiblockValidationException if the tested block is not allowed on the machine's side faces + */ + protected void isBlockGoodForExteriorLevel(int level, World world, int x, int y, int z) throws MultiblockValidationException { + Block block = world.getBlock(x, y, z); + throw new MultiblockValidationException(StringUtil.localizeAndFormatRaw("for.multiblock.error.invalid.interior", x, y, z, block.getLocalizedName())); + } + + /** + * The interior is any block that does not touch blocks outside the machine. + * @param world World object for the world in which this controller is located. + * @param x X coordinate of the block being tested + * @param y Y coordinate of the block being tested + * @param z Z coordinate of the block being tested + * @throws MultiblockValidationException if the tested block is not allowed in the machine's interior + */ + protected void isBlockGoodForInterior(World world, int x, int y, int z) throws MultiblockValidationException { + Block block = world.getBlock(x, y, z); + throw new MultiblockValidationException(StringUtil.localizeAndFormatRaw("for.multiblock.error.invalid.interior", x, y, z, block.getLocalizedName())); + } + + /** + * @return The reference coordinate, the block with the lowest x, y, z coordinates, evaluated in that order. + */ + public CoordTriplet getReferenceCoord() { + if (referenceCoord == null) { + selectNewReferenceCoord(); + } + return referenceCoord; + } + + /** + * @return The number of blocks connected to this controller. + */ + public int getNumConnectedBlocks() { + return connectedParts.size(); + } + + public void writeToNBT(NBTTagCompound data) { + accessHandler.writeToNBT(data); + } + + public void readFromNBT(NBTTagCompound data) { + accessHandler.readFromNBT(data); + } + + /** + * Force this multiblock to recalculate its minimum and maximum coordinates + * from the list of connected parts. + */ + public void recalculateMinMaxCoords() { + minimumCoord = new CoordTriplet(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + maximumCoord = new CoordTriplet(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + + for (IMultiblockPart part : connectedParts) { + if (part.xCoord < minimumCoord.x) { + minimumCoord.x = part.xCoord; + } + if (part.xCoord > maximumCoord.x) { + maximumCoord.x = part.xCoord; + } + if (part.yCoord < minimumCoord.y) { + minimumCoord.y = part.yCoord; + } + if (part.yCoord > maximumCoord.y) { + maximumCoord.y = part.yCoord; + } + if (part.zCoord < minimumCoord.z) { + minimumCoord.z = part.zCoord; + } + if (part.zCoord > maximumCoord.z) { + maximumCoord.z = part.zCoord; + } + } + } + + /** + * @return The minimum bounding-box coordinate containing this machine's blocks. + */ + public CoordTriplet getMinimumCoord() { + if (minimumCoord == null) { + recalculateMinMaxCoords(); + } + return minimumCoord.copy(); + } + + /** + * @return The maximum bounding-box coordinate containing this machine's blocks. + */ + public CoordTriplet getMaximumCoord() { + if (maximumCoord == null) { + recalculateMinMaxCoords(); + } + return maximumCoord.copy(); + } + + public final CoordTriplet getCenterCoord() { + CoordTriplet minCoord = getMinimumCoord(); + CoordTriplet maxCoord = getMaximumCoord(); + + return new CoordTriplet( + (minCoord.x + maxCoord.x) / 2, + (minCoord.y + maxCoord.y) / 2, + (minCoord.z + maxCoord.z) / 2 + ); + } + + public final CoordTriplet getTopCenterCoord() { + CoordTriplet minCoord = getMinimumCoord(); + CoordTriplet maxCoord = getMaximumCoord(); + + return new CoordTriplet( + (minCoord.x + maxCoord.x) / 2, + maxCoord.y, + (minCoord.z + maxCoord.z) / 2 + ); + } + + public final boolean isCoordInMultiblock(int x, int y, int z) { + return (x >= minimumCoord.x && x <= maximumCoord.x) && (y >= minimumCoord.y && y <= maximumCoord.y) && (z >= minimumCoord.z && z <= maximumCoord.z); + } + + /** + * Called when the save delegate's tile entity is being asked for its description packet + * @param data A fresh compound tag to write your multiblock data into + */ + public abstract void formatDescriptionPacket(NBTTagCompound data); + + /** + * Called when the save delegate's tile entity receiving a description packet + * @param data A compound tag containing multiblock data to import + */ + public abstract void decodeDescriptionPacket(NBTTagCompound data); + + /** + * @return True if this controller has no associated blocks, false otherwise + */ + public boolean isEmpty() { + return connectedParts.isEmpty(); + } + + /** + * Tests whether this multiblock should consume the other multiblock + * and become the new multiblock master when the two multiblocks + * are adjacent. Assumes both multiblocks are the same type. + * @param otherController The other multiblock controller. + * @return True if this multiblock should consume the other, false otherwise. + */ + public boolean shouldConsume(MultiblockControllerBase otherController) { + if (!otherController.getClass().equals(getClass())) { + throw new IllegalArgumentException("Attempting to merge two multiblocks with different master classes - this should never happen!"); + } + + if (otherController == this) { + return false; + } // Don't be silly, don't eat yourself. + + int res = _shouldConsume(otherController); + if (res < 0) { + return true; + } else if (res > 0) { + return false; + } else { + // Strip dead parts from both and retry + Proxies.log.warning("[%s] Encountered two controllers with the same reference coordinate. Auditing connected parts and retrying.", worldObj.isRemote ? "CLIENT" : "SERVER"); + auditParts(); + otherController.auditParts(); + + res = _shouldConsume(otherController); + if (res < 0) { + return true; + } else if (res > 0) { + return false; + } else { + Proxies.log.severe("My Controller (%d): size (%d), parts: %s", hashCode(), connectedParts.size(), getPartsListString()); + Proxies.log.severe("Other Controller (%d): size (%d), coords: %s", otherController.hashCode(), otherController.connectedParts.size(), otherController.getPartsListString()); + throw new IllegalArgumentException("[" + (worldObj.isRemote ? "CLIENT" : "SERVER") + "] Two controllers with the same reference coord that somehow both have valid parts - this should never happen!"); + } + + } + } + + private int _shouldConsume(MultiblockControllerBase otherController) { + CoordTriplet myCoord = getReferenceCoord(); + CoordTriplet theirCoord = otherController.getReferenceCoord(); + + // Always consume other controllers if their reference coordinate is null - this means they're empty and can be assimilated on the cheap + if (theirCoord == null) { + return -1; + } else { + return myCoord.compareTo(theirCoord); + } + } + + private String getPartsListString() { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (IMultiblockPart part : connectedParts) { + if (!first) { + sb.append(", "); + } + sb.append(String.format("(%d: %d, %d, %d)", part.hashCode(), part.xCoord, part.yCoord, part.zCoord)); + first = false; + } + + return sb.toString(); + } + + /** + * Checks all of the parts in the controller. If any are dead or do not exist in the world, they are removed. + */ + private void auditParts() { + HashSet deadParts = new HashSet(); + for (IMultiblockPart part : connectedParts) { + if (part.isInvalid() || worldObj.getTileEntity(part.xCoord, part.yCoord, part.zCoord) != part) { + onDetachBlock(part); + deadParts.add(part); + } + } + + connectedParts.removeAll(deadParts); + Proxies.log.warning("[%s] Controller found %d dead parts during an audit, %d parts remain attached", worldObj.isRemote ? "CLIENT" : "SERVER", deadParts.size(), connectedParts.size()); + } + + /** + * Called when this machine may need to check for blocks that are no + * longer physically connected to the reference coordinate. + * @return + */ + public Set checkForDisconnections() { + if (!this.shouldCheckForDisconnections) { + return null; + } + + if (this.isEmpty()) { + MultiblockRegistry.addDeadController(worldObj, this); + return null; + } + + TileEntity te; + IChunkProvider chunkProvider = worldObj.getChunkProvider(); + + // Invalidate our reference coord, we'll recalculate it shortly + referenceCoord = null; + + // Reset visitations and find the minimum coordinate + Set deadParts = new HashSet(); + CoordTriplet c; + IMultiblockPart referencePart = null; + + int originalSize = connectedParts.size(); + + for (IMultiblockPart part : connectedParts) { + // This happens during chunk unload. + if (!chunkProvider.chunkExists(part.xCoord >> 4, part.zCoord >> 4) || part.isInvalid()) { + deadParts.add(part); + onDetachBlock(part); + continue; + } + + if (worldObj.getTileEntity(part.xCoord, part.yCoord, part.zCoord) != part) { + deadParts.add(part); + onDetachBlock(part); + continue; + } + + part.setUnvisited(); + part.forfeitMultiblockSaveDelegate(); + + c = part.getWorldLocation(); + if (referenceCoord == null) { + referenceCoord = c; + referencePart = part; + } else if (c.compareTo(referenceCoord) < 0) { + referenceCoord = c; + referencePart = part; + } + } + + connectedParts.removeAll(deadParts); + deadParts.clear(); + + if (referencePart == null || isEmpty()) { + // There are no valid parts remaining. The entire multiblock was unloaded during a chunk unload. Halt. + shouldCheckForDisconnections = false; + MultiblockRegistry.addDeadController(worldObj, this); + return null; + } else { + referencePart.becomeMultiblockSaveDelegate(); + } + + // Now visit all connected parts, breadth-first, starting from reference coord's part + IMultiblockPart part; + LinkedList partsToCheck = new LinkedList(); + IMultiblockPart[] nearbyParts = null; + int visitedParts = 0; + + partsToCheck.add(referencePart); + + while (!partsToCheck.isEmpty()) { + part = partsToCheck.removeFirst(); + part.setVisited(); + visitedParts++; + + nearbyParts = part.getNeighboringParts(); // Chunk-safe on server, but not on client + for (IMultiblockPart nearbyPart : nearbyParts) { + // Ignore different machines + if (nearbyPart.getMultiblockController() != this) { + continue; + } + + if (!nearbyPart.isVisited()) { + nearbyPart.setVisited(); + partsToCheck.add(nearbyPart); + } + } + } + + // Finally, remove all parts that remain disconnected. + Set removedParts = new HashSet(); + for (IMultiblockPart orphanCandidate : connectedParts) { + if (!orphanCandidate.isVisited()) { + deadParts.add(orphanCandidate); + orphanCandidate.onOrphaned(this, originalSize, visitedParts); + onDetachBlock(orphanCandidate); + removedParts.add(orphanCandidate); + } + } + + // Trim any blocks that were invalid, or were removed. + connectedParts.removeAll(deadParts); + + // Cleanup. Not necessary, really. + deadParts.clear(); + + // Juuuust in case. + if (referenceCoord == null) { + selectNewReferenceCoord(); + } + + // We've run the checks from here on out. + shouldCheckForDisconnections = false; + + return removedParts; + } + + /** + * Detach all parts. Return a set of all parts which still + * have a valid tile entity. Chunk-safe. + * @return A set of all parts which still have a valid tile entity. + */ + public Set detachAllBlocks() { + if (worldObj == null) { + return new HashSet(); + } + + IChunkProvider chunkProvider = worldObj.getChunkProvider(); + for (IMultiblockPart part : connectedParts) { + if (chunkProvider.chunkExists(part.xCoord >> 4, part.zCoord >> 4)) { + onDetachBlock(part); + } + } + + Set detachedParts = connectedParts; + connectedParts = new HashSet(); + return detachedParts; + } + + /** + * @return True if this multiblock machine is considered assembled and ready to go. + */ + public boolean isAssembled() { + return this.assemblyState == AssemblyState.Assembled; + } + + private void selectNewReferenceCoord() { + IChunkProvider chunkProvider = worldObj.getChunkProvider(); + TileEntity theChosenOne = null; + referenceCoord = null; + + for (IMultiblockPart part : connectedParts) { + if (part.isInvalid() || !chunkProvider.chunkExists(part.xCoord >> 4, part.zCoord >> 4)) { + // Chunk is unloading, skip this coord to prevent chunk thrashing + continue; + } + + if (referenceCoord == null || referenceCoord.compareTo(part.xCoord, part.yCoord, part.zCoord) > 0) { + referenceCoord = part.getWorldLocation(); + theChosenOne = part; + } + } + + if (theChosenOne != null) { + ((IMultiblockPart) theChosenOne).becomeMultiblockSaveDelegate(); + } + } + + /** + * Marks the reference coord dirty & updateable. + * + * On the server, this will mark the for a data-update, so that + * nearby clients will receive an updated description packet from the server + * after a short time. The block's chunk will also be marked dirty and the + * block's chunk will be saved to disk the next time chunks are saved. + * + * On the client, this will mark the block for a rendering update. + */ + protected void markReferenceCoordForUpdate() { + CoordTriplet rc = getReferenceCoord(); + if (worldObj != null && rc != null) { + worldObj.markBlockForUpdate(rc.x, rc.y, rc.z); + } + } + + /** + * Marks the reference coord dirty. + * + * On the server, this marks the reference coord's chunk as dirty; the block (and chunk) + * will be saved to disk the next time chunks are saved. This does NOT mark it dirty for + * a description-packet update. + * + * On the client, does nothing. + * @see MultiblockControllerBase#markReferenceCoordForUpdate() + */ + protected void markReferenceCoordDirty() { + if (worldObj == null || worldObj.isRemote) { + return; + } + + CoordTriplet referenceCoord = getReferenceCoord(); + if (referenceCoord == null) { + return; + } + + TileEntity saveTe = worldObj.getTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z); + worldObj.markTileEntityChunkModified(referenceCoord.x, referenceCoord.y, referenceCoord.z, saveTe); + } + + /* INVENTORY */ + public IInventoryAdapter getInternalInventory() { + return FakeInventoryAdapter.instance(); + } + + @Override + public void markDirty() { + getInternalInventory().markDirty(); + } + + @Override + public final int getSizeInventory() { + return getInternalInventory().getSizeInventory(); + } + + @Override + public final ItemStack getStackInSlot(int slotIndex) { + return getInternalInventory().getStackInSlot(slotIndex); + } + + @Override + public final ItemStack decrStackSize(int slotIndex, int amount) { + return getInternalInventory().decrStackSize(slotIndex, amount); + } + + @Override + public final ItemStack getStackInSlotOnClosing(int slotIndex) { + return getInternalInventory().getStackInSlotOnClosing(slotIndex); + } + + @Override + public final void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + getInternalInventory().setInventorySlotContents(slotIndex, itemstack); + } + + @Override + public final int getInventoryStackLimit() { + return getInternalInventory().getInventoryStackLimit(); + } + + @Override + public final void openInventory() { + getInternalInventory().openInventory(); + } + + @Override + public final void closeInventory() { + getInternalInventory().closeInventory(); + } + + @Override + public final String getInventoryName() { + return getInternalInventory().getInventoryName(); + } + + @Override + public final boolean isUseableByPlayer(EntityPlayer player) { + return getInternalInventory().isUseableByPlayer(player); + } + + @Override + public final boolean hasCustomInventoryName() { + return getInternalInventory().hasCustomInventoryName(); + } + + @Override + public final boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) { + return getInternalInventory().isItemValidForSlot(slotIndex, itemStack); + } + + @Override + public final int[] getAccessibleSlotsFromSide(int side) { + return getInternalInventory().getAccessibleSlotsFromSide(side); + } + + @Override + public final boolean canInsertItem(int slotIndex, ItemStack itemStack, int side) { + return getInternalInventory().canInsertItem(slotIndex, itemStack, side); + } + + @Override + public final boolean canExtractItem(int slotIndex, ItemStack itemStack, int side) { + return getInternalInventory().canExtractItem(slotIndex, itemStack, side); + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + accessHandler.writeData(data); + errorLogic.writeData(data); + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + accessHandler.readData(data); + errorLogic.readData(data); + } +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockEventHandler.java b/src/main/java/forestry/core/multiblock/MultiblockEventHandler.java new file mode 100644 index 000000000..0bb1e7161 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockEventHandler.java @@ -0,0 +1,31 @@ +package forestry.core.multiblock; + +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; + +import net.minecraftforge.event.world.ChunkEvent; +import net.minecraftforge.event.world.WorldEvent; + +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +/** + * In your mod, subscribe this on both the client and server sides side to handle chunk + * load events for your multiblock machines. + * Chunks can load asynchronously in environments like MCPC+, so we cannot + * process any blocks that are in chunks which are still loading. + */ +public class MultiblockEventHandler { + @SubscribeEvent(priority = EventPriority.NORMAL) + public void onChunkLoad(ChunkEvent.Load loadEvent) { + Chunk chunk = loadEvent.getChunk(); + World world = loadEvent.world; + MultiblockRegistry.onChunkLoaded(world, chunk.xPosition, chunk.zPosition); + } + + // Cleanup, for nice memory usageness + @SubscribeEvent(priority = EventPriority.NORMAL) + public void onWorldUnload(WorldEvent.Unload unloadWorldEvent) { + MultiblockRegistry.onWorldUnloaded(unloadWorldEvent.world); + } +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockRegistry.java b/src/main/java/forestry/core/multiblock/MultiblockRegistry.java new file mode 100644 index 000000000..19e689d9d --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockRegistry.java @@ -0,0 +1,128 @@ +package forestry.core.multiblock; + +import java.util.HashMap; +import java.util.Set; + +import net.minecraft.world.World; + +import forestry.core.proxy.Proxies; + +/** + * This is a very static singleton registry class which directs incoming events to sub-objects, which + * actually manage each individual world's multiblocks. + * @author Erogenous Beef + */ +public class MultiblockRegistry { + // World > WorldRegistry map + private static HashMap registries = new HashMap(); + + /** + * Called before Tile Entities are ticked in the world. Do bookkeeping here. + * @param world The world being ticked + */ + public static void tickStart(World world) { + if (registries.containsKey(world)) { + MultiblockWorldRegistry registry = registries.get(world); + registry.processMultiblockChanges(); + registry.tickStart(); + } + } + + /** + * Called when the world has finished loading a chunk. + * @param world The world which has finished loading a chunk + * @param chunkX The X coordinate of the chunk + * @param chunkZ The Z coordinate of the chunk + */ + public static void onChunkLoaded(World world, int chunkX, int chunkZ) { + if (registries.containsKey(world)) { + registries.get(world).onChunkLoaded(chunkX, chunkZ); + } + } + + /** + * Register a new part in the system. The part has been created either through user action or via a chunk loading. + * @param world The world into which this part is loading. + * @param part The part being loaded. + */ + public static void onPartAdded(World world, IMultiblockPart part) { + MultiblockWorldRegistry registry = getOrCreateRegistry(world); + registry.onPartAdded(part); + } + + /** + * Call to remove a part from world lists. + * @param world The world from which a multiblock part is being removed. + * @param part The part being removed. + */ + public static void onPartRemovedFromWorld(World world, IMultiblockPart part) { + if (registries.containsKey(world)) { + registries.get(world).onPartRemovedFromWorld(part); + } + + } + + + /** + * Called whenever a world is unloaded. Unload the relevant registry, if we have one. + * @param world The world being unloaded. + */ + public static void onWorldUnloaded(World world) { + if (registries.containsKey(world)) { + registries.get(world).onWorldUnloaded(); + registries.remove(world); + } + } + + /** + * Call to mark a controller as dirty. Dirty means that parts have + * been added or removed this tick. + * @param world The world containing the multiblock + * @param controller The dirty controller + */ + public static void addDirtyController(World world, MultiblockControllerBase controller) { + if (registries.containsKey(world)) { + registries.get(world).addDirtyController(controller); + } else { + throw new IllegalArgumentException("Adding a dirty controller to a world that has no registered controllers!"); + } + } + + /** + * Call to mark a controller as dead. It should only be marked as dead + * when it has no connected parts. It will be removed after the next world tick. + * @param world The world formerly containing the multiblock + * @param controller The dead controller + */ + public static void addDeadController(World world, MultiblockControllerBase controller) { + if (registries.containsKey(world)) { + registries.get(world).addDeadController(controller); + } else { + Proxies.log.warning("Controller %d in world %s marked as dead, but that world is not tracked! Controller is being ignored.", controller.hashCode(), world); + } + } + + /** + * @param world The world whose controllers you wish to retrieve. + * @return An unmodifiable set of controllers active in the given world, or null if there are none. + */ + public static Set getControllersFromWorld(World world) { + if (registries.containsKey(world)) { + return registries.get(world).getControllers(); + } + return null; + } + + /// *** PRIVATE HELPERS *** /// + + private static MultiblockWorldRegistry getOrCreateRegistry(World world) { + if (registries.containsKey(world)) { + return registries.get(world); + } else { + MultiblockWorldRegistry newRegistry = new MultiblockWorldRegistry(world); + registries.put(world, newRegistry); + return newRegistry; + } + } + +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockServerTickHandler.java b/src/main/java/forestry/core/multiblock/MultiblockServerTickHandler.java new file mode 100644 index 000000000..2b63b4690 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockServerTickHandler.java @@ -0,0 +1,23 @@ +package forestry.core.multiblock; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; + +/** + * This is a generic multiblock tick handler. If you are using this code on your own, + * you will need to register this with the Forge TickRegistry on both the + * client AND server sides. + * Note that different types of ticks run on different parts of the system. + * CLIENT ticks only run on the client, at the start/end of each game loop. + * SERVER and WORLD ticks only run on the server. + * WORLDLOAD ticks run only on the server, and only when worlds are loaded. + */ +public class MultiblockServerTickHandler { + + @SubscribeEvent + public void onWorldTick(TickEvent.WorldTickEvent event) { + if (event.phase == TickEvent.Phase.START) { + MultiblockRegistry.tickStart(event.world); + } + } +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockTileEntityBase.java b/src/main/java/forestry/core/multiblock/MultiblockTileEntityBase.java new file mode 100644 index 000000000..74398ba5f --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockTileEntityBase.java @@ -0,0 +1,520 @@ +package forestry.core.multiblock; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.chunk.IChunkProvider; + +import com.mojang.authlib.GameProfile; + +import forestry.core.config.Defaults; +import forestry.core.interfaces.IFilterSlotDelegate; +import forestry.core.interfaces.IOwnable; +import forestry.core.inventory.FakeInventoryAdapter; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.proxy.Proxies; +import forestry.core.utils.PlayerUtil; + +/** + * Base logic class for Multiblock-connected tile entities. Most multiblock machines + * should derive from this and implement their game logic in certain abstract methods. + */ +public abstract class MultiblockTileEntityBase extends IMultiblockPart implements ISidedInventory, IFilterSlotDelegate, IOwnable { + private MultiblockControllerBase controller; + private boolean visited; + + private boolean saveMultiblockData; + private NBTTagCompound cachedMultiblockData; + private boolean paused; + + private GameProfile owner; + + public MultiblockTileEntityBase() { + super(); + controller = null; + visited = false; + saveMultiblockData = false; + paused = false; + cachedMultiblockData = null; + } + + ///// Multiblock Connection Base Logic + @Override + public final Set attachToNeighbors() { + Set controllers = null; + MultiblockControllerBase bestController = null; + + // Look for a compatible controller in our neighboring parts. + IMultiblockPart[] partsToCheck = getNeighboringParts(); + for (IMultiblockPart neighborPart : partsToCheck) { + if (neighborPart.isConnected()) { + MultiblockControllerBase candidate = neighborPart.getMultiblockController(); + if (!candidate.getClass().equals(this.getMultiblockControllerType())) { + // Skip multiblocks with incompatible types + continue; + } + + if (controllers == null) { + controllers = new HashSet(); + bestController = candidate; + } else if (!controllers.contains(candidate) && candidate.shouldConsume(bestController)) { + bestController = candidate; + } + + controllers.add(candidate); + } + } + + // If we've located a valid neighboring controller, attach to it. + if (bestController != null) { + // attachBlock will call onAttached, which will set the controller. + this.controller = bestController; + bestController.attachBlock(this); + } + + return controllers; + } + + @Override + public final void assertDetached() { + if (this.controller != null) { + Proxies.log.info("[assert] Part @ (%d, %d, %d) should be detached already, but detected that it was not. This is not a fatal error, and will be repaired, but is unusual.", xCoord, yCoord, zCoord); + this.controller = null; + } + } + + ///// Overrides from base TileEntity methods + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + + // We can't directly initialize a multiblock controller yet, so we cache the data here until + // we receive a validate() call, which creates the controller and hands off the cached data. + if (data.hasKey("multiblockData")) { + this.cachedMultiblockData = data.getCompoundTag("multiblockData"); + } + + if (data.hasKey("owner")) { + owner = NBTUtil.func_152459_a(data.getCompoundTag("owner")); + } + + getInternalInventory().readFromNBT(data); + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + + if (isMultiblockSaveDelegate() && isConnected()) { + NBTTagCompound multiblockData = new NBTTagCompound(); + this.controller.writeToNBT(multiblockData); + data.setTag("multiblockData", multiblockData); + } + + if (this.owner != null) { + NBTTagCompound nbt = new NBTTagCompound(); + NBTUtil.func_152460_a(nbt, owner); + data.setTag("owner", nbt); + } + + getInternalInventory().writeToNBT(data); + } + + /** + * Generally, TileEntities that are part of a multiblock should not subscribe to updates + * from the main game loop. Instead, you should have lists of TileEntities which need to + * be notified during an update() in your Controller and perform callbacks from there. + * @see net.minecraft.tileentity.TileEntity#canUpdate() + */ + @Override + public boolean canUpdate() { + return false; + } + + /** + * Called when a block is removed by game actions, such as a player breaking the block + * or the block being changed into another block. + * @see net.minecraft.tileentity.TileEntity#invalidate() + */ + @Override + public final void invalidate() { + super.invalidate(); + detachSelf(false); + } + + /** + * Called from Minecraft's tile entity loop, after all tile entities have been ticked, + * as the chunk in which this tile entity is contained is unloading. + * Happens before the Forge TickEnd event. + * @see net.minecraft.tileentity.TileEntity#onChunkUnload() + */ + @Override + public final void onChunkUnload() { + super.onChunkUnload(); + detachSelf(true); + } + + /** + * This is called when a block is being marked as valid by the chunk, but has not yet fully + * been placed into the world's TileEntity cache. this.worldObj, xCoord, yCoord and zCoord have + * been initialized, but any attempts to read data about the world can cause infinite loops - + * if you call getTileEntity on this TileEntity's coordinate from within validate(), you will + * blow your call stack. + * + * TL;DR: Here there be dragons. + * @see net.minecraft.tileentity.TileEntity#validate() + */ + @Override + public final void validate() { + super.validate(); + MultiblockRegistry.onPartAdded(this.worldObj, this); + } + + // Network Communication + @Override + public final Packet getDescriptionPacket() { + NBTTagCompound packetData = new NBTTagCompound(); + encodeDescriptionPacket(packetData); + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, packetData); + } + + @Override + public final void onDataPacket(NetworkManager network, S35PacketUpdateTileEntity packet) { + decodeDescriptionPacket(packet.func_148857_g()); + } + + ///// Things to override in most implementations (IMultiblockPart) + + /** + * Override this to easily modify the description packet's data without having + * to worry about sending the packet itself. + * Decode this data in decodeDescriptionPacket. + * @param packetData An NBT compound tag into which you should write your custom description data. + * @see forestry.core.multiblock.MultiblockTileEntityBase#decodeDescriptionPacket(NBTTagCompound) + */ + protected void encodeDescriptionPacket(NBTTagCompound packetData) { + if (this.isMultiblockSaveDelegate() && isConnected()) { + NBTTagCompound tag = new NBTTagCompound(); + getMultiblockController().formatDescriptionPacket(tag); + packetData.setTag("multiblockData", tag); + } + } + + /** + * Override this to easily read in data from a TileEntity's description packet. + * Encoded in encodeDescriptionPacket. + * @param packetData The NBT data from the tile entity's description packet. + * @see forestry.core.multiblock.MultiblockTileEntityBase#encodeDescriptionPacket(NBTTagCompound) + */ + protected void decodeDescriptionPacket(NBTTagCompound packetData) { + if (packetData.hasKey("multiblockData")) { + NBTTagCompound tag = packetData.getCompoundTag("multiblockData"); + if (isConnected()) { + getMultiblockController().decodeDescriptionPacket(tag); + } else { + // This part hasn't been added to a machine yet, so cache the data. + this.cachedMultiblockData = tag; + } + } + } + + @Override + public final boolean hasMultiblockSaveData() { + return this.cachedMultiblockData != null; + } + + @Override + public final NBTTagCompound getMultiblockSaveData() { + return this.cachedMultiblockData; + } + + @Override + public final void onMultiblockDataAssimilated() { + this.cachedMultiblockData = null; + } + + ///// Game logic callbacks (IMultiblockPart) + + @Override + public abstract void onMachineAssembled(MultiblockControllerBase multiblockControllerBase); + + @Override + public abstract void onMachineBroken(); + + @Override + public abstract void onMachineActivated(); + + @Override + public abstract void onMachineDeactivated(); + + ///// Miscellaneous multiblock-assembly callbacks and support methods (IMultiblockPart) + + @Override + public final boolean isConnected() { + return (controller != null); + } + + @Override + public final MultiblockControllerBase getMultiblockController() { + return controller; + } + + @Override + public final CoordTriplet getWorldLocation() { + return new CoordTriplet(this.xCoord, this.yCoord, this.zCoord); + } + + @Override + public final void becomeMultiblockSaveDelegate() { + this.saveMultiblockData = true; + } + + @Override + public final void forfeitMultiblockSaveDelegate() { + this.saveMultiblockData = false; + } + + @Override + public final boolean isMultiblockSaveDelegate() { + return this.saveMultiblockData; + } + + @Override + public final void setUnvisited() { + this.visited = false; + } + + @Override + public final void setVisited() { + this.visited = true; + } + + @Override + public final boolean isVisited() { + return this.visited; + } + + @Override + public final void onAssimilated(MultiblockControllerBase newController) { + assert (this.controller != newController); + this.controller = newController; + } + + @Override + public void onAttached(MultiblockControllerBase newController) { + this.controller = newController; + } + + @Override + public final void onDetached(MultiblockControllerBase oldController) { + this.controller = null; + } + + @Override + public abstract MultiblockControllerBase createNewMultiblock(); + + @Override + public final IMultiblockPart[] getNeighboringParts() { + CoordTriplet[] neighbors = new CoordTriplet[]{ + new CoordTriplet(this.xCoord - 1, this.yCoord, this.zCoord), + new CoordTriplet(this.xCoord, this.yCoord - 1, this.zCoord), + new CoordTriplet(this.xCoord, this.yCoord, this.zCoord - 1), + new CoordTriplet(this.xCoord, this.yCoord, this.zCoord + 1), + new CoordTriplet(this.xCoord, this.yCoord + 1, this.zCoord), + new CoordTriplet(this.xCoord + 1, this.yCoord, this.zCoord) + }; + + TileEntity te; + List neighborParts = new ArrayList(); + IChunkProvider chunkProvider = worldObj.getChunkProvider(); + for (CoordTriplet neighbor : neighbors) { + if (!chunkProvider.chunkExists(neighbor.getChunkX(), neighbor.getChunkZ())) { + // Chunk not loaded, skip it. + continue; + } + + te = this.worldObj.getTileEntity(neighbor.x, neighbor.y, neighbor.z); + if (te instanceof IMultiblockPart) { + neighborParts.add((IMultiblockPart) te); + } + } + IMultiblockPart[] tmp = new IMultiblockPart[neighborParts.size()]; + return neighborParts.toArray(tmp); + } + + @Override + public final void onOrphaned(MultiblockControllerBase controller, int oldSize, int newSize) { + this.markDirty(); + worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this); + } + + //// Helper functions for notifying neighboring blocks + public void notifyNeighborsOfBlockChange() { + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockType()); + } + + protected void notifyNeighborsOfTileChange() { + worldObj.func_147453_f(xCoord, yCoord, zCoord, getBlockType()); + } + + ///// Private/Protected Logic Helpers + /* + * Detaches this block from its controller. Calls detachBlock() and clears the controller member. + */ + protected void detachSelf(boolean chunkUnloading) { + if (this.controller != null) { + // Clean part out of controller + this.controller.detachBlock(this, chunkUnloading); + + // The above should call onDetached, but, just in case... + this.controller = null; + } + + // Clean part out of lists in the registry + MultiblockRegistry.onPartRemovedFromWorld(worldObj, this); + } + + /* IOwnable */ + @Override + public boolean isOwned() { + return owner != null; + } + + @Override + public GameProfile getOwner() { + return owner; + } + + @Override + public void setOwner(GameProfile owner) { + this.owner = owner; + } + + @Override + public boolean isOwner(EntityPlayer player) { + return PlayerUtil.isSameGameProfile(owner, player.getGameProfile()); + } + + /* INVENTORY */ + public IInventoryAdapter getInternalInventory() { + return FakeInventoryAdapter.instance(); + } + + public boolean allowsAutomation() { + return false; + } + + @Override + public final int getSizeInventory() { + return getInternalInventory().getSizeInventory(); + } + + @Override + public final ItemStack getStackInSlot(int slotIndex) { + return getInternalInventory().getStackInSlot(slotIndex); + } + + @Override + public final ItemStack decrStackSize(int slotIndex, int amount) { + return getInternalInventory().decrStackSize(slotIndex, amount); + } + + @Override + public final ItemStack getStackInSlotOnClosing(int slotIndex) { + return getInternalInventory().getStackInSlotOnClosing(slotIndex); + } + + @Override + public final void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + getInternalInventory().setInventorySlotContents(slotIndex, itemstack); + } + + @Override + public final int getInventoryStackLimit() { + return getInternalInventory().getInventoryStackLimit(); + } + + @Override + public final void openInventory() { + getInternalInventory().openInventory(); + } + + @Override + public final void closeInventory() { + getInternalInventory().closeInventory(); + } + + @Override + public final String getInventoryName() { + return getInternalInventory().getInventoryName(); + } + + @Override + public final boolean isUseableByPlayer(EntityPlayer player) { + return getInternalInventory().isUseableByPlayer(player); + } + + @Override + public final boolean hasCustomInventoryName() { + return getInternalInventory().hasCustomInventoryName(); + } + + @Override + public final boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) { + return getInternalInventory().isItemValidForSlot(slotIndex, itemStack); + } + + @Override + public final int[] getAccessibleSlotsFromSide(int side) { + if (allowsAutomation()) { + return getInternalInventory().getAccessibleSlotsFromSide(side); + } else { + return Defaults.SLOTS_NONE; + } + } + + @Override + public final boolean canInsertItem(int slotIndex, ItemStack itemStack, int side) { + if (allowsAutomation()) { + return getInternalInventory().canInsertItem(slotIndex, itemStack, side); + } else { + return false; + } + } + + @Override + public final boolean canExtractItem(int slotIndex, ItemStack itemStack, int side) { + if (allowsAutomation()) { + return getInternalInventory().canExtractItem(slotIndex, itemStack, side); + } else { + return false; + } + } + + @Override + public final boolean canSlotAccept(int slotIndex, ItemStack itemStack) { + return getInternalInventory().canSlotAccept(slotIndex, itemStack); + } + + @Override + public final boolean isLocked(int slotIndex) { + return getInternalInventory().isLocked(slotIndex); + } + + + public void openGui(EntityPlayer player) { + + } +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockValidationException.java b/src/main/java/forestry/core/multiblock/MultiblockValidationException.java new file mode 100644 index 000000000..b0cda81f1 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockValidationException.java @@ -0,0 +1,13 @@ +package forestry.core.multiblock; + +/** + * An exception thrown when trying to validate a multiblock. Requires a string describing why the multiblock + * could not assemble. + * @author Erogenous Beef + */ +public class MultiblockValidationException extends Exception { + + public MultiblockValidationException(String reason) { + super(reason); + } +} diff --git a/src/main/java/forestry/core/multiblock/MultiblockWorldRegistry.java b/src/main/java/forestry/core/multiblock/MultiblockWorldRegistry.java new file mode 100644 index 000000000..62a12ecc2 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/MultiblockWorldRegistry.java @@ -0,0 +1,415 @@ +package forestry.core.multiblock; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; + +import forestry.core.proxy.Proxies; + +/** + * This class manages all the multiblock controllers that exist in a given world, + * either client- or server-side. + * You must create different registries for server and client worlds. + * + * @author Erogenous Beef + */ +public class MultiblockWorldRegistry { + + private World worldObj; + + private final Set controllers; // Active controllers + private final Set dirtyControllers; // Controllers whose parts lists have changed + private final Set deadControllers; // Controllers which are empty + + // A list of orphan parts - parts which currently have no master, but should seek one this tick + // Indexed by the hashed chunk coordinate + // This can be added-to asynchronously via chunk loads! + private Set orphanedParts; + + // A list of parts which have been detached during internal operations + private final Set detachedParts; + + // A list of parts whose chunks have not yet finished loading + // They will be added to the orphan list when they are finished loading. + // Indexed by the hashed chunk coordinate + // This can be added-to asynchronously via chunk loads! + private final HashMap> partsAwaitingChunkLoad; + + // Mutexes to protect lists which may be changed due to asynchronous events, such as chunk loads + private final Object partsAwaitingChunkLoadMutex; + private final Object orphanedPartsMutex; + + public MultiblockWorldRegistry(World world) { + worldObj = world; + + controllers = new HashSet(); + deadControllers = new HashSet(); + dirtyControllers = new HashSet(); + + detachedParts = new HashSet(); + orphanedParts = new HashSet(); + + partsAwaitingChunkLoad = new HashMap>(); + partsAwaitingChunkLoadMutex = new Object(); + orphanedPartsMutex = new Object(); + } + + /** + * Called before Tile Entities are ticked in the world. Run game logic. + */ + public void tickStart() { + if (controllers.size() > 0) { + for (MultiblockControllerBase controller : controllers) { + if (controller.worldObj == worldObj && controller.worldObj.isRemote == worldObj.isRemote) { + if (controller.isEmpty()) { + // This happens on the server when the user breaks the last block. It's fine. + // Mark 'er dead and move on. + deadControllers.add(controller); + } else { + // Run the game logic for this world + controller.updateMultiblockEntity(); + } + } + } + } + } + + /** + * Called prior to processing multiblock controllers. Do bookkeeping. + */ + public void processMultiblockChanges() { + IChunkProvider chunkProvider = worldObj.getChunkProvider(); + CoordTriplet coord; + + // Merge pools - sets of adjacent machines which should be merged later on in processing + List> mergePools = null; + if (orphanedParts.size() > 0) { + Set orphansToProcess = null; + + // Keep the synchronized block small. We can't iterate over orphanedParts directly + // because the client does not know which chunks are actually loaded, so attachToNeighbors() + // is not chunk-safe on the client, because Minecraft is stupid. + // It's possible to polyfill this, but the polyfill is too slow for comfort. + synchronized (orphanedPartsMutex) { + if (orphanedParts.size() > 0) { + orphansToProcess = orphanedParts; + orphanedParts = new HashSet(); + } + } + + if (orphansToProcess != null && orphansToProcess.size() > 0) { + Set compatibleControllers; + + // Process orphaned blocks + // These are blocks that exist in a valid chunk and require a controller + for (IMultiblockPart orphan : orphansToProcess) { + coord = orphan.getWorldLocation(); + if (!chunkProvider.chunkExists(coord.getChunkX(), coord.getChunkZ())) { + continue; + } + + // This can occur on slow machines. + if (orphan.isInvalid()) { + continue; + } + + if (worldObj.getTileEntity(coord.x, coord.y, coord.z) != orphan) { + // This block has been replaced by another. + continue; + } + + // THIS IS THE ONLY PLACE WHERE PARTS ATTACH TO MACHINES + // Try to attach to a neighbor's master controller + compatibleControllers = orphan.attachToNeighbors(); + if (compatibleControllers == null) { + // FOREVER ALONE! Create and register a new controller. + // THIS IS THE ONLY PLACE WHERE NEW CONTROLLERS ARE CREATED. + MultiblockControllerBase newController = orphan.createNewMultiblock(); + newController.attachBlock(orphan); + this.controllers.add(newController); + } else if (compatibleControllers.size() > 1) { + if (mergePools == null) { + mergePools = new ArrayList>(); + } + + // THIS IS THE ONLY PLACE WHERE MERGES ARE DETECTED + // Multiple compatible controllers indicates an impending merge. + // Locate the appropriate merge pool(s) + boolean hasAddedToPool = false; + List> candidatePools = new ArrayList>(); + for (Set candidatePool : mergePools) { + if (!Collections.disjoint(candidatePool, compatibleControllers)) { + // They share at least one element, so that means they will all touch after the merge + candidatePools.add(candidatePool); + } + } + + if (candidatePools.size() <= 0) { + // No pools nearby, create a new merge pool + mergePools.add(compatibleControllers); + } else if (candidatePools.size() == 1) { + // Only one pool nearby, simply add to that one + candidatePools.get(0).addAll(compatibleControllers); + } else { + // Multiple pools- merge into one, then add the compatible controllers + Set masterPool = candidatePools.get(0); + Set consumedPool; + for (int i = 1; i < candidatePools.size(); i++) { + consumedPool = candidatePools.get(i); + masterPool.addAll(consumedPool); + mergePools.remove(consumedPool); + } + masterPool.addAll(compatibleControllers); + } + } + } + } + } + + if (mergePools != null && mergePools.size() > 0) { + // Process merges - any machines that have been marked for merge should be merged + // into the "master" machine. + // To do this, we combine lists of machines that are touching one another and therefore + // should voltron the fuck up. + for (Set mergePool : mergePools) { + // Search for the new master machine, which will take over all the blocks contained in the other machines + MultiblockControllerBase newMaster = null; + for (MultiblockControllerBase controller : mergePool) { + if (newMaster == null || controller.shouldConsume(newMaster)) { + newMaster = controller; + } + } + + if (newMaster == null) { + Proxies.log.severe("Multiblock system checked a merge pool of size %d, found no master candidates. This should never happen.", mergePool.size()); + } else { + // Merge all the other machines into the master machine, then unregister them + addDirtyController(newMaster); + for (MultiblockControllerBase controller : mergePool) { + if (controller != newMaster) { + newMaster.assimilate(controller); + addDeadController(controller); + addDirtyController(newMaster); + } + } + } + } + } + + // Process splits and assembly + // Any controllers which have had parts removed must be checked to see if some parts are no longer + // physically connected to their master. + if (dirtyControllers.size() > 0) { + Set newlyDetachedParts = null; + for (MultiblockControllerBase controller : dirtyControllers) { + // Tell the machine to check if any parts are disconnected. + // It should return a set of parts which are no longer connected. + // POSTCONDITION: The controller must have informed those parts that + // they are no longer connected to this machine. + newlyDetachedParts = controller.checkForDisconnections(); + + if (!controller.isEmpty()) { + controller.recalculateMinMaxCoords(); + controller.checkIfMachineIsWhole(); + } else { + addDeadController(controller); + } + + if (newlyDetachedParts != null && newlyDetachedParts.size() > 0) { + // Controller has shed some parts - add them to the detached list for delayed processing + detachedParts.addAll(newlyDetachedParts); + } + } + + dirtyControllers.clear(); + } + + // Unregister dead controllers + if (deadControllers.size() > 0) { + for (MultiblockControllerBase controller : deadControllers) { + // Go through any controllers which have marked themselves as potentially dead. + // Validate that they are empty/dead, then unregister them. + if (!controller.isEmpty()) { + Proxies.log.severe("Found a non-empty controller. Forcing it to shed its blocks and die. This should never happen!"); + detachedParts.addAll(controller.detachAllBlocks()); + } + + // THIS IS THE ONLY PLACE WHERE CONTROLLERS ARE UNREGISTERED. + this.controllers.remove(controller); + } + + deadControllers.clear(); + } + + // Process detached blocks + // Any blocks which have been detached this tick should be moved to the orphaned + // list, and will be checked next tick to see if their chunk is still loaded. + for (IMultiblockPart part : detachedParts) { + // Ensure parts know they're detached + part.assertDetached(); + } + + addAllOrphanedPartsThreadsafe(detachedParts); + detachedParts.clear(); + } + + /** + * Called when a multiblock part is added to the world, either via chunk-load or user action. + * If its chunk is loaded, it will be processed during the next tick. + * If the chunk is not loaded, it will be added to a list of objects waiting for a chunkload. + * @param part The part which is being added to this world. + */ + public void onPartAdded(IMultiblockPart part) { + CoordTriplet worldLocation = part.getWorldLocation(); + + if (!worldObj.getChunkProvider().chunkExists(worldLocation.getChunkX(), worldLocation.getChunkZ())) { + // Part goes into the waiting-for-chunk-load list + Set partSet; + long chunkHash = worldLocation.getChunkXZHash(); + synchronized (partsAwaitingChunkLoadMutex) { + if (!partsAwaitingChunkLoad.containsKey(chunkHash)) { + partSet = new HashSet(); + partsAwaitingChunkLoad.put(chunkHash, partSet); + } else { + partSet = partsAwaitingChunkLoad.get(chunkHash); + } + + partSet.add(part); + } + } else { + // Part goes into the orphan queue, to be checked this tick + addOrphanedPartThreadsafe(part); + } + } + + /** + * Called when a part is removed from the world, via user action or via chunk unloads. + * This part is removed from any lists in which it may be, and its machine is marked for recalculation. + * @param part The part which is being removed. + */ + public void onPartRemovedFromWorld(IMultiblockPart part) { + CoordTriplet coord = part.getWorldLocation(); + if (coord != null) { + long hash = coord.getChunkXZHash(); + + if (partsAwaitingChunkLoad.containsKey(hash)) { + synchronized (partsAwaitingChunkLoadMutex) { + if (partsAwaitingChunkLoad.containsKey(hash)) { + partsAwaitingChunkLoad.get(hash).remove(part); + if (partsAwaitingChunkLoad.get(hash).size() <= 0) { + partsAwaitingChunkLoad.remove(hash); + } + } + } + } + } + + detachedParts.remove(part); + if (orphanedParts.contains(part)) { + synchronized (orphanedPartsMutex) { + orphanedParts.remove(part); + } + } + + part.assertDetached(); + } + + /** + * Called when the world which this World Registry represents is fully unloaded from the system. + * Does some housekeeping just to be nice. + */ + public void onWorldUnloaded() { + controllers.clear(); + deadControllers.clear(); + dirtyControllers.clear(); + + detachedParts.clear(); + + synchronized (partsAwaitingChunkLoadMutex) { + partsAwaitingChunkLoad.clear(); + } + + synchronized (orphanedPartsMutex) { + orphanedParts.clear(); + } + + worldObj = null; + } + + /** + * Called when a chunk has finished loading. Adds all of the parts which are awaiting + * load to the list of parts which are orphans and therefore will be added to machines + * after the next world tick. + * + * @param chunkX Chunk X coordinate (world coordate >> 4) of the chunk that was loaded + * @param chunkZ Chunk Z coordinate (world coordate >> 4) of the chunk that was loaded + */ + public void onChunkLoaded(int chunkX, int chunkZ) { + long chunkHash = ChunkCoordIntPair.chunkXZ2Int(chunkX, chunkZ); + if (partsAwaitingChunkLoad.containsKey(chunkHash)) { + synchronized (partsAwaitingChunkLoadMutex) { + if (partsAwaitingChunkLoad.containsKey(chunkHash)) { + addAllOrphanedPartsThreadsafe(partsAwaitingChunkLoad.get(chunkHash)); + partsAwaitingChunkLoad.remove(chunkHash); + } + } + } + } + + /** + * Registers a controller as dead. It will be cleaned up at the end of the next world tick. + * Note that a controller must shed all of its blocks before being marked as dead, or the system + * will complain at you. + * + * @param deadController The controller which is dead. + */ + public void addDeadController(MultiblockControllerBase deadController) { + this.deadControllers.add(deadController); + } + + /** + * Registers a controller as dirty - its list of attached blocks has changed, and it + * must be re-checked for assembly and, possibly, for orphans. + * + * @param dirtyController The dirty controller. + */ + public void addDirtyController(MultiblockControllerBase dirtyController) { + this.dirtyControllers.add(dirtyController); + } + + /** + * Use this only if you know what you're doing. You should rarely need to iterate + * over all controllers in a world! + * + * @return An (unmodifiable) set of controllers which are active in this world. + */ + public Set getControllers() { + return Collections.unmodifiableSet(controllers); + } + + /* *** PRIVATE HELPERS *** */ + + private void addOrphanedPartThreadsafe(IMultiblockPart part) { + synchronized (orphanedPartsMutex) { + orphanedParts.add(part); + } + } + + private void addAllOrphanedPartsThreadsafe(Collection parts) { + synchronized (orphanedPartsMutex) { + orphanedParts.addAll(parts); + } + } + + private String clientOrServer() { + return worldObj.isRemote ? "CLIENT" : "SERVER"; + } +} diff --git a/src/main/java/forestry/core/multiblock/rectangular/PartPosition.java b/src/main/java/forestry/core/multiblock/rectangular/PartPosition.java new file mode 100644 index 000000000..7b502f386 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/rectangular/PartPosition.java @@ -0,0 +1,28 @@ +package forestry.core.multiblock.rectangular; + +public enum PartPosition { + Unknown, + Interior, + FrameCorner, + Frame, + TopFace, + BottomFace, + NorthFace, + SouthFace, + EastFace, + WestFace; + + public static boolean isFace(PartPosition position) { + switch (position) { + case TopFace: + case BottomFace: + case NorthFace: + case SouthFace: + case EastFace: + case WestFace: + return true; + default: + return false; + } + } +} diff --git a/src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockControllerBase.java b/src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockControllerBase.java new file mode 100644 index 000000000..7331fe878 --- /dev/null +++ b/src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockControllerBase.java @@ -0,0 +1,124 @@ +package forestry.core.multiblock.rectangular; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +import forestry.core.multiblock.CoordTriplet; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockValidationException; + +public abstract class RectangularMultiblockControllerBase extends MultiblockControllerBase { + + protected RectangularMultiblockControllerBase(World world) { + super(world); + } + + @Override + protected void isMachineWhole() throws MultiblockValidationException { + int minX = getMinimumXSize(); + int minY = getMinimumYSize(); + int minZ = getMinimumZSize(); + + if (connectedParts.size() < getMinimumNumberOfBlocksForAssembledMachine()) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.small", minX, minY, minZ)); + } + + CoordTriplet maximumCoord = getMaximumCoord(); + CoordTriplet minimumCoord = getMinimumCoord(); + + // Quickly check for exceeded dimensions + int deltaX = maximumCoord.x - minimumCoord.x + 1; + int deltaY = maximumCoord.y - minimumCoord.y + 1; + int deltaZ = maximumCoord.z - minimumCoord.z + 1; + + int maxX = getMaximumXSize(); + int maxY = getMaximumYSize(); + int maxZ = getMaximumZSize(); + + if (maxX > 0 && deltaX > maxX) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.large.x", maxX)); + } + if (maxY > 0 && deltaY > maxY) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.large.y", maxY)); + } + if (maxZ > 0 && deltaZ > maxZ) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.large.z", maxZ)); + } + if (deltaX < minX) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.small.x", minX)); + } + if (deltaY < minY) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.small.y", minY)); + } + if (deltaZ < minZ) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.small.z", minZ)); + } + + // Now we run a simple check on each block within that volume. + // Any block deviating = NO DEAL SIR + TileEntity te; + RectangularMultiblockTileEntityBase part; + Class myClass = this.getClass(); + + for (int x = minimumCoord.x; x <= maximumCoord.x; x++) { + for (int y = minimumCoord.y; y <= maximumCoord.y; y++) { + for (int z = minimumCoord.z; z <= maximumCoord.z; z++) { + // Okay, figure out what sort of block this should be. + + te = this.worldObj.getTileEntity(x, y, z); + if (te instanceof RectangularMultiblockTileEntityBase) { + part = (RectangularMultiblockTileEntityBase) te; + + // Ensure this part should actually be allowed within a cube of this controller's type + if (!myClass.equals(part.getMultiblockControllerType())) { + throw new MultiblockValidationException(StatCollector.translateToLocalFormatted("for.multiblock.error.invalid.part", x, y, z, myClass.getSimpleName())); + } + } else { + // This is permitted so that we can incorporate certain non-multiblock parts inside interiors + part = null; + } + + // Validate block type against both part-level and material-level validators. + int extremes = 0; + if (x == minimumCoord.x) { + extremes++; + } + if (y == minimumCoord.y) { + extremes++; + } + if (z == minimumCoord.z) { + extremes++; + } + + if (x == maximumCoord.x) { + extremes++; + } + if (y == maximumCoord.y) { + extremes++; + } + if (z == maximumCoord.z) { + extremes++; + } + + if (extremes >= 1) { + // Side + int exteriorLevel = y - minimumCoord.y; + if (part != null) { + part.isGoodForExteriorLevel(exteriorLevel); + } else { + isBlockGoodForExteriorLevel(exteriorLevel, this.worldObj, x, y, z); + } + } else { + if (part != null) { + part.isGoodForInterior(); + } else { + isBlockGoodForInterior(this.worldObj, x, y, z); + } + } + } + } + } + } + +} diff --git a/src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockTileEntityBase.java b/src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockTileEntityBase.java new file mode 100644 index 000000000..0bb463c7b --- /dev/null +++ b/src/main/java/forestry/core/multiblock/rectangular/RectangularMultiblockTileEntityBase.java @@ -0,0 +1,105 @@ +package forestry.core.multiblock.rectangular; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.core.multiblock.CoordTriplet; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockTileEntityBase; +import forestry.core.multiblock.MultiblockValidationException; + +public abstract class RectangularMultiblockTileEntityBase extends MultiblockTileEntityBase { + + PartPosition position; + ForgeDirection outwards; + + public RectangularMultiblockTileEntityBase() { + super(); + + position = PartPosition.Unknown; + outwards = ForgeDirection.UNKNOWN; + } + + // Positional Data + public ForgeDirection getOutwardsDir() { + return outwards; + } + + public PartPosition getPartPosition() { + return position; + } + + // Handlers from MultiblockTileEntityBase + @Override + public void onAttached(MultiblockControllerBase newController) { + super.onAttached(newController); + recalculateOutwardsDirection(newController.getMinimumCoord(), newController.getMaximumCoord()); + } + + + @Override + public void onMachineAssembled(MultiblockControllerBase controller) { + CoordTriplet maxCoord = controller.getMaximumCoord(); + CoordTriplet minCoord = controller.getMinimumCoord(); + + // Discover where I am on the reactor + recalculateOutwardsDirection(minCoord, maxCoord); + } + + @Override + public void onMachineBroken() { + position = PartPosition.Unknown; + outwards = ForgeDirection.UNKNOWN; + } + + // Positional helpers + public void recalculateOutwardsDirection(CoordTriplet minCoord, CoordTriplet maxCoord) { + outwards = ForgeDirection.UNKNOWN; + position = PartPosition.Unknown; + + int facesMatching = 0; + if (maxCoord.x == this.xCoord || minCoord.x == this.xCoord) { + facesMatching++; + } + if (maxCoord.y == this.yCoord || minCoord.y == this.yCoord) { + facesMatching++; + } + if (maxCoord.z == this.zCoord || minCoord.z == this.zCoord) { + facesMatching++; + } + + if (facesMatching <= 0) { + position = PartPosition.Interior; + } else if (facesMatching >= 3) { + position = PartPosition.FrameCorner; + } else if (facesMatching == 2) { + position = PartPosition.Frame; + } else { + // 1 face matches + if (maxCoord.x == this.xCoord) { + position = PartPosition.EastFace; + outwards = ForgeDirection.EAST; + } else if (minCoord.x == this.xCoord) { + position = PartPosition.WestFace; + outwards = ForgeDirection.WEST; + } else if (maxCoord.z == this.zCoord) { + position = PartPosition.SouthFace; + outwards = ForgeDirection.SOUTH; + } else if (minCoord.z == this.zCoord) { + position = PartPosition.NorthFace; + outwards = ForgeDirection.NORTH; + } else if (maxCoord.y == this.yCoord) { + position = PartPosition.TopFace; + outwards = ForgeDirection.UP; + } else { + position = PartPosition.BottomFace; + outwards = ForgeDirection.DOWN; + } + } + } + + ///// Validation Helpers (IMultiblockPart) + + public abstract void isGoodForExteriorLevel(int level) throws MultiblockValidationException; + + public abstract void isGoodForInterior() throws MultiblockValidationException; +} diff --git a/src/main/java/forestry/core/network/ILocatedPacket.java b/src/main/java/forestry/core/network/ILocatedPacket.java index a8bcd8920..73c8536ba 100755 --- a/src/main/java/forestry/core/network/ILocatedPacket.java +++ b/src/main/java/forestry/core/network/ILocatedPacket.java @@ -17,6 +17,8 @@ public interface ILocatedPacket { TileEntity getTarget(World world); int getPosX(); + int getPosY(); + int getPosZ(); } diff --git a/src/main/java/forestry/apiculture/gadgets/TileAlvearyFan.java b/src/main/java/forestry/core/network/IStreamableGui.java old mode 100755 new mode 100644 similarity index 63% rename from src/main/java/forestry/apiculture/gadgets/TileAlvearyFan.java rename to src/main/java/forestry/core/network/IStreamableGui.java index 30232fe34..89ebfdd39 --- a/src/main/java/forestry/apiculture/gadgets/TileAlvearyFan.java +++ b/src/main/java/forestry/core/network/IStreamableGui.java @@ -1,22 +1,23 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.apiculture.gadgets; - -public class TileAlvearyFan extends TileAlvearyClimatiser { - - /* CONSTANTS */ - public static final int BLOCK_META = 3; - - public TileAlvearyFan() { - super(new ClimateControl(-0.01f, 0.05f, 2.5f), BlockAlveary.ALVEARY_FAN_OFF, BlockAlveary.ALVEARY_FAN_ON, BLOCK_META); - } - -} +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.network; + +import java.io.IOException; + +import net.minecraft.util.ChunkCoordinates; + +public interface IStreamableGui { + ChunkCoordinates getCoordinates(); + + void writeGuiData(DataOutputStreamForestry data) throws IOException; + + void readGuiData(DataInputStreamForestry data) throws IOException; +} diff --git a/src/main/java/forestry/core/network/PacketErrorUpdate.java b/src/main/java/forestry/core/network/PacketErrorUpdate.java index ac555bb59..6cf42b0e0 100644 --- a/src/main/java/forestry/core/network/PacketErrorUpdate.java +++ b/src/main/java/forestry/core/network/PacketErrorUpdate.java @@ -14,12 +14,13 @@ import java.io.IOException; import net.minecraft.tileentity.TileEntity; -import forestry.core.gadgets.TileForestry; +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorLogicSource; import forestry.core.proxy.Proxies; public class PacketErrorUpdate extends PacketCoordinates { - private TileForestry tileForestry; + private IErrorLogic errorLogic; public static void onPacketData(DataInputStreamForestry data) throws IOException { new PacketErrorUpdate(data); @@ -29,15 +30,15 @@ public class PacketErrorUpdate extends PacketCoordinates { super(data); } - public PacketErrorUpdate(TileForestry tileForestry) { - super(PacketId.TILE_FORESTRY_ERROR_UPDATE, tileForestry); - this.tileForestry = tileForestry; + public PacketErrorUpdate(TileEntity tile, IErrorLogicSource errorLogicSource) { + super(PacketId.TILE_FORESTRY_ERROR_UPDATE, tile); + this.errorLogic = errorLogicSource.getErrorLogic(); } @Override protected void writeData(DataOutputStreamForestry data) throws IOException { super.writeData(data); - tileForestry.writeErrorData(data); + errorLogic.writeData(data); } @Override @@ -45,8 +46,10 @@ public class PacketErrorUpdate extends PacketCoordinates { super.readData(data); TileEntity tile = getTarget(Proxies.common.getRenderWorld()); - if (tile instanceof TileForestry) { - ((TileForestry) tile).readErrorData(data); + if (tile instanceof IErrorLogicSource) { + IErrorLogicSource errorSourceTile = (IErrorLogicSource) tile; + errorLogic = errorSourceTile.getErrorLogic(); + errorLogic.readData(data); } } } diff --git a/src/main/java/forestry/core/network/PacketTileGuiOpened.java b/src/main/java/forestry/core/network/PacketGuiUpdate.java similarity index 66% rename from src/main/java/forestry/core/network/PacketTileGuiOpened.java rename to src/main/java/forestry/core/network/PacketGuiUpdate.java index ab5ee0c96..0e30c96e7 100644 --- a/src/main/java/forestry/core/network/PacketTileGuiOpened.java +++ b/src/main/java/forestry/core/network/PacketGuiUpdate.java @@ -14,30 +14,29 @@ import java.io.IOException; import net.minecraft.tileentity.TileEntity; -import forestry.core.gadgets.TileForestry; import forestry.core.proxy.Proxies; -public class PacketTileGuiOpened extends PacketCoordinates { +public class PacketGuiUpdate extends PacketCoordinates { - private TileForestry tileForestry; + private IStreamableGui guiDataTile; public static void onPacketData(DataInputStreamForestry data) throws IOException { - new PacketTileGuiOpened(data); + new PacketGuiUpdate(data); } - private PacketTileGuiOpened(DataInputStreamForestry data) throws IOException { + private PacketGuiUpdate(DataInputStreamForestry data) throws IOException { super(data); } - public PacketTileGuiOpened(TileForestry tileForestry) { - super(PacketId.TILE_FORESTRY_GUI_OPENED, tileForestry); - this.tileForestry = tileForestry; + public PacketGuiUpdate(IStreamableGui guiDataTile) { + super(PacketId.TILE_FORESTRY_GUI_OPENED, guiDataTile.getCoordinates()); + this.guiDataTile = guiDataTile; } @Override protected void writeData(DataOutputStreamForestry data) throws IOException { super.writeData(data); - tileForestry.writeGuiData(data); + guiDataTile.writeGuiData(data); } @Override @@ -45,8 +44,8 @@ public class PacketTileGuiOpened extends PacketCoordinates { super.readData(data); TileEntity tile = getTarget(Proxies.common.getRenderWorld()); - if (tile instanceof TileForestry) { - ((TileForestry) tile).readGuiData(data); + if (tile instanceof IStreamableGui) { + ((IStreamableGui) tile).readGuiData(data); } } } diff --git a/src/main/java/forestry/core/network/PacketHandler.java b/src/main/java/forestry/core/network/PacketHandler.java old mode 100755 new mode 100644 index dc9663ec8..fbee1636c --- a/src/main/java/forestry/core/network/PacketHandler.java +++ b/src/main/java/forestry/core/network/PacketHandler.java @@ -33,16 +33,20 @@ import forestry.api.core.ForestryEvent; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IBreedingTracker; import forestry.api.genetics.ISpeciesRoot; +import forestry.apiculture.multiblock.IAlvearyController; +import forestry.apiculture.multiblock.TileAlveary; import forestry.apiculture.network.PacketActiveUpdate; import forestry.core.circuits.ContainerSolderingIron; import forestry.core.circuits.ItemCircuitBoard; -import forestry.core.gadgets.TileForestry; import forestry.core.genetics.BreedingTracker; import forestry.core.gui.ContainerLiquidTanks; import forestry.core.gui.ContainerSocketed; import forestry.core.gui.IGuiSelectable; +import forestry.core.interfaces.IRestrictedAccessTile; import forestry.core.interfaces.ISocketable; import forestry.core.proxy.Proxies; +import forestry.farming.multiblock.IFarmController; +import forestry.farming.multiblock.TileFarm; import forestry.plugins.PluginManager; import io.netty.buffer.ByteBufInputStream; @@ -88,7 +92,7 @@ public class PacketHandler { return true; } case TILE_FORESTRY_GUI_OPENED: { - PacketTileGuiOpened.onPacketData(data); + PacketGuiUpdate.onPacketData(data); return true; } case TILE_FORESTRY_ACTIVE: { @@ -272,12 +276,21 @@ public class PacketHandler { private static void onAccessSwitch(PacketCoordinates packet, EntityPlayer playerEntity) { assert FMLCommonHandler.instance().getEffectiveSide().isServer(); - TileForestry tile = (TileForestry) packet.getTarget(playerEntity.worldObj); - if (tile == null) { - return; - } + TileEntity tile = packet.getTarget(playerEntity.worldObj); - tile.switchAccessRule(playerEntity); + if (tile instanceof TileAlveary) { + TileAlveary tileAlveary = (TileAlveary) tile; + IAlvearyController alvearyController = tileAlveary.getAlvearyController(); + alvearyController.getAccessHandler().switchAccessRule(playerEntity); + } else if (tile instanceof TileFarm) { + TileFarm tileFarm = (TileFarm) tile; + IFarmController farmController = tileFarm.getFarmController(); + farmController.getAccessHandler().switchAccessRule(playerEntity); + } else if (tile instanceof IRestrictedAccessTile) { + IRestrictedAccessTile restrictedAccessTile = (IRestrictedAccessTile) tile; + + restrictedAccessTile.getAccessHandler().switchAccessRule(playerEntity); + } } private static void onPipetteClick(PacketSlotClick packet, EntityPlayerMP player) { diff --git a/src/main/java/forestry/core/network/PacketId.java b/src/main/java/forestry/core/network/PacketId.java index 2dcdf8a03..c11781d17 100644 --- a/src/main/java/forestry/core/network/PacketId.java +++ b/src/main/java/forestry/core/network/PacketId.java @@ -23,6 +23,7 @@ public enum PacketId { HABITAT_BIOME_POINTER, CANDLE, + BEE_LOGIC_ACTIVE, GUI_SELECTION_CHANGE, IMPRINT_SELECTION_GET, @@ -51,13 +52,12 @@ public enum PacketId { POBOX_INFO_REQUEST, RIPENING_UPDATE, - + // Propolis pipe PROP_SEND_FILTER_SET, PROP_REQUEST_FILTER_SET, PROP_SEND_FILTER_CHANGE_GENOME, - PROP_SEND_FILTER_CHANGE_TYPE - ; + PROP_SEND_FILTER_CHANGE_TYPE; public static final PacketId[] VALUES = values(); } diff --git a/src/main/java/forestry/core/network/PacketSocketUpdate.java b/src/main/java/forestry/core/network/PacketSocketUpdate.java index 6e1f7570b..6674d8caf 100755 --- a/src/main/java/forestry/core/network/PacketSocketUpdate.java +++ b/src/main/java/forestry/core/network/PacketSocketUpdate.java @@ -13,8 +13,8 @@ package forestry.core.network; import java.io.IOException; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; -import forestry.core.gadgets.TileForestry; import forestry.core.interfaces.ISocketable; public class PacketSocketUpdate extends PacketCoordinates { @@ -25,7 +25,7 @@ public class PacketSocketUpdate extends PacketCoordinates { super(data); } - public PacketSocketUpdate(PacketId id, T tile) { + public PacketSocketUpdate(PacketId id, T tile) { super(id, tile); itemStacks = new ItemStack[tile.getSocketCount()]; diff --git a/src/main/java/forestry/core/proxy/ClientProxyCommon.java b/src/main/java/forestry/core/proxy/ClientProxyCommon.java index dc4289114..e0dec954e 100755 --- a/src/main/java/forestry/core/proxy/ClientProxyCommon.java +++ b/src/main/java/forestry/core/proxy/ClientProxyCommon.java @@ -35,7 +35,9 @@ import forestry.apiculture.render.TextureHabitatLocator; import forestry.core.ForestryClient; import forestry.core.TickHandlerCoreClient; import forestry.core.WorldGenerator; +import forestry.core.multiblock.MultiblockClientTickHandler; import forestry.core.render.EntityHoneydustFX; +import forestry.core.render.EntitySnowFX; import forestry.core.render.SpriteSheet; public class ClientProxyCommon extends ProxyCommon { @@ -55,6 +57,7 @@ public class ClientProxyCommon extends ProxyCommon { super.registerTickHandlers(worldGenerator); FMLCommonHandler.instance().bus().register(new TickHandlerCoreClient()); + FMLCommonHandler.instance().bus().register(new MultiblockClientTickHandler()); } @Override @@ -189,6 +192,15 @@ public class ClientProxyCommon extends ProxyCommon { getClientInstance().effectRenderer.addEffect(new EntityExplodeFX(world, d1, d2, d3, f1, f2, f3)); } + @Override + public void addEntitySnowFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + if (!ClientProxyRender.shouldSpawnParticle(world)) { + return; + } + + getClientInstance().effectRenderer.addEffect(new EntitySnowFX(world, d1, d2, d3, f1, f2, f3)); + } + @Override public void addBlockDestroyEffects(World world, int xCoord, int yCoord, int zCoord, Block block, int i) { if (!isSimulating(world)) { diff --git a/src/main/java/forestry/core/proxy/ClientProxyRender.java b/src/main/java/forestry/core/proxy/ClientProxyRender.java index 0f6001b20..679250943 100755 --- a/src/main/java/forestry/core/proxy/ClientProxyRender.java +++ b/src/main/java/forestry/core/proxy/ClientProxyRender.java @@ -24,7 +24,6 @@ import forestry.core.config.Config; import forestry.core.gadgets.MachineDefinition; import forestry.core.interfaces.IBlockRenderer; import forestry.core.render.BlockRenderingHandler; -import forestry.core.render.EntitySnowFX; import forestry.core.render.RenderEscritoire; import forestry.core.render.RenderMachine; import forestry.core.render.RenderMill; @@ -97,19 +96,6 @@ public class ClientProxyRender extends ProxyRender { return true; } - @Override - public void addSnowFX(World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { - if (!shouldSpawnParticle(world)) { - return; - } - - double spawnX = xCoord + world.rand.nextInt(areaX * 2) - areaX; - double spawnY = yCoord + world.rand.nextInt(areaY); - double spawnZ = zCoord + world.rand.nextInt(areaZ * 2) - areaZ; - - Proxies.common.getClientInstance().effectRenderer.addEffect(new EntitySnowFX(world, spawnX, spawnY, spawnZ, 0.0f, 0.0f, 0.0f)); - } - @Override public short registerItemTexUID(IIconRegister register, short uid, String ident) { TextureManager.getInstance().registerTexUID(register, uid, ident); diff --git a/src/main/java/forestry/core/proxy/ProxyCommon.java b/src/main/java/forestry/core/proxy/ProxyCommon.java index b25b3fcee..612317e94 100755 --- a/src/main/java/forestry/core/proxy/ProxyCommon.java +++ b/src/main/java/forestry/core/proxy/ProxyCommon.java @@ -54,6 +54,7 @@ import forestry.core.WorldGenerator; import forestry.core.config.Defaults; import forestry.core.config.ForestryBlock; import forestry.core.config.ForestryItem; +import forestry.core.multiblock.MultiblockServerTickHandler; import forestry.core.network.PacketCoordinates; import forestry.core.network.PacketFXSignal; import forestry.core.network.PacketId; @@ -71,6 +72,8 @@ public class ProxyCommon { TickHandlerCoreServer tickHandlerCoreServer = new TickHandlerCoreServer(worldGenerator); FMLCommonHandler.instance().bus().register(tickHandlerCoreServer); MinecraftForge.EVENT_BUS.register(tickHandlerCoreServer); + + FMLCommonHandler.instance().bus().register(new MultiblockServerTickHandler()); } public void registerBlock(Block block, Class itemClass) { @@ -221,6 +224,9 @@ public class ProxyCommon { public void addEntityExplodeFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { } + public void addEntitySnowFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + } + public void addBlockDestroyEffects(World world, int xCoord, int yCoord, int zCoord, Block block, int i) { sendFXSignal(PacketFXSignal.VisualFXType.BLOCK_DESTROY, PacketFXSignal.SoundFXType.BLOCK_DESTROY, world, xCoord, yCoord, zCoord, block, i); } diff --git a/src/main/java/forestry/core/proxy/ProxyRender.java b/src/main/java/forestry/core/proxy/ProxyRender.java index 93aa1e800..9d47db1ea 100755 --- a/src/main/java/forestry/core/proxy/ProxyRender.java +++ b/src/main/java/forestry/core/proxy/ProxyRender.java @@ -11,7 +11,6 @@ package forestry.core.proxy; import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.world.World; import forestry.core.gadgets.MachineDefinition; import forestry.core.interfaces.IBlockRenderer; @@ -49,9 +48,6 @@ public class ProxyRender { return null; } - public void addSnowFX(World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { - } - public short registerItemTexUID(IIconRegister register, short uid, String ident) { return uid; } diff --git a/src/main/java/forestry/core/utils/GeneticsUtil.java b/src/main/java/forestry/core/utils/GeneticsUtil.java index 05b94a7bb..7a802184b 100644 --- a/src/main/java/forestry/core/utils/GeneticsUtil.java +++ b/src/main/java/forestry/core/utils/GeneticsUtil.java @@ -15,7 +15,6 @@ import java.util.Map; import java.util.Set; import net.minecraft.block.Block; -import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.Item; @@ -139,7 +138,7 @@ public class GeneticsUtil { // Treat them as decorative and don't pollinate. return null; } - if(block == Blocks.leaves2) { + if (block == Blocks.leaves2) { meta = meta + 4; //Dark Oak and Acacia are their own leaf block, but added on the end of sapling } block = Blocks.sapling; diff --git a/src/main/java/forestry/core/utils/Utils.java b/src/main/java/forestry/core/utils/Utils.java index f6145d565..ba892380a 100755 --- a/src/main/java/forestry/core/utils/Utils.java +++ b/src/main/java/forestry/core/utils/Utils.java @@ -19,87 +19,64 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.inventory.ISidedInventory; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.world.World; +import net.minecraftforge.oredict.OreDictionary; + import cpw.mods.fml.common.registry.EntityRegistry; import forestry.api.core.ForestryAPI; -import forestry.api.core.ITileStructure; -import forestry.core.gadgets.TileForestry; import forestry.core.proxy.Proxies; import buildcraft.api.tools.IToolWrench; public class Utils { - private static Random rand; + private static final int slabWoodId = OreDictionary.getOreID("slabWood"); + private static final Random rand = new Random(); public static int getUID() { - if (rand == null) { - rand = new Random(); - } - return rand.nextInt(); } - public static void dropInventory(TileForestry tile, World world, int x, int y, int z) { - if (tile == null) { + public static void dropInventory(IInventory inventory, World world, int x, int y, int z) { + if (inventory == null) { return; } // Release inventory - if (tile instanceof ITileStructure) { + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { - ISidedInventory inventory = ((ITileStructure) tile).getStructureInventory(); - if (inventory != null) { - for (int i = 0; i < inventory.getSizeInventory(); i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } + ItemStack itemstack = inventory.getStackInSlot(slot); - StackUtils.dropItemStackAsEntity(inventory.getStackInSlot(i), world, x, y, z); - inventory.setInventorySlotContents(i, null); - } + if (itemstack == null) { + continue; } - } else { - for (int slot = 0; slot < tile.getSizeInventory(); slot++) { + float f = world.rand.nextFloat() * 0.8F + 0.1F; + float f1 = world.rand.nextFloat() * 0.8F + 0.1F; + float f2 = world.rand.nextFloat() * 0.8F + 0.1F; - ItemStack itemstack = tile.getStackInSlot(slot); - - if (itemstack == null) { - continue; + while (itemstack.stackSize > 0) { + int stackPartial = world.rand.nextInt(21) + 10; + if (stackPartial > itemstack.stackSize) { + stackPartial = itemstack.stackSize; } - - float f = world.rand.nextFloat() * 0.8F + 0.1F; - float f1 = world.rand.nextFloat() * 0.8F + 0.1F; - float f2 = world.rand.nextFloat() * 0.8F + 0.1F; - - while (itemstack.stackSize > 0) { - - int stackPartial = world.rand.nextInt(21) + 10; - if (stackPartial > itemstack.stackSize) { - stackPartial = itemstack.stackSize; - } - ItemStack drop = itemstack.splitStack(stackPartial); - EntityItem entityitem = new EntityItem(world, x + f, y + f1, z + f2, drop); - float accel = 0.05F; - entityitem.motionX = (float) world.rand.nextGaussian() * accel; - entityitem.motionY = (float) world.rand.nextGaussian() * accel + 0.2F; - entityitem.motionZ = (float) world.rand.nextGaussian() * accel; - world.spawnEntityInWorld(entityitem); - - } - - tile.setInventorySlotContents(slot, null); - + ItemStack drop = itemstack.splitStack(stackPartial); + EntityItem entityitem = new EntityItem(world, x + f, y + f1, z + f2, drop); + float accel = 0.05F; + entityitem.motionX = (float) world.rand.nextGaussian() * accel; + entityitem.motionY = (float) world.rand.nextGaussian() * accel + 0.2F; + entityitem.motionZ = (float) world.rand.nextGaussian() * accel; + world.spawnEntityInWorld(entityitem); } + + inventory.setInventorySlotContents(slot, null); } - } public static boolean canWrench(EntityPlayer player, int x, int y, int z) { @@ -146,6 +123,17 @@ public class Utils { } } + public static boolean isWoodSlabBlock(Block block) { + int[] oreIds = OreDictionary.getOreIDs(new ItemStack(block)); + for (int oreId : oreIds) { + if (oreId == slabWoodId) { + return true; + } + } + + return false; + } + public static boolean isReplaceableBlock(World world, int x, int y, int z) { Block block = world.getBlock(x, y, z); @@ -216,6 +204,17 @@ public class Utils { Proxies.log.finer("Registered entity %s (%s) with id %s.", ident, entityClass.toString(), id); } + public static T getTile(World world, int x, int y, int z, Class tileClass) { + T tileEntity = null; + try { + tileEntity = tileClass.cast(world.getTileEntity(x, y, z)); + } catch (ClassCastException ex) { + Proxies.log.warning("Failed to cast a tile entity to a " + tileClass.getName() + " at " + x + '/' + y + '/' + z); + } + + return tileEntity; + } + public static int addRGBComponents(int colour, int r, int g, int b) { r = ((colour & 0xff0000) >> 16) + r; g = ((colour & 0xff00) >> 8) + g; diff --git a/src/main/java/forestry/core/vect/IVect.java b/src/main/java/forestry/core/vect/IVect.java index 8524dcd01..dc18195ce 100644 --- a/src/main/java/forestry/core/vect/IVect.java +++ b/src/main/java/forestry/core/vect/IVect.java @@ -12,6 +12,8 @@ package forestry.core.vect; import net.minecraftforge.common.util.ForgeDirection; +import forestry.api.farming.FarmDirection; + /** * Represents a position or dimensions. */ @@ -28,5 +30,7 @@ public interface IVect { IVect add(ForgeDirection direction); + IVect add(FarmDirection direction); + int[] toArray(); } diff --git a/src/main/java/forestry/core/vect/MutableVect.java b/src/main/java/forestry/core/vect/MutableVect.java index 164e35b14..7f151c81e 100644 --- a/src/main/java/forestry/core/vect/MutableVect.java +++ b/src/main/java/forestry/core/vect/MutableVect.java @@ -10,8 +10,12 @@ ******************************************************************************/ package forestry.core.vect; +import net.minecraft.util.ChunkCoordinates; + import net.minecraftforge.common.util.ForgeDirection; +import forestry.api.farming.FarmDirection; + /** * Represents changeable positions or dimensions. */ @@ -26,6 +30,22 @@ public class MutableVect implements IVect { this.z = z; } + public MutableVect(int[] dim) { + if (dim.length != 3) { + throw new RuntimeException("Cannot instantiate a vector with less or more than 3 points."); + } + + this.x = dim[0]; + this.y = dim[1]; + this.z = dim[2]; + } + + public MutableVect(ChunkCoordinates coordinates) { + this.x = coordinates.posX; + this.y = coordinates.posY; + this.z = coordinates.posZ; + } + public MutableVect(IVect vect) { this.x = vect.getX(); this.y = vect.getY(); @@ -54,11 +74,23 @@ public class MutableVect implements IVect { return this; } + @Override + public IVect add(FarmDirection direction) { + return add(direction.getForgeDirection()); + } + @Override public int[] toArray() { return new int[]{x, y, z}; } + public MutableVect multiply(float factor) { + this.x *= factor; + this.y *= factor; + this.z *= factor; + return this; + } + public boolean advancePositionInArea(Vect area) { // Increment z first until end reached if (z < area.z - 1) { diff --git a/src/main/java/forestry/core/vect/Vect.java b/src/main/java/forestry/core/vect/Vect.java index 1c6339416..efcc08b76 100644 --- a/src/main/java/forestry/core/vect/Vect.java +++ b/src/main/java/forestry/core/vect/Vect.java @@ -13,9 +13,12 @@ package forestry.core.vect; import java.util.Random; import net.minecraft.entity.Entity; +import net.minecraft.util.ChunkCoordinates; import net.minecraftforge.common.util.ForgeDirection; +import forestry.api.farming.FarmDirection; + /** * Represents an unchangeable position or dimensions. */ @@ -44,6 +47,12 @@ public class Vect implements IVect { this.z = z; } + public Vect(ChunkCoordinates coordinates) { + this.x = coordinates.posX; + this.y = coordinates.posY; + this.z = coordinates.posZ; + } + public Vect(Entity entity) { this.x = (int) Math.round(entity.posX); this.y = (int) Math.round(entity.posY); @@ -84,6 +93,11 @@ public class Vect implements IVect { return add(direction.offsetX, direction.offsetY, direction.offsetZ); } + @Override + public Vect add(FarmDirection direction) { + return add(direction.getForgeDirection()); + } + @Override public int[] toArray() { return new int[]{x, y, z}; diff --git a/src/main/java/forestry/energy/GuiHandlerEnergy.java b/src/main/java/forestry/energy/GuiHandlerEnergy.java index f73ddbc6e..3c0a05f3c 100755 --- a/src/main/java/forestry/energy/GuiHandlerEnergy.java +++ b/src/main/java/forestry/energy/GuiHandlerEnergy.java @@ -43,16 +43,16 @@ public class GuiHandlerEnergy extends GuiHandlerBase { switch (GuiId.values()[id]) { case EngineBronzeGUI: - return new GuiEngineBronze(player.inventory, getTileForestry(world, x, y, z, player, EngineBronze.class)); + return new GuiEngineBronze(player.inventory, getTile(world, x, y, z, player, EngineBronze.class)); case EngineCopperGUI: - return new GuiEngineCopper(player.inventory, getTileForestry(world, x, y, z, player, EngineCopper.class)); + return new GuiEngineCopper(player.inventory, getTile(world, x, y, z, player, EngineCopper.class)); case EngineTinGUI: - return new GuiEngineTin(player.inventory, getTileForestry(world, x, y, z, player, EngineTin.class)); + return new GuiEngineTin(player.inventory, getTile(world, x, y, z, player, EngineTin.class)); case GeneratorGUI: - return new GuiGenerator(player.inventory, getTileForestry(world, x, y, z, player, MachineGenerator.class)); + return new GuiGenerator(player.inventory, getTile(world, x, y, z, player, MachineGenerator.class)); default: return null; @@ -69,18 +69,18 @@ public class GuiHandlerEnergy extends GuiHandlerBase { switch (GuiId.values()[id]) { case EngineBronzeGUI: - return new ContainerEngineBronze(player.inventory, getTileForestry(world, x, y, z, player, EngineBronze.class)); + return new ContainerEngineBronze(player.inventory, getTile(world, x, y, z, player, EngineBronze.class)); case EngineCopperGUI: - return new ContainerEngineCopper(player.inventory, getTileForestry(world, x, y, z, player, EngineCopper.class)); + return new ContainerEngineCopper(player.inventory, getTile(world, x, y, z, player, EngineCopper.class)); case EngineTinGUI: - EngineTin tile = getTileForestry(world, x, y, z, player, EngineTin.class); + EngineTin tile = getTile(world, x, y, z, player, EngineTin.class); Proxies.net.sendToPlayer(new PacketSocketUpdate(PacketId.SOCKET_UPDATE, tile), player); return new ContainerEngineTin(player.inventory, tile); case GeneratorGUI: - return new ContainerGenerator(player.inventory, getTileForestry(world, x, y, z, player, MachineGenerator.class)); + return new ContainerGenerator(player.inventory, getTile(world, x, y, z, player, MachineGenerator.class)); default: return null; diff --git a/src/main/java/forestry/energy/circuits/CircuitElectricChange.java b/src/main/java/forestry/energy/circuits/CircuitElectricChange.java index 8149d0e7a..fb56f3c9e 100755 --- a/src/main/java/forestry/energy/circuits/CircuitElectricChange.java +++ b/src/main/java/forestry/energy/circuits/CircuitElectricChange.java @@ -10,8 +10,6 @@ ******************************************************************************/ package forestry.energy.circuits; -import net.minecraft.tileentity.TileEntity; - import forestry.core.circuits.Circuit; import forestry.energy.gadgets.EngineTin; @@ -30,12 +28,12 @@ public abstract class CircuitElectricChange extends Circuit { } @Override - public boolean isCircuitable(TileEntity tile) { + public boolean isCircuitable(Object tile) { return tile instanceof EngineTin; } @Override - public void onInsertion(int slot, TileEntity tile) { + public void onInsertion(int slot, Object tile) { if (!isCircuitable(tile)) { return; } @@ -45,12 +43,12 @@ public abstract class CircuitElectricChange extends Circuit { } @Override - public void onLoad(int slot, TileEntity tile) { + public void onLoad(int slot, Object tile) { onInsertion(slot, tile); } @Override - public void onRemoval(int slot, TileEntity tile) { + public void onRemoval(int slot, Object tile) { if (!isCircuitable(tile)) { return; } @@ -60,6 +58,6 @@ public abstract class CircuitElectricChange extends Circuit { } @Override - public void onTick(int slot, TileEntity tile) { + public void onTick(int slot, Object tile) { } } diff --git a/src/main/java/forestry/energy/circuits/CircuitFireDampener.java b/src/main/java/forestry/energy/circuits/CircuitFireDampener.java index 15b48da85..780d94038 100755 --- a/src/main/java/forestry/energy/circuits/CircuitFireDampener.java +++ b/src/main/java/forestry/energy/circuits/CircuitFireDampener.java @@ -10,8 +10,6 @@ ******************************************************************************/ package forestry.energy.circuits; -import net.minecraft.tileentity.TileEntity; - import forestry.core.circuits.Circuit; import forestry.energy.gadgets.EngineCopper; @@ -22,12 +20,12 @@ public class CircuitFireDampener extends Circuit { } @Override - public boolean isCircuitable(TileEntity tile) { + public boolean isCircuitable(Object tile) { return tile instanceof EngineCopper; } @Override - public void onInsertion(int slot, TileEntity tile) { + public void onInsertion(int slot, Object tile) { if (!isCircuitable(tile)) { return; } @@ -35,16 +33,16 @@ public class CircuitFireDampener extends Circuit { } @Override - public void onLoad(int slot, TileEntity tile) { + public void onLoad(int slot, Object tile) { onInsertion(slot, tile); } @Override - public void onRemoval(int slot, TileEntity tile) { + public void onRemoval(int slot, Object tile) { } @Override - public void onTick(int slot, TileEntity tile) { + public void onTick(int slot, Object tile) { } } diff --git a/src/main/java/forestry/energy/gadgets/EngineBronze.java b/src/main/java/forestry/energy/gadgets/EngineBronze.java index 260316b85..33c786fb1 100755 --- a/src/main/java/forestry/energy/gadgets/EngineBronze.java +++ b/src/main/java/forestry/energy/gadgets/EngineBronze.java @@ -26,6 +26,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.fuels.EngineBronzeFuel; import forestry.api.fuels.FuelManager; import forestry.core.EnumErrorCode; @@ -97,11 +98,13 @@ public class EngineBronze extends Engine implements ISidedInventory, ILiquidTank FluidHelper.drainContainers(tankManager, inventory, SLOT_CAN); } + IErrorLogic errorLogic = getErrorLogic(); + boolean hasHeat = getHeatLevel() > 0.2 || heatingTank.getFluidAmount() > 0; - setErrorCondition(!hasHeat, EnumErrorCode.NOHEAT); + errorLogic.setCondition(!hasHeat, EnumErrorCode.NOHEAT); boolean hasFuel = burnTime > 0 || fuelTank.getFluidAmount() > 0; - setErrorCondition(!hasFuel, EnumErrorCode.NOFUEL); + errorLogic.setCondition(!hasFuel, EnumErrorCode.NOFUEL); } /** @@ -286,12 +289,14 @@ public class EngineBronze extends Engine implements ISidedInventory, ILiquidTank public void writeData(DataOutputStreamForestry data) throws IOException { super.writeData(data); data.writeBoolean(shutdown); + tankManager.writePacketData(data); } @Override public void readData(DataInputStreamForestry data) throws IOException { super.readData(data); shutdown = data.readBoolean(); + tankManager.readPacketData(data); } /* GUI */ diff --git a/src/main/java/forestry/energy/gadgets/EngineCopper.java b/src/main/java/forestry/energy/gadgets/EngineCopper.java index 98fb11851..646af7969 100755 --- a/src/main/java/forestry/energy/gadgets/EngineCopper.java +++ b/src/main/java/forestry/energy/gadgets/EngineCopper.java @@ -120,7 +120,7 @@ public class EngineCopper extends Engine implements ISidedInventory { int fuelSlot = getFuelSlot(); boolean hasFuel = fuelSlot >= 0 && determineBurnDuration(getInternalInventory().getStackInSlot(fuelSlot)) > 0; - setErrorCondition(!hasFuel, EnumErrorCode.NOFUEL); + getErrorLogic().setCondition(!hasFuel, EnumErrorCode.NOFUEL); } @Override @@ -249,7 +249,7 @@ public class EngineCopper extends Engine implements ISidedInventory { return; } - if (!InvTools.moveOneItemToPipe(wasteInventory, tileCache)) { + if (!InvTools.moveOneItemToPipe(wasteInventory, getTileCache())) { InvTools.moveItemStack(wasteInventory, inventoryCache.getAdjacentInventories()); } } diff --git a/src/main/java/forestry/energy/gadgets/EngineTin.java b/src/main/java/forestry/energy/gadgets/EngineTin.java index 872dc177f..329436692 100755 --- a/src/main/java/forestry/energy/gadgets/EngineTin.java +++ b/src/main/java/forestry/energy/gadgets/EngineTin.java @@ -20,6 +20,7 @@ import net.minecraft.nbt.NBTTagCompound; import forestry.api.circuits.ChipsetManager; import forestry.api.circuits.ICircuitBoard; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.core.EnumErrorCode; import forestry.core.TemperatureState; import forestry.core.config.Config; @@ -30,7 +31,6 @@ import forestry.core.interfaces.ISocketable; import forestry.core.inventory.InventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; import forestry.core.network.GuiId; -import forestry.core.utils.DelayTimer; import forestry.plugins.PluginIC2; import ic2.api.energy.prefab.BasicSink; @@ -57,8 +57,6 @@ public class EngineTin extends Engine implements ISocketable, IInventory { protected BasicSink ic2EnergySink; - private final DelayTimer delayUpdateTimer = new DelayTimer(); - public EngineTin() { super(Defaults.ENGINE_TIN_HEAT_MAX, 100000, 4000); setHints(Config.hints.get("engine.tin")); @@ -162,8 +160,10 @@ public class EngineTin extends Engine implements ISocketable, IInventory { // / WORK @Override public void updateServerSide() { + IErrorLogic errorLogic = getErrorLogic(); + // No work to be done if IC2 is unavailable. - if (setErrorCondition(ic2EnergySink == null, EnumErrorCode.NOENERGYNET)) { + if (errorLogic.setCondition(ic2EnergySink == null, EnumErrorCode.NOENERGYNET)) { return; } @@ -180,12 +180,12 @@ public class EngineTin extends Engine implements ISocketable, IInventory { } // Updating of gui delayed to prevent it from going crazy - if (!delayUpdateTimer.delayPassed(worldObj, 80)) { + if (!updateOnInterval(80)) { return; } boolean canUseEnergy = ic2EnergySink.canUseEnergy(euConfig.euForCycle); - setErrorCondition(!canUseEnergy, EnumErrorCode.NOFUEL); + errorLogic.setCondition(!canUseEnergy, EnumErrorCode.NOFUEL); } @Override diff --git a/src/main/java/forestry/energy/gadgets/MachineGenerator.java b/src/main/java/forestry/energy/gadgets/MachineGenerator.java index ab8ee1e79..522ce591f 100755 --- a/src/main/java/forestry/energy/gadgets/MachineGenerator.java +++ b/src/main/java/forestry/energy/gadgets/MachineGenerator.java @@ -10,6 +10,8 @@ ******************************************************************************/ package forestry.energy.gadgets; +import java.io.IOException; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.ICrafting; @@ -23,6 +25,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.fuels.FuelManager; import forestry.api.fuels.GeneratorFuel; import forestry.core.EnumErrorCode; @@ -36,6 +39,8 @@ import forestry.core.interfaces.ILiquidTankContainer; import forestry.core.interfaces.IRenderableMachine; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.Utils; @@ -95,6 +100,18 @@ public class MachineGenerator extends TileBase implements ISidedInventory, ILiqu tankManager.readTanksFromNBT(nbttagcompound); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + @Override public void onChunkUnload() { if (ic2EnergySource != null) { @@ -124,8 +141,10 @@ public class MachineGenerator extends TileBase implements ISidedInventory, ILiqu } } + IErrorLogic errorLogic = getErrorLogic(); + // No work to be done if IC2 is unavailable. - if (setErrorCondition(ic2EnergySource == null, EnumErrorCode.NOENERGYNET)) { + if (errorLogic.setCondition(ic2EnergySource == null, EnumErrorCode.NOENERGYNET)) { return; } @@ -148,7 +167,7 @@ public class MachineGenerator extends TileBase implements ISidedInventory, ILiqu } boolean hasFuel = resourceTank.getFluidAmount() > 0; - setErrorCondition(!hasFuel, EnumErrorCode.NOFUEL); + errorLogic.setCondition(!hasFuel, EnumErrorCode.NOFUEL); } public boolean isWorking() { diff --git a/src/main/java/forestry/factory/DummyManagers.java b/src/main/java/forestry/factory/DummyManagers.java index d8cf70414..7debe890d 100644 --- a/src/main/java/forestry/factory/DummyManagers.java +++ b/src/main/java/forestry/factory/DummyManagers.java @@ -1,6 +1,5 @@ package forestry.factory; -import java.util.HashMap; import java.util.Map; import net.minecraft.item.ItemStack; @@ -53,26 +52,6 @@ public class DummyManagers { } - @Override - public void addRecipe(int timePerItem, ItemStack resource, HashMap products) { - - } - - @Override - public void addRecipe(int timePerItem, ItemStack resource, ItemStack[] produce, int[] chances) { - - } - - @Override - public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary, ItemStack secondary, int chance) { - - } - - @Override - public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary) { - - } - @Override public Map getRecipes() { return null; diff --git a/src/main/java/forestry/factory/GuiHandlerFactory.java b/src/main/java/forestry/factory/GuiHandlerFactory.java index cc1c4e851..a3b74cca2 100755 --- a/src/main/java/forestry/factory/GuiHandlerFactory.java +++ b/src/main/java/forestry/factory/GuiHandlerFactory.java @@ -58,34 +58,34 @@ public class GuiHandlerFactory extends GuiHandlerBase { switch (GuiId.values()[id]) { case BottlerGUI: - return new GuiBottler(player.inventory, getTileForestry(world, x, y, z, player, MachineBottler.class)); + return new GuiBottler(player.inventory, getTile(world, x, y, z, player, MachineBottler.class)); case CarpenterGUI: - return new GuiCarpenter(player.inventory, getTileForestry(world, x, y, z, player, MachineCarpenter.class)); + return new GuiCarpenter(player.inventory, getTile(world, x, y, z, player, MachineCarpenter.class)); case CentrifugeGUI: - return new GuiCentrifuge(player.inventory, getTileForestry(world, x, y, z, player, MachineCentrifuge.class)); + return new GuiCentrifuge(player.inventory, getTile(world, x, y, z, player, MachineCentrifuge.class)); case FabricatorGUI: - return new GuiFabricator(player.inventory, getTileForestry(world, x, y, z, player, MachineFabricator.class)); + return new GuiFabricator(player.inventory, getTile(world, x, y, z, player, MachineFabricator.class)); case FermenterGUI: - return new GuiFermenter(player.inventory, getTileForestry(world, x, y, z, player, MachineFermenter.class)); + return new GuiFermenter(player.inventory, getTile(world, x, y, z, player, MachineFermenter.class)); case MoistenerGUI: - return new GuiMoistener(player.inventory, getTileForestry(world, x, y, z, player, MachineMoistener.class)); + return new GuiMoistener(player.inventory, getTile(world, x, y, z, player, MachineMoistener.class)); case RaintankGUI: - return new GuiRaintank(player.inventory, getTileForestry(world, x, y, z, player, MachineRaintank.class)); + return new GuiRaintank(player.inventory, getTile(world, x, y, z, player, MachineRaintank.class)); case SqueezerGUI: - return new GuiSqueezer(player.inventory, getTileForestry(world, x, y, z, player, MachineSqueezer.class)); + return new GuiSqueezer(player.inventory, getTile(world, x, y, z, player, MachineSqueezer.class)); case StillGUI: - return new GuiStill(player.inventory, getTileForestry(world, x, y, z, player, MachineStill.class)); + return new GuiStill(player.inventory, getTile(world, x, y, z, player, MachineStill.class)); case WorktableGUI: - return new GuiWorktable(player, getTileForestry(world, x, y, z, player, TileWorktable.class)); + return new GuiWorktable(player, getTile(world, x, y, z, player, TileWorktable.class)); default: return null; @@ -103,34 +103,34 @@ public class GuiHandlerFactory extends GuiHandlerBase { switch (GuiId.values()[id]) { case BottlerGUI: - return new ContainerBottler(player.inventory, getTileForestry(world, x, y, z, player, MachineBottler.class)); + return new ContainerBottler(player.inventory, getTile(world, x, y, z, player, MachineBottler.class)); case CarpenterGUI: - return new ContainerCarpenter(player.inventory, getTileForestry(world, x, y, z, player, MachineCarpenter.class)); + return new ContainerCarpenter(player.inventory, getTile(world, x, y, z, player, MachineCarpenter.class)); case CentrifugeGUI: - return new ContainerCentrifuge(player.inventory, getTileForestry(world, x, y, z, player, MachineCentrifuge.class)); + return new ContainerCentrifuge(player.inventory, getTile(world, x, y, z, player, MachineCentrifuge.class)); case FabricatorGUI: - return new ContainerFabricator(player.inventory, getTileForestry(world, x, y, z, player, MachineFabricator.class)); + return new ContainerFabricator(player.inventory, getTile(world, x, y, z, player, MachineFabricator.class)); case FermenterGUI: - return new ContainerFermenter(player.inventory, getTileForestry(world, x, y, z, player, MachineFermenter.class)); + return new ContainerFermenter(player.inventory, getTile(world, x, y, z, player, MachineFermenter.class)); case MoistenerGUI: - return new ContainerMoistener(player.inventory, getTileForestry(world, x, y, z, player, MachineMoistener.class)); + return new ContainerMoistener(player.inventory, getTile(world, x, y, z, player, MachineMoistener.class)); case RaintankGUI: - return new ContainerRaintank(player.inventory, getTileForestry(world, x, y, z, player, MachineRaintank.class)); + return new ContainerRaintank(player.inventory, getTile(world, x, y, z, player, MachineRaintank.class)); case SqueezerGUI: - return new ContainerSqueezer(player.inventory, getTileForestry(world, x, y, z, player, MachineSqueezer.class)); + return new ContainerSqueezer(player.inventory, getTile(world, x, y, z, player, MachineSqueezer.class)); case StillGUI: - return new ContainerStill(player.inventory, getTileForestry(world, x, y, z, player, MachineStill.class)); + return new ContainerStill(player.inventory, getTile(world, x, y, z, player, MachineStill.class)); case WorktableGUI: - return new ContainerWorktable(player, getTileForestry(world, x, y, z, player, TileWorktable.class)); + return new ContainerWorktable(player, getTile(world, x, y, z, player, TileWorktable.class)); default: return null; diff --git a/src/main/java/forestry/factory/gadgets/MachineBottler.java b/src/main/java/forestry/factory/gadgets/MachineBottler.java index 7c3c3d15b..065144e2a 100755 --- a/src/main/java/forestry/factory/gadgets/MachineBottler.java +++ b/src/main/java/forestry/factory/gadgets/MachineBottler.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -47,6 +48,8 @@ import forestry.core.interfaces.ILiquidTankContainer; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.InvTools; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.Utils; @@ -180,6 +183,18 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq checkRecipe(); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + @Override public void updateServerSide() { super.updateServerSide(); @@ -210,7 +225,7 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq boolean added = InvTools.tryAddStack(this, currentRecipe.bottled, SLOT_OUTPUT, 1, true, false); - if (setErrorCondition(!added, EnumErrorCode.NOSPACE)) { + if (getErrorLogic().setCondition(!added, EnumErrorCode.NOSPACE)) { return false; } @@ -236,7 +251,7 @@ public class MachineBottler extends TilePowered implements ISidedInventory, ILiq resetRecipe(); } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + getErrorLogic().setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); } private void resetRecipe() { diff --git a/src/main/java/forestry/factory/gadgets/MachineCarpenter.java b/src/main/java/forestry/factory/gadgets/MachineCarpenter.java index 0987ef083..05ed5e6ff 100755 --- a/src/main/java/forestry/factory/gadgets/MachineCarpenter.java +++ b/src/main/java/forestry/factory/gadgets/MachineCarpenter.java @@ -11,6 +11,7 @@ package forestry.factory.gadgets; import javax.annotation.Nullable; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -36,6 +37,7 @@ import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.oredict.OreDictionary; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.recipes.ICarpenterManager; import forestry.core.EnumErrorCode; import forestry.core.config.Config; @@ -52,6 +54,8 @@ import forestry.core.interfaces.ILiquidTankContainer; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.InvTools; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.proxy.Proxies; import forestry.core.utils.EnumTankLevel; @@ -80,7 +84,6 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL @Nullable public MachineCarpenter.Recipe currentRecipe; - public MachineCarpenter.Recipe lastRecipe; private int packageTime; private int totalTime; private ItemStack pendingProduct; @@ -149,6 +152,18 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL setCurrentRecipe(RecipeManager.findMatchingRecipe(resourceTank.getFluid(), getBoxStack(), craftingInventory, worldObj)); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + public void resetRecipe() { if (worldObj.isRemote) { return; @@ -162,7 +177,6 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL final ItemStack craftingResult; if (currentRecipe != null) { - lastRecipe = currentRecipe; craftingResult = currentRecipe.getCraftingResult(); } else { craftingResult = null; @@ -195,8 +209,9 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL } } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); - setErrorCondition(!validateResources(), EnumErrorCode.NORESOURCE); + IErrorLogic errorLogic = getErrorLogic(); + errorLogic.setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + errorLogic.setCondition(!validateResources(), EnumErrorCode.NORESOURCE); } @Override @@ -296,7 +311,7 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL } private boolean removeSets(int count, ItemStack[] set) { - EntityPlayer player = Proxies.common.getPlayer(worldObj, getOwner()); + EntityPlayer player = Proxies.common.getPlayer(worldObj, getAccessHandler().getOwner()); return InvTools.removeSets(getInternalInventory(), count, set, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT, player, true, true, true); } @@ -311,7 +326,7 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL pendingProduct = null; } - setErrorCondition(!added, EnumErrorCode.NOSPACE); + getErrorLogic().setCondition(!added, EnumErrorCode.NOSPACE); return added; } @@ -447,16 +462,6 @@ public class MachineCarpenter extends TilePowered implements ISidedInventory, IL return GuiUtil.isIndexInRange(slotIndex, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT); } - @Override - public boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) { - if (GuiUtil.isIndexInRange(slotIndex, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT)) { - if (tile.lastRecipe != null) { - return tile.lastRecipe.isIngredient(itemStack); - } - } - return true; - } - @Override public boolean canExtractItem(int slotIndex, ItemStack itemstack, int side) { return slotIndex == SLOT_PRODUCT; diff --git a/src/main/java/forestry/factory/gadgets/MachineCentrifuge.java b/src/main/java/forestry/factory/gadgets/MachineCentrifuge.java index 83bc4752b..bf69280a5 100755 --- a/src/main/java/forestry/factory/gadgets/MachineCentrifuge.java +++ b/src/main/java/forestry/factory/gadgets/MachineCentrifuge.java @@ -176,7 +176,7 @@ public class MachineCentrifuge extends TilePowered implements ISidedInventory { resetRecipeTimes(); } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + getErrorLogic().setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); } private void resetRecipeTimes() { @@ -203,7 +203,7 @@ public class MachineCentrifuge extends TilePowered implements ISidedInventory { pendingProducts.pop(); } - setErrorCondition(!added, EnumErrorCode.NOSPACE); + getErrorLogic().setCondition(!added, EnumErrorCode.NOSPACE); return added; } @@ -345,46 +345,6 @@ public class MachineCentrifuge extends TilePowered implements ISidedInventory { addRecipe(recipe); } - @Override - public void addRecipe(int timePerItem, ItemStack resource, HashMap products) { - Map floatProducts = new HashMap(); - for (Map.Entry entry : products.entrySet()) { - floatProducts.put(entry.getKey(), entry.getValue() / 100.0f); - } - - addRecipe(timePerItem, resource, floatProducts); - } - - @Override - public void addRecipe(int timePerItem, ItemStack resource, ItemStack[] produce, int[] chances) { - Map products = new HashMap(); - - int i = 0; - for (ItemStack prod : produce) { - products.put(prod, chances[i] / 100f); - i++; - } - - addRecipe(timePerItem, resource, products); - } - - @Override - public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary, ItemStack secondary, int chance) { - Map products = new HashMap(); - products.put(primary, 1.0f); - if (secondary != null) { - products.put(secondary, chance / 100f); - } - addRecipe(timePerItem, resource, products); - } - - @Override - public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary) { - Map products = new HashMap(); - products.put(primary, 1.0f); - addRecipe(timePerItem, resource, products); - } - public static ICentrifugeRecipe findMatchingRecipe(ItemStack item) { for (ICentrifugeRecipe recipe : recipes) { ItemStack recipeInput = recipe.getInput(); diff --git a/src/main/java/forestry/factory/gadgets/MachineFabricator.java b/src/main/java/forestry/factory/gadgets/MachineFabricator.java index 2db6d2212..02b8296de 100755 --- a/src/main/java/forestry/factory/gadgets/MachineFabricator.java +++ b/src/main/java/forestry/factory/gadgets/MachineFabricator.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -31,7 +32,6 @@ import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.ForestryAPI; import forestry.api.recipes.IFabricatorManager; -import forestry.core.EnumErrorCode; import forestry.core.config.Defaults; import forestry.core.fluids.Fluids; import forestry.core.fluids.TankManager; @@ -46,6 +46,8 @@ import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.InvTools; import forestry.core.inventory.InventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.GuiUtil; import forestry.core.utils.ShapedRecipeCustom; @@ -295,6 +297,18 @@ public class MachineFabricator extends TilePowered implements ICrafter, ILiquidT } } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + /* UPDATING */ @Override public void updateServerSide() { @@ -578,14 +592,14 @@ public class MachineFabricator extends TilePowered implements ICrafter, ILiquidT } else if (slotIndex == SLOT_PLAN) { return RecipeManager.isPlan(itemStack); } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT)) { - if (RecipeManager.isPlan(itemStack) ) { + if (RecipeManager.isPlan(itemStack)) { return false; - }else if (RecipeManager.findMatchingSmelting(itemStack) != null) { + } else if (RecipeManager.findMatchingSmelting(itemStack) != null) { return false; } } - return GuiUtil.isIndexInRange(slotIndex, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT); - } + return GuiUtil.isIndexInRange(slotIndex, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT); + } @Override public boolean canExtractItem(int slotIndex, ItemStack stack, int side) { diff --git a/src/main/java/forestry/factory/gadgets/MachineFermenter.java b/src/main/java/forestry/factory/gadgets/MachineFermenter.java index 2c5e08d89..3fab84919 100755 --- a/src/main/java/forestry/factory/gadgets/MachineFermenter.java +++ b/src/main/java/forestry/factory/gadgets/MachineFermenter.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -33,6 +34,7 @@ import net.minecraftforge.fluids.FluidTankInfo; import cpw.mods.fml.common.Optional; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.fuels.FuelManager; import forestry.api.recipes.IFermenterManager; import forestry.api.recipes.IVariableFermentable; @@ -49,6 +51,8 @@ import forestry.core.gadgets.TilePowered; import forestry.core.interfaces.ILiquidTankContainer; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.StackUtils; @@ -216,6 +220,18 @@ public class MachineFermenter extends TilePowered implements ISidedInventory, IL tankManager.readTanksFromNBT(nbttagcompound); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + @Override public void updateServerSide() { super.updateServerSide(); @@ -238,14 +254,16 @@ public class MachineFermenter extends TilePowered implements ISidedInventory, IL } } + IErrorLogic errorLogic = getErrorLogic(); + boolean hasRecipe = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE), resourceTank.getFluid()) != null; - setErrorCondition(!hasRecipe, EnumErrorCode.NORECIPE); + errorLogic.setCondition(!hasRecipe, EnumErrorCode.NORECIPE); boolean hasResource = resourceTank.getFluidAmount() >= fuelCurrentFerment; - setErrorCondition(!hasResource, EnumErrorCode.NORESOURCE); + errorLogic.setCondition(!hasResource, EnumErrorCode.NORESOURCE); boolean hasFuel = inventory.getStackInSlot(SLOT_FUEL) != null || fuelBurnTime > 0; - setErrorCondition(!hasFuel, EnumErrorCode.NOFUEL); + errorLogic.setCondition(!hasFuel, EnumErrorCode.NOFUEL); } @Override diff --git a/src/main/java/forestry/factory/gadgets/MachineMoistener.java b/src/main/java/forestry/factory/gadgets/MachineMoistener.java index a9b683fc4..c9ee2d86f 100755 --- a/src/main/java/forestry/factory/gadgets/MachineMoistener.java +++ b/src/main/java/forestry/factory/gadgets/MachineMoistener.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -28,6 +29,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.fuels.FuelManager; import forestry.api.fuels.MoistenerFuel; import forestry.api.recipes.IMoistenerManager; @@ -43,6 +45,8 @@ import forestry.core.interfaces.IRenderableMachine; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.InvTools; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.GuiUtil; @@ -192,6 +196,18 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu checkRecipe(); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + @Override public void updateServerSide() { @@ -204,9 +220,11 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu // Let's get to work int lightvalue = worldObj.getBlockLightValue(xCoord, yCoord + 1, zCoord); + IErrorLogic errorLogic = getErrorLogic(); + // Not working in broad daylight boolean gloomy = lightvalue <= 11; - if (setErrorCondition(!gloomy, EnumErrorCode.NOTGLOOMY)) { + if (errorLogic.setCondition(!gloomy, EnumErrorCode.NOTGLOOMY)) { return; } @@ -226,7 +244,7 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu if (burnTime > 0 && pendingProduct == null) { // Not working if there is no water available. boolean hasLiquid = resourceTank.getFluidAmount() > 0; - if (setErrorCondition(!hasLiquid, EnumErrorCode.NORESOURCE)) { + if (errorLogic.setCondition(!hasLiquid, EnumErrorCode.NORESOURCE)) { return; } @@ -269,7 +287,7 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu } } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + errorLogic.setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); } private boolean tryAddPending() { @@ -278,7 +296,7 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu } boolean added = InvTools.tryAddStack(this, pendingProduct, SLOT_PRODUCT, 1, true); - setErrorCondition(!added, EnumErrorCode.NOSPACE); + getErrorLogic().setCondition(!added, EnumErrorCode.NOSPACE); if (added) { pendingProduct = null; @@ -294,7 +312,7 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu resetRecipe(); } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + getErrorLogic().setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); } private void resetRecipe() { @@ -373,45 +391,46 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu } private boolean rotateWorkingSlot() { - IInventoryAdapter inventory = getInternalInventory(); + IErrorLogic errorLogic = getErrorLogic(); + // Put working slot contents into inventory if space is available - if (inventory.getStackInSlot(SLOT_WORKING) != null) { + if (getStackInSlot(SLOT_WORKING) != null) { // Get the result of the consumed item in the working slot ItemStack deposit; - if (FuelManager.moistenerResource.containsKey(inventory.getStackInSlot(SLOT_WORKING))) { - MoistenerFuel res = FuelManager.moistenerResource.get(inventory.getStackInSlot(SLOT_WORKING)); + if (FuelManager.moistenerResource.containsKey(getStackInSlot(SLOT_WORKING))) { + MoistenerFuel res = FuelManager.moistenerResource.get(getStackInSlot(SLOT_WORKING)); deposit = res.product.copy(); } else { - deposit = inventory.getStackInSlot(SLOT_WORKING).copy(); + deposit = getStackInSlot(SLOT_WORKING).copy(); } int targetSlot = getFreeReservoirSlot(deposit); // We stop the whole thing, if we don't have any room anymore. - if (setErrorCondition(targetSlot < 0, EnumErrorCode.NOSPACE)) { + if (errorLogic.setCondition(targetSlot < 0, EnumErrorCode.NOSPACE)) { return false; } - if (inventory.getStackInSlot(targetSlot) == null) { - inventory.setInventorySlotContents(targetSlot, deposit); + if (getStackInSlot(targetSlot) == null) { + setInventorySlotContents(targetSlot, deposit); } else { - inventory.getStackInSlot(targetSlot).stackSize++; + getStackInSlot(targetSlot).stackSize++; } decrStackSize(SLOT_WORKING, 1); } - if (inventory.getStackInSlot(SLOT_WORKING) != null) { + if (getStackInSlot(SLOT_WORKING) != null) { return true; } // Let's look for a new resource to put into the working slot. int resourceSlot = getNextResourceSlot(SLOT_RESERVOIR_1, SLOT_RESERVOIR_1 + SLOT_RESERVOIR_COUNT); // Nothing found, stop. - if (setErrorCondition(resourceSlot < 0, EnumErrorCode.NORESOURCE)) { + if (errorLogic.setCondition(resourceSlot < 0, EnumErrorCode.NORESOURCE)) { return false; } - inventory.setInventorySlotContents(SLOT_WORKING, inventory.decrStackSize(resourceSlot, 1)); + setInventorySlotContents(SLOT_WORKING, decrStackSize(resourceSlot, 1)); return true; } @@ -634,7 +653,7 @@ public class MachineMoistener extends TileBase implements ISidedInventory, ILiqu return true; } - if (GuiUtil.isIndexInRange(slotIndex, SLOT_STASH_1, (SLOT_STASH_COUNT+SLOT_RESERVOIR_COUNT))) { + if (GuiUtil.isIndexInRange(slotIndex, SLOT_STASH_1, (SLOT_STASH_COUNT + SLOT_RESERVOIR_COUNT))) { return !FuelManager.moistenerResource.containsKey(itemstack); } diff --git a/src/main/java/forestry/factory/gadgets/MachineRaintank.java b/src/main/java/forestry/factory/gadgets/MachineRaintank.java index 19a473214..26a2d1a35 100755 --- a/src/main/java/forestry/factory/gadgets/MachineRaintank.java +++ b/src/main/java/forestry/factory/gadgets/MachineRaintank.java @@ -10,6 +10,8 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.ICrafting; @@ -26,6 +28,7 @@ import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.BiomeHelper; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.core.EnumErrorCode; import forestry.core.config.Config; import forestry.core.config.Defaults; @@ -35,11 +38,11 @@ import forestry.core.fluids.TankManager; import forestry.core.fluids.tanks.FilteredTank; import forestry.core.gadgets.TileBase; import forestry.core.interfaces.ILiquidTankContainer; -import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.StackUtils; -import forestry.core.utils.Utils; public class MachineRaintank extends TileBase implements ISidedInventory, ILiquidTankContainer { @@ -69,7 +72,7 @@ public class MachineRaintank extends TileBase implements ISidedInventory, ILiqui if (worldObj != null) { BiomeGenBase biome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); isValidBiome = BiomeHelper.canRainOrSnow(biome); - setErrorCondition(!isValidBiome, EnumErrorCode.INVALIDBIOME); + getErrorLogic().setCondition(!isValidBiome, EnumErrorCode.INVALIDBIOME); } super.validate(); @@ -98,6 +101,18 @@ public class MachineRaintank extends TileBase implements ISidedInventory, ILiqui tankManager.readTanksFromNBT(nbttagcompound); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + @Override public void updateServerSide() { @@ -105,14 +120,16 @@ public class MachineRaintank extends TileBase implements ISidedInventory, ILiqui return; } - setErrorCondition(!isValidBiome, EnumErrorCode.INVALIDBIOME); + IErrorLogic errorLogic = getErrorLogic(); + + errorLogic.setCondition(!isValidBiome, EnumErrorCode.INVALIDBIOME); boolean hasSky = worldObj.canBlockSeeTheSky(xCoord, yCoord + 1, zCoord); - setErrorCondition(!hasSky, EnumErrorCode.NOSKY); + errorLogic.setCondition(!hasSky, EnumErrorCode.NOSKY); - setErrorCondition(!worldObj.isRaining(), EnumErrorCode.NOTRAINING); + errorLogic.setCondition(!worldObj.isRaining(), EnumErrorCode.NOTRAINING); - if (!hasErrorState()) { + if (!errorLogic.hasErrors()) { resourceTank.fill(STACK_WATER, true); } diff --git a/src/main/java/forestry/factory/gadgets/MachineSqueezer.java b/src/main/java/forestry/factory/gadgets/MachineSqueezer.java index b53d5ca0b..5956c5a8e 100755 --- a/src/main/java/forestry/factory/gadgets/MachineSqueezer.java +++ b/src/main/java/forestry/factory/gadgets/MachineSqueezer.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -29,6 +30,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.recipes.ISqueezerManager; import forestry.core.EnumErrorCode; import forestry.core.config.Config; @@ -43,6 +45,8 @@ import forestry.core.interfaces.ILiquidTankContainer; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.InvTools; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.proxy.Proxies; import forestry.core.utils.EnumTankLevel; @@ -182,6 +186,18 @@ public class MachineSqueezer extends TilePowered implements ISidedInventory, ILi checkRecipe(); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + // / WORKING @Override public void updateServerSide() { @@ -210,9 +226,11 @@ public class MachineSqueezer extends TilePowered implements ISidedInventory, ILi return false; } + IErrorLogic errorLogic = getErrorLogic(); + FluidStack resultFluid = currentRecipe.liquid; boolean canFill = productTank.fill(resultFluid, false) == resultFluid.amount; - setErrorCondition(!canFill, EnumErrorCode.NOSPACETANK); + errorLogic.setCondition(!canFill, EnumErrorCode.NOSPACETANK); if (!canFill) { return false; @@ -222,7 +240,7 @@ public class MachineSqueezer extends TilePowered implements ISidedInventory, ILi if (currentRecipe.remnants != null) { remnant = currentRecipe.remnants.copy(); boolean canAdd = InvTools.tryAddStack(getInternalInventory(), remnant, SLOT_REMNANT, SLOT_REMNANT_COUNT, true, false); - setErrorCondition(!canAdd, EnumErrorCode.NOSPACE); + errorLogic.setCondition(!canAdd, EnumErrorCode.NOSPACE); if (!canAdd) { return false; } @@ -266,7 +284,7 @@ public class MachineSqueezer extends TilePowered implements ISidedInventory, ILi resetRecipeTimes(); } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + getErrorLogic().setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); return currentRecipe != null; } @@ -282,7 +300,7 @@ public class MachineSqueezer extends TilePowered implements ISidedInventory, ILi } private boolean removeResources(ItemStack[] stacks) { - EntityPlayer player = Proxies.common.getPlayer(worldObj, getOwner()); + EntityPlayer player = Proxies.common.getPlayer(worldObj, getAccessHandler().getOwner()); return InvTools.removeSets(getInternalInventory(), 1, stacks, SLOT_RESOURCE_1, SLOTS_RESOURCE_COUNT, player, false, true, true); } diff --git a/src/main/java/forestry/factory/gadgets/MachineStill.java b/src/main/java/forestry/factory/gadgets/MachineStill.java index d054d4a79..537bdbd55 100755 --- a/src/main/java/forestry/factory/gadgets/MachineStill.java +++ b/src/main/java/forestry/factory/gadgets/MachineStill.java @@ -10,6 +10,7 @@ ******************************************************************************/ package forestry.factory.gadgets; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -28,6 +29,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.recipes.IStillManager; import forestry.core.EnumErrorCode; import forestry.core.config.Config; @@ -41,6 +43,8 @@ import forestry.core.gadgets.TilePowered; import forestry.core.interfaces.ILiquidTankContainer; import forestry.core.inventory.IInventoryAdapter; import forestry.core.inventory.TileInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.Utils; @@ -165,6 +169,18 @@ public class MachineStill extends TilePowered implements ISidedInventory, ILiqui checkRecipe(); } + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + super.writeData(data); + tankManager.writePacketData(data); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + super.readData(data); + tankManager.readPacketData(data); + } + @Override public void updateServerSide() { super.updateServerSide(); @@ -193,10 +209,12 @@ public class MachineStill extends TilePowered implements ISidedInventory, ILiqui @Override public boolean workCycle() { + IErrorLogic errorLogic = getErrorLogic(); + checkRecipe(); // Ongoing process - if (distillationTime > 0 && !hasErrorState()) { + if (distillationTime > 0 && !errorLogic.hasErrors()) { distillationTime -= currentRecipe.input.amount; productTank.fill(currentRecipe.output, true); @@ -208,12 +226,12 @@ public class MachineStill extends TilePowered implements ISidedInventory, ILiqui int resourceRequired = currentRecipe.timePerUnit * currentRecipe.input.amount; boolean canFill = productTank.fill(currentRecipe.output, false) == currentRecipe.output.amount; - setErrorCondition(!canFill, EnumErrorCode.NOSPACETANK); + errorLogic.setCondition(!canFill, EnumErrorCode.NOSPACETANK); boolean hasResource = resourceTank.getFluidAmount() >= resourceRequired; - setErrorCondition(!hasResource, EnumErrorCode.NORESOURCE); + errorLogic.setCondition(!hasResource, EnumErrorCode.NORESOURCE); - if (!hasErrorState()) { + if (!errorLogic.hasErrors()) { // Start next cycle if enough bio mass is available distillationTime = distillationTotalTime = resourceRequired; resourceTank.drain(resourceRequired, true); @@ -238,7 +256,7 @@ public class MachineStill extends TilePowered implements ISidedInventory, ILiqui currentRecipe = matchingRecipe; } - setErrorCondition(currentRecipe == null, EnumErrorCode.NORECIPE); + getErrorLogic().setCondition(currentRecipe == null, EnumErrorCode.NORECIPE); } @Override diff --git a/src/main/java/forestry/factory/gui/GuiWorktable.java b/src/main/java/forestry/factory/gui/GuiWorktable.java index 7d27bdbf4..192fa0575 100755 --- a/src/main/java/forestry/factory/gui/GuiWorktable.java +++ b/src/main/java/forestry/factory/gui/GuiWorktable.java @@ -72,7 +72,7 @@ public class GuiWorktable extends GuiForestryTitled bricks = ImmutableSet.of( Blocks.brick_block, @@ -73,85 +25,8 @@ public class StructureLogicFarm extends StructureLogic { Blocks.quartz_block ); - public StructureLogicFarm(ITileStructure structure) { - super(UID_FARM, structure); - schematas = new Schemata[]{SCHEMATA_FARM_3x3, SCHEMATA_FARM_4x3, SCHEMATA_FARM_5x3, SCHEMATA_FARM_5x5, SCHEMATA_FARM_4x4}; - metaOnValid.put(EnumStructureBlock.BLOCK_B, 1); - } + private StructureLogicFarm() { - @Override - protected EnumStructureState determineMasterState(Schemata schemata, boolean rotate) { - - Vect dimensions = schemata.getDimensions(rotate); - int offsetX = schemata.getxOffset(); - int offsetZ = schemata.getzOffset(); - if (rotate) { - offsetX = schemata.getzOffset(); - offsetZ = schemata.getxOffset(); - } - - for (int i = 0; i < dimensions.x; i++) { - for (int j = 0; j < schemata.getHeight(); j++) { - for (int k = 0; k < dimensions.z; k++) { - - int x = structureTile.xCoord + i + offsetX; - int y = structureTile.yCoord + j + schemata.getyOffset(); - int z = structureTile.zCoord + k + offsetZ; - - if (!structureTile.getWorldObj().blockExists(x, y, z)) { - return EnumStructureState.INDETERMINATE; - } - - EnumStructureBlock required = schemata.getAt(i, j, k, rotate); - - if (required == EnumStructureBlock.ANY) { - continue; - } - - TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); - Block block = structureTile.getWorldObj().getBlock(x, y, z); - - switch (required) { - case AIR: - if (!block.isAir(structureTile.getWorldObj(), x, y, z)) { - return EnumStructureState.INVALID; - } - break; - case BLOCK_A: - if (tile == null || !(tile instanceof IFarmComponent)) { - return EnumStructureState.INVALID; - } - if (!((ITileStructure) tile).getTypeUID().equals(UID_FARM)) { - return EnumStructureState.INVALID; - } - break; - case BLOCK_B: - case MASTER: - if (tile == null || !(tile instanceof TileFarm)) { - return EnumStructureState.INVALID; - } - if (((TileFarm) tile).hasFunction()) { - return EnumStructureState.INVALID; - } - break; - case BLOCK_C: - if (!bricks.contains(block)) { - return EnumStructureState.INVALID; - } - break; - case FOREIGN: - if (tile instanceof ITileStructure) { - return EnumStructureState.INVALID; - } - break; - default: - return EnumStructureState.INDETERMINATE; - } - } - } - } - - return EnumStructureState.VALID; } } diff --git a/src/main/java/forestry/farming/gadgets/TileControl.java b/src/main/java/forestry/farming/gadgets/TileControl.java deleted file mode 100755 index ca13969de..000000000 --- a/src/main/java/forestry/farming/gadgets/TileControl.java +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.farming.gadgets; - -import java.util.Collection; - -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; - -import net.minecraftforge.common.util.ForgeDirection; - -import forestry.api.core.ITileStructure; -import forestry.api.farming.ICrop; -import forestry.api.farming.IFarmComponent; -import forestry.api.farming.IFarmListener; -import forestry.api.farming.IFarmLogic; -import forestry.core.vect.Vect; - -public class TileControl extends TileFarm implements IFarmListener { - - private boolean isRegistered = false; - - public TileControl() { - fixedType = TYPE_CONTROL; - } - - @Override - protected void updateServerSide() { - if (!isRegistered) { - registerWithMaster(); - isRegistered = true; - } - } - - @Override - public void setCentralTE(TileEntity tile) { - super.setCentralTE(tile); - registerWithMaster(); - } - - private void registerWithMaster() { - - if (!hasMaster()) { - return; - } - - ITileStructure central = getCentralTE(); - if (!(central instanceof IFarmComponent)) { - return; - } - - ((IFarmComponent) central).registerListener(this); - } - - @Override - public boolean hasFunction() { - return true; - } - - /* IFARMLISTENER */ - @Override - public boolean cancelTask(IFarmLogic logic, ForgeDirection direction) { - return hasRedstoneSignal(direction) || hasRedstoneSignal(ForgeDirection.UP) || hasRedstoneSignal(ForgeDirection.DOWN); - } - - private boolean hasRedstoneSignal(ForgeDirection direction) { - Vect side = new Vect(xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ); - - ForgeDirection opp = direction.getOpposite(); - int dir; - if (opp.offsetZ < 0) { - dir = 2; - } else if (opp.offsetZ > 0) { - dir = 3; - } else if (opp.offsetX < 0) { - dir = 4; - } else if (opp.offsetX > 0) { - dir = 5; - } else { - dir = 0; - } - - return worldObj.getIndirectPowerLevelTo(side.x, side.y, side.z, dir) > 0 || worldObj.isBlockProvidingPowerTo(side.x, side.y, side.z, dir) > 0; - } - - @Override - public boolean beforeCropHarvest(ICrop crop) { - return false; - } - - @Override - public void afterCropHarvest(Collection harvested, ICrop crop) { - } - - @Override - public void hasCollected(Collection collected, IFarmLogic logic) { - } - - @Override - public void hasCultivated(IFarmLogic logic, int x, int y, int z, ForgeDirection direction, int extent) { - } - - @Override - public void hasScheduledHarvest(Collection harvested, IFarmLogic logic, int x, int y, int z, ForgeDirection direction, int extent) { - } - -} diff --git a/src/main/java/forestry/farming/gadgets/TileFarm.java b/src/main/java/forestry/farming/gadgets/TileFarm.java deleted file mode 100755 index 06cc97f0e..000000000 --- a/src/main/java/forestry/farming/gadgets/TileFarm.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.farming.gadgets; - -import java.io.IOException; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.IIcon; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -import forestry.api.core.ForestryAPI; -import forestry.api.core.IStructureLogic; -import forestry.api.core.ITileStructure; -import forestry.api.farming.Farmables; -import forestry.api.farming.IFarmComponent; -import forestry.api.farming.IFarmListener; -import forestry.core.gadgets.TileForestry; -import forestry.core.inventory.IInventoryAdapter; -import forestry.core.network.DataInputStreamForestry; -import forestry.core.network.DataOutputStreamForestry; -import forestry.core.network.GuiId; - -public abstract class TileFarm extends TileForestry implements IFarmComponent { - - public static final int TYPE_PLAIN = 0; - public static final int TYPE_REVERSE = 1; - public static final int TYPE_TOP = 2; - public static final int TYPE_BAND = 3; - public static final int TYPE_GEARS = 4; - public static final int TYPE_HATCH = 5; - public static final int TYPE_VALVE = 6; - public static final int TYPE_CONTROL = 7; - - public TileFarm() { - this.structureLogic = Farmables.farmInterface.createFarmStructureLogic(this); - } - - /* GUI */ - @Override - public void openGui(EntityPlayer player) { - if (this.isMaster()) { - player.openGui(ForestryAPI.instance, GuiId.MultiFarmGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); - } else if (this.hasMaster()) { - player.openGui(ForestryAPI.instance, GuiId.MultiFarmGUI.ordinal(), worldObj, masterX, masterY, masterZ); - } - } - - /* SAVING & LOADING */ - @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - this.isMaster = nbttagcompound.getBoolean("IsMaster"); - this.masterX = nbttagcompound.getInteger("MasterX"); - this.masterY = nbttagcompound.getInteger("MasterY"); - this.masterZ = nbttagcompound.getInteger("MasterZ"); - - farmBlock = EnumFarmBlock.getFromCompound(nbttagcompound); - - // Init for master state - if (isMaster) { - makeMaster(); - } - - structureLogic.readFromNBT(nbttagcompound); - - super.readFromNBT(nbttagcompound); - } - - @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - - nbttagcompound.setBoolean("IsMaster", isMaster); - nbttagcompound.setInteger("MasterX", masterX); - nbttagcompound.setInteger("MasterY", masterY); - nbttagcompound.setInteger("MasterZ", masterZ); - - farmBlock.saveToCompound(nbttagcompound); - - structureLogic.writeToNBT(nbttagcompound); - } - - /* UPDATING */ - @Override - public void initialize() { - } - - protected void updateServerSide() { - // Periodic validation if needed - if (updateOnInterval(200) && (!isIntegratedIntoStructure() || isMaster())) { - validateStructure(); - } - } - - /* CONSTRUCTION MATERIAL */ - EnumFarmBlock farmBlock = EnumFarmBlock.BRICK_STONE; - protected int fixedType = -1; - - public void setFarmBlock(EnumFarmBlock block) { - farmBlock = block; - sendNetworkUpdate(); - } - - public EnumFarmBlock getFarmBlock() { - return farmBlock; - } - - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) { - /* - * if(fixedType >= 0) return farmBlock.getIcon(fixedType); - * - * int type = 0; if (meta == 1) type = TYPE_BAND; - * - * if (meta == 0 && side == 2) type = TYPE_REVERSE; else if (meta == 0 && (side == 0 || side == 1)) type = TYPE_TOP; - * - * return farmBlock.getIcon(type); - */ - return null; - } - - /* TILEFORESTRY */ - - @Override - public void writeData(DataOutputStreamForestry data) throws IOException { - super.writeData(data); - data.writeShort(farmBlock.ordinal()); - data.writeBoolean(isMaster()); - - // so the client can know if it is part of an integrated structure - data.writeShort(masterY); - } - - @Override - public void readData(DataInputStreamForestry data) throws IOException { - super.readData(data); - short farmBlockOrdinal = data.readShort(); - EnumFarmBlock farmType = EnumFarmBlock.values()[farmBlockOrdinal]; - if (data.readBoolean() && !isMaster()) { - makeMaster(); - } - - // so the client can know if it is part of an integrated structure - this.masterY = data.readShort(); - - if (this.farmBlock != farmType) { - this.farmBlock = farmType; - worldObj.func_147479_m(xCoord, yCoord, zCoord); - } - } - - /* ITILESTRUCTURE */ - private final IStructureLogic structureLogic; - private boolean isMaster; - private int masterX, masterZ; - private int masterY = -99; - - @Override - public String getTypeUID() { - return structureLogic.getTypeUID(); - } - - @Override - public void validateStructure() { - structureLogic.validateStructure(); - } - - @Override - public void makeMaster() { - setCentralTE(null); - this.isMaster = true; - - if (worldObj != null && !worldObj.isRemote) { - setNeedsNetworkUpdate(); - } - } - - @Override - public void onStructureReset() { - setCentralTE(null); - if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord) == 1) { - worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 0); - } - isMaster = false; - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - } - - @Override - public ITileStructure getCentralTE() { - - if (!isIntegratedIntoStructure()) { - return null; - } - - if (isMaster) { - return this; - } - - TileEntity tile = worldObj.getTileEntity(masterX, masterY, masterZ); - if (tile instanceof ITileStructure) { - ITileStructure master = (ITileStructure) tile; - if (master.isMaster()) { - return master; - } - } - return null; - } - - private boolean isSameTile(TileEntity tile) { - return tile.xCoord == xCoord && tile.yCoord == yCoord && tile.zCoord == zCoord; - } - - @Override - public void setCentralTE(TileEntity tile) { - if (tile == null || tile == this || isSameTile(tile)) { - this.masterX = this.masterZ = 0; - this.masterY = -99; - return; - } - - this.isMaster = false; - this.masterX = tile.xCoord; - this.masterY = tile.yCoord; - this.masterZ = tile.zCoord; - - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - } - - @Override - public boolean isMaster() { - return isMaster; - } - - protected boolean hasMaster() { - return this.masterY >= 0; - } - - @Override - public IInventoryAdapter getStructureInventory() { - return getInternalInventory(); - } - - @Override - public boolean isIntegratedIntoStructure() { - return isMaster || this.masterY >= 0; - } - - @Override - public void registerListener(IFarmListener listener) { - } - - @Override - public void removeListener(IFarmListener listener) { - } -} diff --git a/src/main/java/forestry/farming/gadgets/TileFarmPlain.java b/src/main/java/forestry/farming/gadgets/TileFarmPlain.java deleted file mode 100755 index 6000a6f16..000000000 --- a/src/main/java/forestry/farming/gadgets/TileFarmPlain.java +++ /dev/null @@ -1,1019 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.farming.gadgets; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.TreeMap; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.ICrafting; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; - -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; - -import forestry.api.circuits.ChipsetManager; -import forestry.api.circuits.ICircuitBoard; -import forestry.api.core.BiomeHelper; -import forestry.api.core.EnumHumidity; -import forestry.api.core.EnumTemperature; -import forestry.api.farming.ICrop; -import forestry.api.farming.IFarmHousing; -import forestry.api.farming.IFarmListener; -import forestry.api.farming.IFarmLogic; -import forestry.api.farming.IFarmable; -import forestry.core.EnumErrorCode; -import forestry.core.GameMode; -import forestry.core.config.Config; -import forestry.core.config.Defaults; -import forestry.core.fluids.FluidHelper; -import forestry.core.fluids.Fluids; -import forestry.core.fluids.TankManager; -import forestry.core.fluids.tanks.FilteredTank; -import forestry.core.interfaces.IClimatised; -import forestry.core.interfaces.IHintSource; -import forestry.core.interfaces.ISocketable; -import forestry.core.inventory.IInventoryAdapter; -import forestry.core.inventory.InvTools; -import forestry.core.inventory.InventoryAdapter; -import forestry.core.inventory.TileInventoryAdapter; -import forestry.core.proxy.Proxies; -import forestry.core.utils.DelayTimer; -import forestry.core.utils.GuiUtil; -import forestry.core.utils.StackUtils; -import forestry.core.vect.Vect; -import forestry.core.vect.VectUtil; -import forestry.farming.FarmHelper; -import forestry.farming.FarmTarget; -import forestry.farming.logic.FarmLogic; -import forestry.farming.logic.FarmLogicArboreal; -import forestry.plugins.PluginFarming; - -public class TileFarmPlain extends TileFarm implements IFarmHousing, ISocketable, IClimatised, IHintSource { - - private enum Stage { - CULTIVATE, HARVEST; - - public Stage next() { - Stage[] values = values(); - int ordinal = (this.ordinal() + 1) % values.length; - return values[ordinal]; - } - } - - public static final ForgeDirection[] CARDINAL_DIRECTIONS = {ForgeDirection.NORTH, ForgeDirection.EAST, ForgeDirection.SOUTH, ForgeDirection.WEST}; - - public static ForgeDirection getLayoutDirection(ForgeDirection farmSide) { - switch (farmSide) { - case NORTH: - return ForgeDirection.WEST; - case WEST: - return ForgeDirection.SOUTH; - case SOUTH: - return ForgeDirection.EAST; - case EAST: - return ForgeDirection.NORTH; - default: - return ForgeDirection.UNKNOWN; - } - } - - public static final int SLOT_RESOURCES_1 = 0; - public static final int SLOT_RESOURCES_COUNT = 6; - public static final int SLOT_GERMLINGS_1 = 6; - public static final int SLOT_GERMLINGS_COUNT = 6; - public static final int SLOT_PRODUCTION_1 = 12; - public static final int SLOT_PRODUCTION_COUNT = 8; - - public static final int SLOT_FERTILIZER = 20; - public static final int SLOT_FERTILIZER_COUNT = 1; - public static final int SLOT_CAN = 21; - public static final int SLOT_CAN_COUNT = 1; - - public static final int SLOT_COUNT = SLOT_RESOURCES_COUNT + SLOT_GERMLINGS_COUNT + SLOT_PRODUCTION_COUNT + SLOT_FERTILIZER_COUNT + SLOT_CAN_COUNT; - - private static final int DELAY_HYDRATION = 100; - private static final float RAINFALL_MODIFIER_CAP = 15f; - private static final int BUFFER_FERTILIZER = 200; - - private IFarmLogic[] farmLogics = new IFarmLogic[4]; - - private TreeMap> targets; - private int allowedExtent = 0; - private final DelayTimer checkTimer = new DelayTimer(); - - private final InventoryAdapter sockets = new InventoryAdapter(1, "sockets"); - - private TankManager tankManager; - - private IFarmLogic harvestProvider; // The farm logic which supplied the pending crops. - private final Stack pendingCrops = new Stack(); - private final Stack pendingProduce = new Stack(); - private int storedFertilizer; - private int fertilizerValue = 2000; - - private Stage stage = Stage.CULTIVATE; - - private BiomeGenBase biome; - - private int hydrationDelay = 0; - private int ticksSinceRainfall = 0; - - public TileFarmPlain() { - fertilizerValue = GameMode.getGameMode().getIntegerSetting("farms.fertilizer.value"); - } - - @Override - public void validate() { - super.validate(); - setBiomeInformation(); - } - - /* SAVING & LOADING */ - @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - super.readFromNBT(nbttagcompound); - - storedFertilizer = nbttagcompound.getInteger("StoredFertilizer"); - hydrationDelay = nbttagcompound.getInteger("HydrationDelay"); - ticksSinceRainfall = nbttagcompound.getInteger("TicksSinceRainfall"); - sockets.readFromNBT(nbttagcompound); - - refreshFarmLogics(); - - if (tankManager != null) { - tankManager.readTanksFromNBT(nbttagcompound); - } - } - - @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - - sockets.writeToNBT(nbttagcompound); - nbttagcompound.setInteger("StoredFertilizer", storedFertilizer); - nbttagcompound.setInteger("HydrationDelay", hydrationDelay); - nbttagcompound.setInteger("TicksSinceRainfall", ticksSinceRainfall); - - if (tankManager != null) { - tankManager.writeTanksToNBT(nbttagcompound); - } - } - - /* UPDATING */ - @Override - protected void updateServerSide() { - super.updateServerSide(); - - if (!isMaster()) { - return; - } - - if (worldObj.isRaining()) { - if (hydrationDelay > 0) { - hydrationDelay--; - } else { - ticksSinceRainfall = 0; - } - } else { - hydrationDelay = DELAY_HYDRATION; - if (ticksSinceRainfall < Integer.MAX_VALUE) { - ticksSinceRainfall++; - } - } - - if (!updateOnInterval(20)) { - return; - } - - // Check if we have suitable items waiting in the item slot - if (getInternalInventory().getStackInSlot(SLOT_CAN) != null) { - FluidHelper.drainContainers(tankManager, getInternalInventory(), SLOT_CAN); - } - - } - - private void setBiomeInformation() { - this.biome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); - } - - private static TreeMap> createTargets(World world, Vect targetStart, final int allowedExtent, final int farmSizeNorthSouth, final int farmSizeEastWest) { - - TreeMap> targets = new TreeMap>(); - - for (ForgeDirection farmSide : CARDINAL_DIRECTIONS) { - - int farmSize; - if (farmSide == ForgeDirection.NORTH || farmSide == ForgeDirection.SOUTH) { - farmSize = farmSizeNorthSouth; - } else { - farmSize = farmSizeEastWest; - } - - // targets extend sideways in a pinwheel pattern around the farm, so they need to go a little extra distance - final int targetMaxLimit = allowedExtent + farmSize; - - ForgeDirection layoutDirection = getLayoutDirection(farmSide); - - Vect targetLocation = FarmHelper.getFarmMultiblockCorner(world, targetStart, farmSide, layoutDirection.getOpposite()); - Vect firstLocation = targetLocation.add(farmSide); - Vect firstGroundPosition = getGroundPosition(world, firstLocation); - if (firstGroundPosition == null) { - break; - } - int groundHeight = firstGroundPosition.getY(); - - List farmSideTargets = new ArrayList(); - for (int i = 0; i < allowedExtent; i++) { - targetLocation = targetLocation.add(farmSide); - Vect groundLocation = new Vect(targetLocation.getX(), groundHeight, targetLocation.getZ()); - - int targetLimit = targetMaxLimit; - if (!Config.squareFarms) { - targetLimit = targetMaxLimit - i - 1; - } - - Block platform = VectUtil.getBlock(world, groundLocation); - Vect soilPosition = new Vect(groundLocation.x, groundLocation.y + 1, groundLocation.z); - if (!StructureLogicFarm.bricks.contains(platform)) { - break; - } - - FarmTarget target = new FarmTarget(targetLocation, layoutDirection, targetLimit); - farmSideTargets.add(target); - } - - targets.put(farmSide, farmSideTargets); - } - - return targets; - } - - private void setExtents() { - for (List targetsList : targets.values()) { - if (!targetsList.isEmpty()) { - Vect groundPosition = getGroundPosition(worldObj, targetsList.get(0).getStart()); - - for (FarmTarget target : targetsList) { - target.setExtentAndYOffset(worldObj, groundPosition); - } - } - } - } - - private static Vect getGroundPosition(World world, Vect targetPosition) { - for (int yOffset = 2; yOffset > -4; yOffset--) { - Vect position = targetPosition.add(0, yOffset, 0); - Block ground = VectUtil.getBlock(world, position); - if (StructureLogicFarm.bricks.contains(ground)) { - return position; - } - } - return null; - } - - protected void createInventory() { - setInternalInventory(new FarmPlainInventoryAdapter(this)); - FilteredTank liquidTank = new FilteredTank(Defaults.PROCESSOR_TANK_CAPACITY, FluidRegistry.WATER); - tankManager = new TankManager(liquidTank); - } - - @Override - public boolean doWork() { - // System.out.println("Starting doWork()"); - if (targets == null || checkTimer.delayPassed(worldObj, 400)) { - Vect targetStart = new Vect(xCoord, yCoord, zCoord); - - int sizeNorthSouth = FarmHelper.getFarmSizeNorthSouth(worldObj, targetStart); - int sizeEastWest = FarmHelper.getFarmSizeEastWest(worldObj, targetStart); - - // Set the maximum allowed extent. - allowedExtent = Math.max(sizeNorthSouth, sizeEastWest) * 3; - - targets = createTargets(worldObj, targetStart, allowedExtent, sizeNorthSouth, sizeEastWest); - setExtents(); - } - - // System.out.println("Targets set"); - if (tryAddPending()) { - return true; - } - - // System.out.println("Nothing pending added."); - // Abort if we still have produce waiting. - if (setErrorCondition(!pendingProduce.isEmpty(), EnumErrorCode.NOSPACE)) { - return false; - } - - // System.out.println("Product queue empty."); - if (storedFertilizer <= BUFFER_FERTILIZER) { - replenishFertilizer(); - if (setErrorCondition(storedFertilizer <= 0, EnumErrorCode.NOFERTILIZER)) { - return false; - } - } - - // Cull queued crops. - if (!pendingCrops.isEmpty()) { - if (cullCrop(pendingCrops.peek(), harvestProvider)) { - pendingCrops.pop(); - return true; - } else { - return false; - } - } - - // Cultivation and collection - FarmWorkStatus farmWorkStatus = new FarmWorkStatus(); - - for (Map.Entry> entry : targets.entrySet()) { - - ForgeDirection farmSide = entry.getKey(); - IFarmLogic logic = getFarmLogic(farmSide); - if (logic == null) { - continue; - } - - // Allow listeners to cancel this cycle. - if (isCycleCanceledByListeners(logic, farmSide)) { - continue; - } - - // Always try to collect windfall first. - if (collectWindfall(logic)) { - farmWorkStatus.didWork = true; - } else { - List farmTargets = entry.getValue(); - - if (stage == Stage.HARVEST) { - farmWorkStatus.didWork = harvestTargets(farmTargets, logic); - } else { - farmWorkStatus = cultivateTargets(farmWorkStatus, farmTargets, logic); - } - } - - if (farmWorkStatus.didWork) { - break; - } - } - - if (!farmWorkStatus.didWork) { - if (stage == Stage.CULTIVATE) { - setErrorCondition(!farmWorkStatus.hasFarmland, EnumErrorCode.NOFARMLAND); - setErrorCondition(!farmWorkStatus.hasFertilizer, EnumErrorCode.NOFERTILIZER); - setErrorCondition(!farmWorkStatus.hasLiquid, EnumErrorCode.NOLIQUID); - } - } - - // Farms alternate between cultivation and harvest. - stage = stage.next(); - - return farmWorkStatus.didWork; - } - - private IFarmLogic getFarmLogic(ForgeDirection direction) { - int logicOrdinal = direction.ordinal() - 2; - if (farmLogics.length <= logicOrdinal) { - return null; - } - - return farmLogics[logicOrdinal]; - } - - private boolean isCycleCanceledByListeners(IFarmLogic logic, ForgeDirection direction) { - - for (IFarmListener listener : eventHandlers) { - if (listener.cancelTask(logic, direction)) { - return true; - } - } - - return false; - } - - private static class FarmWorkStatus { - public boolean didWork = false; - public boolean hasFarmland = false; - public boolean hasFertilizer = false; - public boolean hasLiquid = false; - } - - private FarmWorkStatus cultivateTargets(FarmWorkStatus farmWorkStatus, List farmTargets, IFarmLogic logic) { - - for (FarmTarget target : farmTargets) { - - if (target.getExtent() <= 0) { - break; - } else { - farmWorkStatus.hasFarmland = true; - } - - // Check fertilizer and water - if (!hasFertilizer(logic.getFertilizerConsumption())) { - continue; - } else { - farmWorkStatus.hasFertilizer = true; - } - - int liquidAmount = logic.getWaterConsumption(getHydrationModifier()); - FluidStack liquid = Fluids.WATER.getFluid(liquidAmount); - if (liquid.amount > 0 && !hasLiquid(liquid)) { - continue; - } else { - farmWorkStatus.hasLiquid = true; - } - - if (cultivateTarget(target, logic)) { - // Remove fertilizer and water - removeFertilizer(logic.getFertilizerConsumption()); - removeLiquid(liquid); - - farmWorkStatus.didWork = true; - } - } - - return farmWorkStatus; - } - - private boolean cultivateTarget(FarmTarget target, IFarmLogic logic) { - Vect targetPosition = target.getStart().add(0, target.getYOffset(), 0); - if (logic.cultivate(targetPosition.x, targetPosition.y, targetPosition.z, target.getDirection(), target.getExtent())) { - for (IFarmListener listener : eventHandlers) { - listener.hasCultivated(logic, targetPosition.x, targetPosition.y, targetPosition.z, target.getDirection(), target.getExtent()); - } - return true; - } - - return false; - } - - private boolean harvestTargets(List farmTargets, IFarmLogic logic) { - for (FarmTarget target : farmTargets) { - if (harvestTarget(target, logic)) { - return true; - } - } - - return false; - } - - private boolean harvestTarget(FarmTarget target, IFarmLogic logic) { - Collection next = logic.harvest(target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, target.getDirection(), target.getExtent()); - if (next == null || next.size() <= 0) { - return false; - } - - // Let event handlers know. - for (IFarmListener listener : eventHandlers) { - listener.hasScheduledHarvest(next, logic, target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, target.getDirection(), target.getExtent()); - } - - pendingCrops.addAll(next); - harvestProvider = logic; - return true; - } - - private boolean collectWindfall(IFarmLogic logic) { - - Collection collected = logic.collect(); - if (collected == null || collected.size() <= 0) { - return false; - } - - // Let event handlers know. - for (IFarmListener listener : eventHandlers) { - listener.hasCollected(collected, logic); - } - - for (ItemStack produce : collected) { - addProduceToInventory(produce); - pendingProduce.push(produce); - } - - return true; - } - - private void addProduceToInventory(ItemStack produce) { - IInventoryAdapter inventory = getInternalInventory(); - for (IFarmLogic logic : getFarmLogics()) { - // Germlings try to go into germling slots first. - if (logic.isAcceptedGermling(produce)) { - produce.stackSize -= InvTools.addStack(inventory, produce, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT, true); - } - if (produce.stackSize <= 0) { - return; - } - - if (logic.isAcceptedResource(produce)) { - produce.stackSize -= InvTools.addStack(inventory, produce, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT, true); - } - if (produce.stackSize <= 0) { - return; - } - } - - produce.stackSize -= InvTools.addStack(inventory, produce, SLOT_PRODUCTION_1, SLOT_PRODUCTION_COUNT, true); - } - - private boolean cullCrop(ICrop crop, IFarmLogic provider) { - - // Let event handlers handle the harvest first. - for (IFarmListener listener : eventHandlers) { - if (listener.beforeCropHarvest(crop)) { - return true; - } - } - - // Check fertilizer - Boolean hasFertilizer = hasFertilizer(provider.getFertilizerConsumption()); - if (setErrorCondition(!hasFertilizer, EnumErrorCode.NOFERTILIZER)) { - return false; - } - - // Check water - FluidStack requiredLiquid = Fluids.WATER.getFluid(provider.getWaterConsumption(getHydrationModifier())); - boolean hasLiquid = requiredLiquid.amount == 0 || hasLiquid(requiredLiquid); - - if (setErrorCondition(!hasLiquid, EnumErrorCode.NOLIQUID)) { - return false; - } - - Collection harvested = crop.harvest(); - if (harvested == null) { - Proxies.log.fine("Failed to harvest crop: " + crop.toString()); - return true; - } - - // Remove fertilizer and water - removeFertilizer(provider.getFertilizerConsumption()); - removeLiquid(requiredLiquid); - - // Let event handlers handle the harvest first. - for (IFarmListener listener : eventHandlers) { - listener.afterCropHarvest(harvested, crop); - } - - IInventoryAdapter inventory = getInternalInventory(); - - // Stow harvest. - for (ItemStack harvest : harvested) { - - // Special case germlings - for (IFarmLogic logic : farmLogics) { - if (logic.isAcceptedGermling(harvest)) { - harvest.stackSize -= InvTools.addStack(inventory, harvest, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT, true); - break; - } - } - - // Handle the rest - if (harvest.stackSize <= 0) { - continue; - } - - harvest.stackSize -= InvTools.addStack(inventory, harvest, SLOT_PRODUCTION_1, SLOT_PRODUCTION_COUNT, true); - if (harvest.stackSize <= 0) { - continue; - } - - pendingProduce.push(harvest); - } - - return true; - } - - private boolean tryAddPending() { - if (pendingProduce.isEmpty()) { - return false; - } - - ItemStack next = pendingProduce.peek(); - boolean added = InvTools.tryAddStack(getInternalInventory(), next, SLOT_PRODUCTION_1, SLOT_PRODUCTION_COUNT, true, true); - - if (added) { - pendingProduce.pop(); - } - - setErrorCondition(!added, EnumErrorCode.NOSPACE); - - return added; - } - - /* FERTILIZER HANDLING */ - private void replenishFertilizer() { - if (fertilizerValue < 0) { - storedFertilizer += 2000; - return; - } - - IInventoryAdapter inventory = getInternalInventory(); - ItemStack fertilizer = inventory.getStackInSlot(SLOT_FERTILIZER); - if (fertilizer == null || fertilizer.stackSize <= 0) { - return; - } - - if (!acceptsAsFertilizer(fertilizer)) { - return; - } - - inventory.decrStackSize(SLOT_FERTILIZER, 1); - storedFertilizer += fertilizerValue; - } - - private boolean hasFertilizer(int amount) { - if (fertilizerValue < 0) { - return true; - } - - return storedFertilizer >= amount; - } - - private void removeFertilizer(int amount) { - - if (fertilizerValue < 0) { - return; - } - - storedFertilizer -= amount; - if (storedFertilizer < 0) { - storedFertilizer = 0; - } - } - - public int getStoredFertilizerScaled(int scale) { - if (storedFertilizer == 0) { - return 0; - } - - return (storedFertilizer * scale) / (fertilizerValue + BUFFER_FERTILIZER); - } - - /* STRUCTURE HANDLING */ - @Override - public void makeMaster() { - super.makeMaster(); - refreshFarmLogics(); - createInventory(); - } - - public TankManager getTankManager() { - return tankManager; - } - - @Override - public void setFarmLogic(ForgeDirection direction, IFarmLogic logic) { - farmLogics[direction.ordinal() - 2] = logic; - } - - @Override - public void resetFarmLogic(ForgeDirection direction) { - setFarmLogic(direction, new FarmLogicArboreal(this)); - } - - public IFarmLogic[] getFarmLogics() { - return farmLogics; - } - - private void refreshFarmLogics() { - - farmLogics = new IFarmLogic[]{new FarmLogicArboreal(this), new FarmLogicArboreal(this), new FarmLogicArboreal(this), new FarmLogicArboreal(this)}; - - // See whether we have socketed stuff. - ItemStack chip = sockets.getStackInSlot(0); - if (chip != null) { - ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(chip); - if (chipset != null) { - chipset.onLoad(this); - } - } - } - - /* ISOCKETABLE */ - @Override - public int getSocketCount() { - return sockets.getSizeInventory(); - } - - @Override - public ItemStack getSocket(int slot) { - return sockets.getStackInSlot(slot); - } - - @Override - public void setSocket(int slot, ItemStack stack) { - - if (stack != null && !ChipsetManager.circuitRegistry.isChipset(stack)) { - return; - } - - // Dispose correctly of old chipsets - if (sockets.getStackInSlot(slot) != null) { - if (ChipsetManager.circuitRegistry.isChipset(sockets.getStackInSlot(slot))) { - ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(sockets.getStackInSlot(slot)); - if (chipset != null) { - chipset.onRemoval(this); - } - } - } - - sockets.setInventorySlotContents(slot, stack); - refreshFarmLogics(); - - if (stack == null) { - return; - } - - ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(stack); - if (chipset != null) { - chipset.onInsertion(this); - } - } - - /* IFARMHOUSING */ - @Override - public World getWorld() { - return worldObj; - } - - @Override - public boolean hasResources(ItemStack[] resources) { - return InvTools.contains(getInternalInventory(), resources, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT); - } - - public boolean hasResourcesAmount(int amount) { - return InvTools.containsAmount(getInternalInventory(), amount, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT); - } - - public boolean hasGermlingsPercent(float percent) { - return InvTools.containsPercent(getInternalInventory(), percent, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT); - } - - public boolean hasFertilizerPercent(float percent) { - return InvTools.containsPercent(getInternalInventory(), percent, SLOT_FERTILIZER, 1); - } - - @Override - public void removeResources(ItemStack[] resources) { - EntityPlayer player = Proxies.common.getPlayer(worldObj, getOwner()); - InvTools.removeSets(getInternalInventory(), 1, resources, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT, player, false, true, true); - } - - @Override - public boolean hasLiquid(FluidStack liquid) { - return tankManager.get(0).getFluidAmount() >= liquid.amount; - } - - @Override - public void removeLiquid(FluidStack liquid) { - tankManager.drain(liquid, true); - } - - public boolean hasGermlings(ItemStack[] germlings) { - return InvTools.contains(getInternalInventory(), germlings, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT); - } - - @Override - public boolean plantGermling(IFarmable germling, World world, int x, int y, int z) { - IInventoryAdapter inventory = getInternalInventory(); - for (int i = SLOT_GERMLINGS_1; i < SLOT_GERMLINGS_1 + SLOT_GERMLINGS_COUNT; i++) { - if (inventory.getStackInSlot(i) == null) { - continue; - } - if (!germling.isGermling(inventory.getStackInSlot(i))) { - continue; - } - - EntityPlayer player = Proxies.common.getPlayer(world, getOwner()); - if (!germling.plantSaplingAt(player, inventory.getStackInSlot(i), world, x, y, z)) { - continue; - } - - inventory.decrStackSize(i, 1); - return true; - } - return false; - } - - /* IFARMCOMPONENT */ - private final Set eventHandlers = new LinkedHashSet(); - - @Override - public boolean hasFunction() { - return false; - } - - @Override - public void registerListener(IFarmListener listener) { - eventHandlers.add(listener); - } - - @Override - public void removeListener(IFarmListener listener) { - eventHandlers.remove(listener); - } - - @Override - public boolean acceptsAsGermling(ItemStack itemstack) { - if (itemstack == null) { - return false; - } - if (farmLogics == null) { - return false; - } - - for (IFarmLogic logic : farmLogics) { - if (logic.isAcceptedGermling(itemstack)) { - return true; - } - } - - return false; - } - - @Override - public boolean acceptsAsResource(ItemStack itemstack) { - if (itemstack == null) { - return false; - } - if (farmLogics == null) { - return false; - } - - for (IFarmLogic logic : farmLogics) { - if (logic.isAcceptedResource(itemstack)) { - return true; - } - } - - return false; - } - - @Override - public boolean acceptsAsFertilizer(ItemStack itemstack) { - if (itemstack == null) { - return false; - } - - return StackUtils.isIdenticalItem(PluginFarming.farmFertilizer, itemstack); - } - - private int[] coords; - private int[] offset; - private int[] area; - - @Override - public int[] getCoords() { - if (coords == null) { - coords = new int[]{xCoord, yCoord, zCoord}; - } - return coords; - } - - @Override - public int[] getOffset() { - if (offset == null) { - offset = new int[]{-getArea()[0] / 2, -2, -getArea()[2] / 2}; - } - return offset; - } - - @Override - public int[] getArea() { - if (area == null) { - area = new int[]{7 + (allowedExtent * 2), 13, 7 + (allowedExtent * 2)}; - } - return area; - } - - /* NETWORK GUI */ - public void getGUINetworkData(int i, int j) { - if (tankManager != null) { - i -= tankManager.maxMessageId() + 1; - } - switch (i) { - case 0: - storedFertilizer = j; - break; - case 5: - ticksSinceRainfall = j; - break; - } - } - - public void sendGUINetworkData(Container container, ICrafting iCrafting) { - int i = tankManager.maxMessageId() + 1; - iCrafting.sendProgressBarUpdate(container, i, storedFertilizer); - iCrafting.sendProgressBarUpdate(container, i + 5, ticksSinceRainfall); - } - - /* ICLIMATISED */ - public float getHydrationModifier() { - return getHydrationTempModifier() * getHydrationHumidModifier() * getHydrationRainfallModifier(); - } - - public float getHydrationTempModifier() { - float temperature = getExactTemperature(); - return temperature > 0.8f ? temperature : 0.8f; - } - - public float getHydrationHumidModifier() { - float mod = 1 / getExactHumidity(); - return mod < 2.0f ? mod : 2.0f; - } - - public float getHydrationRainfallModifier() { - float mod = (float) ticksSinceRainfall / 24000; - return mod > 0.5f ? mod < RAINFALL_MODIFIER_CAP ? mod : RAINFALL_MODIFIER_CAP : 0.5f; - } - - public double getDrought() { - return Math.round(((double) ticksSinceRainfall / 24000) * 10) / 10.; - } - - @Override - public boolean isClimatized() { - return true; - } - - @Override - public EnumTemperature getTemperature() { - if (BiomeHelper.isBiomeHellish(biome)) { - return EnumTemperature.HELLISH; - } - - return EnumTemperature.getFromValue(getExactTemperature()); - } - - @Override - public EnumHumidity getHumidity() { - return EnumHumidity.getFromValue(getExactHumidity()); - } - - @Override - public float getExactTemperature() { - return biome.getFloatTemperature(xCoord, yCoord, zCoord); - } - - @Override - public float getExactHumidity() { - return biome.rainfall; - } - - /* IHINTSOURCE */ - @Override - public boolean hasHints() { - return Config.hints.get("farm").length > 0; - } - - @Override - public String[] getHints() { - return Config.hints.get("farm"); - } - - private static class FarmPlainInventoryAdapter extends TileInventoryAdapter { - public FarmPlainInventoryAdapter(TileFarmPlain tile) { - super(tile, TileFarmPlain.SLOT_COUNT, "Items"); - } - - @Override - public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { - if (GuiUtil.isIndexInRange(slotIndex, SLOT_FERTILIZER, SLOT_FERTILIZER_COUNT)) { - return tile.acceptsAsFertilizer(itemStack); - } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT)) { - return tile.acceptsAsGermling(itemStack); - } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT)) { - return tile.acceptsAsResource(itemStack); - } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_CAN, SLOT_CAN_COUNT)) { - Fluid fluid = FluidHelper.getFluidInContainer(itemStack); - return tile.tankManager.accepts(fluid); - } - return false; - } - - @Override - public boolean canExtractItem(int slotIndex, ItemStack stack, int side) { - return GuiUtil.isIndexInRange(slotIndex, SLOT_PRODUCTION_1, SLOT_PRODUCTION_COUNT); - } - } -} diff --git a/src/main/java/forestry/farming/gadgets/TileHatch.java b/src/main/java/forestry/farming/gadgets/TileHatch.java deleted file mode 100755 index 59613c6a5..000000000 --- a/src/main/java/forestry/farming/gadgets/TileHatch.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.farming.gadgets; - -import java.util.Collection; -import java.util.LinkedList; - -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.ISidedInventory; -import net.minecraft.tileentity.TileEntity; - -import net.minecraftforge.common.util.ForgeDirection; - -import cpw.mods.fml.common.Optional; - -import forestry.api.core.ITileStructure; -import forestry.core.inventory.AdjacentInventoryCache; -import forestry.core.inventory.IInventoryAdapter; -import forestry.core.inventory.ITileFilter; -import forestry.core.inventory.InvTools; -import forestry.core.inventory.wrappers.InventoryMapper; -import forestry.farming.triggers.FarmingTriggers; - -import buildcraft.api.statements.ITriggerExternal; - -public class TileHatch extends TileFarm implements ISidedInventory { - - private static final ForgeDirection[] dumpDirections = new ForgeDirection[]{ForgeDirection.DOWN}; - - private final AdjacentInventoryCache inventoryCache = new AdjacentInventoryCache(this, getTileCache(), new ITileFilter() { - - @Override - public boolean matches(TileEntity tile) { - return !(tile instanceof TileFarm) && tile.yCoord < yCoord; - } - }, null); - - public TileHatch() { - fixedType = TYPE_HATCH; - } - - @Override - public boolean hasFunction() { - return true; - } - - @Override - protected void updateServerSide() { - if (updateOnInterval(40)) { - dumpStash(); - } - } - - /* AUTO-EJECTING */ - private IInventory getProductInventory() { - IInventoryAdapter inventory = getStructureInventory(); - return new InventoryMapper(inventory, TileFarmPlain.SLOT_PRODUCTION_1, TileFarmPlain.SLOT_PRODUCTION_COUNT); - } - - protected void dumpStash() { - IInventory productInventory = getProductInventory(); - if (productInventory == null) { - return; - } - - if (!InvTools.moveOneItemToPipe(productInventory, tileCache, dumpDirections)) { - InvTools.moveItemStack(productInventory, inventoryCache.getAdjacentInventories()); - } - } - - /* IINVENTORY */ - @Override - public IInventoryAdapter getInternalInventory() { - ITileStructure central = getCentralTE(); - if (central instanceof TileFarmPlain) { - return ((TileFarmPlain) central).getInternalInventory(); - } - - return super.getInternalInventory(); - } - - /* ITRIGGERPROVIDER */ - @Optional.Method(modid = "BuildCraftAPI|statements") - @Override - public Collection getExternalTriggers(ForgeDirection side, TileEntity tile) { - if (!hasMaster()) { - return null; - } - - LinkedList list = new LinkedList(); - list.add(FarmingTriggers.lowResourceLiquid50); - list.add(FarmingTriggers.lowResourceLiquid25); - list.add(FarmingTriggers.lowSoil128); - list.add(FarmingTriggers.lowSoil64); - list.add(FarmingTriggers.lowSoil32); - list.add(FarmingTriggers.lowFertilizer50); - list.add(FarmingTriggers.lowFertilizer25); - list.add(FarmingTriggers.lowGermlings25); - list.add(FarmingTriggers.lowGermlings10); - return list; - } - -} diff --git a/src/main/java/forestry/farming/gui/ContainerFarm.java b/src/main/java/forestry/farming/gui/ContainerFarm.java index 176cad194..0d204278d 100755 --- a/src/main/java/forestry/farming/gui/ContainerFarm.java +++ b/src/main/java/forestry/farming/gui/ContainerFarm.java @@ -11,88 +11,73 @@ package forestry.farming.gui; import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.inventory.ICrafting; -import forestry.core.fluids.TankManager; -import forestry.core.fluids.tanks.StandardTank; +import net.minecraftforge.fluids.IFluidTank; + +import forestry.core.fluids.ITankManager; import forestry.core.gui.ContainerSocketed; import forestry.core.gui.slots.SlotFiltered; import forestry.core.gui.slots.SlotOutput; -import forestry.farming.gadgets.TileFarmPlain; +import forestry.core.network.PacketGuiUpdate; +import forestry.farming.multiblock.FarmInventory; +import forestry.farming.multiblock.TileFarm; -public class ContainerFarm extends ContainerSocketed { +public class ContainerFarm extends ContainerSocketed { - public ContainerFarm(InventoryPlayer playerInventory, TileFarmPlain tile) { + public ContainerFarm(InventoryPlayer playerInventory, TileFarm tile) { super(tile, playerInventory, 28, 138); // Resources for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { - addSlotToContainer(new SlotFiltered(tile, TileFarmPlain.SLOT_RESOURCES_1 + j + i * 2, 123 + j * 18, 22 + i * 18)); + addSlotToContainer(new SlotFiltered(tile, FarmInventory.SLOT_RESOURCES_1 + j + i * 2, 123 + j * 18, 22 + i * 18)); } } // Germlings for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { - addSlotToContainer(new SlotFiltered(tile, TileFarmPlain.SLOT_GERMLINGS_1 + j + i * 2, 164 + j * 18, 22 + i * 18)); + addSlotToContainer(new SlotFiltered(tile, FarmInventory.SLOT_GERMLINGS_1 + j + i * 2, 164 + j * 18, 22 + i * 18)); } } // Production 1 for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { - addSlotToContainer(new SlotOutput(tile, TileFarmPlain.SLOT_PRODUCTION_1 + j + i * 2, 123 + j * 18, 86 + i * 18)); + addSlotToContainer(new SlotOutput(tile, FarmInventory.SLOT_PRODUCTION_1 + j + i * 2, 123 + j * 18, 86 + i * 18)); } } // Production 2 for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { - addSlotToContainer(new SlotOutput(tile, TileFarmPlain.SLOT_PRODUCTION_1 + 4 + j + i * 2, 164 + j * 18, 86 + i * 18)); + addSlotToContainer(new SlotOutput(tile, FarmInventory.SLOT_PRODUCTION_1 + 4 + j + i * 2, 164 + j * 18, 86 + i * 18)); } } // Fertilizer - addSlotToContainer(new SlotFiltered(tile, TileFarmPlain.SLOT_FERTILIZER, 63, 95)); + addSlotToContainer(new SlotFiltered(tile, FarmInventory.SLOT_FERTILIZER, 63, 95)); // Can Slot - addSlotToContainer(new SlotFiltered(tile, TileFarmPlain.SLOT_CAN, 15, 95)); + addSlotToContainer(new SlotFiltered(tile, FarmInventory.SLOT_CAN, 15, 95)); } @Override public void updateProgressBar(int i, int j) { - tile.getGUINetworkData(i, j); - TankManager tankManager = tile.getTankManager(); + ITankManager tankManager = tile.getFarmController().getTankManager(); if (tankManager != null) { tankManager.processGuiUpdate(i, j); } } @Override - @SuppressWarnings("unchecked") public void detectAndSendChanges() { super.detectAndSendChanges(); - TankManager tankManager = tile.getTankManager(); - if (tankManager != null) { - tankManager.updateGuiData(this, crafters); - } - - for (Object crafter : crafters) { - tile.sendGUINetworkData(this, (ICrafting) crafter); - } + PacketGuiUpdate packet = new PacketGuiUpdate(tile); + sendPacketToCrafters(packet); } - @Override - public void addCraftingToCrafters(ICrafting iCrafting) { - super.addCraftingToCrafters(iCrafting); - TankManager tankManager = tile.getTankManager(); - if (tankManager != null) { - tankManager.initGuiData(this, iCrafting); - } - } - - public StandardTank getTank(int slot) { - return tile.getTankManager().get(slot); + public IFluidTank getTank(int slot) { + return tile.getFarmController().getTankManager().getTank(slot); } } diff --git a/src/main/java/forestry/farming/gui/FarmLedger.java b/src/main/java/forestry/farming/gui/FarmLedger.java new file mode 100644 index 000000000..b95f02708 --- /dev/null +++ b/src/main/java/forestry/farming/gui/FarmLedger.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.gui; + +import net.minecraft.init.Items; + +import forestry.core.gui.Ledger; +import forestry.core.gui.LedgerManager; +import forestry.core.utils.StringUtil; + +public class FarmLedger extends Ledger { + private final IFarmLedgerDelegate delegate; + + + public FarmLedger(LedgerManager ledgerManager, IFarmLedgerDelegate delegate) { + super(ledgerManager, "farm"); + this.maxHeight = 118; + this.delegate = delegate; + } + + @Override + public void draw(int x, int y) { + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(Items.water_bucket.getIconFromDamage(0), x + 3, y + 4); + + if (!isFullyOpened()) { + return; + } + + drawHeader(StringUtil.localize("gui.hydration"), x + 22, y + 8); + + drawSubheader(StringUtil.localize("gui.hydr.heat") + ':', x + 22, y + 20); + drawText(StringUtil.floatAsPercent(delegate.getHydrationTempModifier()), x + 22, y + 32); + + drawSubheader(StringUtil.localize("gui.hydr.humid") + ':', x + 22, y + 44); + drawText(StringUtil.floatAsPercent(delegate.getHydrationHumidModifier()), x + 22, y + 56); + + drawSubheader(StringUtil.localize("gui.hydr.rainfall") + ':', x + 22, y + 68); + drawText(StringUtil.floatAsPercent(delegate.getHydrationRainfallModifier()) + " (" + delegate.getDrought() + " d)", x + 22, y + 80); + + drawSubheader(StringUtil.localize("gui.hydr.overall") + ':', x + 22, y + 92); + drawText(StringUtil.floatAsPercent(delegate.getHydrationModifier()), x + 22, y + 104); + } + + @Override + public String getTooltip() { + return StringUtil.floatAsPercent(delegate.getHydrationModifier()) + ' ' + StringUtil.localize("gui.hydration"); + } +} \ No newline at end of file diff --git a/src/main/java/forestry/farming/gui/GuiFarm.java b/src/main/java/forestry/farming/gui/GuiFarm.java index c7fd937b5..cff75ee1b 100755 --- a/src/main/java/forestry/farming/gui/GuiFarm.java +++ b/src/main/java/forestry/farming/gui/GuiFarm.java @@ -11,78 +11,83 @@ package forestry.farming.gui; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; import net.minecraft.util.IIcon; import org.lwjgl.opengl.GL11; +import forestry.api.farming.FarmDirection; import forestry.api.farming.IFarmLogic; import forestry.core.config.Defaults; +import forestry.core.gui.ClimateLedger; import forestry.core.gui.GuiForestry; -import forestry.core.gui.Ledger; +import forestry.core.gui.OwnerLedger; import forestry.core.gui.WidgetManager; import forestry.core.gui.tooltips.ToolTip; import forestry.core.gui.widgets.SocketWidget; import forestry.core.gui.widgets.TankWidget; import forestry.core.gui.widgets.Widget; +import forestry.core.interfaces.IClimatised; import forestry.core.proxy.Proxies; import forestry.core.utils.StringUtil; -import forestry.farming.gadgets.TileFarmPlain; +import forestry.farming.multiblock.IFarmController; +import forestry.farming.multiblock.TileFarm; -public class GuiFarm extends GuiForestry { +public class GuiFarm extends GuiForestry { - protected class FarmLedger extends Ledger { + public GuiFarm(EntityPlayer player, TileFarm tile) { + super(Defaults.TEXTURE_PATH_GUI + "/mfarm.png", new ContainerFarm(player.inventory, tile), tile); - public FarmLedger() { - super(ledgerManager, "farm"); - maxHeight = 118; - } + widgetManager.add(new TankWidget(widgetManager, 15, 19, 0).setOverlayOrigin(216, 18)); - @Override - public void draw(int x, int y) { + widgetManager.add(new SocketWidget(widgetManager, 69, 40, tile, 0)); - // Draw background - drawBackground(x, y); + widgetManager.add(new FarmLogicSlot(widgetManager, 69, 22, FarmDirection.NORTH)); + widgetManager.add(new FarmLogicSlot(widgetManager, 69, 58, FarmDirection.SOUTH)); + widgetManager.add(new FarmLogicSlot(widgetManager, 51, 40, FarmDirection.EAST)); + widgetManager.add(new FarmLogicSlot(widgetManager, 87, 40, FarmDirection.WEST)); - // Draw icon - drawIcon(Items.water_bucket.getIconFromDamage(0), x + 3, y + 4); + this.xSize = 216; + this.ySize = 220; + } - if (!isFullyOpened()) { - return; - } + @Override + protected void initLedgers() { + super.initLedgers(); + IFarmController farmController = inventory.getFarmController(); + ledgerManager.add(new ClimateLedger(ledgerManager, farmController)); + ledgerManager.add(new FarmLedger(ledgerManager, farmController.getFarmLedgerDelegate())); + ledgerManager.add(new OwnerLedger(ledgerManager, farmController)); + } - drawHeader(StringUtil.localize("gui.hydration"), x + 22, y + 8); + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String title = StringUtil.localize("gui.farm.title"); + this.fontRendererObj.drawString(title, getCenteredOffset(title), 6, fontColor.get("gui.title")); + } - drawSubheader(StringUtil.localize("gui.hydr.heat") + ':', x + 22, y + 20); - drawText(StringUtil.floatAsPercent(inventory.getHydrationTempModifier()), x + 22, y + 32); + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); - drawSubheader(StringUtil.localize("gui.hydr.humid") + ':', x + 22, y + 44); - drawText(StringUtil.floatAsPercent(inventory.getHydrationHumidModifier()), x + 22, y + 56); - - drawSubheader(StringUtil.localize("gui.hydr.rainfall") + ':', x + 22, y + 68); - drawText(StringUtil.floatAsPercent(inventory.getHydrationRainfallModifier()) + " (" + inventory.getDrought() + " d)", x + 22, y + 80); - - drawSubheader(StringUtil.localize("gui.hydr.overall") + ':', x + 22, y + 92); - drawText(StringUtil.floatAsPercent(inventory.getHydrationModifier()), x + 22, y + 104); - } - - @Override - public String getTooltip() { - return StringUtil.floatAsPercent(inventory.getHydrationModifier()) + ' ' + StringUtil.localize("gui.hydration"); + // Fuel remaining + int fertilizerRemain = inventory.getFarmController().getStoredFertilizerScaled(16); + if (fertilizerRemain > 0) { + drawTexturedModalRect(guiLeft + 81, guiTop + 94 + 17 - fertilizerRemain, xSize, 17 - fertilizerRemain, 4, fertilizerRemain); } } private class FarmLogicSlot extends Widget { - private final int slot; + private final FarmDirection farmDirection; - public FarmLogicSlot(WidgetManager manager, int xPos, int yPos, int slot) { + public FarmLogicSlot(WidgetManager manager, int xPos, int yPos, FarmDirection farmDirection) { super(manager, xPos, yPos); - this.slot = slot; + this.farmDirection = farmDirection; } private IFarmLogic getLogic() { - return inventory.getFarmLogics()[slot]; + return inventory.getFarmController().getFarmLogic(farmDirection); } private IIcon getIconIndex() { @@ -121,49 +126,9 @@ public class GuiFarm extends GuiForestry { } toolTip.add(getLogic().getName()); toolTip.add("Fertilizer: " + getLogic().getFertilizerConsumption()); - toolTip.add("Water: " + getLogic().getWaterConsumption(inventory.getHydrationModifier())); + toolTip.add("Water: " + getLogic().getWaterConsumption(inventory.getFarmController().getFarmLedgerDelegate().getHydrationModifier())); } }; } - public GuiFarm(EntityPlayer player, TileFarmPlain tile) { - super(Defaults.TEXTURE_PATH_GUI + "/mfarm.png", new ContainerFarm(player.inventory, tile), tile); - - widgetManager.add(new TankWidget(widgetManager, 15, 19, 0).setOverlayOrigin(216, 18)); - - widgetManager.add(new SocketWidget(widgetManager, 69, 40, tile, 0)); - - widgetManager.add(new FarmLogicSlot(widgetManager, 69, 22, 0)); - widgetManager.add(new FarmLogicSlot(widgetManager, 69, 58, 1)); - widgetManager.add(new FarmLogicSlot(widgetManager, 51, 40, 2)); - widgetManager.add(new FarmLogicSlot(widgetManager, 87, 40, 3)); - - this.xSize = 216; - this.ySize = 220; - } - - @Override - protected void initLedgers() { - super.initLedgers(); - ledgerManager.insert(new FarmLedger()); - } - - @Override - protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { - super.drawGuiContainerForegroundLayer(mouseX, mouseY); - String title = StringUtil.localize("gui.farm.title"); - this.fontRendererObj.drawString(title, getCenteredOffset(title), 6, fontColor.get("gui.title")); - } - - @Override - protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { - super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); - - // Fuel remaining - int fertilizerRemain = inventory.getStoredFertilizerScaled(16); - if (fertilizerRemain > 0) { - drawTexturedModalRect(guiLeft + 81, guiTop + 94 + 17 - fertilizerRemain, xSize, 17 - fertilizerRemain, 4, fertilizerRemain); - } - - } } diff --git a/src/main/java/forestry/core/interfaces/IErrorSource.java b/src/main/java/forestry/farming/gui/IFarmLedgerDelegate.java old mode 100755 new mode 100644 similarity index 69% rename from src/main/java/forestry/core/interfaces/IErrorSource.java rename to src/main/java/forestry/farming/gui/IFarmLedgerDelegate.java index 4f69cb5fc..90457025c --- a/src/main/java/forestry/core/interfaces/IErrorSource.java +++ b/src/main/java/forestry/farming/gui/IFarmLedgerDelegate.java @@ -1,21 +1,23 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 SirSengir. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v3 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl-3.0.txt - * - * Various Contributors including, but not limited to: - * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges - ******************************************************************************/ -package forestry.core.interfaces; - -import com.google.common.collect.ImmutableSet; - -import forestry.api.core.IErrorState; - -public interface IErrorSource { - - ImmutableSet getErrorStates(); - -} +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.gui; + +public interface IFarmLedgerDelegate { + float getHydrationModifier(); + + float getHydrationTempModifier(); + + float getHydrationHumidModifier(); + + float getHydrationRainfallModifier(); + + double getDrought(); +} diff --git a/src/main/java/forestry/farming/items/ItemFarmBlock.java b/src/main/java/forestry/farming/items/ItemFarmBlock.java index 45554da45..d4d94f33e 100755 --- a/src/main/java/forestry/farming/items/ItemFarmBlock.java +++ b/src/main/java/forestry/farming/items/ItemFarmBlock.java @@ -18,7 +18,7 @@ import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import forestry.core.gadgets.IStructureBlockItem; -import forestry.farming.gadgets.EnumFarmBlock; +import forestry.farming.multiblock.EnumFarmBlockTexture; public class ItemFarmBlock extends ItemBlock implements IStructureBlockItem { @@ -39,7 +39,7 @@ public class ItemFarmBlock extends ItemBlock implements IStructureBlockItem { return; } - info.add(EnumFarmBlock.getFromCompound(itemstack.getTagCompound()).getName()); + info.add(EnumFarmBlockTexture.getFromCompound(itemstack.getTagCompound()).getName()); } @Override diff --git a/src/main/java/forestry/farming/logic/CropBasicAgriCraft.java b/src/main/java/forestry/farming/logic/CropBasicAgriCraft.java index 391777988..2aea9cced 100644 --- a/src/main/java/forestry/farming/logic/CropBasicAgriCraft.java +++ b/src/main/java/forestry/farming/logic/CropBasicAgriCraft.java @@ -44,7 +44,7 @@ public class CropBasicAgriCraft extends Crop { if (harvest.size() > 1) { harvest.remove(1); //AgriCraft returns cropsticks in 0, seeds in 1 in getDrops, removing since harvesting doesn't return them. } - harvest.remove(0); + harvest.remove(0); Proxies.common.addBlockDestroyEffects(world, pos.x, pos.y, pos.z, Blocks.melon_block, 0); world.setBlockMetadataWithNotify(pos.x, pos.y, pos.z, 0, Defaults.FLAG_BLOCK_SYNCH); return harvest; diff --git a/src/main/java/forestry/farming/logic/FarmLogic.java b/src/main/java/forestry/farming/logic/FarmLogic.java index 41a847955..4d798135d 100755 --- a/src/main/java/forestry/farming/logic/FarmLogic.java +++ b/src/main/java/forestry/farming/logic/FarmLogic.java @@ -18,6 +18,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; +import forestry.api.farming.FarmDirection; import forestry.api.farming.IFarmHousing; import forestry.api.farming.IFarmLogic; import forestry.core.config.Defaults; @@ -57,7 +58,8 @@ public abstract class FarmLogic implements IFarmLogic { world.getBlockMetadata(position.x, position.y, position.z) == 0; } - protected final Vect translateWithOffset(int x, int y, int z, ForgeDirection direction, int step) { + protected final Vect translateWithOffset(int x, int y, int z, FarmDirection farmDirection, int step) { + ForgeDirection direction = farmDirection.getForgeDirection(); return new Vect(x + direction.offsetX * step, y + direction.offsetY * step, z + direction.offsetZ * step); } diff --git a/src/main/java/forestry/farming/logic/FarmLogicArboreal.java b/src/main/java/forestry/farming/logic/FarmLogicArboreal.java index 1c6c1ea2e..ab3b265c5 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicArboreal.java +++ b/src/main/java/forestry/farming/logic/FarmLogicArboreal.java @@ -28,11 +28,10 @@ import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -129,7 +128,7 @@ public class FarmLogicArboreal extends FarmLogicHomogeneous { private final HashMap lastExtentsHarvest = new HashMap(); @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { Vect start = new Vect(x, y, z); if (!lastExtentsHarvest.containsKey(start)) { @@ -230,7 +229,7 @@ public class FarmLogicArboreal extends FarmLogicHomogeneous { } @Override - protected boolean maintainGermlings(int x, int ySaplings, int z, ForgeDirection direction, int extent) { + protected boolean maintainGermlings(int x, int ySaplings, int z, FarmDirection direction, int extent) { World world = getWorld(); diff --git a/src/main/java/forestry/farming/logic/FarmLogicCocoa.java b/src/main/java/forestry/farming/logic/FarmLogicCocoa.java index 0fbd8eeb1..841b20e4e 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicCocoa.java +++ b/src/main/java/forestry/farming/logic/FarmLogicCocoa.java @@ -29,6 +29,7 @@ import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; import forestry.api.farming.IFarmable; @@ -83,7 +84,7 @@ public class FarmLogicCocoa extends FarmLogic { private final HashMap lastExtentsCultivation = new HashMap(); @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { Vect start = new Vect(x, y, z); if (!lastExtentsCultivation.containsKey(start)) { @@ -107,7 +108,7 @@ public class FarmLogicCocoa extends FarmLogic { private final HashMap lastExtentsHarvest = new HashMap(); @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { Vect start = new Vect(x, y, z); if (!lastExtentsHarvest.containsKey(start)) { diff --git a/src/main/java/forestry/farming/logic/FarmLogicCrops.java b/src/main/java/forestry/farming/logic/FarmLogicCrops.java index b2ede7c18..e02d0b37c 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicCrops.java +++ b/src/main/java/forestry/farming/logic/FarmLogicCrops.java @@ -22,8 +22,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - +import forestry.api.farming.FarmDirection; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; import forestry.api.farming.IFarmable; @@ -106,7 +105,7 @@ public abstract class FarmLogicCrops extends FarmLogicWatered { } @Override - protected boolean maintainCrops(int x, int y, int z, ForgeDirection direction, int extent) { + protected boolean maintainCrops(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); @@ -143,7 +142,7 @@ public abstract class FarmLogicCrops extends FarmLogicWatered { } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); diff --git a/src/main/java/forestry/farming/logic/FarmLogicEnder.java b/src/main/java/forestry/farming/logic/FarmLogicEnder.java index 922c51c6d..bdce6fb86 100644 --- a/src/main/java/forestry/farming/logic/FarmLogicEnder.java +++ b/src/main/java/forestry/farming/logic/FarmLogicEnder.java @@ -19,11 +19,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -65,7 +64,7 @@ public class FarmLogicEnder extends FarmLogicHomogeneous { } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); @@ -84,7 +83,7 @@ public class FarmLogicEnder extends FarmLogicHomogeneous { } @Override - protected boolean maintainGermlings(int x, int y, int z, ForgeDirection direction, int extent) { + protected boolean maintainGermlings(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); for (int i = 0; i < extent; i++) { diff --git a/src/main/java/forestry/farming/logic/FarmLogicGourd.java b/src/main/java/forestry/farming/logic/FarmLogicGourd.java index cfd4b3f5f..737848ed2 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicGourd.java +++ b/src/main/java/forestry/farming/logic/FarmLogicGourd.java @@ -18,11 +18,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -76,12 +75,12 @@ public class FarmLogicGourd extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { return false; } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); diff --git a/src/main/java/forestry/farming/logic/FarmLogicHomogeneous.java b/src/main/java/forestry/farming/logic/FarmLogicHomogeneous.java index ba631bf3e..60c32b40e 100644 --- a/src/main/java/forestry/farming/logic/FarmLogicHomogeneous.java +++ b/src/main/java/forestry/farming/logic/FarmLogicHomogeneous.java @@ -16,8 +16,7 @@ import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - +import forestry.api.farming.FarmDirection; import forestry.api.farming.IFarmHousing; import forestry.api.farming.IFarmable; import forestry.core.utils.BlockUtil; @@ -70,7 +69,7 @@ public abstract class FarmLogicHomogeneous extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { if (maintainSoil(x, y, z, direction, extent)) { return true; @@ -83,9 +82,9 @@ public abstract class FarmLogicHomogeneous extends FarmLogic { return false; } - private boolean maintainSoil(int x, int yGround, int z, ForgeDirection direction, int extent) { + private boolean maintainSoil(int x, int yGround, int z, FarmDirection direction, int extent) { ItemStack[] resources = new ItemStack[]{resource}; - if (!housing.hasResources(resources)) { + if (!housing.getFarmInventory().hasResources(resources)) { return false; } @@ -114,12 +113,12 @@ public abstract class FarmLogicHomogeneous extends FarmLogic { produce.addAll(BlockUtil.getBlockDrops(world, position)); setBlock(position, StackUtils.getBlock(soilBlock), soilBlock.getItemDamage()); - housing.removeResources(resources); + housing.getFarmInventory().removeResources(resources); return true; } return false; } - protected abstract boolean maintainGermlings(int x, int ySaplings, int z, ForgeDirection direction, int extent); + protected abstract boolean maintainGermlings(int x, int ySaplings, int z, FarmDirection direction, int extent); } diff --git a/src/main/java/forestry/farming/logic/FarmLogicInfernal.java b/src/main/java/forestry/farming/logic/FarmLogicInfernal.java index 55e9dd12e..43a4970e1 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicInfernal.java +++ b/src/main/java/forestry/farming/logic/FarmLogicInfernal.java @@ -19,11 +19,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -65,7 +64,7 @@ public class FarmLogicInfernal extends FarmLogicHomogeneous { } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); @@ -84,7 +83,7 @@ public class FarmLogicInfernal extends FarmLogicHomogeneous { } @Override - protected boolean maintainGermlings(int x, int y, int z, ForgeDirection direction, int extent) { + protected boolean maintainGermlings(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); for (int i = 0; i < extent; i++) { diff --git a/src/main/java/forestry/farming/logic/FarmLogicOrchard.java b/src/main/java/forestry/farming/logic/FarmLogicOrchard.java index 5fd540d61..b392fbd97 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicOrchard.java +++ b/src/main/java/forestry/farming/logic/FarmLogicOrchard.java @@ -27,11 +27,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -88,12 +87,12 @@ public class FarmLogicOrchard extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { return false; } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { Vect start = new Vect(x, y, z); if (!lastExtents.containsKey(start)) { diff --git a/src/main/java/forestry/farming/logic/FarmLogicPeat.java b/src/main/java/forestry/farming/logic/FarmLogicPeat.java index bd9ddd469..911c4e401 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicPeat.java +++ b/src/main/java/forestry/farming/logic/FarmLogicPeat.java @@ -18,11 +18,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; import forestry.core.config.ForestryBlock; @@ -72,7 +71,7 @@ public class FarmLogicPeat extends FarmLogicWatered { } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); diff --git a/src/main/java/forestry/farming/logic/FarmLogicPoale.java b/src/main/java/forestry/farming/logic/FarmLogicPoale.java index 0e6d97952..bcbd84ffa 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicPoale.java +++ b/src/main/java/forestry/farming/logic/FarmLogicPoale.java @@ -19,11 +19,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -90,12 +89,12 @@ public class FarmLogicPoale extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { return false; } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); diff --git a/src/main/java/forestry/farming/logic/FarmLogicRubber.java b/src/main/java/forestry/farming/logic/FarmLogicRubber.java index b9a5b4fd3..ac59af8a5 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicRubber.java +++ b/src/main/java/forestry/farming/logic/FarmLogicRubber.java @@ -23,11 +23,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; import forestry.core.proxy.Proxies; @@ -89,14 +88,14 @@ public class FarmLogicRubber extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { return false; } private final HashMap lastExtents = new HashMap(); @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { if (inActive) { return null; } diff --git a/src/main/java/forestry/farming/logic/FarmLogicSucculent.java b/src/main/java/forestry/farming/logic/FarmLogicSucculent.java index be00a7d92..2041ed72c 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicSucculent.java +++ b/src/main/java/forestry/farming/logic/FarmLogicSucculent.java @@ -19,11 +19,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.farming.FarmDirection; import forestry.api.farming.Farmables; import forestry.api.farming.ICrop; import forestry.api.farming.IFarmHousing; @@ -90,12 +89,12 @@ public class FarmLogicSucculent extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { return false; } @Override - public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + public Collection harvest(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); Stack crops = new Stack(); diff --git a/src/main/java/forestry/farming/logic/FarmLogicWatered.java b/src/main/java/forestry/farming/logic/FarmLogicWatered.java index dd386528d..da92eb223 100755 --- a/src/main/java/forestry/farming/logic/FarmLogicWatered.java +++ b/src/main/java/forestry/farming/logic/FarmLogicWatered.java @@ -18,9 +18,9 @@ import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; +import forestry.api.farming.FarmDirection; import forestry.api.farming.IFarmHousing; import forestry.core.fluids.Fluids; import forestry.core.utils.BlockUtil; @@ -72,7 +72,7 @@ public abstract class FarmLogicWatered extends FarmLogic { } @Override - public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + public boolean cultivate(int x, int y, int z, FarmDirection direction, int extent) { if (maintainSoil(x, y, z, direction, extent)) { return true; @@ -89,7 +89,7 @@ public abstract class FarmLogicWatered extends FarmLogic { return false; } - private boolean maintainSoil(int x, int y, int z, ForgeDirection direction, int extent) { + private boolean maintainSoil(int x, int y, int z, FarmDirection direction, int extent) { World world = getWorld(); ItemStack[] resources = new ItemStack[]{resource}; @@ -99,7 +99,7 @@ public abstract class FarmLogicWatered extends FarmLogic { Block soil = VectUtil.getBlock(world, position); ItemStack soilStack = VectUtil.getAsItemStack(world, position); - if (isAcceptedGround(soilStack) || !housing.hasResources(resources)) { + if (isAcceptedGround(soilStack) || !housing.getFarmInventory().hasResources(resources)) { continue; } @@ -129,7 +129,7 @@ public abstract class FarmLogicWatered extends FarmLogic { return false; } - private boolean maintainWater(int x, int y, int z, ForgeDirection direction, int extent) { + private boolean maintainWater(int x, int y, int z, FarmDirection direction, int extent) { // Still not done, check water then World world = getWorld(); for (int i = 0; i < extent; i++) { @@ -149,17 +149,17 @@ public abstract class FarmLogicWatered extends FarmLogic { return false; } - protected boolean maintainCrops(int x, int y, int z, ForgeDirection direction, int extent) { + protected boolean maintainCrops(int x, int y, int z, FarmDirection direction, int extent) { return false; } private boolean trySetSoil(Vect position) { ItemStack[] resources = new ItemStack[]{resource}; - if (!housing.hasResources(resources)) { + if (!housing.getFarmInventory().hasResources(resources)) { return false; } setBlock(position, StackUtils.getBlock(ground), ground.getItemDamage()); - housing.removeResources(resources); + housing.getFarmInventory().removeResources(resources); return true; } diff --git a/src/main/java/forestry/farming/gadgets/BlockFarm.java b/src/main/java/forestry/farming/multiblock/BlockFarm.java old mode 100755 new mode 100644 similarity index 91% rename from src/main/java/forestry/farming/gadgets/BlockFarm.java rename to src/main/java/forestry/farming/multiblock/BlockFarm.java index 423ba8287..35b2352a3 --- a/src/main/java/forestry/farming/gadgets/BlockFarm.java +++ b/src/main/java/forestry/farming/multiblock/BlockFarm.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.farming.gadgets; +package forestry.farming.multiblock; import java.util.ArrayList; import java.util.List; @@ -59,7 +59,7 @@ public class BlockFarm extends BlockStructure { continue; } - for (EnumFarmBlock block : EnumFarmBlock.values()) { + for (EnumFarmBlockTexture block : EnumFarmBlockTexture.values()) { ItemStack stack = new ItemStack(item, 1, i); NBTTagCompound compound = new NBTTagCompound(); block.saveToCompound(compound); @@ -86,7 +86,7 @@ public class BlockFarm extends BlockStructure { } TileFarm tile = (TileFarm) world.getTileEntity(x, y, z); - tile.setFarmBlock(EnumFarmBlock.getFromCompound(stack.getTagCompound())); + tile.setFarmBlockTexture(EnumFarmBlockTexture.getFromCompound(stack.getTagCompound())); } @Override @@ -111,7 +111,7 @@ public class BlockFarm extends BlockStructure { ItemStack stack = new ItemStack(this, 1, meta != 1 ? meta : 0); NBTTagCompound compound = new NBTTagCompound(); - farm.getFarmBlock().saveToCompound(compound); + farm.getFarmBlockTexture().saveToCompound(compound); stack.setTagCompound(compound); drops.add(stack); } @@ -154,10 +154,9 @@ public class BlockFarm extends BlockStructure { @SideOnly(Side.CLIENT) @Override public void registerBlockIcons(IIconRegister register) { - EnumFarmBlock.registerIcons(register); + EnumFarmBlockTexture.registerIcons(register); } - private static class ParticleCallback implements ParticleHelperCallback { @Override @@ -176,7 +175,6 @@ public class BlockFarm extends BlockStructure { private void setTexture(EntityDiggingFX fx, World world, int x, int y, int z, int meta) { fx.setParticleIcon(instance.getIcon(world, x, y, z, 0)); } - } private static final ParticleHelperCallback callback = new ParticleCallback(); @@ -196,11 +194,11 @@ public class BlockFarm extends BlockStructure { @SideOnly(Side.CLIENT) @Override public IIcon getIcon(int side, int metadata) { - return getBlockTextureFromSideAndMetadata(EnumFarmBlock.BRICK, side, metadata); + return getBlockTextureFromSideAndMetadata(EnumFarmBlockTexture.BRICK, side, metadata); } @SideOnly(Side.CLIENT) - public IIcon getBlockTextureFromSideAndMetadata(EnumFarmBlock type, int side, int metadata) { + public IIcon getBlockTextureFromSideAndMetadata(EnumFarmBlockTexture type, int side, int metadata) { Block block = StackUtils.getBlock(type.getBase()); if (block == null) { return null; @@ -212,7 +210,7 @@ public class BlockFarm extends BlockStructure { @SideOnly(Side.CLIENT) public IIcon getOverlayTextureForBlock(int side, int metadata) { - EnumFarmBlock type = EnumFarmBlock.BRICK_STONE; + EnumFarmBlockTexture type = EnumFarmBlockTexture.BRICK_STONE; if (metadata == 0 && side == 2) { return type.getIcon(TileFarm.TYPE_REVERSE); } else if (metadata == 0 && (side == 0 || side == 1)) { @@ -244,10 +242,10 @@ public class BlockFarm extends BlockStructure { @SideOnly(Side.CLIENT) public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { TileEntity tile = world.getTileEntity(x, y, z); - ItemStack base = EnumFarmBlock.BRICK_STONE.getBase(); + ItemStack base = EnumFarmBlockTexture.BRICK_STONE.getBase(); if (tile instanceof TileFarm) { - base = ((TileFarm) tile).farmBlock.getBase(); + base = ((TileFarm) tile).farmBlockTexture.getBase(); } Block block = StackUtils.getBlock(base); @@ -257,4 +255,5 @@ public class BlockFarm extends BlockStructure { return block.getIcon(side, base.getItemDamage()); } + } diff --git a/src/main/java/forestry/farming/gadgets/EnumFarmBlock.java b/src/main/java/forestry/farming/multiblock/EnumFarmBlockTexture.java similarity index 88% rename from src/main/java/forestry/farming/gadgets/EnumFarmBlock.java rename to src/main/java/forestry/farming/multiblock/EnumFarmBlockTexture.java index 11a946ddb..0d948cd4d 100644 --- a/src/main/java/forestry/farming/gadgets/EnumFarmBlock.java +++ b/src/main/java/forestry/farming/multiblock/EnumFarmBlockTexture.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.farming.gadgets; +package forestry.farming.multiblock; import java.util.Arrays; import java.util.List; @@ -24,7 +24,7 @@ import cpw.mods.fml.relauncher.SideOnly; import forestry.core.render.TextureManager; -public enum EnumFarmBlock { +public enum EnumFarmBlockTexture { BRICK_STONE(new ItemStack(Blocks.stonebrick, 1, 0)), BRICK_MOSSY(new ItemStack(Blocks.stonebrick, 1, 1)), BRICK_CRACKED(new ItemStack(Blocks.stonebrick, 1, 2)), @@ -57,7 +57,7 @@ public enum EnumFarmBlock { private final ItemStack base; - EnumFarmBlock(ItemStack base) { + EnumFarmBlockTexture(ItemStack base) { this.base = base; } @@ -78,15 +78,15 @@ public enum EnumFarmBlock { return base; } - public static EnumFarmBlock getFromCompound(NBTTagCompound compound) { + public static EnumFarmBlockTexture getFromCompound(NBTTagCompound compound) { if (compound != null) { int farmBlockOrdinal = compound.getInteger("FarmBlock"); - if (farmBlockOrdinal < EnumFarmBlock.values().length) { - return EnumFarmBlock.values()[farmBlockOrdinal]; + if (farmBlockOrdinal < EnumFarmBlockTexture.values().length) { + return EnumFarmBlockTexture.values()[farmBlockOrdinal]; } } - return EnumFarmBlock.BRICK_STONE; + return EnumFarmBlockTexture.BRICK_STONE; } } diff --git a/src/main/java/forestry/farming/multiblock/FakeFarmController.java b/src/main/java/forestry/farming/multiblock/FakeFarmController.java new file mode 100644 index 000000000..fdbd1c8b2 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/FakeFarmController.java @@ -0,0 +1,280 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.io.IOException; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; + +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.IErrorLogic; +import forestry.api.farming.FarmDirection; +import forestry.api.farming.IFarmInventory; +import forestry.api.farming.IFarmLogic; +import forestry.api.farming.IFarmable; +import forestry.core.delegates.FakeAccessHandler; +import forestry.core.delegates.FakeErrorLogic; +import forestry.core.fluids.FakeTankManager; +import forestry.core.fluids.ITankManager; +import forestry.core.interfaces.IAccessHandler; +import forestry.core.inventory.FakeInventoryAdapter; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.utils.EnumAccess; +import forestry.farming.gui.IFarmLedgerDelegate; + +import io.netty.util.internal.EmptyArrays; + +public class FakeFarmController implements IFarmController { + public static final FakeFarmController instance = new FakeFarmController(); + + private FakeFarmController() { + + } + + @Override + public EnumTemperature getTemperature() { + return EnumTemperature.NORMAL; + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.NORMAL; + } + + @Override + public float getExactTemperature() { + return 0.5f; + } + + @Override + public float getExactHumidity() { + return 0.5f; + } + + @Override + public int[] getCoords() { + return EmptyArrays.EMPTY_INTS; + } + + @Override + public int[] getArea() { + return EmptyArrays.EMPTY_INTS; + } + + @Override + public int[] getOffset() { + return EmptyArrays.EMPTY_INTS; + } + + @Override + public World getWorld() { + return null; + } + + @Override + public boolean doWork() { + return false; + } + + @Override + public boolean hasLiquid(FluidStack liquid) { + return false; + } + + @Override + public void removeLiquid(FluidStack liquid) { + + } + + @Override + public boolean plantGermling(IFarmable farmable, World world, int x, int y, int z) { + return false; + } + + @Override + public IFarmInventory getFarmInventory() { + return FakeFarmInventory.instance; + } + + @Override + public void setFarmLogic(FarmDirection direction, IFarmLogic logic) { + + } + + @Override + public IFarmLogic getFarmLogic(FarmDirection direction) { + return null; + } + + @Override + public void resetFarmLogic(FarmDirection direction) { + + } + + @Override + public int getStoredFertilizerScaled(int scale) { + return 0; + } + + @Override + public IAccessHandler getAccessHandler() { + return FakeAccessHandler.getInstance(); + } + + @Override + public int getSocketCount() { + return 0; + } + + @Override + public ItemStack getSocket(int slot) { + return null; + } + + @Override + public void setSocket(int slot, ItemStack stack) { + + } + + @Override + public IErrorLogic getErrorLogic() { + return FakeErrorLogic.instance; + } + + @Override + public IFarmLedgerDelegate getFarmLedgerDelegate() { + return FakeFarmLedgerDelegate.instance; + } + + @Override + public IInventoryAdapter getInternalInventory() { + return FakeInventoryAdapter.instance(); + } + + @Override + public ITankManager getTankManager() { + return FakeTankManager.instance; + } + + @Override + public ChunkCoordinates getCoordinates() { + return null; + } + + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + + } + + private static class FakeFarmInventory implements IFarmInventory { + public static final FakeFarmInventory instance = new FakeFarmInventory(); + + private FakeFarmInventory() { + + } + + @Override + public boolean hasResources(ItemStack[] resources) { + return false; + } + + @Override + public void removeResources(ItemStack[] resources) { + + } + + @Override + public boolean acceptsAsGermling(ItemStack itemstack) { + return false; + } + + @Override + public boolean acceptsAsResource(ItemStack itemstack) { + return false; + } + + @Override + public boolean acceptsAsFertilizer(ItemStack itemstack) { + return false; + } + + @Override + public IInventory getProductInventory() { + return FakeInventoryAdapter.instance(); + } + + @Override + public IInventory getGermlingsInventory() { + return FakeInventoryAdapter.instance(); + } + + @Override + public IInventory getResourcesInventory() { + return FakeInventoryAdapter.instance(); + } + + @Override + public IInventory getFertilizerInventory() { + return FakeInventoryAdapter.instance(); + } + } + + private static class FakeFarmLedgerDelegate implements IFarmLedgerDelegate { + public static final FakeFarmLedgerDelegate instance = new FakeFarmLedgerDelegate(); + + private FakeFarmLedgerDelegate() { + + } + + @Override + public float getHydrationModifier() { + return 0; + } + + @Override + public float getHydrationTempModifier() { + return 0; + } + + @Override + public float getHydrationHumidModifier() { + return 0; + } + + @Override + public float getHydrationRainfallModifier() { + return 0; + } + + @Override + public double getDrought() { + return 0; + } + } +} diff --git a/src/main/java/forestry/farming/multiblock/FarmController.java b/src/main/java/forestry/farming/multiblock/FarmController.java new file mode 100644 index 000000000..08350da03 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/FarmController.java @@ -0,0 +1,850 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuitBoard; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.IErrorLogic; +import forestry.api.farming.FarmDirection; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmComponent; +import forestry.api.farming.IFarmInventory; +import forestry.api.farming.IFarmListener; +import forestry.api.farming.IFarmLogic; +import forestry.api.farming.IFarmable; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.fluids.Fluids; +import forestry.core.fluids.TankManager; +import forestry.core.fluids.tanks.FilteredTank; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.inventory.InventoryAdapter; +import forestry.core.multiblock.CoordTriplet; +import forestry.core.multiblock.IMultiblockPart; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockTileEntityBase; +import forestry.core.multiblock.MultiblockValidationException; +import forestry.core.multiblock.rectangular.RectangularMultiblockControllerBase; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.PacketGuiUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; +import forestry.core.vect.Vect; +import forestry.core.vect.VectUtil; +import forestry.farming.FarmHelper; +import forestry.farming.FarmTarget; +import forestry.farming.gadgets.StructureLogicFarm; +import forestry.farming.gui.IFarmLedgerDelegate; +import forestry.farming.logic.FarmLogicArboreal; + +public class FarmController extends RectangularMultiblockControllerBase implements IFarmController { + + private enum Stage { + CULTIVATE, HARVEST; + + public Stage next() { + if (this == CULTIVATE) { + return HARVEST; + } else { + return CULTIVATE; + } + } + } + + public static FarmDirection getLayoutDirection(FarmDirection farmSide) { + switch (farmSide) { + case NORTH: + return FarmDirection.WEST; + case WEST: + return FarmDirection.SOUTH; + case SOUTH: + return FarmDirection.EAST; + case EAST: + return FarmDirection.NORTH; + } + return null; + } + + private final Map> targets = new EnumMap>(FarmDirection.class); + private int allowedExtent = 0; + + private IFarmLogic harvestProvider; // The farm logic which supplied the pending crops. + private final Stack pendingCrops = new Stack(); + private final Stack pendingProduce = new Stack(); + + private Stage stage = Stage.CULTIVATE; + + // active components are stored with a tick offset so they do not all tick together + private final Map farmActiveComponents = new HashMap(); + private final Set farmListeners = new HashSet(); + + private final Map farmLogics = new EnumMap(FarmDirection.class); + + private final InventoryAdapter sockets; + private final FarmInventory inventory; + private final TankManager tankManager; + private final FarmHydrationManager hydrationManager; + private final FarmFertilizerManager fertilizerManager; + + private BiomeGenBase cachedBiome; + + protected FarmController(World world) { + super(world); + + FilteredTank liquidTank = new FilteredTank(Defaults.PROCESSOR_TANK_CAPACITY, FluidRegistry.WATER); + this.tankManager = new TankManager(liquidTank); + + this.inventory = new FarmInventory(this); + this.sockets = new InventoryAdapter(1, "sockets"); + this.hydrationManager = new FarmHydrationManager(this); + this.fertilizerManager = new FarmFertilizerManager(); + + refreshFarmLogics(); + } + + @Override + public IFarmLedgerDelegate getFarmLedgerDelegate() { + return hydrationManager; + } + + @Override + public IInventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + public TankManager getTankManager() { + return tankManager; + } + + public BiomeGenBase getBiome() { + if (cachedBiome == null) { + CoordTriplet coords = getReferenceCoord(); + cachedBiome = worldObj.getBiomeGenForCoords(coords.x, coords.z); + } + return cachedBiome; + } + + @Override + public void onAttachedPartWithMultiblockData(IMultiblockPart part, NBTTagCompound data) { + this.readFromNBT(data); + } + + @Override + protected void onBlockAdded(IMultiblockPart newPart) { + if (newPart instanceof IFarmComponent.Listener) { + IFarmComponent.Listener listenerPart = (IFarmComponent.Listener) newPart; + farmListeners.add(listenerPart.getFarmListener()); + } + + if (newPart instanceof IFarmComponent.Active) { + farmActiveComponents.put((IFarmComponent.Active) newPart, worldObj.rand.nextInt(256)); + } + } + + @Override + protected void onBlockRemoved(IMultiblockPart oldPart) { + if (oldPart instanceof IFarmComponent.Listener) { + IFarmComponent.Listener listenerPart = (IFarmComponent.Listener) oldPart; + farmListeners.remove(listenerPart.getFarmListener()); + } + + if (oldPart instanceof IFarmComponent.Active) { + farmActiveComponents.remove(oldPart); + } + } + + @Override + protected void isMachineWhole() throws MultiblockValidationException { + super.isMachineWhole(); + + boolean hasGearbox = false; + for (IMultiblockPart part : connectedParts) { + if (part instanceof TileGearbox) { + hasGearbox = true; + break; + } + } + + if (!hasGearbox) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.farm.error.needGearbox")); + } + } + + @Override + protected void onMachineDisassembled() { + super.onMachineDisassembled(); + targets.clear(); + } + + @Override + protected int getMinimumNumberOfBlocksForAssembledMachine() { + return 3 * 3 * 4; + } + + @Override + protected int getMaximumXSize() { + return 5; + } + + @Override + protected int getMaximumZSize() { + return 5; + } + + @Override + protected int getMaximumYSize() { + return 4; + } + + @Override + protected int getMinimumXSize() { + return 3; + } + + @Override + protected int getMinimumZSize() { + return 3; + } + + @Override + protected int getMinimumYSize() { + return 4; + } + + @Override + protected void onAssimilate(MultiblockControllerBase assimilated) { + + } + + @Override + protected void onAssimilated(MultiblockControllerBase assimilator) { + + } + + @Override + protected boolean updateServer(int tickCount) { + hydrationManager.updateServer(worldObj); + + if (updateOnInterval(20)) { + inventory.drainCan(tankManager); + } + + for (Map.Entry entry : farmActiveComponents.entrySet()) { + IFarmComponent.Active farmComponent = entry.getKey(); + int tickOffset = entry.getValue(); + farmComponent.updateServer(tickCount + tickOffset); + } + + //FIXME: be smarter about the farm needing to save + return true; + } + + @Override + protected void updateClient(int tickCount) { + for (Map.Entry entry : farmActiveComponents.entrySet()) { + IFarmComponent.Active farmComponent = entry.getKey(); + int tickOffset = entry.getValue(); + farmComponent.updateClient(tickCount + tickOffset); + } + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + sockets.writeToNBT(data); + hydrationManager.writeToNBT(data); + tankManager.writeTanksToNBT(data); + fertilizerManager.writeToNBT(data); + inventory.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + sockets.readFromNBT(data); + hydrationManager.readFromNBT(data); + tankManager.readTanksFromNBT(data); + fertilizerManager.readFromNBT(data); + inventory.readFromNBT(data); + + refreshFarmLogics(); + } + + @Override + public void formatDescriptionPacket(NBTTagCompound data) { + sockets.writeToNBT(data); + hydrationManager.writeToNBT(data); + tankManager.writeTanksToNBT(data); + fertilizerManager.writeToNBT(data); + } + + @Override + public void decodeDescriptionPacket(NBTTagCompound data) { + sockets.readFromNBT(data); + hydrationManager.readFromNBT(data); + tankManager.readTanksFromNBT(data); + fertilizerManager.readFromNBT(data); + + refreshFarmLogics(); + } + + @Override + public ChunkCoordinates getCoordinates() { + CoordTriplet coord = getReferenceCoord(); + return new ChunkCoordinates(coord.x, coord.y, coord.z); + } + + @Override + public void onSwitchAccess(EnumAccess oldAccess, EnumAccess newAccess) { + PacketGuiUpdate packet = new PacketGuiUpdate(this); + Proxies.net.sendNetworkPacket(packet); + + if (oldAccess == EnumAccess.SHARED || newAccess == EnumAccess.SHARED) { + // pipes connected to this need to update + for (IMultiblockPart part : connectedParts) { + if (part instanceof MultiblockTileEntityBase) { + MultiblockTileEntityBase tile = (MultiblockTileEntityBase) part; + tile.notifyNeighborsOfBlockChange(); + } + } + markDirty(); + } + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + super.writeGuiData(data); + tankManager.writePacketData(data); + hydrationManager.writeData(data); + fertilizerManager.writeData(data); + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + super.readGuiData(data); + tankManager.readPacketData(data); + hydrationManager.readData(data); + fertilizerManager.readData(data); + } + + private void refreshFarmLogics() { + for (FarmDirection direction : FarmDirection.values()) { + resetFarmLogic(direction); + } + + // See whether we have socketed stuff. + ItemStack chip = sockets.getStackInSlot(0); + if (chip != null) { + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(chip); + if (chipset != null) { + chipset.onLoad(this); + } + } + } + + @Override + public EnumTemperature getTemperature() { + CoordTriplet coords = getReferenceCoord(); + return EnumTemperature.getFromBiome(getBiome(), coords.x, coords.y, coords.z); + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.getFromValue(getExactHumidity()); + } + + @Override + public float getExactTemperature() { + CoordTriplet coords = getReferenceCoord(); + return getBiome().getFloatTemperature(coords.x, coords.y, coords.z); + } + + @Override + public float getExactHumidity() { + return getBiome().rainfall; + } + + private int[] coords; + private int[] offset; + private int[] area; + + @Override + public int[] getCoords() { + if (coords == null) { + CoordTriplet centerCoord = getCenterCoord(); + coords = new int[]{centerCoord.x, centerCoord.y, centerCoord.z}; + } + return coords; + } + + @Override + public int[] getOffset() { + if (offset == null) { + offset = new int[]{-getArea()[0] / 2, -2, -getArea()[2] / 2}; + } + return offset; + } + + @Override + public int[] getArea() { + if (area == null) { + area = new int[]{7 + (allowedExtent * 2), 13, 7 + (allowedExtent * 2)}; + } + return area; + } + + @Override + public World getWorld() { + return worldObj; + } + + @Override + public boolean doWork() { + if (targets.isEmpty() || updateOnInterval(400)) { + setUpFarmlandTargets(); + } + + IErrorLogic errorLogic = getErrorLogic(); + + if (!pendingProduce.isEmpty()) { + boolean added = inventory.tryAddPendingProduce(pendingProduce); + errorLogic.setCondition(!added, EnumErrorCode.NOSPACE); + return added; + } + + boolean hasFertilizer = fertilizerManager.maintainFertilizer(inventory); + if (errorLogic.setCondition(!hasFertilizer, EnumErrorCode.NOFERTILIZER)) { + return false; + } + + // Cull queued crops. + if (!pendingCrops.isEmpty()) { + if (cullCrop(pendingCrops.peek(), harvestProvider)) { + pendingCrops.pop(); + return true; + } else { + return false; + } + } + + // Cultivation and collection + FarmWorkStatus farmWorkStatus = new FarmWorkStatus(); + + for (FarmDirection farmSide : FarmDirection.values()) { + + IFarmLogic logic = getFarmLogic(farmSide); + if (logic == null) { + continue; + } + + // Allow listeners to cancel this cycle. + if (isCycleCanceledByListeners(logic, farmSide, farmListeners)) { + continue; + } + + // Always try to collect windfall. + if (collectWindfall(logic)) { + farmWorkStatus.didWork = true; + } + + List farmTargets = targets.get(farmSide); + + if (stage == Stage.HARVEST) { + Collection harvested = harvestTargets(farmTargets, logic, farmListeners); + farmWorkStatus.didWork = harvested.size() > 0; + if (harvested.size() > 0) { + pendingCrops.addAll(harvested); + harvestProvider = logic; + } + } else if (stage == Stage.CULTIVATE) { + farmWorkStatus = cultivateTargets(farmWorkStatus, farmTargets, logic); + } + + if (farmWorkStatus.didWork) { + break; + } + } + + if (stage == Stage.CULTIVATE) { + errorLogic.setCondition(!farmWorkStatus.hasFarmland, EnumErrorCode.NOFARMLAND); + errorLogic.setCondition(!farmWorkStatus.hasFertilizer, EnumErrorCode.NOFERTILIZER); + errorLogic.setCondition(!farmWorkStatus.hasLiquid, EnumErrorCode.NOLIQUID); + } + + // alternate between cultivation and harvest. + stage = stage.next(); + + return farmWorkStatus.didWork; + } + + private void setUpFarmlandTargets() { + Vect targetStart = new Vect(getCoords()); + + CoordTriplet max = getMaximumCoord(); + CoordTriplet min = getMinimumCoord(); + + int sizeNorthSouth = Math.abs(max.z - min.z) + 1; + int sizeEastWest = Math.abs(max.x - min.x) + 1; + + // Set the maximum allowed extent. + allowedExtent = Math.max(sizeNorthSouth, sizeEastWest) * Config.farmSize + 1; + + createTargets(worldObj, targets, targetStart, allowedExtent, sizeNorthSouth, sizeEastWest); + setExtents(worldObj, targets); + } + + private static void createTargets(World world, Map> targets, Vect targetStart, final int allowedExtent, final int farmSizeNorthSouth, final int farmSizeEastWest) { + + for (FarmDirection farmSide : FarmDirection.values()) { + + final int farmWidth; + if (farmSide == FarmDirection.NORTH || farmSide == FarmDirection.SOUTH) { + farmWidth = farmSizeEastWest; + } else { + farmWidth = farmSizeNorthSouth; + } + + // targets extend sideways in a pinwheel pattern around the farm, so they need to go a little extra distance + final int targetMaxLimit = allowedExtent + farmWidth; + + FarmDirection layoutDirection = getLayoutDirection(farmSide); + + Vect targetLocation = FarmHelper.getFarmMultiblockCorner(world, targetStart, farmSide, layoutDirection); + Vect firstLocation = targetLocation.add(farmSide); + Vect firstGroundPosition = getGroundPosition(world, firstLocation); + if (firstGroundPosition == null) { + continue; + } + int groundHeight = firstGroundPosition.getY(); + + List farmSideTargets = new ArrayList(); + for (int i = 0; i < allowedExtent; i++) { + targetLocation = targetLocation.add(farmSide); + Vect groundLocation = new Vect(targetLocation.getX(), groundHeight, targetLocation.getZ()); + + int targetLimit = targetMaxLimit; + if (!Config.squareFarms) { + targetLimit = targetMaxLimit - i - 1; + } + + Block platform = VectUtil.getBlock(world, groundLocation); + if (!StructureLogicFarm.bricks.contains(platform)) { + break; + } + + FarmTarget target = new FarmTarget(targetLocation, layoutDirection, targetLimit); + farmSideTargets.add(target); + } + + targets.put(farmSide, farmSideTargets); + } + } + + private static Vect getGroundPosition(World world, Vect targetPosition) { + for (int yOffset = 2; yOffset > -4; yOffset--) { + Vect position = targetPosition.add(0, yOffset, 0); + Block ground = VectUtil.getBlock(world, position); + if (StructureLogicFarm.bricks.contains(ground)) { + return position; + } + } + return null; + } + + private static boolean isCycleCanceledByListeners(IFarmLogic logic, FarmDirection direction, Iterable farmListeners) { + for (IFarmListener listener : farmListeners) { + if (listener.cancelTask(logic, direction)) { + return true; + } + } + return false; + } + + private static void setExtents(World worldObj, Map> targets) { + for (List targetsList : targets.values()) { + if (!targetsList.isEmpty()) { + Vect groundPosition = getGroundPosition(worldObj, targetsList.get(0).getStart()); + + for (FarmTarget target : targetsList) { + target.setExtentAndYOffset(worldObj, groundPosition); + } + } + } + } + + private static class FarmWorkStatus { + public boolean didWork = false; + public boolean hasFarmland = false; + public boolean hasFertilizer = false; + public boolean hasLiquid = false; + } + + private FarmWorkStatus cultivateTargets(FarmWorkStatus farmWorkStatus, List farmTargets, IFarmLogic logic) { + float hydrationModifier = hydrationManager.getHydrationModifier(); + + final int fertilizerConsumption = logic.getFertilizerConsumption(); + int liquidConsumption = logic.getWaterConsumption(hydrationModifier); + FluidStack liquid = Fluids.WATER.getFluid(liquidConsumption); + + if (farmTargets != null) { + for (FarmTarget target : farmTargets) { + if (target.getExtent() <= 0) { + break; + } else { + farmWorkStatus.hasFarmland = true; + } + + // Check fertilizer and water + if (!fertilizerManager.hasFertilizer(fertilizerConsumption)) { + continue; + } + + if (liquid.amount > 0 && !hasLiquid(liquid)) { + continue; + } + + if (cultivateTarget(target, logic, farmListeners)) { + // Remove fertilizer and water + fertilizerManager.removeFertilizer(fertilizerConsumption); + removeLiquid(liquid); + + farmWorkStatus.didWork = true; + } + } + } + + farmWorkStatus.hasLiquid = liquid.amount <= 0 || hasLiquid(liquid); + farmWorkStatus.hasFertilizer = fertilizerManager.hasFertilizer(fertilizerConsumption); + + return farmWorkStatus; + } + + private static boolean cultivateTarget(FarmTarget target, IFarmLogic logic, Iterable farmListeners) { + Vect targetPosition = target.getStart().add(0, target.getYOffset(), 0); + if (logic.cultivate(targetPosition.x, targetPosition.y, targetPosition.z, target.getDirection(), target.getExtent())) { + for (IFarmListener listener : farmListeners) { + listener.hasCultivated(logic, targetPosition.x, targetPosition.y, targetPosition.z, target.getDirection(), target.getExtent()); + } + return true; + } + + return false; + } + + private static Collection harvestTargets(List farmTargets, IFarmLogic logic, Iterable farmListeners) { + if (farmTargets != null) { + for (FarmTarget target : farmTargets) { + Collection harvested = harvestTarget(target, logic, farmListeners); + if (harvested.size() > 0) { + return harvested; + } + } + } + + return Collections.emptyList(); + } + + private static Collection harvestTarget(FarmTarget target, IFarmLogic logic, Iterable farmListeners) { + Collection harvested = logic.harvest(target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, target.getDirection(), target.getExtent()); + if (harvested == null || harvested.size() == 0) { + return Collections.emptyList(); + } + + // Let event handlers know. + for (IFarmListener listener : farmListeners) { + listener.hasScheduledHarvest(harvested, logic, target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, target.getDirection(), target.getExtent()); + } + + return harvested; + } + + private boolean collectWindfall(IFarmLogic logic) { + + Collection collected = logic.collect(); + if (collected == null || collected.size() <= 0) { + return false; + } + + // Let event handlers know. + for (IFarmListener listener : farmListeners) { + listener.hasCollected(collected, logic); + } + + for (ItemStack produce : collected) { + inventory.addProduce(produce); + pendingProduce.push(produce); + } + + return true; + } + + private boolean cullCrop(ICrop crop, IFarmLogic provider) { + + // Let event handlers handle the harvest first. + for (IFarmListener listener : farmListeners) { + if (listener.beforeCropHarvest(crop)) { + return true; + } + } + + final int fertilizerConsumption = provider.getFertilizerConsumption(); + + IErrorLogic errorLogic = getErrorLogic(); + + // Check fertilizer + Boolean hasFertilizer = fertilizerManager.hasFertilizer(fertilizerConsumption); + if (errorLogic.setCondition(!hasFertilizer, EnumErrorCode.NOFERTILIZER)) { + return false; + } + + // Check water + float hydrationModifier = hydrationManager.getHydrationModifier(); + int waterConsumption = provider.getWaterConsumption(hydrationModifier); + FluidStack requiredLiquid = Fluids.WATER.getFluid(waterConsumption); + boolean hasLiquid = requiredLiquid.amount == 0 || hasLiquid(requiredLiquid); + + if (errorLogic.setCondition(!hasLiquid, EnumErrorCode.NOLIQUID)) { + return false; + } + + Collection harvested = crop.harvest(); + if (harvested == null) { + Proxies.log.fine("Failed to harvest crop: " + crop.toString()); + return true; + } + + // Remove fertilizer and water + fertilizerManager.removeFertilizer(fertilizerConsumption); + removeLiquid(requiredLiquid); + + // Let event handlers handle the harvest first. + for (IFarmListener listener : farmListeners) { + listener.afterCropHarvest(harvested, crop); + } + + inventory.stowHarvest(harvested, pendingProduce); + + return true; + } + + @Override + public int getStoredFertilizerScaled(int scale) { + return fertilizerManager.getStoredFertilizerScaled(scale); + } + + @Override + public boolean hasLiquid(FluidStack liquid) { + return tankManager.get(0).getFluidAmount() >= liquid.amount; + } + + @Override + public void removeLiquid(FluidStack liquid) { + tankManager.drain(liquid, true); + } + + @Override + public boolean plantGermling(IFarmable germling, World world, int x, int y, int z) { + EntityPlayer player = Proxies.common.getPlayer(world, getAccessHandler().getOwner()); + return inventory.plantGermling(germling, player, x, y, z); + } + + @Override + public IFarmInventory getFarmInventory() { + return inventory; + } + + @Override + public void setFarmLogic(FarmDirection direction, IFarmLogic logic) { + if (logic == null) { + throw new NullPointerException("logic must not be null"); + } + farmLogics.put(direction, logic); + } + + @Override + public void resetFarmLogic(FarmDirection direction) { + setFarmLogic(direction, new FarmLogicArboreal(this)); + } + + @Override + public IFarmLogic getFarmLogic(FarmDirection direction) { + return farmLogics.get(direction); + } + + @Override + public int getSocketCount() { + return sockets.getSizeInventory(); + } + + @Override + public ItemStack getSocket(int slot) { + return sockets.getStackInSlot(slot); + } + + @Override + public void setSocket(int slot, ItemStack stack) { + if (stack != null && !ChipsetManager.circuitRegistry.isChipset(stack)) { + return; + } + + // Dispose old chipsets correctly + if (sockets.getStackInSlot(slot) != null) { + if (ChipsetManager.circuitRegistry.isChipset(sockets.getStackInSlot(slot))) { + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(sockets.getStackInSlot(slot)); + if (chipset != null) { + chipset.onRemoval(this); + } + } + } + + sockets.setInventorySlotContents(slot, stack); + refreshFarmLogics(); + + if (stack == null) { + return; + } + + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(stack); + if (chipset != null) { + chipset.onInsertion(this); + } + } + +} diff --git a/src/main/java/forestry/farming/multiblock/FarmFertilizerManager.java b/src/main/java/forestry/farming/multiblock/FarmFertilizerManager.java new file mode 100644 index 000000000..c7a98a285 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/FarmFertilizerManager.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.io.IOException; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.core.INBTTagable; +import forestry.core.GameMode; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.IStreamable; + +public class FarmFertilizerManager implements INBTTagable, IStreamable { + private static final int BUFFER_FERTILIZER = 200; + + private final int fertilizerValue; + private int storedFertilizer; + + public FarmFertilizerManager() { + this.fertilizerValue = GameMode.getGameMode().getIntegerSetting("farms.fertilizer.value"); + } + + public boolean hasFertilizer(int amount) { + if (fertilizerValue < 0) { + return true; + } + + return storedFertilizer >= amount; + } + + public void removeFertilizer(int amount) { + if (fertilizerValue < 0) { + return; + } + + storedFertilizer -= amount; + if (storedFertilizer < 0) { + storedFertilizer = 0; + } + } + + public boolean maintainFertilizer(FarmInventory inventory) { + if (storedFertilizer <= BUFFER_FERTILIZER) { + if (fertilizerValue < 0) { + storedFertilizer += 2000; + } else if (inventory.useFertilizer()) { + storedFertilizer += fertilizerValue; + } + } + + return storedFertilizer > 0; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + storedFertilizer = data.getInteger("StoredFertilizer"); + } + + @Override + public void writeToNBT(NBTTagCompound data) { + data.setInteger("StoredFertilizer", storedFertilizer); + } + + public int getStoredFertilizerScaled(int scale) { + if (storedFertilizer == 0) { + return 0; + } + + return (storedFertilizer * scale) / (fertilizerValue + BUFFER_FERTILIZER); + } + + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + data.writeVarInt(storedFertilizer); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + storedFertilizer = data.readVarInt(); + } +} diff --git a/src/main/java/forestry/farming/multiblock/FarmHydrationManager.java b/src/main/java/forestry/farming/multiblock/FarmHydrationManager.java new file mode 100644 index 000000000..c2d3dc15e --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/FarmHydrationManager.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.io.IOException; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.core.INBTTagable; +import forestry.core.interfaces.IClimatised; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.IStreamable; +import forestry.farming.gui.IFarmLedgerDelegate; + +public class FarmHydrationManager implements IFarmLedgerDelegate, INBTTagable, IStreamable { + private static final int DELAY_HYDRATION = 100; + private static final float RAINFALL_MODIFIER_MAX = 15f; + private static final float RAINFALL_MODIFIER_MIN = 0.5f; + + private final IClimatised climatised; + private int hydrationDelay = 0; + private int ticksSinceRainfall = 0; + + public FarmHydrationManager(IClimatised climatised) { + this.climatised = climatised; + } + + public void updateServer(World world) { + if (world.isRaining()) { + if (hydrationDelay > 0) { + hydrationDelay--; + } else { + ticksSinceRainfall = 0; + } + } else { + hydrationDelay = DELAY_HYDRATION; + if (ticksSinceRainfall < Integer.MAX_VALUE) { + ticksSinceRainfall++; + } + } + } + + @Override + public float getHydrationModifier() { + return getHydrationTempModifier() * getHydrationHumidModifier() * getHydrationRainfallModifier(); + } + + @Override + public float getHydrationTempModifier() { + float temperature = climatised.getExactTemperature(); + return temperature > 0.8f ? temperature : 0.8f; + } + + @Override + public float getHydrationHumidModifier() { + float mod = 1 / climatised.getExactHumidity(); + return mod < 2.0f ? mod : 2.0f; + } + + @Override + public float getHydrationRainfallModifier() { + float mod = (float) ticksSinceRainfall / 24000; + if (mod <= RAINFALL_MODIFIER_MIN) { + return RAINFALL_MODIFIER_MIN; + } else if (mod >= RAINFALL_MODIFIER_MAX) { + return RAINFALL_MODIFIER_MAX; + } else { + return mod; + } + } + + @Override + public double getDrought() { + return Math.round(((double) ticksSinceRainfall / 24000) * 10) / 10.; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + hydrationDelay = nbttagcompound.getInteger("HydrationDelay"); + ticksSinceRainfall = nbttagcompound.getInteger("TicksSinceRainfall"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setInteger("HydrationDelay", hydrationDelay); + nbttagcompound.setInteger("TicksSinceRainfall", ticksSinceRainfall); + } + + @Override + public void writeData(DataOutputStreamForestry data) throws IOException { + data.writeVarInt(hydrationDelay); + data.writeVarInt(ticksSinceRainfall); + } + + @Override + public void readData(DataInputStreamForestry data) throws IOException { + hydrationDelay = data.readVarInt(); + ticksSinceRainfall = data.readVarInt(); + } +} diff --git a/src/main/java/forestry/farming/multiblock/FarmInventory.java b/src/main/java/forestry/farming/multiblock/FarmInventory.java new file mode 100644 index 000000000..62d40ce4f --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/FarmInventory.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.util.Stack; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.Fluid; + +import forestry.api.farming.FarmDirection; +import forestry.api.farming.IFarmInventory; +import forestry.api.farming.IFarmLogic; +import forestry.api.farming.IFarmable; +import forestry.core.fluids.FluidHelper; +import forestry.core.fluids.TankManager; +import forestry.core.inventory.InvTools; +import forestry.core.inventory.InventoryAdapterRestricted; +import forestry.core.inventory.wrappers.InventoryMapper; +import forestry.core.proxy.Proxies; +import forestry.core.utils.GuiUtil; +import forestry.core.utils.StackUtils; +import forestry.plugins.PluginFarming; + +public class FarmInventory extends InventoryAdapterRestricted implements IFarmInventory { + public static final int SLOT_RESOURCES_1 = 0; + public static final int SLOT_RESOURCES_COUNT = 6; + public static final int SLOT_GERMLINGS_1 = 6; + public static final int SLOT_GERMLINGS_COUNT = 6; + public static final int SLOT_PRODUCTION_1 = 12; + public static final int SLOT_PRODUCTION_COUNT = 8; + + public static final int SLOT_FERTILIZER = 20; + public static final int SLOT_FERTILIZER_COUNT = 1; + public static final int SLOT_CAN = 21; + public static final int SLOT_CAN_COUNT = 1; + + public static final int SLOT_COUNT = SLOT_RESOURCES_COUNT + SLOT_GERMLINGS_COUNT + SLOT_PRODUCTION_COUNT + SLOT_FERTILIZER_COUNT + SLOT_CAN_COUNT; + + private final FarmController farmController; + + private final IInventory resourcesInventory; + private final IInventory germlingsInventory; + private final IInventory productInventory; + private final IInventory fertilizerInventory; + + public FarmInventory(FarmController farmController) { + super(SLOT_COUNT, "Items", farmController.getAccessHandler()); + this.farmController = farmController; + + this.resourcesInventory = new InventoryMapper(this, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT); + this.germlingsInventory = new InventoryMapper(this, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT); + this.productInventory = new InventoryMapper(this, SLOT_PRODUCTION_1, SLOT_PRODUCTION_COUNT); + this.fertilizerInventory = new InventoryMapper(this, SLOT_FERTILIZER, SLOT_FERTILIZER_COUNT); + } + + @Override + public boolean canSlotAccept(int slotIndex, ItemStack itemStack) { + if (GuiUtil.isIndexInRange(slotIndex, SLOT_FERTILIZER, SLOT_FERTILIZER_COUNT)) { + return acceptsAsFertilizer(itemStack); + } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_GERMLINGS_1, SLOT_GERMLINGS_COUNT)) { + return acceptsAsGermling(itemStack); + } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_RESOURCES_1, SLOT_RESOURCES_COUNT)) { + return acceptsAsResource(itemStack); + } else if (GuiUtil.isIndexInRange(slotIndex, SLOT_CAN, SLOT_CAN_COUNT)) { + Fluid fluid = FluidHelper.getFluidInContainer(itemStack); + return farmController.getTankManager().accepts(fluid); + } + return false; + } + + @Override + public boolean canExtractItem(int slotIndex, ItemStack stack, int side) { + return GuiUtil.isIndexInRange(slotIndex, SLOT_PRODUCTION_1, SLOT_PRODUCTION_COUNT); + } + + @Override + public boolean hasResources(ItemStack[] resources) { + return InvTools.contains(resourcesInventory, resources); + } + + @Override + public void removeResources(ItemStack[] resources) { + EntityPlayer player = Proxies.common.getPlayer(farmController.getWorld(), farmController.getAccessHandler().getOwner()); + InvTools.removeSets(resourcesInventory, 1, resources, player, false, true, true); + } + + @Override + public boolean acceptsAsGermling(ItemStack itemstack) { + if (itemstack == null) { + return false; + } + + for (FarmDirection farmDirection : FarmDirection.values()) { + IFarmLogic logic = farmController.getFarmLogic(farmDirection); + if (logic.isAcceptedGermling(itemstack)) { + return true; + } + } + + return false; + } + + @Override + public boolean acceptsAsResource(ItemStack itemstack) { + if (itemstack == null) { + return false; + } + + for (FarmDirection farmDirection : FarmDirection.values()) { + IFarmLogic logic = farmController.getFarmLogic(farmDirection); + if (logic.isAcceptedResource(itemstack)) { + return true; + } + } + + return false; + } + + @Override + public boolean acceptsAsFertilizer(ItemStack itemstack) { + if (itemstack == null) { + return false; + } + + return StackUtils.isIdenticalItem(PluginFarming.farmFertilizer, itemstack); + } + + @Override + public IInventory getProductInventory() { + return productInventory; + } + + @Override + public IInventory getGermlingsInventory() { + return germlingsInventory; + } + + @Override + public IInventory getResourcesInventory() { + return resourcesInventory; + } + + @Override + public IInventory getFertilizerInventory() { + return fertilizerInventory; + } + + public void drainCan(TankManager tankManager) { + if (getStackInSlot(SLOT_CAN) != null) { + FluidHelper.drainContainers(tankManager, this, SLOT_CAN); + } + } + + public boolean plantGermling(IFarmable germling, EntityPlayer player, int x, int y, int z) { + for (int i = 0; i < germlingsInventory.getSizeInventory(); i++) { + ItemStack germlingStack = germlingsInventory.getStackInSlot(i); + if (germlingStack == null || !germling.isGermling(germlingStack)) { + continue; + } + + if (germling.plantSaplingAt(player, germlingStack, player.worldObj, x, y, z)) { + germlingsInventory.decrStackSize(i, 1); + return true; + } + } + return false; + } + + public void addProduce(ItemStack produce) { + + if (acceptsAsGermling(produce)) { + produce.stackSize -= InvTools.addStack(germlingsInventory, produce, true); + } + + if (produce.stackSize <= 0) { + return; + } + + if (acceptsAsResource(produce)) { + produce.stackSize -= InvTools.addStack(resourcesInventory, produce, true); + } + + if (produce.stackSize <= 0) { + return; + } + + produce.stackSize -= InvTools.addStack(productInventory, produce, true); + } + + public void stowHarvest(Iterable harvested, Stack pendingProduce) { + for (ItemStack harvest : harvested) { + + if (acceptsAsGermling(harvest)) { + harvest.stackSize -= InvTools.addStack(germlingsInventory, harvest, true); + } + + if (harvest.stackSize <= 0) { + continue; + } + + harvest.stackSize -= InvTools.addStack(productInventory, harvest, true); + + if (harvest.stackSize <= 0) { + continue; + } + + pendingProduce.push(harvest); + } + } + + public boolean tryAddPendingProduce(Stack pendingProduce) { + IInventory productInventory = getProductInventory(); + + ItemStack next = pendingProduce.peek(); + boolean added = InvTools.tryAddStack(productInventory, next, true, true); + + if (added) { + pendingProduce.pop(); + } + + return added; + } + + public boolean useFertilizer() { + ItemStack fertilizer = getStackInSlot(SLOT_FERTILIZER); + if (fertilizer == null || fertilizer.stackSize <= 0) { + return false; + } + + if (!acceptsAsFertilizer(fertilizer)) { + return false; + } + + decrStackSize(SLOT_FERTILIZER, 1); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/forestry/farming/multiblock/IFarmController.java b/src/main/java/forestry/farming/multiblock/IFarmController.java new file mode 100644 index 000000000..e963b392b --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/IFarmController.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import forestry.api.core.IErrorLogicSource; +import forestry.api.farming.IFarmHousing; +import forestry.core.fluids.ITankManager; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IRestrictedAccessTile; +import forestry.core.interfaces.ISocketable; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.network.IStreamableGui; +import forestry.farming.gui.IFarmLedgerDelegate; + +public interface IFarmController extends IFarmHousing, ISocketable, IClimatised, IRestrictedAccessTile, IErrorLogicSource, IStreamableGui { + IFarmLedgerDelegate getFarmLedgerDelegate(); + + IInventoryAdapter getInternalInventory(); + + ITankManager getTankManager(); +} diff --git a/src/main/java/forestry/farming/multiblock/TileControl.java b/src/main/java/forestry/farming/multiblock/TileControl.java new file mode 100644 index 000000000..5a7217098 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/TileControl.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.DefaultFarmListener; +import forestry.api.farming.FarmDirection; +import forestry.api.farming.IFarmComponent; +import forestry.api.farming.IFarmListener; +import forestry.api.farming.IFarmLogic; +import forestry.core.vect.Vect; + +public class TileControl extends TileFarm implements IFarmComponent.Listener { + + private final IFarmListener farmListener; + + public TileControl() { + this.fixedType = TYPE_CONTROL; + this.farmListener = new ControlFarmListener(this); + } + + @Override + public IFarmListener getFarmListener() { + return farmListener; + } + + private static class ControlFarmListener extends DefaultFarmListener { + private final TileControl tile; + private final Vect position; + + public ControlFarmListener(TileControl tile) { + this.tile = tile; + this.position = new Vect(tile.xCoord, tile.yCoord, tile.zCoord); + } + + @Override + public boolean cancelTask(IFarmLogic logic, FarmDirection direction) { + return hasRedstoneSignal(direction.getForgeDirection()) || hasRedstoneSignal(ForgeDirection.UP) || hasRedstoneSignal(ForgeDirection.DOWN); + } + + private boolean hasRedstoneSignal(ForgeDirection direction) { + Vect side = position.add(direction); + + ForgeDirection opp = direction.getOpposite(); + int dir; + if (opp.offsetZ < 0) { + dir = 2; + } else if (opp.offsetZ > 0) { + dir = 3; + } else if (opp.offsetX < 0) { + dir = 4; + } else if (opp.offsetX > 0) { + dir = 5; + } else { + dir = 0; + } + + return tile.getWorldObj().getIndirectPowerLevelTo(side.x, side.y, side.z, dir) > 0 || tile.getWorldObj().isBlockProvidingPowerTo(side.x, side.y, side.z, dir) > 0; + } + } + +} diff --git a/src/main/java/forestry/farming/multiblock/TileFarm.java b/src/main/java/forestry/farming/multiblock/TileFarm.java new file mode 100644 index 000000000..a08949166 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/TileFarm.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.io.IOException; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.IIcon; +import net.minecraft.util.StatCollector; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; +import forestry.api.core.IErrorLogicSource; +import forestry.api.farming.IFarmComponent; +import forestry.core.config.Config; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IHintSource; +import forestry.core.interfaces.ISocketable; +import forestry.core.inventory.IInventoryAdapter; +import forestry.core.multiblock.MultiblockControllerBase; +import forestry.core.multiblock.MultiblockValidationException; +import forestry.core.multiblock.rectangular.RectangularMultiblockTileEntityBase; +import forestry.core.network.DataInputStreamForestry; +import forestry.core.network.DataOutputStreamForestry; +import forestry.core.network.GuiId; +import forestry.core.network.IStreamableGui; + +public abstract class TileFarm extends RectangularMultiblockTileEntityBase implements IFarmComponent, IHintSource, ISocketable, IStreamableGui, IErrorLogicSource { + + public static final int TYPE_PLAIN = 0; + public static final int TYPE_REVERSE = 1; + public static final int TYPE_TOP = 2; + public static final int TYPE_BAND = 3; + public static final int TYPE_GEARS = 4; + public static final int TYPE_HATCH = 5; + public static final int TYPE_VALVE = 6; + public static final int TYPE_CONTROL = 7; + + @Override + public void openGui(EntityPlayer player) { + if (this.isConnected()) { + player.openGui(ForestryAPI.instance, GuiId.MultiFarmGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + } + + @Override + public IInventoryAdapter getInternalInventory() { + return getFarmController().getInternalInventory(); + } + + @Override + public boolean allowsAutomation() { + return false; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + farmBlockTexture = EnumFarmBlockTexture.getFromCompound(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + farmBlockTexture.saveToCompound(nbttagcompound); + } + + /* CONSTRUCTION MATERIAL */ + EnumFarmBlockTexture farmBlockTexture = EnumFarmBlockTexture.BRICK_STONE; + protected int fixedType = -1; + + public void setFarmBlockTexture(EnumFarmBlockTexture farmBlockTexture) { + if (this.farmBlockTexture != farmBlockTexture) { + this.farmBlockTexture = farmBlockTexture; + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + } + + public EnumFarmBlockTexture getFarmBlockTexture() { + return farmBlockTexture; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + /* + * if(fixedType >= 0) return farmBlockTexture.getIcon(fixedType); + * + * int type = 0; if (meta == 1) type = TYPE_BAND; + * + * if (meta == 0 && side == 2) type = TYPE_REVERSE; else if (meta == 0 && (side == 0 || side == 1)) type = TYPE_TOP; + * + * return farmBlockTexture.getIcon(type); + */ + return null; + } + + /* TILEFORESTRY */ + + @Override + protected void encodeDescriptionPacket(NBTTagCompound packetData) { + super.encodeDescriptionPacket(packetData); + farmBlockTexture.saveToCompound(packetData); + } + + @Override + protected void decodeDescriptionPacket(NBTTagCompound packetData) { + super.decodeDescriptionPacket(packetData); + EnumFarmBlockTexture farmBlockTexture = EnumFarmBlockTexture.getFromCompound(packetData); + setFarmBlockTexture(farmBlockTexture); + } + + @Override + public void onMachineActivated() { + + } + + @Override + public void onMachineDeactivated() { + + } + + @Override + public MultiblockControllerBase createNewMultiblock() { + return new FarmController(worldObj); + } + + @Override + public Class getMultiblockControllerType() { + return FarmController.class; + } + + public IFarmController getFarmController() { + if (isConnected()) { + return (IFarmController) super.getMultiblockController(); + } else { + return FakeFarmController.instance; + } + } + + @Override + public void isGoodForExteriorLevel(int level) throws MultiblockValidationException { + if (level == 2 && !(this instanceof TileFarmPlain)) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.farm.error.needPlainBand")); + } + } + + @Override + public void isGoodForInterior() throws MultiblockValidationException { + if (!(this instanceof TileFarmPlain)) { + throw new MultiblockValidationException(StatCollector.translateToLocal("for.multiblock.farm.error.needPlainInterior")); + } + } + + /* IHintSource */ + @Override + public boolean hasHints() { + return Config.hints.get("farm").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("farm"); + } + + /* ISocketable */ + @Override + public int getSocketCount() { + return getFarmController().getSocketCount(); + } + + @Override + public ItemStack getSocket(int slot) { + return getFarmController().getSocket(slot); + } + + @Override + public void setSocket(int slot, ItemStack stack) { + getFarmController().setSocket(slot, stack); + } + + /* IStreamableGui */ + @Override + public ChunkCoordinates getCoordinates() { + return getFarmController().getCoordinates(); + } + + @Override + public void writeGuiData(DataOutputStreamForestry data) throws IOException { + getFarmController().writeGuiData(data); + } + + @Override + public void readGuiData(DataInputStreamForestry data) throws IOException { + getFarmController().readGuiData(data); + } + + /* IErrorLogicSource */ + @Override + public IErrorLogic getErrorLogic() { + return getFarmController().getErrorLogic(); + } +} diff --git a/src/main/java/forestry/farming/multiblock/TileFarmPlain.java b/src/main/java/forestry/farming/multiblock/TileFarmPlain.java new file mode 100644 index 000000000..a1f7057c1 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/TileFarmPlain.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import forestry.core.multiblock.MultiblockControllerBase; + +public class TileFarmPlain extends TileFarm { + + + @Override + public void onMachineAssembled(MultiblockControllerBase controller) { + super.onMachineAssembled(controller); + + // set band block meta + int bandY = controller.getMaximumCoord().y - 1; + if (yCoord == bandY) { + this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 1, 2); + } + } + + @Override + public void onMachineBroken() { + super.onMachineBroken(); + + // set band block meta back to normal + this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 2); + } +} diff --git a/src/main/java/forestry/farming/gadgets/TileGearbox.java b/src/main/java/forestry/farming/multiblock/TileGearbox.java similarity index 82% rename from src/main/java/forestry/farming/gadgets/TileGearbox.java rename to src/main/java/forestry/farming/multiblock/TileGearbox.java index 28a8a5264..3a404e20c 100644 --- a/src/main/java/forestry/farming/gadgets/TileGearbox.java +++ b/src/main/java/forestry/farming/multiblock/TileGearbox.java @@ -8,26 +8,27 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.farming.gadgets; +package forestry.farming.multiblock; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.ForgeDirection; -import forestry.api.core.ITileStructure; -import forestry.api.farming.IFarmHousing; +import forestry.api.core.IErrorLogic; +import forestry.api.farming.IFarmComponent; import forestry.core.EnumErrorCode; -import forestry.core.gadgets.TileForestry; import forestry.core.interfaces.IPowerHandler; import forestry.energy.EnergyManager; -public class TileGearbox extends TileFarm implements IPowerHandler { +public class TileGearbox extends TileFarm implements IPowerHandler, IFarmComponent.Active { public static final int WORK_CYCLES = 4; + + private final EnergyManager energyManager; + private int activationDelay = 0; private int previousDelays = 0; private int workCounter; - private final EnergyManager energyManager; public TileGearbox() { energyManager = new EnergyManager(200, 50, 10000); @@ -35,11 +36,6 @@ public class TileGearbox extends TileFarm implements IPowerHandler { fixedType = TYPE_GEARS; } - @Override - public boolean hasFunction() { - return true; - } - /* SAVING & LOADING */ @Override public void readFromNBT(NBTTagCompound nbttagcompound) { @@ -60,19 +56,14 @@ public class TileGearbox extends TileFarm implements IPowerHandler { } @Override - protected void updateServerSide() { - super.updateServerSide(); + public void updateServer(int tickCount) { - ITileStructure central = getCentralTE(); - if (!(central instanceof TileForestry)) { - return; - } - - TileForestry centralHousing = (TileForestry) central; + IFarmController farmController = getFarmController(); + IErrorLogic errorLogic = farmController.getErrorLogic(); boolean hasPower = energyManager.getTotalEnergyStored() > 0; - if (centralHousing.setErrorCondition(!hasPower, EnumErrorCode.NOPOWER)) { + if (errorLogic.setCondition(!hasPower, EnumErrorCode.NOPOWER)) { return; } @@ -86,12 +77,8 @@ public class TileGearbox extends TileFarm implements IPowerHandler { workCounter++; } - if (workCounter >= WORK_CYCLES && updateOnInterval(5)) { - if (!(central instanceof IFarmHousing)) { - return; - } - - if (((IFarmHousing) central).doWork()) { + if (workCounter >= WORK_CYCLES && (tickCount % 5 == 0)) { + if (farmController.doWork()) { workCounter = 0; previousDelays = 0; } else { @@ -102,6 +89,11 @@ public class TileGearbox extends TileFarm implements IPowerHandler { } } + @Override + public void updateClient(int tickCount) { + + } + /* IPowerHandler */ @Override public EnergyManager getEnergyManager() { @@ -132,4 +124,5 @@ public class TileGearbox extends TileFarm implements IPowerHandler { public boolean canConnectEnergy(ForgeDirection from) { return energyManager.canConnectEnergy(from); } + } diff --git a/src/main/java/forestry/farming/multiblock/TileHatch.java b/src/main/java/forestry/farming/multiblock/TileHatch.java new file mode 100644 index 000000000..e359dcae1 --- /dev/null +++ b/src/main/java/forestry/farming/multiblock/TileHatch.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.farming.multiblock; + +import java.util.Collection; +import java.util.Collections; + +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import cpw.mods.fml.common.Optional; + +import forestry.api.farming.IFarmComponent; +import forestry.core.inventory.AdjacentInventoryCache; +import forestry.core.inventory.ITileFilter; +import forestry.core.inventory.InvTools; +import forestry.core.utils.AdjacentTileCache; +import forestry.farming.triggers.FarmingTriggers; + +import buildcraft.api.statements.IStatementContainer; +import buildcraft.api.statements.ITriggerExternal; +import buildcraft.api.statements.ITriggerInternal; +import buildcraft.api.statements.ITriggerProvider; + +@Optional.Interface(iface = "buildcraft.api.statements.ITriggerProvider", modid = "BuildCraftAPI|statements") +public class TileHatch extends TileFarm implements ISidedInventory, IFarmComponent.Active, ITriggerProvider { + + private static final ForgeDirection[] dumpDirections = new ForgeDirection[]{ForgeDirection.DOWN}; + + private final AdjacentTileCache tileCache; + private final AdjacentInventoryCache inventoryCache; + + public TileHatch() { + this.fixedType = TYPE_HATCH; + this.tileCache = new AdjacentTileCache(this); + this.inventoryCache = new AdjacentInventoryCache(this, tileCache, new ITileFilter() { + @Override + public boolean matches(TileEntity tile) { + return !(tile instanceof TileFarm) && tile.yCoord < yCoord; + } + }); + } + + @Override + public boolean allowsAutomation() { + return true; + } + + @Override + public void updateServer(int tickCount) { + if (tickCount % 40 == 0) { + IInventory productInventory = getFarmController().getFarmInventory().getProductInventory(); + + if (!InvTools.moveOneItemToPipe(productInventory, tileCache, dumpDirections)) { + InvTools.moveItemStack(productInventory, inventoryCache.getAdjacentInventories()); + } + } + } + + @Override + public void updateClient(int tickCount) { + + } + + @Optional.Method(modid = "BuildCraftAPI|statements") + @Override + public Collection getInternalTriggers(IStatementContainer container) { + return Collections.emptyList(); + } + + /* ITRIGGERPROVIDER */ + @Optional.Method(modid = "BuildCraftAPI|statements") + @Override + public Collection getExternalTriggers(ForgeDirection side, TileEntity tile) { + if (!isConnected()) { + return Collections.emptyList(); + } + + return FarmingTriggers.allExternalTriggers; + } + +} diff --git a/src/main/java/forestry/farming/gadgets/TileValve.java b/src/main/java/forestry/farming/multiblock/TileValve.java old mode 100755 new mode 100644 similarity index 56% rename from src/main/java/forestry/farming/gadgets/TileValve.java rename to src/main/java/forestry/farming/multiblock/TileValve.java index ea88d7d14..b6ddd76e3 --- a/src/main/java/forestry/farming/gadgets/TileValve.java +++ b/src/main/java/forestry/farming/multiblock/TileValve.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.farming.gadgets; +package forestry.farming.multiblock; import net.minecraft.inventory.Container; import net.minecraft.inventory.ICrafting; @@ -18,91 +18,49 @@ import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; -import forestry.core.fluids.TankManager; -import forestry.core.fluids.tanks.FakeTank; +import forestry.core.fluids.ITankManager; import forestry.core.interfaces.ILiquidTankContainer; public class TileValve extends TileFarm implements ILiquidTankContainer { public TileValve() { - fixedType = TYPE_VALVE; - } - - /* TILEFARM */ - @Override - public boolean hasFunction() { - return true; + this.fixedType = TYPE_VALVE; } /* ILIQUIDTANKCONTAINER */ @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { - TankManager tankManager = getTankManager(); - if (tankManager == null) { - return FakeTank.INSTANCE.fill(resource, doFill); - } - - return tankManager.fill(from, resource, doFill); + return getTankManager().fill(from, resource, doFill); } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { - TankManager tankManager = getTankManager(); - if (tankManager == null) { - return null; - } - - return tankManager.drain(from, resource, doDrain); + return getTankManager().drain(from, resource, doDrain); } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { - TankManager tankManager = getTankManager(); - if (tankManager == null) { - return FakeTank.INSTANCE.drain(maxDrain, doDrain); - } - - return tankManager.drain(from, maxDrain, doDrain); + return getTankManager().drain(from, maxDrain, doDrain); } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { - TankManager tankManager = getTankManager(); - if (tankManager == null) { - return true; - } - - return tankManager.canFill(from, fluid); + return getTankManager().canFill(from, fluid); } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { - TankManager tankManager = getTankManager(); - if (tankManager == null) { - return false; - } - - return tankManager.canDrain(from, fluid); + return getTankManager().canDrain(from, fluid); } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { - TankManager tankManager = getTankManager(); - if (tankManager == null) { - return FakeTank.INFO; - } - - return tankManager.getTankInfo(from); + return getTankManager().getTankInfo(from); } @Override - public TankManager getTankManager() { - TileFarmPlain central = (TileFarmPlain) getCentralTE(); - if (central == null) { - return null; - } - - return central.getTankManager(); + public ITankManager getTankManager() { + return getFarmController().getTankManager(); } @Override diff --git a/src/main/java/forestry/farming/render/FarmItemRenderer.java b/src/main/java/forestry/farming/render/FarmItemRenderer.java index e19c82ac0..f874dd961 100755 --- a/src/main/java/forestry/farming/render/FarmItemRenderer.java +++ b/src/main/java/forestry/farming/render/FarmItemRenderer.java @@ -19,8 +19,8 @@ import net.minecraftforge.client.IItemRenderer; import org.lwjgl.opengl.GL11; import forestry.core.utils.StackUtils; -import forestry.farming.gadgets.BlockFarm; -import forestry.farming.gadgets.EnumFarmBlock; +import forestry.farming.multiblock.BlockFarm; +import forestry.farming.multiblock.EnumFarmBlockTexture; public class FarmItemRenderer implements IItemRenderer { @@ -39,7 +39,7 @@ public class FarmItemRenderer implements IItemRenderer { block.setBlockBoundsForItemRender(); render.setRenderBoundsFromBlock(block); - EnumFarmBlock type = EnumFarmBlock.getFromCompound(item.getTagCompound()); + EnumFarmBlockTexture type = EnumFarmBlockTexture.getFromCompound(item.getTagCompound()); GL11.glTranslatef(translateX, translateY, translateZ); diff --git a/src/main/java/forestry/farming/render/FarmRenderingHandler.java b/src/main/java/forestry/farming/render/FarmRenderingHandler.java index b459768e4..a6b6b3ae9 100755 --- a/src/main/java/forestry/farming/render/FarmRenderingHandler.java +++ b/src/main/java/forestry/farming/render/FarmRenderingHandler.java @@ -17,7 +17,7 @@ import net.minecraft.world.IBlockAccess; import forestry.core.config.ForestryBlock; import forestry.core.render.OverlayRenderingHandler; -import forestry.farming.gadgets.BlockFarm; +import forestry.farming.multiblock.BlockFarm; import forestry.plugins.PluginFarming; public class FarmRenderingHandler extends OverlayRenderingHandler { diff --git a/src/main/java/forestry/farming/triggers/FarmingTriggers.java b/src/main/java/forestry/farming/triggers/FarmingTriggers.java index 355d869f9..fb15d5120 100644 --- a/src/main/java/forestry/farming/triggers/FarmingTriggers.java +++ b/src/main/java/forestry/farming/triggers/FarmingTriggers.java @@ -10,8 +10,13 @@ ******************************************************************************/ package forestry.farming.triggers; +import java.util.Arrays; +import java.util.List; + import forestry.core.triggers.Trigger; +import buildcraft.api.statements.ITriggerExternal; + public class FarmingTriggers { public static Trigger lowResourceLiquid50; public static Trigger lowResourceLiquid25; @@ -22,16 +27,19 @@ public class FarmingTriggers { public static Trigger lowFertilizer25; public static Trigger lowGermlings25; public static Trigger lowGermlings10; + public static List allExternalTriggers; public static void initialize() { - lowResourceLiquid50 = new TriggerLowLiquid("lowLiquid.50", 0.5f); - lowResourceLiquid25 = new TriggerLowLiquid("lowLiquid.25", 0.25f); - lowSoil128 = new TriggerLowSoil(128); - lowSoil64 = new TriggerLowSoil(64); - lowSoil32 = new TriggerLowSoil(32); - lowFertilizer50 = new TriggerLowFertilizer("lowFertilizer.50", 0.5f); - lowFertilizer25 = new TriggerLowFertilizer("lowFertilizer.25", 0.25f); - lowGermlings25 = new TriggerLowGermlings("lowGermlings.25", 0.25f); - lowGermlings10 = new TriggerLowGermlings("lowGermlings.10", 0.1f); + allExternalTriggers = Arrays.asList( + lowResourceLiquid50 = new TriggerLowLiquid("lowLiquid.50", 0.5f), + lowResourceLiquid25 = new TriggerLowLiquid("lowLiquid.25", 0.25f), + lowSoil128 = new TriggerLowSoil(128), + lowSoil64 = new TriggerLowSoil(64), + lowSoil32 = new TriggerLowSoil(32), + lowFertilizer50 = new TriggerLowFertilizer("lowFertilizer.50", 0.5f), + lowFertilizer25 = new TriggerLowFertilizer("lowFertilizer.25", 0.25f), + lowGermlings25 = new TriggerLowGermlings("lowGermlings.25", 0.25f), + lowGermlings10 = new TriggerLowGermlings("lowGermlings.10", 0.1f) + ); } } diff --git a/src/main/java/forestry/farming/triggers/TriggerLowFertilizer.java b/src/main/java/forestry/farming/triggers/TriggerLowFertilizer.java index 5e30b22ea..510c8146e 100755 --- a/src/main/java/forestry/farming/triggers/TriggerLowFertilizer.java +++ b/src/main/java/forestry/farming/triggers/TriggerLowFertilizer.java @@ -10,14 +10,14 @@ ******************************************************************************/ package forestry.farming.triggers; +import net.minecraft.inventory.IInventory; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; -import forestry.api.core.ITileStructure; +import forestry.core.inventory.InvTools; import forestry.core.triggers.Trigger; -import forestry.farming.gadgets.TileFarmPlain; -import forestry.farming.gadgets.TileHatch; +import forestry.farming.multiblock.TileHatch; import buildcraft.api.statements.IStatementContainer; import buildcraft.api.statements.IStatementParameter; @@ -42,11 +42,8 @@ public class TriggerLowFertilizer extends Trigger { return false; } - ITileStructure central = ((TileHatch) tile).getCentralTE(); - if (central == null || !(central instanceof TileFarmPlain)) { - return false; - } - - return !((TileFarmPlain) central).hasFertilizerPercent(threshold); + TileHatch tileHatch = (TileHatch) tile; + IInventory fertilizerInventory = tileHatch.getFarmController().getFarmInventory().getFertilizerInventory(); + return InvTools.containsPercent(fertilizerInventory, threshold); } } diff --git a/src/main/java/forestry/farming/triggers/TriggerLowGermlings.java b/src/main/java/forestry/farming/triggers/TriggerLowGermlings.java index b9579c40a..e22c5e029 100644 --- a/src/main/java/forestry/farming/triggers/TriggerLowGermlings.java +++ b/src/main/java/forestry/farming/triggers/TriggerLowGermlings.java @@ -10,14 +10,14 @@ ******************************************************************************/ package forestry.farming.triggers; +import net.minecraft.inventory.IInventory; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; -import forestry.api.core.ITileStructure; +import forestry.core.inventory.InvTools; import forestry.core.triggers.Trigger; -import forestry.farming.gadgets.TileFarmPlain; -import forestry.farming.gadgets.TileHatch; +import forestry.farming.multiblock.TileHatch; import buildcraft.api.statements.IStatementContainer; import buildcraft.api.statements.IStatementParameter; @@ -45,11 +45,8 @@ public class TriggerLowGermlings extends Trigger { return false; } - ITileStructure central = ((TileHatch) tile).getCentralTE(); - if (central == null || !(central instanceof TileFarmPlain)) { - return false; - } - - return !((TileFarmPlain) central).hasGermlingsPercent(threshold); + TileHatch tileHatch = (TileHatch) tile; + IInventory germlingsInventory = tileHatch.getFarmController().getFarmInventory().getGermlingsInventory(); + return InvTools.containsPercent(germlingsInventory, threshold); } } diff --git a/src/main/java/forestry/farming/triggers/TriggerLowLiquid.java b/src/main/java/forestry/farming/triggers/TriggerLowLiquid.java index 33ad8ed6b..636cb2378 100755 --- a/src/main/java/forestry/farming/triggers/TriggerLowLiquid.java +++ b/src/main/java/forestry/farming/triggers/TriggerLowLiquid.java @@ -13,13 +13,11 @@ package forestry.farming.triggers; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; -import forestry.api.core.ITileStructure; -import forestry.core.fluids.TankManager; +import forestry.core.fluids.ITankManager; import forestry.core.triggers.Trigger; -import forestry.farming.gadgets.TileFarmPlain; -import forestry.farming.gadgets.TileHatch; +import forestry.farming.multiblock.TileHatch; import buildcraft.api.statements.IStatementContainer; import buildcraft.api.statements.IStatementParameter; @@ -48,16 +46,13 @@ public class TriggerLowLiquid extends Trigger { return false; } - ITileStructure central = ((TileHatch) tile).getCentralTE(); - if (central == null || !(central instanceof TileFarmPlain)) { + TileHatch tileHatch = (TileHatch) tile; + ITankManager tankManager = tileHatch.getFarmController().getTankManager(); + + IFluidTank tank = tankManager.getTank(0); + if (tank.getCapacity() == 0) { return false; } - - TankManager tankManager = ((TileFarmPlain) central).getTankManager(); - FluidTankInfo info = tankManager.getTankInfo(0); - if (info.fluid == null) { - return true; - } - return ((float) info.fluid.amount / info.capacity) <= threshold; + return ((float) tank.getFluidAmount() / tank.getCapacity()) <= threshold; } } diff --git a/src/main/java/forestry/farming/triggers/TriggerLowSoil.java b/src/main/java/forestry/farming/triggers/TriggerLowSoil.java index 5a6411f36..53d7d0914 100755 --- a/src/main/java/forestry/farming/triggers/TriggerLowSoil.java +++ b/src/main/java/forestry/farming/triggers/TriggerLowSoil.java @@ -10,15 +10,17 @@ ******************************************************************************/ package forestry.farming.triggers; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; -import forestry.api.core.ITileStructure; +import forestry.api.farming.IFarmInventory; +import forestry.core.inventory.InvTools; import forestry.core.triggers.Trigger; -import forestry.farming.gadgets.TileFarmPlain; -import forestry.farming.gadgets.TileHatch; +import forestry.farming.multiblock.IFarmController; +import forestry.farming.multiblock.TileHatch; import buildcraft.api.statements.IStatementContainer; import buildcraft.api.statements.IStatementParameter; @@ -62,17 +64,17 @@ public class TriggerLowSoil extends Trigger { return false; } - ITileStructure central = ((TileHatch) tile).getCentralTE(); - if (central == null || !(central instanceof TileFarmPlain)) { - return false; - } + TileHatch tileHatch = (TileHatch) tile; + IFarmController farmController = tileHatch.getFarmController(); + IFarmInventory farmInventory = farmController.getFarmInventory(); if (parameter == null || parameter.getItemStack() == null) { - return !((TileFarmPlain) central).hasResourcesAmount(threshold); + IInventory resourcesInventory = farmInventory.getResourcesInventory(); + return InvTools.containsPercent(resourcesInventory, threshold); } else { ItemStack filter = parameter.getItemStack().copy(); filter.stackSize = threshold; - return !((TileFarmPlain) central).hasResources(new ItemStack[]{filter}); + return farmInventory.hasResources(new ItemStack[]{filter}); } } } diff --git a/src/main/java/forestry/lepidopterology/ButterflySpawner.java b/src/main/java/forestry/lepidopterology/ButterflySpawner.java index 31f6dec84..4be79eba0 100755 --- a/src/main/java/forestry/lepidopterology/ButterflySpawner.java +++ b/src/main/java/forestry/lepidopterology/ButterflySpawner.java @@ -22,7 +22,7 @@ import forestry.plugins.PluginLepidopterology; public class ButterflySpawner implements ILeafTickHandler { @Override - public boolean onRandomLeafTick(ITree tree, World world, int biomeId, int x, int y, int z, boolean isDestroyed) { + public boolean onRandomLeafTick(ITree tree, World world, int x, int y, int z, boolean isDestroyed) { if (world.rand.nextFloat() >= tree.getGenome().getSappiness() * tree.getGenome().getYield()) { return false; diff --git a/src/main/java/forestry/lepidopterology/entities/AIButterflyPollinate.java b/src/main/java/forestry/lepidopterology/entities/AIButterflyPollinate.java index 930639e59..c8999757b 100644 --- a/src/main/java/forestry/lepidopterology/entities/AIButterflyPollinate.java +++ b/src/main/java/forestry/lepidopterology/entities/AIButterflyPollinate.java @@ -50,12 +50,12 @@ public class AIButterflyPollinate extends AIButterflyInteract { if (checkPollinatable != null) { if (entity.getPollen() == null) { entity.setPollen(checkPollinatable.getPollen()); -// Proxies.log.finest("A butterfly '%s' grabbed a pollen '%s' at %s/%s/%s.", entity.getButterfly().getIdent(), entity.getPollen().getIdent(), rest.posX, rest.posY, rest.posZ); + // Proxies.log.finest("A butterfly '%s' grabbed a pollen '%s' at %s/%s/%s.", entity.getButterfly().getIdent(), entity.getPollen().getIdent(), rest.posX, rest.posY, rest.posZ); } else if (checkPollinatable.canMateWith(entity.getPollen())) { IPollinatable realPollinatable = GeneticsUtil.getOrCreatePollinatable(null, entity.worldObj, rest.posX, rest.posY, rest.posZ); if (realPollinatable != null) { realPollinatable.mateWith(entity.getPollen()); -// Proxies.log.finest("A butterfly '%s' unloaded pollen '%s' at %s/%s/%s.", entity.getButterfly().getIdent(), entity.getPollen().getIdent(), rest.posX, rest.posY, rest.posZ); + // Proxies.log.finest("A butterfly '%s' unloaded pollen '%s' at %s/%s/%s.", entity.getButterfly().getIdent(), entity.getPollen().getIdent(), rest.posX, rest.posY, rest.posZ); entity.setPollen(null); } } diff --git a/src/main/java/forestry/lepidopterology/genetics/Butterfly.java b/src/main/java/forestry/lepidopterology/genetics/Butterfly.java index 32106e54f..94c36660b 100755 --- a/src/main/java/forestry/lepidopterology/genetics/Butterfly.java +++ b/src/main/java/forestry/lepidopterology/genetics/Butterfly.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Random; import net.minecraft.entity.EntityCreature; import net.minecraft.item.ItemStack; @@ -47,6 +48,8 @@ import forestry.plugins.PluginLepidopterology; public class Butterfly extends IndividualLiving implements IButterfly { + private static final Random rand = new Random(); + public IButterflyGenome genome; public IButterflyGenome mate; @@ -196,8 +199,6 @@ public class Butterfly extends IndividualLiving implements IButterfly { return null; } - World world = nursery.getWorld(); - IChromosome[] chromosomes = new IChromosome[genome.getChromosomes().length]; IChromosome[] parent1 = genome.getChromosomes(); IChromosome[] parent2 = mate.getChromosomes(); @@ -215,7 +216,7 @@ public class Butterfly extends IndividualLiving implements IButterfly { for (int i = 0; i < parent1.length; i++) { if (parent1[i] != null && parent2[i] != null) { - chromosomes[i] = Chromosome.inheritChromosome(world.rand, parent1[i], parent2[i]); + chromosomes[i] = Chromosome.inheritChromosome(rand, parent1[i], parent2[i]); } } @@ -224,8 +225,6 @@ public class Butterfly extends IndividualLiving implements IButterfly { private static IChromosome[] mutateSpecies(IButterflyNursery nursery, IGenome genomeOne, IGenome genomeTwo) { - World world = nursery.getWorld(); - IChromosome[] parent1 = genomeOne.getChromosomes(); IChromosome[] parent2 = genomeTwo.getChromosomes(); @@ -234,7 +233,7 @@ public class Butterfly extends IndividualLiving implements IButterfly { IAllele allele0; IAllele allele1; - if (world.rand.nextBoolean()) { + if (rand.nextBoolean()) { allele0 = parent1[EnumButterflyChromosome.SPECIES.ordinal()].getPrimaryAllele(); allele1 = parent2[EnumButterflyChromosome.SPECIES.ordinal()].getSecondaryAllele(); @@ -250,7 +249,7 @@ public class Butterfly extends IndividualLiving implements IButterfly { for (IButterflyMutation mutation : PluginLepidopterology.butterflyInterface.getMutations(true)) { float chance = mutation.getChance(nursery, allele0, allele1, genome0, genome1); - if (chance > world.rand.nextFloat() * 100) { + if (chance > rand.nextFloat() * 100) { return PluginLepidopterology.butterflyInterface.templateAsChromosomes(mutation.getTemplate()); } } @@ -302,7 +301,7 @@ public class Butterfly extends IndividualLiving implements IButterfly { float metabolism = (float) getGenome().getMetabolism() / 10; for (Map.Entry entry : getGenome().getPrimary().getCaterpillarLoot().entrySet()) { - if (nursery.getWorld().rand.nextFloat() < entry.getValue() * metabolism) { + if (rand.nextFloat() < entry.getValue() * metabolism) { drop.add(entry.getKey().copy()); } } diff --git a/src/main/java/forestry/mail/GuiHandlerMail.java b/src/main/java/forestry/mail/GuiHandlerMail.java index 2fbcceae4..4b6eff1d3 100755 --- a/src/main/java/forestry/mail/GuiHandlerMail.java +++ b/src/main/java/forestry/mail/GuiHandlerMail.java @@ -70,13 +70,13 @@ public class GuiHandlerMail extends GuiHandlerBase { } case MailboxGUI: - return new GuiMailbox(player.inventory, getTileForestry(world, x, y, z, player, MachineMailbox.class)); + return new GuiMailbox(player.inventory, getTile(world, x, y, z, player, MachineMailbox.class)); case PhilatelistGUI: - return new GuiPhilatelist(player.inventory, getTileForestry(world, x, y, z, player, MachinePhilatelist.class)); + return new GuiPhilatelist(player.inventory, getTile(world, x, y, z, player, MachinePhilatelist.class)); case TraderGUI: - return new GuiTrader(player.inventory, getTileForestry(world, x, y, z, player, MachineTrader.class)); + return new GuiTrader(player.inventory, getTile(world, x, y, z, player, MachineTrader.class)); case TraderNameGUI: - return new GuiTradeName(getTileForestry(world, x, y, z, player, MachineTrader.class)); + return new GuiTradeName(getTile(world, x, y, z, player, MachineTrader.class)); default: return null; @@ -116,13 +116,13 @@ public class GuiHandlerMail extends GuiHandlerBase { } case MailboxGUI: - return new ContainerMailbox(player.inventory, getTileForestry(world, x, y, z, player, MachineMailbox.class)); + return new ContainerMailbox(player.inventory, getTile(world, x, y, z, player, MachineMailbox.class)); case PhilatelistGUI: - return new ContainerPhilatelist(player.inventory, getTileForestry(world, x, y, z, player, MachinePhilatelist.class)); + return new ContainerPhilatelist(player.inventory, getTile(world, x, y, z, player, MachinePhilatelist.class)); case TraderGUI: - return new ContainerTrader(player.inventory, getTileForestry(world, x, y, z, player, MachineTrader.class)); + return new ContainerTrader(player.inventory, getTile(world, x, y, z, player, MachineTrader.class)); case TraderNameGUI: - return new ContainerTradeName(getTileForestry(world, x, y, z, player, MachineTrader.class)); + return new ContainerTradeName(getTile(world, x, y, z, player, MachineTrader.class)); default: return null; diff --git a/src/main/java/forestry/mail/gadgets/MachineMailbox.java b/src/main/java/forestry/mail/gadgets/MachineMailbox.java index ee0ace082..d893c3aa7 100755 --- a/src/main/java/forestry/mail/gadgets/MachineMailbox.java +++ b/src/main/java/forestry/mail/gadgets/MachineMailbox.java @@ -80,7 +80,7 @@ public class MachineMailbox extends TileBase implements IMailContainer { @Override public void updateServerSide() { if (!isLinked) { - getOrCreateMailInventory(worldObj, getOwner()); + getOrCreateMailInventory(worldObj, getAccessHandler().getOwner()); isLinked = true; } } @@ -112,7 +112,7 @@ public class MachineMailbox extends TileBase implements IMailContainer { @Override public boolean hasMail() { - IInventory mailInventory = getOrCreateMailInventory(worldObj, getOwner()); + IInventory mailInventory = getOrCreateMailInventory(worldObj, getAccessHandler().getOwner()); for (int i = 0; i < mailInventory.getSizeInventory(); i++) { if (mailInventory.getStackInSlot(i) != null) { return true; diff --git a/src/main/java/forestry/mail/gadgets/MachineTrader.java b/src/main/java/forestry/mail/gadgets/MachineTrader.java index 56ab148e0..bf5df89ae 100755 --- a/src/main/java/forestry/mail/gadgets/MachineTrader.java +++ b/src/main/java/forestry/mail/gadgets/MachineTrader.java @@ -26,6 +26,7 @@ import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.common.Optional; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorLogic; import forestry.api.mail.IMailAddress; import forestry.api.mail.IStamps; import forestry.api.mail.PostManager; @@ -36,7 +37,6 @@ import forestry.core.network.DataInputStreamForestry; import forestry.core.network.DataOutputStreamForestry; import forestry.core.network.GuiId; import forestry.core.proxy.Proxies; -import forestry.core.utils.EnumAccess; import forestry.core.utils.StackUtils; import forestry.mail.MailAddress; import forestry.mail.TradeStation; @@ -128,24 +128,26 @@ public class MachineTrader extends TileBase { return; } - setErrorCondition(!hasPostageMin(3), EnumErrorCode.NOSTAMPS); - setErrorCondition(!hasPaperMin(2), EnumErrorCode.NOPAPER); + IErrorLogic errorLogic = getErrorLogic(); + + errorLogic.setCondition(!hasPostageMin(3), EnumErrorCode.NOSTAMPS); + errorLogic.setCondition(!hasPaperMin(2), EnumErrorCode.NOPAPER); IInventory inventory = getInternalInventory(); ItemStack tradeGood = inventory.getStackInSlot(TradeStation.SLOT_TRADEGOOD); - setErrorCondition(tradeGood == null, EnumErrorCode.NOTRADE); + errorLogic.setCondition(tradeGood == null, EnumErrorCode.NOTRADE); boolean hasRequest = hasItemCount(TradeStation.SLOT_EXCHANGE_1, TradeStation.SLOT_EXCHANGE_COUNT, null, 1); - setErrorCondition(!hasRequest, EnumErrorCode.NOTRADE); + errorLogic.setCondition(!hasRequest, EnumErrorCode.NOTRADE); if (tradeGood != null) { boolean hasSupplies = hasItemCount(TradeStation.SLOT_SEND_BUFFER, TradeStation.SLOT_SEND_BUFFER_COUNT, tradeGood, tradeGood.stackSize); - setErrorCondition(!hasSupplies, EnumErrorCode.NOSUPPLIES); + errorLogic.setCondition(!hasSupplies, EnumErrorCode.NOSUPPLIES); } if (inventory instanceof TradeStation && updateOnInterval(200)) { boolean canReceivePayment = ((TradeStation) inventory).canReceivePayment(); - setErrorCondition(!canReceivePayment, EnumErrorCode.NOSPACE); + errorLogic.setCondition(!canReceivePayment, EnumErrorCode.NOSPACE); } } @@ -155,7 +157,9 @@ public class MachineTrader extends TileBase { return false; } - return !hasErrorState(EnumErrorCode.NOTALPHANUMERIC) && !hasErrorState(EnumErrorCode.NOTUNIQUE); + IErrorLogic errorLogic = getErrorLogic(); + + return !errorLogic.contains(EnumErrorCode.NOTALPHANUMERIC) && !errorLogic.contains(EnumErrorCode.NOTUNIQUE); } /** @@ -277,15 +281,17 @@ public class MachineTrader extends TileBase { } if (Proxies.common.isSimulating(worldObj)) { + IErrorLogic errorLogic = getErrorLogic(); + boolean hasValidTradeAddress = PostManager.postRegistry.isValidTradeAddress(worldObj, address); - setErrorCondition(!hasValidTradeAddress, EnumErrorCode.NOTALPHANUMERIC); + errorLogic.setCondition(!hasValidTradeAddress, EnumErrorCode.NOTALPHANUMERIC); boolean hasUniqueTradeAddress = PostManager.postRegistry.isAvailableTradeAddress(worldObj, address); - setErrorCondition(!hasUniqueTradeAddress, EnumErrorCode.NOTUNIQUE); + errorLogic.setCondition(!hasUniqueTradeAddress, EnumErrorCode.NOTUNIQUE); if (hasValidTradeAddress & hasUniqueTradeAddress) { this.address = address; - PostManager.postRegistry.getOrCreateTradeStation(worldObj, getOwner(), address); + PostManager.postRegistry.getOrCreateTradeStation(worldObj, getAccessHandler().getOwner(), address); } } else { this.address = address; @@ -299,16 +305,7 @@ public class MachineTrader extends TileBase { return super.getInternalInventory(); } - return (TradeStation) PostManager.postRegistry.getOrCreateTradeStation(worldObj, getOwner(), address); - } - - @Override - public EnumAccess getAccess() { - if (isLinked()) { - return super.getAccess(); - } else { - return EnumAccess.PRIVATE; - } + return (TradeStation) PostManager.postRegistry.getOrCreateTradeStation(worldObj, getAccessHandler().getOwner(), address); } /* ITRIGGERPROVIDER */ diff --git a/src/main/java/forestry/mail/gui/ContainerMailbox.java b/src/main/java/forestry/mail/gui/ContainerMailbox.java index a954b7988..0f9ce6e28 100755 --- a/src/main/java/forestry/mail/gui/ContainerMailbox.java +++ b/src/main/java/forestry/mail/gui/ContainerMailbox.java @@ -32,9 +32,9 @@ public class ContainerMailbox extends ContainerTile { private final POBox mailInventory; - public ContainerMailbox(InventoryPlayer player, MachineMailbox tile) { - super(tile, player, 35, 145); - IInventory inventory = tile.getOrCreateMailInventory(player.player.worldObj, player.player.getGameProfile()); + public ContainerMailbox(InventoryPlayer playerInventory, MachineMailbox tile) { + super(tile, playerInventory, 35, 145); + IInventory inventory = tile.getOrCreateMailInventory(playerInventory.player.worldObj, playerInventory.player.getGameProfile()); if (inventory instanceof POBox) { this.mailInventory = (POBox) inventory; diff --git a/src/main/java/forestry/mail/gui/GuiTrader.java b/src/main/java/forestry/mail/gui/GuiTrader.java index a7ab3f8e5..d78c37ea6 100755 --- a/src/main/java/forestry/mail/gui/GuiTrader.java +++ b/src/main/java/forestry/mail/gui/GuiTrader.java @@ -27,7 +27,7 @@ public class GuiTrader extends GuiForestry { @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { - String name = StringUtil.localizeTile(inventory.getUnlocalizedName()); + String name = StringUtil.localizeTile(inventory.getUnlocalizedTitle()); this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.mail.text")); String receive = StringUtil.localize("gui.mail.receive"); diff --git a/src/main/java/forestry/mail/items/ItemLetter.java b/src/main/java/forestry/mail/items/ItemLetter.java index e4f02081e..38acf380f 100755 --- a/src/main/java/forestry/mail/items/ItemLetter.java +++ b/src/main/java/forestry/mail/items/ItemLetter.java @@ -27,12 +27,12 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import forestry.api.core.ForestryAPI; +import forestry.api.core.IErrorSource; import forestry.api.core.IErrorState; import forestry.api.mail.ILetter; import forestry.core.EnumErrorCode; import forestry.core.config.Config; import forestry.core.config.ForestryItem; -import forestry.core.interfaces.IErrorSource; import forestry.core.interfaces.IHintSource; import forestry.core.inventory.ItemInventory; import forestry.core.items.ItemInventoried; diff --git a/src/main/java/forestry/plugins/PluginApiculture.java b/src/main/java/forestry/plugins/PluginApiculture.java index 33862699d..6499369f4 100644 --- a/src/main/java/forestry/plugins/PluginApiculture.java +++ b/src/main/java/forestry/plugins/PluginApiculture.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Random; +import java.util.Set; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -46,7 +47,6 @@ import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.network.IGuiHandler; -import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.VillagerRegistry; import cpw.mods.fml.relauncher.Side; @@ -77,14 +77,6 @@ import forestry.apiculture.gadgets.BlockAlveary; import forestry.apiculture.gadgets.BlockBeehives; import forestry.apiculture.gadgets.BlockCandle; import forestry.apiculture.gadgets.BlockStump; -import forestry.apiculture.gadgets.StructureLogicAlveary; -import forestry.apiculture.gadgets.TileAlvearyFan; -import forestry.apiculture.gadgets.TileAlvearyHeater; -import forestry.apiculture.gadgets.TileAlvearyHygroregulator; -import forestry.apiculture.gadgets.TileAlvearyPlain; -import forestry.apiculture.gadgets.TileAlvearySieve; -import forestry.apiculture.gadgets.TileAlvearyStabiliser; -import forestry.apiculture.gadgets.TileAlvearySwarmer; import forestry.apiculture.gadgets.TileApiaristChest; import forestry.apiculture.gadgets.TileApiary; import forestry.apiculture.gadgets.TileBeehouse; @@ -124,6 +116,14 @@ import forestry.apiculture.items.ItemHiveFrame; import forestry.apiculture.items.ItemHoneycomb; import forestry.apiculture.items.ItemImprinter; import forestry.apiculture.items.ItemWaxCast; +import forestry.apiculture.multiblock.TileAlveary; +import forestry.apiculture.multiblock.TileAlvearyFan; +import forestry.apiculture.multiblock.TileAlvearyHeater; +import forestry.apiculture.multiblock.TileAlvearyHygroregulator; +import forestry.apiculture.multiblock.TileAlvearyPlain; +import forestry.apiculture.multiblock.TileAlvearySieve; +import forestry.apiculture.multiblock.TileAlvearyStabiliser; +import forestry.apiculture.multiblock.TileAlvearySwarmer; import forestry.apiculture.network.PacketHandlerApiculture; import forestry.apiculture.proxy.ProxyApiculture; import forestry.apiculture.trigger.ApicultureTriggers; @@ -164,7 +164,7 @@ public class PluginApiculture extends ForestryPlugin { public static final String[] EMPTY_STRINGS = new String[0]; public static String beekeepingMode = "NORMAL"; private static float secondPrincessChance = 0; - public static int ticksPerBeeWorkCycle = 550; + public static final int ticksPerBeeWorkCycle = 550; public static boolean apiarySideSensitive = false; public static boolean fancyRenderedBees = false; @@ -327,7 +327,7 @@ public class PluginApiculture extends ForestryPlugin { property.comment = plantableFlowerMessage; parsePlantableFlowers(property, flowerType); - List acceptableFlowers = FlowerManager.flowerRegistry.getAcceptableFlowers(flowerType); + Set acceptableFlowers = FlowerManager.flowerRegistry.getAcceptableFlowers(flowerType); if (acceptableFlowers == null || acceptableFlowers.size() == 0) { Proxies.log.severe("Flower type '" + flowerType + "' has no valid flowers set in apiculture.cfg. Add valid flowers or delete the config to set it to default."); } @@ -425,7 +425,7 @@ public class PluginApiculture extends ForestryPlugin { weightDecimalFormat.setGroupingUsed(false); for (String flowerType : FlowerManager.flowerRegistry.getFlowerTypes()) { - List flowers = FlowerManager.flowerRegistry.getAcceptableFlowers(flowerType); + Set flowers = FlowerManager.flowerRegistry.getAcceptableFlowers(flowerType); List acceptedFlowerNames = new ArrayList(); List plantableFlowerNames = new ArrayList(); if (flowers != null) { @@ -475,10 +475,6 @@ public class PluginApiculture extends ForestryPlugin { property.comment = "percent chance of second princess drop, for limited/skyblock maps. Acceptable values up to 2 decimals."; secondPrincessChance = Float.parseFloat(property.value); - property = apicultureConfig.get("beekeeping.flowers.custom", CONFIG_CATEGORY, ""); - property.comment = "add additional flower blocks for apiaries here in the format modid:name or modid:name:meta. separate blocks using ';'. wildcard for metadata: '*'. will be treated like vanilla flowers. not recommended for flowers implemented as tile entities."; - parseAdditionalFlowers(property.value, FlowerManager.plainFlowers); - property = apicultureConfig.get("species.blacklist", CONFIG_CATEGORY, ""); property.comment = "add species to blacklist identified by their uid and seperated with ';'."; parseBeeBlacklist(property.value); @@ -677,14 +673,14 @@ public class PluginApiculture extends ForestryPlugin { '#', ForestryItem.beeswax); // / ALVEARY - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.PLAIN_META), "###", "#X#", "###", 'X', ForestryItem.impregnatedCasing, '#', ForestryItem.craftingMaterial.getItemStack(1, 6)); // SWARMER - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, 2), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.SWARMER_META), "#G#", " X ", "#G#", @@ -692,7 +688,7 @@ public class PluginApiculture extends ForestryPlugin { 'X', ForestryBlock.alveary, 'G', Items.gold_ingot); // FAN - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, 3), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.FAN_META), "I I", " X ", "I#I", @@ -700,7 +696,7 @@ public class PluginApiculture extends ForestryPlugin { 'X', ForestryBlock.alveary, 'I', Items.iron_ingot); // HEATER - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, 4), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.HEATER_META), "#I#", " X ", "YYY", @@ -708,7 +704,7 @@ public class PluginApiculture extends ForestryPlugin { 'X', ForestryBlock.alveary, 'I', Items.iron_ingot, 'Y', Blocks.stone); // HYGROREGULATOR - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, 5), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.HYGRO_META), "GIG", "GXG", "GIG", @@ -716,14 +712,14 @@ public class PluginApiculture extends ForestryPlugin { 'I', Items.iron_ingot, 'G', Blocks.glass); // STABILISER - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, 6), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.STABILIZER_META), "G G", "GXG", "G G", 'X', ForestryBlock.alveary, 'G', Items.quartz); // SIEVE - Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlvearySieve.BLOCK_META), + Proxies.common.addRecipe(ForestryBlock.alveary.getItemStack(1, TileAlveary.SIEVE_META), "III", " X ", "WWW", @@ -1091,17 +1087,8 @@ public class PluginApiculture extends ForestryPlugin { } return true; } else if (message.key.equals("add-alveary-slab") && message.isStringMessage()) { - try { - Block block = GameData.getBlockRegistry().getRaw(message.getStringValue()); - - if (block != null && block != Blocks.air) { - StructureLogicAlveary.addSlabBlock(block); - } else { - logInvalidIMCMessage(message); - } - } catch (Exception e) { - logInvalidIMCMessage(message); - } + String messageString = String.format("Received a '%s' request from mod '%s'. This IMC message has been replaced with the oreDictionary for 'slabWood'. Please contact the author and report this issue.", message.key, message.getSender()); + Proxies.log.warning(messageString); return true; } diff --git a/src/main/java/forestry/plugins/PluginEnergy.java b/src/main/java/forestry/plugins/PluginEnergy.java index 843e30e32..47511ab1b 100755 --- a/src/main/java/forestry/plugins/PluginEnergy.java +++ b/src/main/java/forestry/plugins/PluginEnergy.java @@ -20,7 +20,6 @@ import cpw.mods.fml.common.network.IGuiHandler; import forestry.core.GameMode; import forestry.core.config.Defaults; import forestry.core.config.ForestryBlock; -import forestry.core.config.ForestryItem; import forestry.core.gadgets.BlockBase; import forestry.core.gadgets.MachineDefinition; import forestry.core.items.ItemForestryBlock; diff --git a/src/main/java/forestry/plugins/PluginFarming.java b/src/main/java/forestry/plugins/PluginFarming.java index 3291f679c..1e7743518 100644 --- a/src/main/java/forestry/plugins/PluginFarming.java +++ b/src/main/java/forestry/plugins/PluginFarming.java @@ -40,17 +40,9 @@ import forestry.core.items.ItemTypedBlock; import forestry.core.proxy.Proxies; import forestry.core.utils.ShapedRecipeCustom; import forestry.farming.EventHandlerFarming; -import forestry.farming.FarmHelper; import forestry.farming.GuiHandlerFarming; import forestry.farming.circuits.CircuitFarmLogic; -import forestry.farming.gadgets.BlockFarm; import forestry.farming.gadgets.BlockMushroom; -import forestry.farming.gadgets.EnumFarmBlock; -import forestry.farming.gadgets.TileControl; -import forestry.farming.gadgets.TileFarmPlain; -import forestry.farming.gadgets.TileGearbox; -import forestry.farming.gadgets.TileHatch; -import forestry.farming.gadgets.TileValve; import forestry.farming.items.ItemFarmBlock; import forestry.farming.logic.FarmLogicArboreal; import forestry.farming.logic.FarmLogicCereal; @@ -71,6 +63,13 @@ import forestry.farming.logic.FarmableGourd; import forestry.farming.logic.FarmableStacked; import forestry.farming.logic.FarmableVanillaSapling; import forestry.farming.logic.FarmableVanillaShroom; +import forestry.farming.multiblock.BlockFarm; +import forestry.farming.multiblock.EnumFarmBlockTexture; +import forestry.farming.multiblock.TileControl; +import forestry.farming.multiblock.TileFarmPlain; +import forestry.farming.multiblock.TileGearbox; +import forestry.farming.multiblock.TileHatch; +import forestry.farming.multiblock.TileValve; import forestry.farming.proxy.ProxyFarming; import forestry.farming.triggers.FarmingTriggers; @@ -82,13 +81,6 @@ public class PluginFarming extends ForestryPlugin { public static int modelIdFarmBlock; public static ItemStack farmFertilizer; - @Override - protected void setupAPI() { - super.setupAPI(); - - Farmables.farmInterface = new FarmHelper(); - } - @Override public void preInit() { super.preInit(); @@ -283,7 +275,7 @@ public class PluginFarming extends ForestryPlugin { protected void registerRecipes() { ItemStack basic = ForestryBlock.farm.getItemStack(1, 0); - for (EnumFarmBlock block : EnumFarmBlock.values()) { + for (EnumFarmBlockTexture block : EnumFarmBlockTexture.values()) { NBTTagCompound compound = new NBTTagCompound(); block.saveToCompound(compound); diff --git a/src/main/java/forestry/plugins/PluginHarvestCraft.java b/src/main/java/forestry/plugins/PluginHarvestCraft.java index bd9cdbc34..ef01e5fbc 100644 --- a/src/main/java/forestry/plugins/PluginHarvestCraft.java +++ b/src/main/java/forestry/plugins/PluginHarvestCraft.java @@ -249,7 +249,7 @@ public class PluginHarvestCraft extends ForestryPlugin { Block grainBlock = GameRegistry.findBlock(HC, "pam" + grainName + "Crop"); if (grain != null && wheatamount.stackSize > 0) { Proxies.common.addRecipe(wheatamount, " X ", "X#X", " X ", '#', Blocks.dirt, 'X', grain); - FuelManager.moistenerResource.put(grain, new MoistenerFuel(grain, ForestryItem.mouldyWheat.getItemStack(), 0, 300)); + FuelManager.moistenerResource.put(grain, new MoistenerFuel(grain, ForestryItem.mouldyWheat.getItemStack(), 0, 300)); } if (grainSeed != null) { RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[]{grainSeed}, Fluids.SEEDOIL.getFluid(seedamount)); diff --git a/src/main/java/forestry/plugins/PluginNatura.java b/src/main/java/forestry/plugins/PluginNatura.java index eec2f9dab..ea858c6cc 100755 --- a/src/main/java/forestry/plugins/PluginNatura.java +++ b/src/main/java/forestry/plugins/PluginNatura.java @@ -260,7 +260,7 @@ public class PluginNatura extends ForestryPlugin { ItemStack compostWheat = GameMode.getGameMode().getStackSetting("recipe.output.compost.wheat"); Proxies.common.addRecipe(compostWheat, " X ", "X#X", " X ", '#', Blocks.dirt, 'X', itemBarley); } - FuelManager.moistenerResource.put(itemBarley, new MoistenerFuel(itemBarley, ForestryItem.mouldyWheat.getItemStack(), 0, 300)); + FuelManager.moistenerResource.put(itemBarley, new MoistenerFuel(itemBarley, ForestryItem.mouldyWheat.getItemStack(), 0, 300)); } } diff --git a/src/main/java/forestry/plugins/PluginPlantMegaPack.java b/src/main/java/forestry/plugins/PluginPlantMegaPack.java index 909a8f397..f07f9ddf7 100644 --- a/src/main/java/forestry/plugins/PluginPlantMegaPack.java +++ b/src/main/java/forestry/plugins/PluginPlantMegaPack.java @@ -448,8 +448,9 @@ public class PluginPlantMegaPack extends ForestryPlugin { } if (flowerStack != null && flowerBlock != null) { Farmables.farmables.get("farmWheat").add(new FarmableGenericCrop(flowerStack, flowerBlock, flower.getValue())); - if( flower.getValue() < 5 ) - Farmables.farmables.get("farmOrchard").add(new FarmableBasicFruit(flowerBlock, flower.getValue())); + if (flower.getValue() < 5) { + Farmables.farmables.get("farmOrchard").add(new FarmableBasicFruit(flowerBlock, flower.getValue())); + } } } } diff --git a/src/main/java/forestry/plugins/PluginStorage.java b/src/main/java/forestry/plugins/PluginStorage.java index f837bb48b..3583dae64 100755 --- a/src/main/java/forestry/plugins/PluginStorage.java +++ b/src/main/java/forestry/plugins/PluginStorage.java @@ -126,22 +126,22 @@ public class PluginStorage extends ForestryPlugin { BackpackManager.definitions.put(definition.getKey(), definition); } - definition = new BackpackDefinition("miner", new Color(0x36187d).getRGB()); + definition = new BackpackDefinition("miner", new Color(0x36187d).getRGB()); BackpackManager.definitions.put(definition.getKey(), definition); - definition = new BackpackDefinition("digger", new Color(0x363cc5).getRGB()); + definition = new BackpackDefinition("digger", new Color(0x363cc5).getRGB()); BackpackManager.definitions.put(definition.getKey(), definition); - definition = new BackpackDefinition("forester", new Color(0x347427).getRGB()); + definition = new BackpackDefinition("forester", new Color(0x347427).getRGB()); BackpackManager.definitions.put(definition.getKey(), definition); - definition = new BackpackDefinition("hunter", new Color(0x412215).getRGB()); + definition = new BackpackDefinition("hunter", new Color(0x412215).getRGB()); BackpackManager.definitions.put(definition.getKey(), definition); - definition = new BackpackDefinition("adventurer", new Color(0x7fb8c2).getRGB()); + definition = new BackpackDefinition("adventurer", new Color(0x7fb8c2).getRGB()); BackpackManager.definitions.put(definition.getKey(), definition); - definition = new BackpackDefinition("builder", new Color(0xdd3a3a).getRGB()); + definition = new BackpackDefinition("builder", new Color(0xdd3a3a).getRGB()); BackpackManager.definitions.put(definition.getKey(), definition); } diff --git a/src/main/java/forestry/storage/BackpackDefinition.java b/src/main/java/forestry/storage/BackpackDefinition.java index bce113baa..4ba815122 100755 --- a/src/main/java/forestry/storage/BackpackDefinition.java +++ b/src/main/java/forestry/storage/BackpackDefinition.java @@ -111,10 +111,10 @@ public class BackpackDefinition implements IBackpackDefinition { } public void addValidOreDictName(String oreDictName) { -// if (OreDictionary.doesOreNameExist(oreDictName)) { //TODO: add this back when using a forge version that supports it - int oreId = OreDictionary.getOreID(oreDictName); - validOreIds.add(oreId); -// } + // if (OreDictionary.doesOreNameExist(oreDictName)) { //TODO: add this back when using a forge version that supports it + int oreId = OreDictionary.getOreID(oreDictName); + validOreIds.add(oreId); + // } } public void addValidOreDictNames(List oreDictNames) { diff --git a/src/main/java/forestry/storage/CrateRegistry.java b/src/main/java/forestry/storage/CrateRegistry.java index 4fe25b5a5..f772a5e47 100644 --- a/src/main/java/forestry/storage/CrateRegistry.java +++ b/src/main/java/forestry/storage/CrateRegistry.java @@ -17,7 +17,6 @@ import net.minecraft.item.ItemStack; import forestry.api.storage.ICrateRegistry; import forestry.core.items.ItemCrated; import forestry.core.proxy.Proxies; -import forestry.plugins.PluginManager; import forestry.plugins.PluginStorage; public class CrateRegistry implements ICrateRegistry { diff --git a/src/main/resources/config/forestry/hints.properties b/src/main/resources/config/forestry/hints.properties index 6ac981417..d8820a379 100755 --- a/src/main/resources/config/forestry/hints.properties +++ b/src/main/resources/config/forestry/hints.properties @@ -1,21 +1,20 @@ -alveary=accesscontrol;accessrules;accesspipe; -analyzer=nopowerrequired;accesscontrol;accessrules;accesspipe;pipette;flowerjungle;flowernether;apiaristsuit;honeyfood -apiarist.chest= -apiary=accesscontrol;accessrules;accesspipe;beebiomes;beebreeding;beejubilance;beeflowers;nopowerrequired;flowerjungle;flowernether;apiaristsuit;honeyfood -beealyzer= -bottler=powerrequired;accesscontrol;accessrules;accesspipe;pipette -carpenter=powerrequired;accesscontrol;accessrules;accesspipe;pipette;crating -centrifuge=powerrequired;accesscontrol;accessrules;accesspipe -engine.bronze=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;pipette;enginebronzefuels;enginebronzeheatloss;enginebronzeoutput;enginebronzewaste -engine.copper=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;forcedcooldown;cooldownloss;enginecopperfuels;usesofash;enginecopperwaste;manualpeat;peatharvest -engine.tin=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;forcedcooldown;cooldownloss;enginetinbatteries;enginetinchoke -farm=accesscontrol;accessrules;accesspipe;farmland;gearbox;valve;fertilizer;hatch;circuitboard;manualfarms;farmgui -fermenter=powerrequired;accesscontrol;accessrules;accesspipe;pipette;shortmead -generator=accesscontrol;accessrules;accesspipe;energyunit;pipette;generatorfuels -habitatlocator= -letter=postage -mailbox=nopowerrequired;accesscontrol;accessrules;accesspipe;postage -moistener=nopowerrequired;accesscontrol;accessrules;accesspipe;pipette;moistenerproducts -raintank=powerraintank;accesscontrol;accessrules;accesspipe -squeezer=powerrequired;accesscontrol;accessrules;accesspipe;pipette +analyzer=nopowerrequired;accesscontrol;accessrules;accesspipe;pipette;flowerjungle;flowernether;apiaristsuit;honeyfood +apiarist.chest= +apiary=accesscontrol;accessrules;accesspipe;beebiomes;beebreeding;beejubilance;beeflowers;nopowerrequired;flowerjungle;flowernether;apiaristsuit;honeyfood +beealyzer= +bottler=powerrequired;accesscontrol;accessrules;accesspipe;pipette +carpenter=powerrequired;accesscontrol;accessrules;accesspipe;pipette;crating +centrifuge=powerrequired;accesscontrol;accessrules;accesspipe +engine.bronze=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;pipette;enginebronzefuels;enginebronzeheatloss;enginebronzeoutput;enginebronzewaste +engine.copper=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;forcedcooldown;cooldownloss;enginecopperfuels;usesofash;enginecopperwaste;manualpeat;peatharvest +engine.tin=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;forcedcooldown;cooldownloss;enginetinbatteries;enginetinchoke +farm=accesscontrol;accessrules;accesspipe;farmland;gearbox;valve;fertilizer;hatch;circuitboard;manualfarms;farmgui +fermenter=powerrequired;accesscontrol;accessrules;accesspipe;pipette;shortmead +generator=accesscontrol;accessrules;accesspipe;energyunit;pipette;generatorfuels +habitatlocator= +letter=postage +mailbox=nopowerrequired;accesscontrol;accessrules;accesspipe;postage +moistener=nopowerrequired;accesscontrol;accessrules;accesspipe;pipette;moistenerproducts +raintank=powerraintank;accesscontrol;accessrules;accesspipe +squeezer=powerrequired;accesscontrol;accessrules;accesspipe;pipette still=powerrequired;accesscontrol;accessrules;accesspipe;pipette \ No newline at end of file