aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gtPlusPlus/core/tileentities
diff options
context:
space:
mode:
authorJohann Bernhardt <johann.bernhardt@tum.de>2021-12-12 19:38:06 +0100
committerJohann Bernhardt <johann.bernhardt@tum.de>2021-12-12 19:38:06 +0100
commit311ab89f93558233a40079f7cb16605b141b5346 (patch)
treec5f44ef47f441a57c5f57aa801f639c7879ed760 /src/main/java/gtPlusPlus/core/tileentities
parent896143b96132f5ac54aa8d8f7386f27487e5e530 (diff)
downloadGT5-Unofficial-311ab89f93558233a40079f7cb16605b141b5346.tar.gz
GT5-Unofficial-311ab89f93558233a40079f7cb16605b141b5346.tar.bz2
GT5-Unofficial-311ab89f93558233a40079f7cb16605b141b5346.zip
Move sources and resources
Diffstat (limited to 'src/main/java/gtPlusPlus/core/tileentities')
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/ModTileEntities.java63
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/base/TILE_ENTITY_BASE.java39
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/base/TileBasicTank.java150
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java1347
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/base/TilePoweredGT.java1168
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityCircuitProgrammer.java307
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityDecayablesChest.java359
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityEggBox.java359
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFirepit.java39
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFishTrap.java410
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityHeliumGenerator.java124
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityInfiniteFluid.java139
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityPlayerDoorBase.java285
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityReverter.java312
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityVolumetricFlaskSetter.java403
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/TileEntityXpConverter.java298
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/general/redstone/TileEntityRedstoneHandler.java468
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityAdvPooCollector.java155
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityBaseFluidCollector.java238
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityModularityTable.java480
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPestKiller.java506
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPooCollector.java147
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityProjectTable.java288
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityRoundRobinator.java739
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityTradeTable.java133
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbench.java172
-rw-r--r--src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbenchAdvanced.java245
27 files changed, 9373 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/core/tileentities/ModTileEntities.java b/src/main/java/gtPlusPlus/core/tileentities/ModTileEntities.java
new file mode 100644
index 0000000000..62b545c5c8
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/ModTileEntities.java
@@ -0,0 +1,63 @@
+package gtPlusPlus.core.tileentities;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.block.general.BlockSuperLight.TileEntitySuperLight;
+import gtPlusPlus.core.block.machine.Machine_SuperJukebox.TileEntitySuperJukebox;
+import gtPlusPlus.core.lib.LoadedMods;
+import gtPlusPlus.core.tileentities.general.*;
+import gtPlusPlus.core.tileentities.machines.TileEntityAdvPooCollector;
+import gtPlusPlus.core.tileentities.machines.TileEntityModularityTable;
+import gtPlusPlus.core.tileentities.machines.TileEntityPestKiller;
+import gtPlusPlus.core.tileentities.machines.TileEntityPooCollector;
+import gtPlusPlus.core.tileentities.machines.TileEntityProjectTable;
+import gtPlusPlus.core.tileentities.machines.TileEntityRoundRobinator;
+import gtPlusPlus.core.tileentities.machines.TileEntityTradeTable;
+import gtPlusPlus.core.tileentities.machines.TileEntityWorkbench;
+import gtPlusPlus.core.tileentities.machines.TileEntityWorkbenchAdvanced;
+import gtPlusPlus.plugin.villagers.tile.TileEntityGenericSpawner;
+import gtPlusPlus.xmod.gregtech.common.Meta_GT_Proxy;
+
+public class ModTileEntities {
+
+ public static void init() {
+ Logger.INFO("Registering Tile Entities.");
+ GameRegistry.registerTileEntity(TileEntityPooCollector.class, "TileEntityPooCollector");
+ GameRegistry.registerTileEntity(TileEntityAdvPooCollector.class, "TileEntityAdvPooCollector");
+ GameRegistry.registerTileEntity(TileEntityWorkbench.class, "TileWorkbench");
+ GameRegistry.registerTileEntity(TileEntityWorkbenchAdvanced.class, "TileWorkbenchAdvanced");
+ GameRegistry.registerTileEntity(TileEntityFishTrap.class, "TileFishTrap");
+ GameRegistry.registerTileEntity(TileEntityFirepit.class, "TileFirePit");
+ GameRegistry.registerTileEntity(TileEntityInfiniteFluid.class, "TileInfiniteFluid");
+ GameRegistry.registerTileEntity(TileEntityProjectTable.class, "TileProjectTable");
+ GameRegistry.registerTileEntity(TileEntityTradeTable.class, "TileTradeTable");
+ GameRegistry.registerTileEntity(TileEntityModularityTable.class, "TileEntityModularityTable");
+ GameRegistry.registerTileEntity(TileEntityXpConverter.class, "TileEntityXpConverter");
+ GameRegistry.registerTileEntity(TileEntityGenericSpawner.class, "TileEntityGenericSpawner");
+ GameRegistry.registerTileEntity(TileEntityCircuitProgrammer.class, "TileCircuitProgrammer");
+ GameRegistry.registerTileEntity(TileEntityPlayerDoorBase.class, "TilePlayerDoorBase");
+ GameRegistry.registerTileEntity(TileEntityDecayablesChest.class, "TileDecayablesChest");
+ GameRegistry.registerTileEntity(TileEntitySuperJukebox.class, "TileEntitySuperJukebox");
+ GameRegistry.registerTileEntity(TileEntitySuperLight.class, "TileEntitySuperLight");
+ GameRegistry.registerTileEntity(TileEntityPestKiller.class, "TileEntityPestKiller");
+ GameRegistry.registerTileEntity(TileEntityRoundRobinator.class, "TileEntityRoundRobinator");
+ GameRegistry.registerTileEntity(TileEntityEggBox.class, "TileEggBox");
+
+ if (Meta_GT_Proxy.sDoesVolumetricFlaskExist) {
+ GameRegistry.registerTileEntity(TileEntityVolumetricFlaskSetter.class, "TileEntityVolumetricFlaskSetter");
+ }
+
+ //Mod TEs
+ if (LoadedMods.Thaumcraft){
+
+ }
+ blacklistTilesFromAcceleration();
+ }
+
+ private static void blacklistTilesFromAcceleration() {
+ Meta_GT_Proxy.setTileEntityClassAsBlacklistedInWorldAccelerator("gtPlusPlus.core.tileentities.general.TileEntityFishTrap");
+ Meta_GT_Proxy.setTileEntityClassAsBlacklistedInWorldAccelerator("gtPlusPlus.core.tileentities.general.TileEntityDecayablesChest");
+ Meta_GT_Proxy.setTileEntityClassAsBlacklistedInWorldAccelerator("gtPlusPlus.core.tileentities.general.TileEggBox");
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/base/TILE_ENTITY_BASE.java b/src/main/java/gtPlusPlus/core/tileentities/base/TILE_ENTITY_BASE.java
new file mode 100644
index 0000000000..839bcc353a
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/base/TILE_ENTITY_BASE.java
@@ -0,0 +1,39 @@
+package gtPlusPlus.core.tileentities.base;
+
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.TileEntity;
+
+public class TILE_ENTITY_BASE extends TileEntity {
+
+ @Override
+ public void writeToNBT(final NBTTagCompound tag) {
+ super.writeToNBT(tag);
+ this.writeCustomNBT(tag);
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound tag) {
+ super.readFromNBT(tag);
+ this.readCustomNBT(tag);
+ }
+
+ public void writeCustomNBT(final NBTTagCompound tag) {}
+ public void readCustomNBT(final NBTTagCompound tag) {}
+
+ @Override
+ public Packet getDescriptionPacket() {
+ final NBTTagCompound tag = new NBTTagCompound();
+ this.writeCustomNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, -999, tag);
+ }
+
+ @Override
+ public void onDataPacket(final NetworkManager net, final S35PacketUpdateTileEntity packet) {
+ super.onDataPacket(net, packet);
+ this.readCustomNBT(packet.func_148857_g());
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/base/TileBasicTank.java b/src/main/java/gtPlusPlus/core/tileentities/base/TileBasicTank.java
new file mode 100644
index 0000000000..671a49fca5
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/base/TileBasicTank.java
@@ -0,0 +1,150 @@
+package gtPlusPlus.core.tileentities.base;
+
+import gtPlusPlus.api.objects.minecraft.BTF_FluidTank;
+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.IFluidHandler;
+import net.minecraftforge.fluids.IFluidTank;
+
+public class TileBasicTank extends TileEntityBase implements IFluidHandler, IFluidTank {
+
+ public final BTF_FluidTank mTank;
+
+ public TileBasicTank(int aMaxSlots, int aFluidCapacity) {
+ super(aMaxSlots);
+ mTank = new BTF_FluidTank(aFluidCapacity);
+ }
+
+ @Override
+ public boolean onPreTick(long aTick) {
+
+ if (this.isServerSide()) {
+ if (mTank.isFluidChangingAllowed() && mTank.getFillableStack() != null
+ && mTank.getFillableStack().amount <= 0) {
+ mTank.setFillableStack((FluidStack) null);
+ }
+ }
+
+ return super.onPreTick(aTick);
+
+ }
+
+
+ private final boolean canFillEx(ForgeDirection aSide, Fluid aFluid) {
+ return this.fill(aSide, new FluidStack(aFluid, 1), false) == 1;
+ }
+
+
+ private final boolean canDrainEx(ForgeDirection aSide, Fluid aFluid) {
+ return this.drain(aSide, new FluidStack(aFluid, 1), false) != null;
+ }
+
+
+ private final FluidTankInfo[] getTankInfoEx(ForgeDirection aSide) {
+ return mTank.getCapacity() <= 0 ? new FluidTankInfo[0]
+ : new FluidTankInfo[]{mTank.getInfo()};
+ }
+
+ private final int fill_default(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ return mTank.fill(aFluid, doFill);
+ }
+
+
+ private final int fillEx(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ return this.fill_default(aSide, aFluid, doFill);
+ }
+
+
+ private final FluidStack drainEx(ForgeDirection aSide, FluidStack aFluid, boolean doDrain) {
+ return mTank.getFluid() != null && aFluid != null && mTank.getFluid().isFluidEqual(aFluid)
+ ? mTank.drain(aFluid.amount, doDrain)
+ : null;
+ }
+
+
+ private final FluidStack drainEx(ForgeDirection aSide, int maxDrain, boolean doDrain) {
+ return mTank.drain(maxDrain, doDrain);
+ }
+
+
+ public boolean isLiquidInput(byte aSide) {
+ return true;
+ }
+
+ public boolean isLiquidOutput(byte aSide) {
+ return true;
+ }
+
+ @Override
+ public int fill(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mInputDisabled) && (aSide == ForgeDirection.UNKNOWN || (this.isLiquidInput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid == null ? null : aFluid.getFluid(), this))))
+ return this.fillEx(aSide, aFluid, doFill);
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, int maxDrain, boolean doDrain) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mOutputDisabled) && (aSide == ForgeDirection.UNKNOWN || (this.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), this.getFluid() == null ? null : this.getFluid().getFluid(), this))))
+ return this.drainEx(aSide, maxDrain, doDrain);
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, FluidStack aFluid, boolean doDrain) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mOutputDisabled) && (aSide == ForgeDirection.UNKNOWN || (this.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid == null ? null : aFluid.getFluid(), this))))
+ return this.drainEx(aSide, aFluid, doDrain);
+ return null;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection aSide, Fluid aFluid) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mInputDisabled) && (aSide == ForgeDirection.UNKNOWN || (this.isLiquidInput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid, this))))
+ return this.canFillEx(aSide, aFluid);
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection aSide, Fluid aFluid) {
+ if (mTickTimer > 5 && canAccessData() && (mRunningThroughTick || !mOutputDisabled) && (aSide == ForgeDirection.UNKNOWN || (this.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), aFluid, this))))
+ return this.canDrainEx(aSide, aFluid);
+ return false;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection aSide) {
+ if (canAccessData() && (aSide == ForgeDirection.UNKNOWN || (this.isLiquidInput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidIn((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), null, this)) || (this.isLiquidOutput((byte) aSide.ordinal()) && getCoverBehaviorAtSide((byte) aSide.ordinal()).letsFluidOut((byte) aSide.ordinal(), getCoverIDAtSide((byte) aSide.ordinal()), getCoverDataAtSide((byte) aSide.ordinal()), null, this))))
+ return this.getTankInfoEx(aSide);
+ return new FluidTankInfo[]{};
+ }
+
+ @Override
+ public FluidStack getFluid() {
+ return mTank.getFluid();
+ }
+
+ @Override
+ public int getFluidAmount() {
+ return mTank.getFluidAmount();
+ }
+
+ @Override
+ public FluidTankInfo getInfo() {
+ return mTank.getInfo();
+ }
+
+ @Override
+ public int fill(FluidStack resource, boolean doFill) {
+ return mTank.fill(resource, doFill);
+ }
+
+ @Override
+ public FluidStack drain(int maxDrain, boolean doDrain) {
+ return mTank.drain(maxDrain, doDrain);
+ }
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java b/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java
new file mode 100644
index 0000000000..dba96c6ebc
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java
@@ -0,0 +1,1347 @@
+package gtPlusPlus.core.tileentities.base;
+
+import java.util.UUID;
+
+import gregtech.GT_Mod;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.interfaces.IDescribable;
+import gregtech.api.interfaces.tileentity.IGregTechDeviceInformation;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.net.GT_Packet_Block_Event;
+import gregtech.api.util.GT_CoverBehavior;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Utility;
+import net.minecraft.block.Block;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraft.world.biome.BiomeGenBase;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.IFluidHandler;
+import gtPlusPlus.api.interfaces.ILazyCoverable;
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.api.objects.minecraft.BTF_Inventory;
+import gtPlusPlus.core.util.data.ArrayUtils;
+import gtPlusPlus.core.util.minecraft.gregtech.PollutionUtils;
+import ic2.api.Direction;
+
+public class TileEntityBase extends TileEntity implements ILazyCoverable, IGregTechDeviceInformation, IDescribable {
+
+ private String customName;
+ public String mOwnerName = "null";
+ public String mOwnerUUID = "null";
+ private boolean mIsOwnerOP = false;
+
+ public final BTF_Inventory mInventory;
+
+ public TileEntityBase(int aCapacity) {
+ mInventory = new BTF_Inventory(aCapacity, this);
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag){
+ if(!nbt.hasKey(tag))
+ {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt){
+ super.writeToNBT(nbt);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ nbt.setBoolean("mIsOwnerOP", this.mIsOwnerOP);
+ nbt.setString("mOwnerName", this.mOwnerName);
+ nbt.setString("mOwnerUUID", this.mOwnerUUID);
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt){
+
+ super.readFromNBT(nbt);
+
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+
+ this.mIsOwnerOP = nbt.getBoolean("mIsOwnerOP");
+ this.mOwnerName = nbt.getString("mOwnerName");
+ this.mOwnerUUID = nbt.getString("mOwnerUUID");
+ }
+
+ @Override
+ public void updateEntity() {
+ long aTick = System.currentTimeMillis();
+ this.isDead = false;
+ if (!firstTicked) {
+ onFirstTick();
+ }
+ try{
+ if (this.isServerSide()){
+ onPreTick(aTick);
+ }
+ } catch (Throwable t){
+ Logger.ERROR("Tile Entity Encountered an error in it's pre-tick stage.");
+ t.printStackTrace();
+ }
+ try{
+ if (this.isServerSide()){
+ onTick(aTick);
+ }
+ } catch (Throwable t){
+ Logger.ERROR("Tile Entity Encountered an error in it's tick stage.");
+ t.printStackTrace();
+ }
+ try{
+ if (this.isServerSide()){
+ onPostTick(aTick);
+ }
+ } catch (Throwable t){
+ Logger.ERROR("Tile Entity Encountered an error in it's post-tick stage.");
+ t.printStackTrace();
+ }
+ }
+
+ public boolean onPreTick(long aTick) {
+ return true;
+ }
+
+ public boolean onTick(long aTick){
+ try{
+ if (this.isServerSide()){
+ processRecipe();
+ }
+ } catch (Throwable t){
+ Logger.ERROR("Tile Entity Encountered an error in it's processing of a recipe stage.");
+ t.printStackTrace();
+ }
+ return true;
+ }
+
+ public boolean onPostTick(long aTick){
+ return true;
+ }
+
+ public boolean processRecipe(){
+ return true;
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return true;
+ }
+
+ public String getOwner(){
+ if (this.mOwnerName == null){
+ return "null";
+ }
+ return this.mOwnerName;
+ }
+
+ public UUID getOwnerUUID(){
+ return UUID.fromString(this.mOwnerUUID);
+ }
+
+ public boolean isOwnerOP() {
+ return mIsOwnerOP;
+ }
+
+ public void setOwnerInformation(String mName, String mUUID, boolean mOP){
+ if (isServerSide()){
+ if (this.mOwnerName == null || this.mOwnerUUID == null || this.mOwnerName.equals("null") || this.mOwnerUUID.equals("null")){
+ this.mOwnerName = mName;
+ this.mOwnerUUID = mUUID;
+ this.mIsOwnerOP = mOP;
+ }
+ }
+ }
+
+ public boolean isServerSide(){
+ if (this.hasWorldObj()){
+ if (!this.getWorldObj().isRemote){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public final boolean isClientSide() {
+ return this.worldObj.isRemote;
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.tileentity.name";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return this.customName != null && !this.customName.equals("");
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.mInventory.getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(int aIndex) {
+ return this.mInventory.getStackInSlot(aIndex);
+ }
+
+ @Override
+ public ItemStack decrStackSize(int aIndex, int aAmount) {
+ if (canAccessData()) {
+ mInventoryChanged = true;
+ return mInventory.decrStackSize(aIndex, aAmount);
+ }
+ return null;
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int p_70304_1_) {
+ return this.mInventory.getStackInSlotOnClosing(p_70304_1_);
+ }
+
+ @Override
+ public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_) {
+ this.mInventory.setInventorySlotContents(p_70299_1_, p_70299_2_);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.mInventory.getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer p_70300_1_) {
+ return this.mInventory.isUseableByPlayer(p_70300_1_);
+ }
+
+ @Override
+ public void openInventory() {
+ this.mInventory.openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.mInventory.closeInventory();
+ }
+
+ /**
+ * Can put aStack into Slot
+ */
+ @Override
+ public boolean isItemValidForSlot(int aIndex, ItemStack aStack) {
+ return canAccessData() && mInventory.isItemValidForSlot(aIndex, aStack);
+ }
+
+ /**
+ * returns all valid Inventory Slots, no matter which Side (Unless it's covered).
+ * The Side Stuff is done in the following two Functions.
+ */
+ @Override
+ public int[] getAccessibleSlotsFromSide(int aSide) {
+ if (canAccessData() && (getCoverBehaviorAtSide((byte) aSide).letsItemsOut((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), -1, this) || getCoverBehaviorAtSide((byte) aSide).letsItemsIn((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), -1, this)))
+ return mInventory.getAccessibleSlotsFromSide(aSide);
+ return new int[0];
+ }
+
+ /**
+ * Can put aStack into Slot at Side
+ */
+ @Override
+ public boolean canInsertItem(int aIndex, ItemStack aStack, int aSide) {
+ return canAccessData() && (mRunningThroughTick || !mInputDisabled) && getCoverBehaviorAtSide((byte) aSide).letsItemsIn((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), aIndex, this) && mInventory.canInsertItem(aIndex, aStack, aSide);
+ }
+
+ /**
+ * Can pull aStack out of Slot from Side
+ */
+ @Override
+ public boolean canExtractItem(int aIndex, ItemStack aStack, int aSide) {
+ return canAccessData() && (mRunningThroughTick || !mOutputDisabled) && getCoverBehaviorAtSide((byte) aSide).letsItemsOut((byte) aSide, getCoverIDAtSide((byte) aSide), getCoverDataAtSide((byte) aSide), aIndex, this) && mInventory.canExtractItem(aIndex, aStack, aSide);
+ }
+
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return this.canAccessData() ? this.mInventory.isValidSlot(aIndex) : false;
+ }
+
+
+
+
+ private final GT_CoverBehavior[] mCoverBehaviors = new GT_CoverBehavior[] { GregTech_API.sNoBehavior,
+ GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior,
+ GregTech_API.sNoBehavior };
+ protected TileEntityBase mMetaTileEntity;
+ protected long mStoredEnergy = 0;
+ protected int mAverageEUInputIndex = 0, mAverageEUOutputIndex = 0;
+ protected boolean mReleaseEnergy = false;
+ protected int[] mAverageEUInput = new int[11], mAverageEUOutput = new int[11];
+ private boolean[] mActiveEUInputs = new boolean[] { false, false, false, false, false, false },
+ mActiveEUOutputs = new boolean[] { false, false, false, false, false, false };
+ private byte[] mSidedRedstone = new byte[] { 15, 15, 15, 15, 15, 15 };
+ private int[] mCoverSides = new int[] { 0, 0, 0, 0, 0, 0 }, mCoverData = new int[] { 0, 0, 0, 0, 0, 0 },
+ mTimeStatistics = new int[GregTech_API.TICKS_FOR_LAG_AVERAGING];
+ private boolean mHasEnoughEnergy = true;
+ protected boolean mRunningThroughTick = false;
+ protected boolean mInputDisabled = false;
+ protected boolean mOutputDisabled = false;
+ private boolean mMuffler = false;
+ private boolean mLockUpgrade = false;
+ private boolean mActive = false;
+ private boolean mRedstone = false;
+ private boolean mWorkUpdate = false;
+ private boolean mSteamConverter = false;
+ private boolean mInventoryChanged = false;
+ private boolean mWorks = true;
+ private boolean mNeedsUpdate = true;
+ private boolean mNeedsBlockUpdate = true;
+ private boolean mSendClientData = false;
+ private boolean oRedstone = false;
+ private boolean mEnergyStateReady = false;
+ private byte mColor = 0, oColor = 0, mStrongRedstone = 0, oRedstoneData = 63, oTextureData = 0, oUpdateData = 0,
+ oTexturePage = 0, oLightValueClient = -1, oLightValue = -1, mLightValue = 0, mOtherUpgrades = 0,
+ mFacing = 0, oFacing = 0, mWorkData = 0;
+ private int mDisplayErrorCode = 0, oX = 0, oY = 0, oZ = 0, mTimeStatisticsIndex = 0, mLagWarningCount = 0;
+ private short mID = 0;
+ protected long mTickTimer = 0;
+ private long oOutput = 0;
+ private long mAcceptedAmperes = Long.MAX_VALUE;
+
+
+ /**
+ * Cover Support
+ */
+
+ public void issueClientUpdate() {
+ this.mSendClientData = true;
+ }
+
+ protected final boolean canAccessData() {
+ return !isDead() && !this.isInvalid();
+ }
+
+ @Override
+ public void issueBlockUpdate() {
+ super.markDirty();
+ }
+
+ @Override
+ public void issueCoverUpdate(byte aSide) {
+ this.issueClientUpdate();
+ }
+
+ @Override
+ public void receiveCoverData(byte coverSide, int coverID, int coverData) {
+ if ((coverSide >= 0 && coverSide < 6) && (mCoverSides[coverSide] == coverID))
+ setCoverDataAtSide(coverSide, coverData);
+ }
+
+ @Override
+ public long getTimer() {
+ return this.mTickTimer;
+ }
+
+
+
+
+
+
+
+ public long getOutputAmperage() {
+ return this.canAccessData() && this.mMetaTileEntity.isElectric() ? this.mMetaTileEntity.maxAmperesOut() : 0L;
+ }
+
+ public long getOutputVoltage() {
+ return this.canAccessData() && this.mMetaTileEntity.isElectric() && this.mMetaTileEntity.isEnetOutput()
+ ? this.mMetaTileEntity.maxEUOutput()
+ : 0L;
+ }
+
+ public long getInputAmperage() {
+ return this.canAccessData() && this.mMetaTileEntity.isElectric() ? this.mMetaTileEntity.maxAmperesIn() : 0L;
+ }
+
+ public long getInputVoltage() {
+ return this.canAccessData() && this.mMetaTileEntity.isElectric()
+ ? this.mMetaTileEntity.maxEUInput()
+ : 2147483647L;
+ }
+
+ @Override
+ public boolean decreaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooLessEnergy) {
+ return !this.canAccessData() ? false : (this.mHasEnoughEnergy = this.decreaseStoredEU(aEnergy, aIgnoreTooLessEnergy));
+ }
+
+ @Override
+ public boolean increaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooMuchEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ } else if (this.getStoredEU() >= this.getEUCapacity() && !aIgnoreTooMuchEnergy) {
+ return false;
+ } else {
+ this.setStoredEU(this.mMetaTileEntity.getEUVar() + aEnergy);
+ return true;
+ }
+ }
+
+ @Override
+ public boolean inputEnergyFrom(byte aSide) {
+ return aSide == 6
+ ? true
+ : (!this.isServerSide()
+ ? this.isEnergyInputSide(aSide)
+ : aSide >= 0 && aSide < 6 && this.mActiveEUInputs[aSide] && !this.mReleaseEnergy);
+ }
+
+ @Override
+ public boolean outputsEnergyTo(byte aSide) {
+ return aSide == 6
+ ? true
+ : (!this.isServerSide()
+ ? this.isEnergyOutputSide(aSide)
+ : aSide >= 0 && aSide < 6 && this.mActiveEUOutputs[aSide] || this.mReleaseEnergy);
+ }
+
+ private boolean isEnergyInputSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) {
+ if (!this.getCoverBehaviorAtSide(aSide).letsEnergyIn(aSide, this.getCoverIDAtSide(aSide),
+ this.getCoverDataAtSide(aSide), this)) {
+ return false;
+ }
+
+ if (this.isInvalid() || this.mReleaseEnergy) {
+ return false;
+ }
+
+ if (this.canAccessData() && this.mMetaTileEntity.isElectric() && this.mMetaTileEntity.isEnetInput()) {
+ return this.mMetaTileEntity.isInputFacing(aSide);
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isEnergyOutputSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) {
+ if (!this.getCoverBehaviorAtSide(aSide).letsEnergyOut(aSide, this.getCoverIDAtSide(aSide),
+ this.getCoverDataAtSide(aSide), this)) {
+ return false;
+ }
+
+ if (this.isInvalid() || this.mReleaseEnergy) {
+ return this.mReleaseEnergy;
+ }
+
+ if (this.canAccessData() && this.mMetaTileEntity.isElectric() && this.mMetaTileEntity.isEnetOutput()) {
+ return this.mMetaTileEntity.isOutputFacing(aSide);
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isOutputFacing(byte aSide) {
+ return false;
+ }
+
+ public boolean isInputFacing(byte aSide) {
+ return false;
+ }
+
+ private final TileEntity[] mBufferedTileEntities = new TileEntity[6];
+ public boolean ignoreUnloadedChunks = true;
+ public boolean isDead = false;
+
+ private final void clearNullMarkersFromTileEntityBuffer() {
+ for (int i = 0; i < this.mBufferedTileEntities.length; ++i) {
+ if (this.mBufferedTileEntities[i] == this) {
+ this.mBufferedTileEntities[i] = null;
+ }
+ }
+
+ }
+
+ protected final void clearTileEntityBuffer() {
+ for (int i = 0; i < this.mBufferedTileEntities.length; ++i) {
+ this.mBufferedTileEntities[i] = null;
+ }
+
+ }
+
+ public final World getWorld() {
+ return this.worldObj;
+ }
+
+ public final int getXCoord() {
+ return this.xCoord;
+ }
+
+ public final short getYCoord() {
+ return (short) this.yCoord;
+ }
+
+ public final int getZCoord() {
+ return this.zCoord;
+ }
+
+ public final int getOffsetX(byte aSide, int aMultiplier) {
+ return this.xCoord + ForgeDirection.getOrientation(aSide).offsetX * aMultiplier;
+ }
+
+ public final short getOffsetY(byte aSide, int aMultiplier) {
+ return (short) (this.yCoord + ForgeDirection.getOrientation(aSide).offsetY * aMultiplier);
+ }
+
+ public final int getOffsetZ(byte aSide, int aMultiplier) {
+ return this.zCoord + ForgeDirection.getOrientation(aSide).offsetZ * aMultiplier;
+ }
+
+ public final boolean openGUI(EntityPlayer aPlayer) {
+ return this.openGUI(aPlayer, 0);
+ }
+
+ public final boolean openGUI(EntityPlayer aPlayer, int aID) {
+ if (aPlayer == null) {
+ return false;
+ } else {
+ aPlayer.openGui(GT_Values.GT, aID, this.worldObj, this.xCoord, this.yCoord, this.zCoord);
+ return true;
+ }
+ }
+
+ public final int getRandomNumber(int aRange) {
+ return this.worldObj.rand.nextInt(aRange);
+ }
+
+ public final BiomeGenBase getBiome(int aX, int aZ) {
+ return this.worldObj.getBiomeGenForCoords(aX, aZ);
+ }
+
+ public final BiomeGenBase getBiome() {
+ return this.getBiome(this.xCoord, this.zCoord);
+ }
+
+ public final Block getBlockOffset(int aX, int aY, int aZ) {
+ return this.getBlock(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final Block getBlockAtSide(byte aSide) {
+ return this.getBlockAtSideAndDistance(aSide, 1);
+ }
+
+ public final Block getBlockAtSideAndDistance(byte aSide, int aDistance) {
+ return this.getBlock(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final byte getMetaIDOffset(int aX, int aY, int aZ) {
+ return this.getMetaID(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final byte getMetaIDAtSide(byte aSide) {
+ return this.getMetaIDAtSideAndDistance(aSide, 1);
+ }
+
+ public final byte getMetaIDAtSideAndDistance(byte aSide, int aDistance) {
+ return this.getMetaID(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final byte getLightLevelOffset(int aX, int aY, int aZ) {
+ return this.getLightLevel(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final byte getLightLevelAtSide(byte aSide) {
+ return this.getLightLevelAtSideAndDistance(aSide, 1);
+ }
+
+ public final byte getLightLevelAtSideAndDistance(byte aSide, int aDistance) {
+ return this.getLightLevel(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final boolean getOpacityOffset(int aX, int aY, int aZ) {
+ return this.getOpacity(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final boolean getOpacityAtSide(byte aSide) {
+ return this.getOpacityAtSideAndDistance(aSide, 1);
+ }
+
+ public final boolean getOpacityAtSideAndDistance(byte aSide, int aDistance) {
+ return this.getOpacity(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final boolean getSkyOffset(int aX, int aY, int aZ) {
+ return this.getSky(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final boolean getSkyAtSide(byte aSide) {
+ return this.getSkyAtSideAndDistance(aSide, 1);
+ }
+
+ public final boolean getSkyAtSideAndDistance(byte aSide, int aDistance) {
+ return this.getSky(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final boolean getAirOffset(int aX, int aY, int aZ) {
+ return this.getAir(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final boolean getAirAtSide(byte aSide) {
+ return this.getAirAtSideAndDistance(aSide, 1);
+ }
+
+ public final boolean getAirAtSideAndDistance(byte aSide, int aDistance) {
+ return this.getAir(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final TileEntity getTileEntityOffset(int aX, int aY, int aZ) {
+ return this.getTileEntity(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ public final TileEntity getTileEntityAtSideAndDistance(byte aSide, int aDistance) {
+ return aDistance == 1
+ ? this.getTileEntityAtSide(aSide)
+ : this.getTileEntity(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ public final IInventory getIInventory(int aX, int aY, int aZ) {
+ TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ);
+ return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null;
+ }
+
+ public final IInventory getIInventoryOffset(int aX, int aY, int aZ) {
+ TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ);
+ return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null;
+ }
+
+ public final IInventory getIInventoryAtSide(byte aSide) {
+ TileEntity tTileEntity = this.getTileEntityAtSide(aSide);
+ return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null;
+ }
+
+ public final IInventory getIInventoryAtSideAndDistance(byte aSide, int aDistance) {
+ TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(aSide, aDistance);
+ return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null;
+ }
+
+ public final IFluidHandler getITankContainer(int aX, int aY, int aZ) {
+ TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ);
+ return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null;
+ }
+
+ public final IFluidHandler getITankContainerOffset(int aX, int aY, int aZ) {
+ TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ);
+ return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null;
+ }
+
+ public final IFluidHandler getITankContainerAtSide(byte aSide) {
+ TileEntity tTileEntity = this.getTileEntityAtSide(aSide);
+ return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null;
+ }
+
+ public final IFluidHandler getITankContainerAtSideAndDistance(byte aSide, int aDistance) {
+ TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(aSide, aDistance);
+ return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null;
+ }
+
+ public final IGregTechTileEntity getIGregTechTileEntity(int aX, int aY, int aZ) {
+ TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ);
+ return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null;
+ }
+
+ public final IGregTechTileEntity getIGregTechTileEntityOffset(int aX, int aY, int aZ) {
+ TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ);
+ return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null;
+ }
+
+ public final IGregTechTileEntity getIGregTechTileEntityAtSide(byte aSide) {
+ TileEntity tTileEntity = this.getTileEntityAtSide(aSide);
+ return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null;
+ }
+
+ public final IGregTechTileEntity getIGregTechTileEntityAtSideAndDistance(byte aSide, int aDistance) {
+ TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(aSide, aDistance);
+ return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null;
+ }
+
+ public final Block getBlock(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? Blocks.air
+ : this.worldObj.getBlock(aX, aY, aZ);
+ }
+
+ public final byte getMetaID(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? 0
+ : (byte) this.worldObj.getBlockMetadata(aX, aY, aZ);
+ }
+
+ public final byte getLightLevel(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? 0
+ : (byte) ((int) (this.worldObj.getLightBrightness(aX, aY, aZ) * 15.0F));
+ }
+
+ public final boolean getSky(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? true
+ : this.worldObj.canBlockSeeTheSky(aX, aY, aZ);
+ }
+
+ public final boolean getOpacity(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? false
+ : GT_Utility.isOpaqueBlock(this.worldObj, aX, aY, aZ);
+ }
+
+ public final boolean getAir(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? true
+ : GT_Utility.isBlockAir(this.worldObj, aX, aY, aZ);
+ }
+
+ public final TileEntity getTileEntity(int aX, int aY, int aZ) {
+ return this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)
+ ? null
+ : this.worldObj.getTileEntity(aX, aY, aZ);
+ }
+
+ public final TileEntity getTileEntityAtSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6 && this.mBufferedTileEntities[aSide] != this) {
+ int tX = this.getOffsetX(aSide, 1);
+ short tY = this.getOffsetY(aSide, 1);
+ int tZ = this.getOffsetZ(aSide, 1);
+ if (this.crossedChunkBorder(tX, tZ)) {
+ this.mBufferedTileEntities[aSide] = null;
+ if (this.ignoreUnloadedChunks && !this.worldObj.blockExists(tX, tY, tZ)) {
+ return null;
+ }
+ }
+
+ if (this.mBufferedTileEntities[aSide] == null) {
+ this.mBufferedTileEntities[aSide] = this.worldObj.getTileEntity(tX, tY, tZ);
+ if (this.mBufferedTileEntities[aSide] == null) {
+ this.mBufferedTileEntities[aSide] = this;
+ return null;
+ } else {
+ return this.mBufferedTileEntities[aSide];
+ }
+ } else if (this.mBufferedTileEntities[aSide].isInvalid()) {
+ this.mBufferedTileEntities[aSide] = null;
+ return this.getTileEntityAtSide(aSide);
+ } else {
+ return this.mBufferedTileEntities[aSide].xCoord == tX && this.mBufferedTileEntities[aSide].yCoord == tY
+ && this.mBufferedTileEntities[aSide].zCoord == tZ ? this.mBufferedTileEntities[aSide] : null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ public boolean isDead() {
+ return this.isDead || this.isInvalidTileEntity();
+ }
+
+ public void validate() {
+ this.clearNullMarkersFromTileEntityBuffer();
+ super.validate();
+ }
+
+ public void invalidate() {
+ this.clearNullMarkersFromTileEntityBuffer();
+ super.invalidate();
+ }
+
+ public void onChunkUnload() {
+ this.clearNullMarkersFromTileEntityBuffer();
+ super.onChunkUnload();
+ this.isDead = true;
+ }
+
+ public final void onAdjacentBlockChange(int aX, int aY, int aZ) {
+ this.clearNullMarkersFromTileEntityBuffer();
+ }
+
+ public final void sendBlockEvent(byte aID, byte aValue) {
+ GT_Values.NW.sendPacketToAllPlayersInRange(this.worldObj,
+ new GT_Packet_Block_Event(this.xCoord, (short) this.yCoord, this.zCoord, aID, aValue), this.xCoord,
+ this.zCoord);
+ }
+
+ private boolean crossedChunkBorder(int aX, int aZ) {
+ return aX >> 4 != this.xCoord >> 4 || aZ >> 4 != this.zCoord >> 4;
+ }
+
+ public final void setOnFire() {
+ GT_Utility.setCoordsOnFire(this.worldObj, this.xCoord, this.yCoord, this.zCoord, false);
+ }
+
+ public final void setToFire() {
+ this.worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, Blocks.fire);
+ }
+
+ public String trans(String aKey, String aEnglish) {
+ return GT_LanguageManager.addStringLocalization("Interaction_DESCRIPTION_Index_" + aKey, aEnglish, false);
+ }
+
+ @Override
+ public byte getInternalInputRedstoneSignal(byte aSide) {
+ return (byte) (getCoverBehaviorAtSide(aSide).getRedstoneInput(aSide, getInputRedstoneSignal(aSide), getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this) & 15);
+ }
+
+ @Override
+ public byte getInputRedstoneSignal(byte aSide) {
+ return (byte) (worldObj.getIndirectPowerLevelTo(getOffsetX(aSide, 1), getOffsetY(aSide, 1), getOffsetZ(aSide, 1), aSide) & 15);
+ }
+
+ @Override
+ public byte getOutputRedstoneSignal(byte aSide) {
+ return getCoverBehaviorAtSide(aSide).manipulatesSidedRedstoneOutput(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this) ? mSidedRedstone[aSide] : getGeneralRS(aSide);
+ }
+
+ public boolean allowGeneralRedstoneOutput() {
+ return false;
+ }
+
+ public byte getGeneralRS(byte aSide){
+ return allowGeneralRedstoneOutput() ? mSidedRedstone[aSide] : 0;
+ }
+
+ @Override
+ public void setInternalOutputRedstoneSignal(byte aSide, byte aStrength) {
+ if (!getCoverBehaviorAtSide(aSide).manipulatesSidedRedstoneOutput(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this))
+ setOutputRedstoneSignal(aSide, aStrength);
+ }
+
+ @Override
+ public void setOutputRedstoneSignal(byte aSide, byte aStrength) {
+ aStrength = (byte) Math.min(Math.max(0, aStrength), 15);
+ if (aSide >= 0 && aSide < 6 && mSidedRedstone[aSide] != aStrength) {
+ mSidedRedstone[aSide] = aStrength;
+ issueBlockUpdate();
+ }
+ }
+
+ @Override
+ public boolean hasInventoryBeenModified() {
+ return mInventoryChanged;
+ }
+
+ @Override
+ public void setGenericRedstoneOutput(boolean aOnOff) {
+ mRedstone = aOnOff;
+ }
+
+ @Override
+ public GT_CoverBehavior getCoverBehaviorAtSide(byte aSide) {
+ return aSide >= 0 && aSide < mCoverBehaviors.length ? mCoverBehaviors[aSide] : GregTech_API.sNoBehavior;
+ }
+
+ @Override
+ public void setCoverIDAtSide(byte aSide, int aID) {
+ if (aSide >= 0 && aSide < 6) {
+ mCoverSides[aSide] = aID;
+ mCoverData[aSide] = 0;
+ mCoverBehaviors[aSide] = GregTech_API.getCoverBehavior(aID);
+ issueCoverUpdate(aSide);
+ issueBlockUpdate();
+ }
+ }
+
+ @Override
+ public void setCoverItemAtSide(byte aSide, ItemStack aCover) {
+ GregTech_API.getCoverBehavior(aCover).placeCover(aSide, aCover, this);
+ }
+
+ @Override
+ public int getCoverIDAtSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) return mCoverSides[aSide];
+ return 0;
+ }
+
+ @Override
+ public ItemStack getCoverItemAtSide(byte aSide) {
+ return GT_Utility.intToStack(getCoverIDAtSide(aSide));
+ }
+
+ @Override
+ public boolean canPlaceCoverIDAtSide(byte aSide, int aID) {
+ return getCoverIDAtSide(aSide) == 0;
+ }
+
+ @Override
+ public boolean canPlaceCoverItemAtSide(byte aSide, ItemStack aCover) {
+ return getCoverIDAtSide(aSide) == 0;
+ }
+
+ @Override
+ public void setCoverDataAtSide(byte aSide, int aData) {
+ if (aSide >= 0 && aSide < 6) mCoverData[aSide] = aData;
+ }
+
+ @Override
+ public int getCoverDataAtSide(byte aSide) {
+ if (aSide >= 0 && aSide < 6) return mCoverData[aSide];
+ return 0;
+ }
+
+ public byte getLightValue() {
+ return mLightValue;
+ }
+
+ @Override
+ public void setLightValue(byte aLightValue) {
+ mLightValue = (byte) (aLightValue & 15);
+ }
+
+ @Override
+ public long getAverageElectricInput() {
+ int rEU = 0;
+ for (int i = 0; i < mAverageEUInput.length; i++) {
+ if (i != mAverageEUInputIndex)
+ rEU += mAverageEUInput[i];
+ }
+ return rEU / (mAverageEUInput.length - 1);
+ }
+
+ @Override
+ public long getAverageElectricOutput() {
+ int rEU = 0;
+ for (int i = 0; i < mAverageEUOutput.length; i++) {
+ if (i != mAverageEUOutputIndex)
+ rEU += mAverageEUOutput[i];
+ }
+ return rEU / (mAverageEUOutput.length - 1);
+ }
+
+ public boolean hasSidedRedstoneOutputBehavior() {
+ return false;
+ }
+
+ @Override
+ public boolean dropCover(byte aSide, byte aDroppedSide, boolean aForced) {
+ if (getCoverBehaviorAtSide(aSide).onCoverRemoval(aSide, getCoverIDAtSide(aSide), mCoverData[aSide], this, aForced) || aForced) {
+ ItemStack tStack = getCoverBehaviorAtSide(aSide).getDrop(aSide, getCoverIDAtSide(aSide), getCoverDataAtSide(aSide), this);
+ if (tStack != null) {
+ tStack.setTagCompound(null);
+ EntityItem tEntity = new EntityItem(worldObj, getOffsetX(aDroppedSide, 1) + 0.5, getOffsetY(aDroppedSide, 1) + 0.5, getOffsetZ(aDroppedSide, 1) + 0.5, tStack);
+ tEntity.motionX = 0;
+ tEntity.motionY = 0;
+ tEntity.motionZ = 0;
+ worldObj.spawnEntityInWorld(tEntity);
+ }
+ setCoverIDAtSide(aSide, 0);
+ if (mMetaTileEntity.hasSidedRedstoneOutputBehavior()) {
+ setOutputRedstoneSignal(aSide, (byte) 0);
+ } else {
+ setOutputRedstoneSignal(aSide, (byte) 15);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public String getOwnerName() {
+ if (GT_Utility.isStringInvalid(mOwnerName)) return "Player";
+ return mOwnerName;
+ }
+
+ public String setOwnerName(String aName) {
+ if (GT_Utility.isStringInvalid(aName)) return mOwnerName = "Player";
+ return mOwnerName = aName;
+ }
+
+ @Override
+ public byte getComparatorValue(byte aSide) {
+ return canAccessData() ? mMetaTileEntity.getComparatorValue(aSide) : 0;
+ }
+
+ @Override
+ public byte getStrongOutputRedstoneSignal(byte aSide) {
+ return aSide >= 0 && aSide < 6 && (mStrongRedstone & (1 << aSide)) != 0 ? (byte) (mSidedRedstone[aSide] & 15) : 0;
+ }
+
+ @Override
+ public void setStrongOutputRedstoneSignal(byte aSide, byte aStrength) {
+ mStrongRedstone |= (1 << aSide);
+ setOutputRedstoneSignal(aSide, aStrength);
+ }
+
+ @Override
+ public long injectEnergyUnits(byte aSide, long aVoltage, long aAmperage) {
+ if (!canAccessData() || !mMetaTileEntity.isElectric() || !inputEnergyFrom(aSide) || aAmperage <= 0 || aVoltage <= 0 || getStoredEU() >= getEUCapacity() || mMetaTileEntity.maxAmperesIn() <= mAcceptedAmperes)
+ return 0;
+ if (aVoltage > getInputVoltage()) {
+ doExplosion(aVoltage);
+ return 0;
+ }
+ if (increaseStoredEnergyUnits(aVoltage * (aAmperage = Math.min(aAmperage, Math.min(mMetaTileEntity.maxAmperesIn() - mAcceptedAmperes, 1 + ((getEUCapacity() - getStoredEU()) / aVoltage)))), true)) {
+ mAverageEUInput[mAverageEUInputIndex] += aVoltage * aAmperage;
+ mAcceptedAmperes += aAmperage;
+ return aAmperage;
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean drainEnergyUnits(byte aSide, long aVoltage, long aAmperage) {
+ if (!canAccessData() || !mMetaTileEntity.isElectric() || !outputsEnergyTo(aSide) || getStoredEU() - (aVoltage * aAmperage) < mMetaTileEntity.getMinimumStoredEU())
+ return false;
+ if (decreaseStoredEU(aVoltage * aAmperage, false)) {
+ mAverageEUOutput[mAverageEUOutputIndex] += aVoltage * aAmperage;
+ return true;
+ }
+ return false;
+ }
+
+
+ public double getOutputEnergyUnitsPerTick() {
+ return oOutput;
+ }
+
+
+ public boolean isTeleporterCompatible(ForgeDirection aSide) {
+ return false;
+ }
+
+
+ public double demandedEnergyUnits() {
+ if (mReleaseEnergy || !canAccessData() || !mMetaTileEntity.isEnetInput()) return 0;
+ return getEUCapacity() - getStoredEU();
+ }
+
+
+ public double injectEnergyUnits(ForgeDirection aDirection, double aAmount) {
+ return injectEnergyUnits((byte) aDirection.ordinal(), (int) aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+
+ public boolean acceptsEnergyFrom(TileEntity aEmitter, ForgeDirection aDirection) {
+ return inputEnergyFrom((byte) aDirection.ordinal());
+ }
+
+
+ public boolean emitsEnergyTo(TileEntity aReceiver, ForgeDirection aDirection) {
+ return outputsEnergyTo((byte) aDirection.ordinal());
+ }
+
+
+ public double getOfferedEnergy() {
+ return (canAccessData() && getStoredEU() - mMetaTileEntity.getMinimumStoredEU() >= oOutput) ? Math.max(0, oOutput) : 0;
+ }
+
+
+ public void drawEnergy(double amount) {
+ mAverageEUOutput[mAverageEUOutputIndex] += amount;
+ decreaseStoredEU((int) amount, true);
+ }
+
+
+ public int injectEnergy(ForgeDirection aForgeDirection, int aAmount) {
+ return injectEnergyUnits((byte) aForgeDirection.ordinal(), aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+
+ public int addEnergy(int aEnergy) {
+ if (!canAccessData()) return 0;
+ if (aEnergy > 0)
+ increaseStoredEnergyUnits(aEnergy, true);
+ else
+ decreaseStoredEU(-aEnergy, true);
+ return (int) Math.min(Integer.MAX_VALUE, mMetaTileEntity.getEUVar());
+ }
+
+
+ public boolean isAddedToEnergyNet() {
+ return false;
+ }
+
+
+ public int demandsEnergy() {
+ if (mReleaseEnergy || !canAccessData() || !mMetaTileEntity.isEnetInput()) return 0;
+ return getCapacity() - getStored();
+ }
+
+
+ public int getCapacity() {
+ return (int) Math.min(Integer.MAX_VALUE, getEUCapacity());
+ }
+
+
+ public int getStored() {
+ return (int) Math.min(Integer.MAX_VALUE, Math.min(getStoredEU(), getCapacity()));
+ }
+
+
+ public void setStored(int aEU) {
+ if (canAccessData()) setStoredEU(aEU);
+ }
+
+
+ public int getMaxSafeInput() {
+ return (int) Math.min(Integer.MAX_VALUE, getInputVoltage());
+ }
+
+
+ public int getMaxEnergyOutput() {
+ if (mReleaseEnergy) return Integer.MAX_VALUE;
+ return getOutput();
+ }
+
+
+ public int getOutput() {
+ return (int) Math.min(Integer.MAX_VALUE, oOutput);
+ }
+
+
+ public int injectEnergy(Direction aDirection, int aAmount) {
+ return injectEnergyUnits((byte) aDirection.toSideValue(), aAmount, 1) > 0 ? 0 : aAmount;
+ }
+
+ public boolean acceptsEnergyFrom(TileEntity aReceiver, Direction aDirection) {
+ return inputEnergyFrom((byte) aDirection.toSideValue());
+ }
+
+
+ public boolean emitsEnergyTo(TileEntity aReceiver, Direction aDirection) {
+ return outputsEnergyTo((byte) aDirection.toSideValue());
+ }
+
+ @Override
+ public boolean isInvalidTileEntity() {
+ return isInvalid();
+ }
+
+ @Override
+ public boolean addStackToSlot(int aIndex, ItemStack aStack) {
+ if (GT_Utility.isStackInvalid(aStack)) return true;
+ if (aIndex < 0 || aIndex >= getSizeInventory()) return false;
+ ItemStack tStack = getStackInSlot(aIndex);
+ if (GT_Utility.isStackInvalid(tStack)) {
+ setInventorySlotContents(aIndex, aStack);
+ return true;
+ }
+ aStack = GT_OreDictUnificator.get(aStack);
+ if (GT_Utility.areStacksEqual(tStack, aStack) && tStack.stackSize + aStack.stackSize <= Math.min(aStack.getMaxStackSize(), getInventoryStackLimit())) {
+ tStack.stackSize += aStack.stackSize;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount) {
+ return addStackToSlot(aIndex, GT_Utility.copyAmount(aAmount, aStack));
+ }
+
+ @Override
+ public void markDirty() {
+ super.markDirty();
+ mInventoryChanged = true;
+ }
+
+
+
+ /**
+ * To Do
+ */
+
+ public boolean isElectric() {
+ return true;
+ }
+
+ public boolean isEnetOutput() {
+ return false;
+ }
+
+ public boolean isEnetInput() {
+ return false;
+ }
+
+ public long maxEUStore() {
+ return 0L;
+ }
+
+ public long maxEUInput() {
+ return 0L;
+ }
+
+ public long maxEUOutput() {
+ return 0L;
+ }
+
+ public long maxAmperesOut() {
+ return 1L;
+ }
+
+ public long maxAmperesIn() {
+ return 1L;
+ }
+
+ public void doEnergyExplosion() {
+ if (this.getUniversalEnergyCapacity() > 0L
+ && this.getUniversalEnergyStored() >= this.getUniversalEnergyCapacity() / 5L) {
+ this.doExplosion(this.oOutput * (long) (this.getUniversalEnergyStored() >= this.getUniversalEnergyCapacity()
+ ? 4
+ : (this.getUniversalEnergyStored() >= this.getUniversalEnergyCapacity() / 2L ? 2 : 1)));
+ GT_Mod arg9999 = GT_Mod.instance;
+ GT_Mod.achievements.issueAchievement(this.getWorldObj().getPlayerEntityByName(this.mOwnerName),
+ "electricproblems");
+ }
+
+ }
+
+ public void doExplosion(long aAmount) {
+ if (this.canAccessData()) {
+ if (GregTech_API.sMachineWireFire && this.mMetaTileEntity.isElectric()) {
+ try {
+ this.mReleaseEnergy = true;
+ Util.emitEnergyToNetwork(GT_Values.V[5], Math.max(1L, this.getStoredEU() / GT_Values.V[5]), this);
+ } catch (Exception arg4) {
+ }
+ }
+ this.mReleaseEnergy = false;
+ this.onExplosion();
+ PollutionUtils.addPollution(this, 100000);
+ this.mMetaTileEntity.doExplosion(aAmount);
+ }
+
+ }
+
+ public void onExplosion() {
+
+ }
+
+ @Override
+ public String[] getDescription() {
+ return this.canAccessData() ? this.mMetaTileEntity.getDescription() : new String[0];
+ }
+
+ @Override
+ public boolean isGivingInformation() {
+ return true;
+ }
+
+ @Override
+ public String[] getInfoData() {
+ return null;
+ }
+
+ public long getEUVar() {
+ return this.mStoredEnergy;
+ }
+
+ public void setEUVar(long aEnergy) {
+ this.mStoredEnergy = aEnergy;
+ }
+
+ public long getStoredEU() {
+ return this.canAccessData() ? Math.min(this.mMetaTileEntity.getEUVar(), this.getEUCapacity()) : 0L;
+ }
+
+ public long getEUCapacity() {
+ return this.canAccessData() ? this.mMetaTileEntity.maxEUStore() : 0L;
+ }
+
+ public long getMinimumStoredEU() {
+ return 512L;
+ }
+
+ public boolean setStoredEU(long aEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ } else {
+ if (aEnergy < 0L) {
+ aEnergy = 0L;
+ }
+
+ this.mMetaTileEntity.setEUVar(aEnergy);
+ return true;
+ }
+ }
+
+ public boolean decreaseStoredEU(long aEnergy, boolean aIgnoreTooLessEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ } else if (this.mMetaTileEntity.getEUVar() - aEnergy < 0L && !aIgnoreTooLessEnergy) {
+ return false;
+ } else {
+ this.setStoredEU(this.mMetaTileEntity.getEUVar() - aEnergy);
+ if (this.mMetaTileEntity.getEUVar() < 0L) {
+ this.setStoredEU(0L);
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ //Required as of 5.09.32-pre5
+ public boolean energyStateReady() {
+ return false;
+ }
+
+
+ private boolean firstTicked = false;
+
+ public boolean onFirstTick() {
+ if (!firstTicked) {
+ firstTicked = true;
+ if (this.mInventory != null) {
+ this.mInventory.purgeNulls();
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Adds support for the newer function added by https://github.com/Blood-Asp/GT5-Unofficial/commit/73ee102b63efd92c0f164a7ed7a79ebcd2619617#diff-3051838621d8ae87aa5ccd1345e1f07d
+ */
+ public boolean inputEnergyFrom(byte arg0, boolean arg1) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+
+ /**
+ * Adds support for the newer function added by https://github.com/Blood-Asp/GT5-Unofficial/commit/73ee102b63efd92c0f164a7ed7a79ebcd2619617#diff-3051838621d8ae87aa5ccd1345e1f07d
+ */
+ public boolean outputsEnergyTo(byte arg0, boolean arg1) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/base/TilePoweredGT.java b/src/main/java/gtPlusPlus/core/tileentities/base/TilePoweredGT.java
new file mode 100644
index 0000000000..fb599b0bae
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/base/TilePoweredGT.java
@@ -0,0 +1,1168 @@
+/*package gtPlusPlus.core.tileentities.base;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.Entity;
+import net.minecraft.init.Blocks;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.Packet;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.net.GT_Packet;
+import gregtech.api.net.GT_Packet_Block_Event;
+import gregtech.api.util.GT_Utility;
+
+import gtPlusPlus.api.interfaces.IGregtechPower;
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.core.lib.CORE;
+import gtPlusPlus.core.util.Utils;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public abstract class TilePoweredGT extends TileEntityBase implements IGregtechPower {
+
+ public static AutoMap<TilePoweredGT> mPoweredEntities = new AutoMap<TilePoweredGT>();
+
+ //Base Tile Fields
+ public boolean ignoreUnloadedChunks;
+ public boolean isDead;
+ //Meta Tile Fields
+ private long mAcceptedAmperes;
+
+ private boolean[] mActiveEUInputs;
+ private boolean[] mActiveEUOutputs;
+ protected int[] mAverageEUInput;
+ protected int mAverageEUInputIndex;
+ protected int[] mAverageEUOutput;
+ protected int mAverageEUOutputIndex;
+ private final TileEntity[] mBufferedTileEntities;
+ private byte mFacing = 0;
+ private boolean mHasEnoughEnergy;
+ private boolean mNeedsUpdate;
+ private boolean mNeedsBlockUpdate;
+ private boolean mRunningThroughTick;
+ private boolean mSendClientData;
+ protected boolean mReleaseEnergy;
+ private long mTickTimer;
+ protected long mStoredEnergy;
+ protected long mStoredSteam;
+
+ public TilePoweredGT() {
+ super();
+ this.mBufferedTileEntities = new TileEntity[6];
+ this.ignoreUnloadedChunks = true;
+ this.isDead = false;
+ mPoweredEntities.put(this);
+ }
+
+ @Override
+ public boolean acceptsRotationalEnergy(byte p0) {
+ return false;
+ }
+
+ private boolean canAccessData() {
+ return this.isInvalid() ? false : true;
+ }
+
+ private final void clearNullMarkersFromTileEntityBuffer() {
+ for (int i = 0; i < this.mBufferedTileEntities.length; ++i) {
+ if (this.mBufferedTileEntities[i] == this) {
+ this.mBufferedTileEntities[i] = null;
+ }
+ }
+ }
+
+ protected final void clearTileEntityBuffer() {
+ for (int i = 0; i < this.mBufferedTileEntities.length; ++i) {
+ this.mBufferedTileEntities[i] = null;
+ }
+ }
+
+ private boolean crossedChunkBorder(final int aX, final int aZ) {
+ return aX >> 4 != this.xCoord >> 4 || aZ >> 4 != this.zCoord >> 4;
+ }
+
+ @Override
+ public boolean decreaseStoredEnergyUnits(final long aEnergy, final boolean aIgnoreTooLessEnergy) {
+ return this.canAccessData() && (this.mHasEnoughEnergy = (this.decreaseStoredEU(aEnergy, aIgnoreTooLessEnergy)
+ || this.decreaseStoredSteam(aEnergy, false)
+ || (aIgnoreTooLessEnergy && this.decreaseStoredSteam(aEnergy, true))));
+ }
+
+ public boolean decreaseStoredEU(final long aEnergy, final boolean aIgnoreTooLessEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ }
+ if (this.getEUVar() - aEnergy < 0L && !aIgnoreTooLessEnergy) {
+ return false;
+ }
+ this.setStoredEU(this.getEUVar() - aEnergy);
+ if (this.getEUVar() < 0L) {
+ this.setStoredEU(0L);
+ return false;
+ }
+ return true;
+ }
+
+ public boolean decreaseStoredSteam(final long aEnergy, final boolean aIgnoreTooLessEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ }
+ if (this.getSteamVar() - aEnergy < 0L && !aIgnoreTooLessEnergy) {
+ return false;
+ }
+ this.setStoredSteam(this.getSteamVar() - aEnergy);
+ if (this.getSteamVar() < 0L) {
+ this.setStoredSteam(0L);
+ return false;
+ }
+ return true;
+ }
+
+ public void doExplosion(final long aExplosionPower) {
+ final float tStrength = (aExplosionPower < GT_Values.V[0])
+ ? 1.0f
+ : ((aExplosionPower < GT_Values.V[1])
+ ? 2.0f
+ : ((aExplosionPower < GT_Values.V[2])
+ ? 3.0f
+ : ((aExplosionPower < GT_Values.V[3])
+ ? 4.0f
+ : ((aExplosionPower < GT_Values.V[4])
+ ? 5.0f
+ : ((aExplosionPower < GT_Values.V[4] * 2L)
+ ? 6.0f
+ : ((aExplosionPower < GT_Values.V[5])
+ ? 7.0f
+ : ((aExplosionPower < GT_Values.V[6])
+ ? 8.0f
+ : ((aExplosionPower < GT_Values.V[7])
+ ? 9.0f
+ : 10.0f))))))));
+ final int tX = this.getXCoord();
+ final int tY = this.getYCoord();
+ final int tZ = this.getZCoord();
+ final World tWorld = this.getWorld();
+ GT_Utility.sendSoundToPlayers(tWorld, (String) GregTech_API.sSoundList.get(209), 1.0f, -1.0f, tX, tY, tZ);
+ tWorld.setBlock(tX, tY, tZ, Blocks.air);
+ if (GregTech_API.sMachineExplosions) {
+ tWorld.createExplosion((Entity) null, tX + 0.5, tY + 0.5, tZ + 0.5, tStrength, true);
+ }
+ }
+
+ public boolean drainEnergyUnits(final byte aSide, final long aVoltage, final long aAmperage) {
+ if (!this.canAccessData() || !this.isElectric() || !this.outputsEnergyTo(aSide)
+ || this.getStoredEU() - aVoltage * aAmperage < this.getMinimumStoredEU()) {
+ return false;
+ }
+ if (this.decreaseStoredEU(aVoltage * aAmperage, false)) {
+ final int[] mAverageEUOutput = this.mAverageEUOutput;
+ final int mAverageEUOutputIndex = this.mAverageEUOutputIndex;
+ mAverageEUOutput[mAverageEUOutputIndex] += (int) (aVoltage * aAmperage);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean getAir(final int aX, final int aY, final int aZ) {
+ return (this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ))
+ || GT_Utility.isBlockAir(this.worldObj, aX, aY, aZ);
+ }
+
+ @Override
+ public final boolean getAirAtSide(final byte aSide) {
+ return this.getAirAtSideAndDistance(aSide, 1);
+ }
+
+ @Override
+ public final boolean getAirAtSideAndDistance(final byte aSide, final int aDistance) {
+ return this.getAir(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ @Override
+ public final boolean getAirOffset(final int aX, final int aY, final int aZ) {
+ return this.getAir(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ @Override
+ public long getAverageElectricInput() {
+ int rEU = 0;
+ for (int i = 0; i < this.mAverageEUInput.length; ++i) {
+ if (i != this.mAverageEUInputIndex) {
+ rEU += this.mAverageEUInput[i];
+ }
+ }
+ return rEU / (this.mAverageEUInput.length - 1);
+ }
+
+ public long getAverageElectricOutput() {
+ int rEU = 0;
+ for (int i = 0; i < this.mAverageEUOutput.length; ++i) {
+ if (i != this.mAverageEUOutputIndex) {
+ rEU += this.mAverageEUOutput[i];
+ }
+ }
+ return rEU / (this.mAverageEUOutput.length - 1);
+ }
+
+ @Override
+ public byte getBackFacing() {
+ return GT_Utility.getOppositeSide((int) this.mFacing);
+ }
+
+ @Override
+ public final Block getBlock(final int aX, final int aY, final int aZ) {
+ if (this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)) {
+ return Blocks.air;
+ }
+ return this.worldObj.getBlock(aX, aY, aZ);
+ }
+
+
+ @Override
+ public final Block getBlockAtSide(final byte aSide) {
+ return this.getBlockAtSideAndDistance(aSide, 1);
+ }
+
+ @Override
+ public final Block getBlockAtSideAndDistance(final byte aSide, final int aDistance) {
+ return this.getBlock(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+ @Override
+ public final Block getBlockOffset(final int aX, final int aY, final int aZ) {
+ return this.getBlock(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ @Override
+ public String[] getDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+
+
+
+
+
+ @Override
+ public long getEUCapacity() {
+ if (this.canAccessData()) {
+ return this.maxEUStore();
+ }
+ return 0L;
+ }
+
+ public long getEUVar() {
+ return mStoredEnergy;
+ }
+
+ @Override
+ public byte getFrontFacing() {
+ return this.mFacing;
+ }
+
+ @Override
+ public final IGregTechTileEntity getIGregTechTileEntity(final int aX, final int aY, final int aZ) {
+ final TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ);
+ if (tTileEntity instanceof IGregTechTileEntity) {
+ return (IGregTechTileEntity) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IGregTechTileEntity getIGregTechTileEntityAtSide(final byte aSide) {
+ final TileEntity tTileEntity = this.getTileEntityAtSide(aSide);
+ if (tTileEntity instanceof IGregTechTileEntity) {
+ return (IGregTechTileEntity) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IGregTechTileEntity getIGregTechTileEntityAtSideAndDistance(final byte aSide, final int aDistance) {
+ final TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(aSide, aDistance);
+ if (tTileEntity instanceof IGregTechTileEntity) {
+ return (IGregTechTileEntity) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IGregTechTileEntity getIGregTechTileEntityOffset(final int aX, final int aY, final int aZ) {
+ final TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ);
+ if (tTileEntity instanceof IGregTechTileEntity) {
+ return (IGregTechTileEntity) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IInventory getIInventory(final int aX, final int aY, final int aZ) {
+ final TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ);
+ if (tTileEntity instanceof IInventory) {
+ return (IInventory) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IInventory getIInventoryAtSide(final byte aSide) {
+ final TileEntity tTileEntity = this.getTileEntityAtSide(aSide);
+ if (tTileEntity instanceof IInventory) {
+ return (IInventory) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IInventory getIInventoryAtSideAndDistance(final byte aSide, final int aDistance) {
+ final TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(aSide, aDistance);
+ if (tTileEntity instanceof IInventory) {
+ return (IInventory) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public final IInventory getIInventoryOffset(final int aX, final int aY, final int aZ) {
+ final TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ);
+ if (tTileEntity instanceof IInventory) {
+ return (IInventory) tTileEntity;
+ }
+ return null;
+ }
+
+ @Override
+ public String[] getInfoData() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public long getInputAmperage() {
+ if (this.canAccessData() && this.isElectric()) {
+ return this.maxAmperesIn();
+ }
+ return 0L;
+ }
+
+ public long getInputTier() {
+ return GT_Utility.getTier(this.getInputVoltage());
+ }
+
+ @Override
+ public long getInputVoltage() {
+ if (this.canAccessData() && this.isElectric()) {
+ return this.maxEUInput();
+ }
+ return 2147483647L;
+ }
+
+ private long getMinimumStoredEU() {
+ return 0;
+ }
+
+ @Override
+ public final int getOffsetX(final byte aSide, final int aMultiplier) {
+ return this.xCoord + ForgeDirection.getOrientation((int) aSide).offsetX * aMultiplier;
+ }
+
+ public final short getOffsetY(final byte aSide, final int aMultiplier) {
+ return (short) (this.yCoord + ForgeDirection.getOrientation((int) aSide).offsetY * aMultiplier);
+ }
+
+ public final int getOffsetZ(final byte aSide, final int aMultiplier) {
+ return this.zCoord + ForgeDirection.getOrientation((int) aSide).offsetZ * aMultiplier;
+ }
+
+ @Override
+ public long getOutputAmperage() {
+ if (this.canAccessData() && this.isElectric()) {
+ return this.maxAmperesOut();
+ }
+ return 0L;
+ }
+
+ public long getOutputTier() {
+ return GT_Utility.getTier(this.getOutputVoltage());
+ }
+
+ @Override
+ public long getOutputVoltage() {
+ if (this.canAccessData() && this.isElectric() && this.isEnetOutput()) {
+ return this.maxEUOutput();
+ }
+ return 0L;
+ }
+
+ @Override
+ public int getRandomNumber(int p0) {
+ return CORE.RANDOM.nextInt();
+ }
+
+ @Override
+ public long getSteamCapacity() {
+ if (this.canAccessData()) {
+ return this.maxSteamStore();
+ }
+ return 0L;
+ }
+
+ public long getSteamVar() {
+ return mStoredSteam;
+ }
+
+ @Override
+ public long getStoredEU() {
+ if (this.canAccessData()) {
+ return Math.min(this.getEUVar(), this.getEUCapacity());
+ }
+ return 0L;
+ }
+
+
+
+
+
+
+
+
+
+ @Override
+ public long getStoredSteam() {
+ if (this.canAccessData()) {
+ return Math.min(this.getSteamVar(), this.getSteamCapacity());
+ }
+ return 0L;
+ }
+
+ @Override
+ public final TileEntity getTileEntity(final int aX, final int aY, final int aZ) {
+ if (this.ignoreUnloadedChunks && this.crossedChunkBorder(aX, aZ) && !this.worldObj.blockExists(aX, aY, aZ)) {
+ return null;
+ }
+ return this.worldObj.getTileEntity(aX, aY, aZ);
+ }
+
+ public final TileEntity getTileEntityAtSide(final byte aSide) {
+ if (aSide < 0 || aSide >= 6 || this.mBufferedTileEntities[aSide] == this) {
+ return null;
+ }
+ final int tX = this.getOffsetX(aSide, 1);
+ final int tY = this.getOffsetY(aSide, 1);
+ final int tZ = this.getOffsetZ(aSide, 1);
+ if (this.crossedChunkBorder(tX, tZ)) {
+ this.mBufferedTileEntities[aSide] = null;
+ if (this.ignoreUnloadedChunks && !this.worldObj.blockExists(tX, tY, tZ)) {
+ return null;
+ }
+ }
+ if (this.mBufferedTileEntities[aSide] == null) {
+ this.mBufferedTileEntities[aSide] = this.worldObj.getTileEntity(tX, tY, tZ);
+ if (this.mBufferedTileEntities[aSide] == null) {
+ this.mBufferedTileEntities[aSide] = this;
+ return null;
+ }
+ return this.mBufferedTileEntities[aSide];
+ } else {
+ if (this.mBufferedTileEntities[aSide].isInvalid()) {
+ this.mBufferedTileEntities[aSide] = null;
+ return this.getTileEntityAtSide(aSide);
+ }
+ if (this.mBufferedTileEntities[aSide].xCoord == tX && this.mBufferedTileEntities[aSide].yCoord == tY
+ && this.mBufferedTileEntities[aSide].zCoord == tZ) {
+ return this.mBufferedTileEntities[aSide];
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public final TileEntity getTileEntityAtSideAndDistance(final byte aSide, final int aDistance) {
+ if (aDistance == 1) {
+ return this.getTileEntityAtSide(aSide);
+ }
+ return this.getTileEntity(this.getOffsetX(aSide, aDistance), this.getOffsetY(aSide, aDistance),
+ this.getOffsetZ(aSide, aDistance));
+ }
+
+
+
+
+
+
+
+
+
+
+ @Override
+ public final TileEntity getTileEntityOffset(final int aX, final int aY, final int aZ) {
+ return this.getTileEntity(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ);
+ }
+
+ @Override
+ public long getUniversalEnergyCapacity() {
+ return 0;
+ }
+
+ @Override
+ public long getUniversalEnergyStored() {
+ return 0;
+ }
+
+ @Override
+ public World getWorld() {
+ return this.getWorldObj();
+ }
+
+
+
+
+
+
+ @Override
+ public int getXCoord() {
+ return this.xCoord;
+ }
+
+
+
+
+
+ @Override
+ public short getYCoord() {
+ return (short) this.yCoord;
+ }
+
+ @Override
+ public int getZCoord() {
+ return this.zCoord;
+ }
+
+ public boolean hasEnoughEnergy() {
+ return (this.getStoredEU() > 0 ? (mHasEnoughEnergy = true) : (mHasEnoughEnergy = false));
+ }
+
+
+
+
+ @Override
+ public boolean increaseStoredEnergyUnits(final long aEnergy, final boolean aIgnoreTooMuchEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ }
+ if (this.getStoredEU() < this.getEUCapacity() || aIgnoreTooMuchEnergy) {
+ this.setStoredEU(this.getEUVar() + aEnergy);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean increaseStoredSteam(final long aEnergy, final boolean aIgnoreTooMuchEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ }
+ if (this.getSteamVar() < this.getSteamCapacity() || aIgnoreTooMuchEnergy) {
+ this.setStoredSteam(this.getSteamVar() + aEnergy);
+ return true;
+ }
+ return false;
+ }
+
+ public long injectEnergyUnits(final byte aSide, final long aVoltage, long aAmperage) {
+ if (!this.canAccessData() || !this.isElectric() || !this.inputEnergyFrom(aSide)
+ || aAmperage <= 0L || aVoltage <= 0L || this.getStoredEU() >= this.getEUCapacity()
+ || this.maxAmperesIn() <= this.mAcceptedAmperes) {
+ return 0L;
+ }
+ if (aVoltage > this.getInputVoltage()) {
+ this.doExplosion(aVoltage);
+ return 0L;
+ }
+ if (this.increaseStoredEnergyUnits(aVoltage
+ * (aAmperage = Math.min(aAmperage, Math.min(this.maxAmperesIn() - this.mAcceptedAmperes,
+ 1L + (this.getEUCapacity() - this.getStoredEU()) / aVoltage))),
+ true)) {
+ final int[] mAverageEUInput = this.mAverageEUInput;
+ final int mAverageEUInputIndex = this.mAverageEUInputIndex;
+ mAverageEUInput[mAverageEUInputIndex] += (int) (aVoltage * aAmperage);
+ this.mAcceptedAmperes += aAmperage;
+ return aAmperage;
+ }
+ return 0L;
+ }
+
+ @Override
+ public boolean injectRotationalEnergy(byte p0, long p1, long p2) {
+ return false;
+ }
+
+ @Override
+ public boolean inputEnergyFrom(final byte aSide) {
+ if (aSide == 6) {
+ return true;
+ }
+ if (this.isServerSide()) {
+ return aSide >= 0 && aSide < 6 && this.mActiveEUInputs[aSide] && !this.mReleaseEnergy;
+ }
+ return this.isEnergyInputSide(aSide);
+ }
+
+
+ public final boolean isClientSide() {
+ return this.worldObj.isRemote;
+ }
+
+ @Override
+ public boolean isDead() {
+ return this.isDead;
+ }
+
+ private boolean isElectric() {
+ return true;
+ }
+
+ private boolean isEnergyInputSide(final byte aSide) {
+ if (aSide >= 0 && aSide < 6) {
+ if (this.isInvalid() || this.mReleaseEnergy) {
+ return false;
+ }
+ if (this.canAccessData() && this.isElectric() && this.isEnetInput()) {
+ return this.isInputFacing(aSide);
+ }
+ }
+ return false;
+ }
+
+ private boolean isEnergyOutputSide(final byte aSide) {
+ if (aSide >= 0 && aSide < 6) {
+ if (this.isInvalid() || this.mReleaseEnergy) {
+ return this.mReleaseEnergy;
+ }
+ if (this.canAccessData() && this.isElectric() && this.isEnetOutput()) {
+ return this.isOutputFacing(aSide);
+ }
+ }
+ return false;
+ }
+
+ public boolean isEnetInput() {
+ return false;
+ }
+
+ public boolean isEnetOutput() {
+ return false;
+ }
+
+ @Override
+ public boolean isGivingInformation() {
+ return this.canAccessData() && this.isGivingInformation();
+ }
+
+ public boolean isInputFacing(final byte aSide) {
+ return false;
+ }
+
+
+
+
+ @Override
+ public boolean isInvalidTileEntity() {
+ return isDead() ? true : false;
+ }
+
+ public boolean isOutputFacing(final byte aSide) {
+ return false;
+ }
+
+ public final boolean isServerSide() {
+ return !this.worldObj.isRemote;
+ }
+
+ public boolean isUniversalEnergyStored(final long aEnergyAmount) {
+ return this.getUniversalEnergyStored() >= aEnergyAmount || (this.mHasEnoughEnergy = false);
+ }
+
+ @Override
+ public boolean isValidFacing(final byte aSide) {
+ return this.canAccessData();
+ }
+
+ public long maxAmperesIn() {
+ return 1L;
+ }
+
+ public long maxAmperesOut() {
+ return 1L;
+ }
+
+ public long maxEUInput() {
+ return 0L;
+ }
+
+ public long maxEUOutput() {
+ return 0L;
+ }
+
+ public long maxEUStore() {
+ return 0L;
+ }
+
+ public long maxSteamStore() {
+ return 256000L;
+ }
+
+ public final void onAdjacentBlockChange(final int aX, final int aY, final int aZ) {
+ this.clearNullMarkersFromTileEntityBuffer();
+ }
+
+ @Override
+ public boolean outputsEnergyTo(final byte aSide) {
+ if (aSide == 6) {
+ return true;
+ }
+ if (this.isServerSide()) {
+ if (aSide < 0 || aSide >= 6 || !this.mActiveEUOutputs[aSide]) {
+ if (!this.mReleaseEnergy) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return this.isEnergyOutputSide(aSide);
+ }
+
+ public final void sendBlockEvent(final byte aID, final byte aValue) {
+ GT_Values.NW.sendPacketToAllPlayersInRange(this.worldObj,
+ (GT_Packet) new GT_Packet_Block_Event(this.xCoord, (short) this.yCoord, this.zCoord, aID, aValue),
+ this.xCoord, this.zCoord);
+ }
+
+ public void setEUVar(final long aEnergy) {
+ mStoredEnergy = aEnergy;
+ }
+
+ @Override
+ public void setFrontFacing(byte aFacing) {
+ if (this.isValidFacing(aFacing)) {
+ this.mFacing = aFacing;
+ //this.onFacingChange();
+ //this.onMachineBlockUpdate();
+ }
+ }
+
+ public void setSteamVar(final long aSteam) {
+ mStoredSteam = aSteam;
+ }
+
+ public boolean setStoredEU(long aEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ }
+ if (aEnergy < 0L) {
+ aEnergy = 0L;
+ }
+ this.setEUVar(aEnergy);
+ return true;
+ }
+
+ public boolean setStoredSteam(long aEnergy) {
+ if (!this.canAccessData()) {
+ return false;
+ }
+ if (aEnergy < 0L) {
+ aEnergy = 0L;
+ }
+ this.setSteamVar(aEnergy);
+ return true;
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt) {
+ // TODO Auto-generated method stub
+ super.writeToNBT(nbt);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt) {
+ // TODO Auto-generated method stub
+ super.readFromNBT(nbt);
+ }
+
+
+
+
+ @Override
+ public boolean onPreTick(long aTick) {
+ return onPreTick(this, this.mTickTimer);
+ }
+
+ @Override
+ public boolean onTick(long aTick) {
+ return onTick(this, this.mTickTimer);
+ }
+
+ @Override
+ public boolean onPostTick(long aTick) {
+ return onPostTick(this, this.mTickTimer);
+ }
+
+ @Override
+ public boolean onPreTick(TilePoweredGT tilePoweredGT, long mTickTimer2) {
+ return super.onPreTick(mTickTimer2);
+ }
+
+ @Override
+ public boolean onTick(TilePoweredGT iGregTechTileEntity, long mTickTimer2) {
+ return super.onTick(mTickTimer2);
+ }
+
+ @Override
+ public boolean onPostTick(TilePoweredGT iGregTechTileEntity, long mTickTimer2) {
+ return super.onPostTick(mTickTimer2);
+ }
+
+ @Override
+ public void markDirty() {
+ super.markDirty();
+ }
+
+ @Override
+ public boolean receiveClientEvent(int p_145842_1_, int p_145842_2_) {
+ // TODO Auto-generated method stub
+ return super.receiveClientEvent(p_145842_1_, p_145842_2_);
+ }
+
+ @Override
+ public void onChunkUnload() {
+ this.clearNullMarkersFromTileEntityBuffer();
+ super.onChunkUnload();
+ this.isDead = true;
+ }
+
+
+ public void updateEntity() {
+ super.updateEntity();
+ this.isDead = false;
+
+ this.mRunningThroughTick = true;
+ long tTime = System.currentTimeMillis();
+ int tCode = 0;
+ final boolean aSideServer = this.isServerSide();
+ final boolean aSideClient = this.isClientSide();
+ try {
+ for (tCode = 0; this.hasValidMetaTileEntity() && tCode >= 0; tCode = -1) {
+ Label_1743 : {
+ switch (tCode) {
+ case 0 : {
+ ++tCode;
+ if (this.mTickTimer++ != 0L) {
+ break Label_1743;
+ }
+ this.oX = this.xCoord;
+ this.oY = this.yCoord;
+ this.oZ = this.zCoord;
+
+ this.worldObj.markTileEntityChunkModified(this.xCoord, this.yCoord, this.zCoord,
+ (TileEntity) this);
+ this.onFirstTick(this);
+ if (!this.hasValidMetaTileEntity()) {
+ this.mRunningThroughTick = false;
+ return;
+ }
+ break Label_1743;
+ }
+ case 1 : {
+ ++tCode;
+ if (!aSideClient) {
+ break Label_1743;
+ }
+ if (this.mNeedsUpdate) {
+ this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
+ this.mNeedsUpdate = false;
+ }
+ break Label_1743;
+ }
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ case 6 :
+ case 7 : {
+ if (aSideServer && this.mTickTimer > 10L) {
+ for (byte i = (byte) (tCode - 2); i < 6; ++i) {
+
+ }
+ }
+ }
+ case 8 : {
+ tCode = 9;
+ if (aSideServer) {
+ if (++this.mAverageEUInputIndex >= this.mAverageEUInput.length) {
+ this.mAverageEUInputIndex = 0;
+ }
+ if (++this.mAverageEUOutputIndex >= this.mAverageEUOutput.length) {
+ this.mAverageEUOutputIndex = 0;
+ }
+ this.mAverageEUInput[this.mAverageEUInputIndex] = 0;
+ this.mAverageEUOutput[this.mAverageEUOutputIndex] = 0;
+ }
+ }
+ case 9 : {
+ ++tCode;
+ this.onPreTick(this, this.mTickTimer);
+ if (!this.hasValidMetaTileEntity()) {
+ this.mRunningThroughTick = false;
+ return;
+ }
+ }
+ case 10 : {
+ ++tCode;
+ if (!aSideServer) {
+ break Label_1743;
+ }
+
+ if (this.xCoord != this.oX || this.yCoord != this.oY || this.zCoord != this.oZ) {
+ this.oX = this.xCoord;
+ this.oY = this.yCoord;
+ this.oZ = this.zCoord;
+ this.issueClientUpdate();
+ this.clearTileEntityBuffer();
+ }
+ if (this.mFacing != this.oFacing) {
+ this.oFacing = this.mFacing;
+ this.issueBlockUpdate();
+ }
+ if (this.mTickTimer > 20L && this.isElectric()) {
+ this.mAcceptedAmperes = 0L;
+ if (this.getOutputVoltage() != this.oOutput) {
+ this.oOutput = this.getOutputVoltage();
+ }
+ if (this.isEnetOutput() || this.isEnetInput()) {
+ for (byte i = 0; i < 6; ++i) {
+ boolean temp = this.isEnergyInputSide(i);
+ if (temp != this.mActiveEUInputs[i]) {
+ this.mActiveEUInputs[i] = temp;
+ }
+ temp = this.isEnergyOutputSide(i);
+ if (temp != this.mActiveEUOutputs[i]) {
+ this.mActiveEUOutputs[i] = temp;
+ }
+ }
+ }
+ if (this.isEnetOutput() && this.oOutput > 0L) {
+ final long tOutputVoltage = Math.max(this.oOutput,
+ this.oOutput + (1 << GT_Utility.getTier(this.oOutput)));
+ final long tUsableAmperage = Math.min(this.getOutputAmperage(),
+ (this.getStoredEU() - this.getMinimumStoredEU())
+ / tOutputVoltage);
+ if (tUsableAmperage > 0L) {
+ final long tEU = tOutputVoltage * IEnergyConnected.Util.emitEnergyToNetwork(
+ this.oOutput, tUsableAmperage, (IEnergyConnected) this);
+ final int[] mAverageEUOutput = this.mAverageEUOutput;
+ final int mAverageEUOutputIndex = this.mAverageEUOutputIndex;
+ mAverageEUOutput[mAverageEUOutputIndex] += (int) tEU;
+ this.decreaseStoredEU(tEU, true);
+ }
+ }
+ if (this.getEUCapacity() > 0L) {
+ if (GregTech_API.sMachineFireExplosions && this.getRandomNumber(1000) == 0) {
+ final Block tBlock = this.getBlockAtSide((byte) this.getRandomNumber(6));
+ if (tBlock instanceof BlockFire) {
+ this.doEnergyExplosion();
+ }
+ }
+ if (!this.hasValidMetaTileEntity()) {
+ this.mRunningThroughTick = false;
+ return;
+ }
+ }
+ }
+ if (!this.hasValidMetaTileEntity()) {
+ this.mRunningThroughTick = false;
+ return;
+ }
+ break Label_1743;
+ }
+ case 13 : {
+ ++tCode;
+ this.updateStatus();
+ if (!this.hasValidMetaTileEntity()) {
+ this.mRunningThroughTick = false;
+ return;
+ }
+ }
+ case 14 : {
+ ++tCode;
+ this.onPostTick((IGregTechTileEntity) this, this.mTickTimer);
+ if (!this.hasValidMetaTileEntity()) {
+ this.mRunningThroughTick = false;
+ return;
+ }
+ }
+ case 15 : {
+ ++tCode;
+ if (!aSideServer) {
+ break;
+ }
+ if (this.mTickTimer % 10L == 0L && this.mSendClientData) {
+ final IGT_NetworkHandler nw = GT_Values.NW;
+ final World worldObj = this.worldObj;
+ final int xCoord = this.xCoord;
+ final short n = (short) this.yCoord;
+ final int zCoord = this.zCoord;
+ final short mid = this.mID;
+ final int n2 = this.mCoverSides[0];
+ final int n3 = this.mCoverSides[1];
+ final int n4 = this.mCoverSides[2];
+ final int n5 = this.mCoverSides[3];
+ final int n6 = this.mCoverSides[4];
+ final int n7 = this.mCoverSides[5];
+ final byte oTextureData = (byte) ((this.mFacing & 0x7) | (this.mActive ? 8 : 0)
+ | (this.mRedstone ? 16 : 0) | (this.mLockUpgrade ? 32 : 0));
+ this.oTextureData = oTextureData;
+ final byte oTexturePage = (byte) ((this.hasValidMetaTileEntity()
+ && this.mMetaTileEntity instanceof GT_MetaTileEntity_Hatch)
+ ? ((GT_MetaTileEntity_Hatch) this.mMetaTileEntity).getTexturePage()
+ : 0);
+ this.oTexturePage = oTexturePage;
+ final byte oUpdateData = (byte) (this.hasValidMetaTileEntity()
+ ? this.mMetaTileEntity.getUpdateData()
+ : 0);
+ this.oUpdateData = oUpdateData;
+ final byte oRedstoneData = (byte) (((this.mSidedRedstone[0] > 0) ? 1 : 0)
+ | ((this.mSidedRedstone[1] > 0) ? 2 : 0)
+ | ((this.mSidedRedstone[2] > 0) ? 4 : 0)
+ | ((this.mSidedRedstone[3] > 0) ? 8 : 0)
+ | ((this.mSidedRedstone[4] > 0) ? 16 : 0)
+ | ((this.mSidedRedstone[5] > 0) ? 32 : 0));
+ this.oRedstoneData = oRedstoneData;
+ final byte mColor = this.mColor;
+ this.oColor = mColor;
+ nw.sendPacketToAllPlayersInRange(worldObj,
+ (GT_Packet) new GT_Packet_TileEntity(xCoord, n, zCoord, mid, n2, n3, n4, n5, n6,
+ n7, oTextureData, oTexturePage, oUpdateData, oRedstoneData, mColor),
+ this.xCoord, this.zCoord);
+ this.mSendClientData = false;
+ }
+ if (this.mTickTimer > 10L) {
+ byte tData = (byte) ((this.mFacing & 0x7) | (this.mActive ? 8 : 0)
+ | (this.mRedstone ? 16 : 0) | (this.mLockUpgrade ? 32 : 0));
+ if (tData != this.oTextureData) {
+ this.sendBlockEvent((byte) 0, this.oTextureData = tData);
+ }
+ tData = this.mMetaTileEntity.getUpdateData();
+ if (tData != this.oUpdateData) {
+ this.sendBlockEvent((byte) 1, this.oUpdateData = tData);
+ }
+ if (this.mMetaTileEntity instanceof GT_MetaTileEntity_Hatch) {
+ tData = ((GT_MetaTileEntity_Hatch) this.mMetaTileEntity).getTexturePage();
+ if (tData != this.oTexturePage) {
+ final byte b = 1;
+ final byte oTexturePage2 = tData;
+ this.oTexturePage = oTexturePage2;
+ this.sendBlockEvent(b, (byte) (oTexturePage2 | 0x80));
+ }
+ }
+ if (this.mColor != this.oColor) {
+ this.sendBlockEvent((byte) 2, this.oColor = this.mColor);
+ }
+ tData = (byte) (((this.mSidedRedstone[0] > 0) ? 1 : 0)
+ | ((this.mSidedRedstone[1] > 0) ? 2 : 0)
+ | ((this.mSidedRedstone[2] > 0) ? 4 : 0)
+ | ((this.mSidedRedstone[3] > 0) ? 8 : 0)
+ | ((this.mSidedRedstone[4] > 0) ? 16 : 0)
+ | ((this.mSidedRedstone[5] > 0) ? 32 : 0));
+ if (tData != this.oRedstoneData) {
+ this.sendBlockEvent((byte) 3, this.oRedstoneData = tData);
+ }
+ if (this.mLightValue != this.oLightValue) {
+ this.worldObj.setLightValue(EnumSkyBlock.Block, this.xCoord, this.yCoord,
+ this.zCoord, (int) this.mLightValue);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord, this.yCoord,
+ this.zCoord);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord + 1, this.yCoord,
+ this.zCoord);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord - 1, this.yCoord,
+ this.zCoord);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord, this.yCoord + 1,
+ this.zCoord);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord, this.yCoord - 1,
+ this.zCoord);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord, this.yCoord,
+ this.zCoord + 1);
+ this.worldObj.updateLightByType(EnumSkyBlock.Block, this.xCoord, this.yCoord,
+ this.zCoord - 1);
+ this.issueTextureUpdate();
+ this.sendBlockEvent((byte) 7, this.oLightValue = this.mLightValue);
+ }
+ }
+ if (this.mNeedsBlockUpdate) {
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord,
+ this.getBlockOffset(0, 0, 0));
+ this.mNeedsBlockUpdate = false;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace(GT_Log.err);
+ }
+ if (aSideServer && this.hasValidMetaTileEntity()) {
+ tTime = System.currentTimeMillis() - tTime;
+ if (this.mTimeStatistics.length > 0) {
+ this.mTimeStatistics[this.mTimeStatisticsIndex = (this.mTimeStatisticsIndex + 1)
+ % this.mTimeStatistics.length] = (int) tTime;
+ }
+ if (tTime > 0L && tTime > GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING && this.mTickTimer > 1000L
+ && this.getMetaTileEntity().doTickProfilingMessageDuringThisTick()
+ && this.mLagWarningCount++ < 10) {
+ System.out.println("WARNING: Possible Lag Source at [" + this.xCoord + ", " + this.yCoord + ", "
+ + this.zCoord + "] in Dimension " + this.worldObj.provider.dimensionId + " with " + tTime
+ + "ms caused by an instance of " + this.getMetaTileEntity().getClass());
+ }
+ }
+ final boolean mWorkUpdate = false;
+ this.mRunningThroughTick = mWorkUpdate;
+ this.mInventoryChanged = mWorkUpdate;
+ this.mWorkUpdate = mWorkUpdate;
+ }
+
+ private void onFirstTick(TilePoweredGT tilePoweredGT) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private boolean hasValidMetaTileEntity() {
+ return Utils.invertBoolean(isDead());
+ }
+
+ public void issueBlockUpdate() {
+ this.mNeedsBlockUpdate = true;
+ }
+
+ public void issueClientUpdate() {
+ this.mSendClientData = true;
+ }
+
+ public Packet getDescriptionPacket() {
+ this.issueClientUpdate();
+ return null;
+ }
+
+}
+*/ \ No newline at end of file
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityCircuitProgrammer.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityCircuitProgrammer.java
new file mode 100644
index 0000000000..835d9da2cd
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityCircuitProgrammer.java
@@ -0,0 +1,307 @@
+package gtPlusPlus.core.tileentities.general;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.TileEntity;
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.core.inventories.InventoryCircuitProgrammer;
+import gtPlusPlus.core.recipe.common.CI;
+import gtPlusPlus.core.slots.SlotIntegratedCircuit;
+import gtPlusPlus.core.util.minecraft.PlayerUtils;
+
+public class TileEntityCircuitProgrammer extends TileEntity implements ISidedInventory {
+
+ private int tickCount = 0;
+ private final InventoryCircuitProgrammer inventoryContents;
+ private String customName;
+ public int locationX;
+ public int locationY;
+ public int locationZ;
+ private int aCurrentMode = 0;
+
+ public TileEntityCircuitProgrammer() {
+ this.inventoryContents = new InventoryCircuitProgrammer();
+ this.setTileLocation();
+ }
+
+ public boolean setTileLocation() {
+ if (this.hasWorldObj()) {
+ if (!this.getWorldObj().isRemote) {
+ this.locationX = this.xCoord;
+ this.locationY = this.yCoord;
+ this.locationZ = this.zCoord;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //Rename to hasCircuitToConfigure
+ public final boolean hasCircuitToConfigure() {
+ for (ItemStack i : this.getInventory().getInventory()) {
+ if (i == null) {
+ continue;
+ }
+ else {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public InventoryCircuitProgrammer getInventory() {
+ return this.inventoryContents;
+ }
+
+ public boolean addOutput() {
+ ItemStack[] aInputs = this.getInventory().getInventory().clone();
+ //Check if there is output in slot.
+ Boolean hasOutput = false;
+ if (aInputs[25] != null) {
+ hasOutput = true;
+ }
+ AutoMap<Integer> aValidSlots = new AutoMap<Integer>();
+ int aSlotCount = 0;
+ for (ItemStack i : aInputs) {
+ if (i != null) {
+ aValidSlots.put(aSlotCount);
+ }
+ aSlotCount++;
+ }
+ for (int e : aValidSlots) {
+ boolean doAdd = false;
+ ItemStack g = this.getStackInSlot(e);
+ int aSize = 0;
+ ItemStack aInputStack = null;
+ int aTypeInSlot = SlotIntegratedCircuit.isRegularProgrammableCircuit(g);
+ if (aTypeInSlot >= 0 && g != null) {
+ // No Existing Output
+ if (!hasOutput) {
+ aSize = g.stackSize;
+ doAdd = true;
+ }
+ // Existing Output
+ else {
+ ItemStack f = this.getStackInSlot(25);
+ int aTypeInCheckedSlot = SlotIntegratedCircuit.isRegularProgrammableCircuit(f);
+ // Check that the Circuit in the Output slot is not null and the same type as the circuit input.
+ if (aTypeInCheckedSlot >= 0 && (aTypeInSlot == aTypeInCheckedSlot) && f != null) {
+ if (g.getItem() == f.getItem() && f.getItemDamage() == e) {
+ aSize = f.stackSize + g.stackSize;
+ if (aSize > 64) {
+ aInputStack = g.copy();
+ aInputStack.stackSize = (aSize-64);
+ }
+ doAdd = true;
+ }
+ }
+ }
+ if (doAdd) {
+ // Check Circuit Type
+ ItemStack aOutput;
+ if (aTypeInSlot == 0) {
+ aOutput = CI.getNumberedCircuit(e);
+ }
+ else if (aTypeInSlot == 1) {
+ aOutput = CI.getNumberedBioCircuit(e);
+ }
+ else if (aTypeInSlot == 2) {
+ aOutput = CI.getNumberedAdvancedCircuit(e);
+ }
+ else {
+ aOutput = null;
+ }
+
+ if (aOutput != null) {
+ aOutput.stackSize = aSize;
+ this.setInventorySlotContents(e, aInputStack);
+ this.setInventorySlotContents(25, aOutput);
+ return true;
+ }
+ }
+ }
+ continue;
+ }
+ return false;
+ }
+
+ @Override
+ public void updateEntity() {
+ try{
+ if (!this.worldObj.isRemote) {
+ if (tickCount % 10 == 0) {
+ if (hasCircuitToConfigure()) {
+ this.addOutput();
+ this.markDirty();
+ }
+ }
+ this.tickCount++;
+ }
+ }
+ catch (final Throwable t){}
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ // Utils.LOG_WARNING("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.inventoryContents.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ nbt.setInteger("aCurrentMode", aCurrentMode);
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ // Utils.LOG_WARNING("Trying to read NBT data from TE.");
+ this.inventoryContents.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ aCurrentMode = nbt.getInteger("aCurrentMode");
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.getInventory().getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(final int slot) {
+ return this.getInventory().getStackInSlot(slot);
+ }
+
+ @Override
+ public ItemStack decrStackSize(final int slot, final int count) {
+ return this.getInventory().decrStackSize(slot, count);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(final int slot) {
+ return this.getInventory().getStackInSlotOnClosing(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(final int slot, final ItemStack stack) {
+ this.getInventory().setInventorySlotContents(slot, stack);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.getInventory().getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return this.getInventory().isItemValidForSlot(slot, itemstack);
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int p_94128_1_) {
+ final int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r=0; r<this.getInventory().getSizeInventory(); r++){
+ accessibleSides[r]=r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(final int p_102007_1_, final ItemStack p_102007_2_, final int p_102007_3_) {
+ return p_102007_1_ >= 0 && p_102007_1_ <= 24;
+ }
+
+ @Override
+ public boolean canExtractItem(final int p_102008_1_, final ItemStack p_102008_2_, final int p_102008_3_) {
+ return p_102008_1_ == 25;
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.circuitprogrammer";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.customName != null) && !this.customName.equals("");
+ }
+
+ @Override
+ public Packet getDescriptionPacket() {
+ final NBTTagCompound tag = new NBTTagCompound();
+ this.writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public void onDataPacket(final NetworkManager net, final S35PacketUpdateTileEntity pkt) {
+ final NBTTagCompound tag = pkt.func_148857_g();
+ this.readFromNBT(tag);
+ }
+
+ public boolean onScrewdriverRightClick(byte side, EntityPlayer player, int x, int y, int z) {
+ try {
+ if (aCurrentMode == 24) {
+ aCurrentMode = 0;
+ }
+ else {
+ aCurrentMode++;
+ }
+ PlayerUtils.messagePlayer(player, "Now configuring units for type "+aCurrentMode+".");
+ return true;
+ }
+ catch (Throwable t) {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityDecayablesChest.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityDecayablesChest.java
new file mode 100644
index 0000000000..db93e9c4fc
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityDecayablesChest.java
@@ -0,0 +1,359 @@
+package gtPlusPlus.core.tileentities.general;
+
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.inventories.Inventory_DecayablesChest;
+import gtPlusPlus.core.item.materials.DustDecayable;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+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;
+
+public class TileEntityDecayablesChest extends TileEntity implements ISidedInventory {
+
+ private final Inventory_DecayablesChest inventoryContents;
+
+ /** Determines if the check for adjacent chests has taken place. */
+ public boolean adjacentChestChecked;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityDecayablesChest adjacentChestZNeg;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityDecayablesChest adjacentChestXPos;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityDecayablesChest adjacentChestXNeg;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityDecayablesChest adjacentChestZPos;
+ /** The current angle of the lid (between 0 and 1) */
+ public float lidAngle;
+ /** The angle of the lid last tick */
+ public float prevLidAngle;
+ /** The number of players currently using this chest */
+ public int numPlayersUsing;
+
+ private String customName;
+
+ private int cachedChestType;
+ private int tickCount = 0;
+
+ public TileEntityDecayablesChest() {
+ this.inventoryContents = new Inventory_DecayablesChest();
+ }
+
+ public Inventory_DecayablesChest getInventory() {
+ return this.inventoryContents;
+ }
+
+ @Override
+ public void updateEntity() {
+
+ // Try do chesty stuff
+ try {
+ this.updateEntityChest();
+ } catch (Throwable t) {
+
+ }
+
+ try {
+ if (!this.worldObj.isRemote) {
+ this.tickCount++;
+ if ((this.tickCount % 10) == 0) {
+ cachedChestType = 1;
+ }
+
+ if ((this.tickCount % 20) == 0) {
+ for (ItemStack inv : this.getInventory().getInventory()) {
+ if (inv == null) {
+ continue;
+ }
+ if (inv.getItem() instanceof DustDecayable) {
+ DustDecayable D = (DustDecayable) inv.getItem();
+ tryUpdateDecayable(D, inv, this.worldObj);
+ }
+ }
+
+ }
+ updateSlots();
+ }
+ } catch (final Throwable t) {
+ }
+ }
+
+ public void tryUpdateDecayable(final DustDecayable b, ItemStack iStack, final World world) {
+ if (world == null || iStack == null) {
+ return;
+ }
+ if (world.isRemote) {
+ return;
+ }
+
+ boolean a1, a2;
+ int u = 0;
+ a1 = b.isTicking(world, iStack);
+ a2 = false;
+ int SECONDS_TO_PROCESS = 1;
+ while (u < (20 * SECONDS_TO_PROCESS)) {
+ if (!a1) {
+ break;
+ }
+ a1 = b.isTicking(world, iStack);
+ a2 = b.tickItemTag(world, iStack);
+ u++;
+ }
+ Logger.MACHINE_INFO("| "+b.getUnlocalizedName()+" | "+a1+"/"+a2);
+
+ if (!a1 && !a2) {
+ ItemStack replacement = ItemUtils.getSimpleStack(b.getDecayResult());
+ replacement.stackSize = 1;
+ //iStack = replacement.copy();
+ for (int fff = 0; fff < this.inventoryContents.getSizeInventory(); fff++) {
+ if (this.inventoryContents.getStackInSlot(fff) == iStack) {
+ this.inventoryContents.setInventorySlotContents(fff, replacement.copy());
+ }
+ }
+
+ updateSlots();
+ this.inventoryContents.
+ markDirty();
+ }
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ // Utils.LOG_WARNING("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.inventoryContents.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ // Utils.LOG_WARNING("Trying to read NBT data from TE.");
+ this.inventoryContents.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.getInventory().getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(final int slot) {
+ return this.getInventory().getStackInSlot(slot);
+ }
+
+ @Override
+ public ItemStack decrStackSize(final int slot, final int count) {
+ return this.getInventory().decrStackSize(slot, count);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(final int slot) {
+ return this.getInventory().getStackInSlotOnClosing(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(final int slot, final ItemStack stack) {
+ this.getInventory().setInventorySlotContents(slot, stack);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.getInventory().getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ if (this.numPlayersUsing < 0) {
+ this.numPlayersUsing = 0;
+ }
+ if (!this.worldObj.isRemote) {
+ this.numPlayersUsing++;
+ cachedChestType = 1;
+ }
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, this.numPlayersUsing);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ if (!this.worldObj.isRemote) {
+ this.numPlayersUsing--;
+ cachedChestType = 1;
+ }
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, this.numPlayersUsing);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return this.getInventory().isItemValidForSlot(slot, itemstack);
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int p_94128_1_) {
+ final int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r = 0; r < this.getInventory().getSizeInventory(); r++) {
+ accessibleSides[r] = r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(final int p_102007_1_, final ItemStack p_102007_2_, final int p_102007_3_) {
+ return this.getInventory().isItemValidForSlot(0, p_102007_2_);
+ }
+
+ @Override
+ public boolean canExtractItem(final int p_102008_1_, final ItemStack p_102008_2_, final int p_102008_3_) {
+ return this.getInventory().isItemValidForSlot(0, p_102008_2_);
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.DecayablesChest";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.customName != null) && !this.customName.equals("");
+ }
+
+ /**
+ * Causes the TileEntity to reset all it's cached values for it's container
+ * Block, metadata and in the case of chests, the adjacent chest check
+ */
+ public void updateContainingBlockInfo() {
+ super.updateContainingBlockInfo();
+ this.adjacentChestChecked = false;
+ }
+
+ /**
+ * Performs the check for adjacent chests to determine if this chest is double
+ * or not.
+ */
+ public void checkForAdjacentChests() {
+ if (!this.adjacentChestChecked) {
+ this.adjacentChestChecked = true;
+ this.adjacentChestZNeg = null;
+ this.adjacentChestXPos = null;
+ this.adjacentChestXNeg = null;
+ this.adjacentChestZPos = null;
+ }
+ }
+
+ public void updateEntityChest() {
+ float f;
+ this.prevLidAngle = this.lidAngle;
+ f = 0.04F;
+ double d2;
+ if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F && this.adjacentChestZNeg == null
+ && this.adjacentChestXNeg == null) {
+ double d1 = (double) this.xCoord + 0.5D;
+ d2 = (double) this.zCoord + 0.5D;
+ this.worldObj.playSoundEffect(d1, (double) this.yCoord + 0.5D, d2, "random.chestopen", 0.5F,
+ this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
+ }
+
+ if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F) {
+ float f1 = this.lidAngle;
+ if (this.numPlayersUsing > 0) {
+ //this.lidAngle += f;
+ this.lidAngle += (float) (f * (1 + 0.10 * 0.01));
+ } else {
+ //this.lidAngle -= f;
+ this.lidAngle -= (float) (f * (1 + 0.10 * 0.01));
+ }
+ if (this.lidAngle > 1.0F) {
+ this.lidAngle = 1.0F;
+ }
+ float f2 = 0.5F;
+ if (this.lidAngle < f2 && f1 >= f2 && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null) {
+ d2 = (double) this.xCoord + 0.5D;
+ double d0 = (double) this.zCoord + 0.5D;
+ this.worldObj.playSoundEffect(d2, (double) this.yCoord + 0.5D, d0, "random.chestclosed", 0.5F,
+ this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
+ }
+
+ if (this.lidAngle < 0.0F) {
+ this.lidAngle = 0.0F;
+ }
+ }
+ }
+
+ /**
+ * Called when a client event is received with the event number and argument,
+ * see World.sendClientEvent
+ */
+ public boolean receiveClientEvent(int p_145842_1_, int p_145842_2_) {
+ if (p_145842_1_ == 1)
+ {
+ this.numPlayersUsing = p_145842_2_;
+ return true;
+ }
+ else
+ {
+ return super.receiveClientEvent(p_145842_1_, p_145842_2_);
+ }
+ }
+
+ /**
+ * invalidates a tile entity
+ */
+ public final void invalidate() {
+ super.invalidate();
+ cachedChestType = 1;
+ this.updateContainingBlockInfo();
+ this.checkForAdjacentChests();
+ }
+
+ private final int updateSlots() {
+ //Have slots changed?
+ if (cachedChestType == 0) {
+ return 0;
+ }
+ ItemUtils.organiseInventory(getInventory());
+ cachedChestType = 0;
+ return cachedChestType;
+
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityEggBox.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityEggBox.java
new file mode 100644
index 0000000000..0c428537cb
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityEggBox.java
@@ -0,0 +1,359 @@
+package gtPlusPlus.core.tileentities.general;
+
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.inventories.Inventory_EggBox;
+import gtPlusPlus.core.item.general.ItemGiantEgg;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+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;
+
+public class TileEntityEggBox extends TileEntity implements ISidedInventory {
+
+ private final Inventory_EggBox inventoryContents;
+
+ /** Determines if the check for adjacent chests has taken place. */
+ public boolean adjacentChestChecked;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityEggBox adjacentChestZNeg;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityEggBox adjacentChestXPos;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityEggBox adjacentChestXNeg;
+ /** Contains the chest tile located adjacent to this one (if any) */
+ public TileEntityEggBox adjacentChestZPos;
+ /** The current angle of the lid (between 0 and 1) */
+ public float lidAngle;
+ /** The angle of the lid last tick */
+ public float prevLidAngle;
+ /** The number of players currently using this chest */
+ public int numPlayersUsing;
+
+ private String customName;
+
+ private int cachedChestType;
+ private int tickCount = 0;
+
+ public TileEntityEggBox() {
+ this.inventoryContents = new Inventory_EggBox();
+ }
+
+ public Inventory_EggBox getInventory() {
+ return this.inventoryContents;
+ }
+
+ @Override
+ public void updateEntity() {
+
+ // Try do chesty stuff
+ try {
+ this.updateEntityChest();
+ } catch (Throwable t) {
+
+ }
+
+ try {
+ if (!this.worldObj.isRemote) {
+ this.tickCount++;
+ if ((this.tickCount % 10) == 0) {
+ cachedChestType = 1;
+ }
+
+ if ((this.tickCount % 20) == 0) {
+ for (ItemStack inv : this.getInventory().getInventory()) {
+ if (inv == null) {
+ continue;
+ }
+ if (inv.getItem() instanceof ItemGiantEgg) {
+ ItemGiantEgg D = (ItemGiantEgg) inv.getItem();
+ tryUpdateDecayable(D, inv, this.worldObj);
+ }
+ }
+
+ }
+ updateSlots();
+ }
+ } catch (final Throwable t) {
+ }
+ }
+
+ public void tryUpdateDecayable(final ItemGiantEgg d, ItemStack iStack, final World world) {
+ if (world == null || iStack == null) {
+ return;
+ }
+ if (world.isRemote) {
+ return;
+ }
+
+ boolean a1, a2;
+ int u = 0;
+ a1 = d.isTicking(world, iStack);
+ a2 = false;
+ int SECONDS_TO_PROCESS = 1;
+ while (u < (20 * SECONDS_TO_PROCESS)) {
+ if (!a1) {
+ break;
+ }
+ a1 = d.isTicking(world, iStack);
+ a2 = d.tickItemTag(world, iStack);
+ u++;
+ }
+ Logger.MACHINE_INFO("| "+d.getUnlocalizedName()+" | "+a1+"/"+a2);
+
+ if (!a1 && !a2) {
+ ItemStack replacement = ItemUtils.getSimpleStack(d.getHatchResult(), 1);
+ replacement.stackSize = 1;
+ //iStack = replacement.copy();
+ for (int fff = 0; fff < this.inventoryContents.getSizeInventory(); fff++) {
+ if (this.inventoryContents.getStackInSlot(fff) == iStack) {
+ this.inventoryContents.setInventorySlotContents(fff, replacement.copy());
+ }
+ }
+
+ updateSlots();
+ this.inventoryContents.
+ markDirty();
+ }
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ // Utils.LOG_WARNING("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.inventoryContents.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ // Utils.LOG_WARNING("Trying to read NBT data from TE.");
+ this.inventoryContents.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.getInventory().getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(final int slot) {
+ return this.getInventory().getStackInSlot(slot);
+ }
+
+ @Override
+ public ItemStack decrStackSize(final int slot, final int count) {
+ return this.getInventory().decrStackSize(slot, count);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(final int slot) {
+ return this.getInventory().getStackInSlotOnClosing(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(final int slot, final ItemStack stack) {
+ this.getInventory().setInventorySlotContents(slot, stack);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.getInventory().getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ if (this.numPlayersUsing < 0) {
+ this.numPlayersUsing = 0;
+ }
+ if (!this.worldObj.isRemote) {
+ this.numPlayersUsing++;
+ cachedChestType = 1;
+ }
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, this.numPlayersUsing);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ if (!this.worldObj.isRemote) {
+ this.numPlayersUsing--;
+ cachedChestType = 1;
+ }
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, this.numPlayersUsing);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return this.getInventory().isItemValidForSlot(slot, itemstack);
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int p_94128_1_) {
+ final int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r = 0; r < this.getInventory().getSizeInventory(); r++) {
+ accessibleSides[r] = r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(final int p_102007_1_, final ItemStack p_102007_2_, final int p_102007_3_) {
+ return this.getInventory().isItemValidForSlot(0, p_102007_2_);
+ }
+
+ @Override
+ public boolean canExtractItem(final int p_102008_1_, final ItemStack p_102008_2_, final int p_102008_3_) {
+ return this.getInventory().isItemValidForSlot(0, p_102008_2_);
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.EggBox";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.customName != null) && !this.customName.equals("");
+ }
+
+ /**
+ * Causes the TileEntity to reset all it's cached values for it's container
+ * Block, metadata and in the case of chests, the adjacent chest check
+ */
+ public void updateContainingBlockInfo() {
+ super.updateContainingBlockInfo();
+ this.adjacentChestChecked = false;
+ }
+
+ /**
+ * Performs the check for adjacent chests to determine if this chest is double
+ * or not.
+ */
+ public void checkForAdjacentChests() {
+ if (!this.adjacentChestChecked) {
+ this.adjacentChestChecked = true;
+ this.adjacentChestZNeg = null;
+ this.adjacentChestXPos = null;
+ this.adjacentChestXNeg = null;
+ this.adjacentChestZPos = null;
+ }
+ }
+
+ public void updateEntityChest() {
+ float f;
+ this.prevLidAngle = this.lidAngle;
+ f = 0.04F;
+ double d2;
+ if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F && this.adjacentChestZNeg == null
+ && this.adjacentChestXNeg == null) {
+ double d1 = (double) this.xCoord + 0.5D;
+ d2 = (double) this.zCoord + 0.5D;
+ this.worldObj.playSoundEffect(d1, (double) this.yCoord + 0.5D, d2, "random.chestopen", 0.5F,
+ this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
+ }
+
+ if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F) {
+ float f1 = this.lidAngle;
+ if (this.numPlayersUsing > 0) {
+ //this.lidAngle += f;
+ this.lidAngle += (float) (f * (1 + 0.10 * 0.01));
+ } else {
+ //this.lidAngle -= f;
+ this.lidAngle -= (float) (f * (1 + 0.10 * 0.01));
+ }
+ if (this.lidAngle > 1.0F) {
+ this.lidAngle = 1.0F;
+ }
+ float f2 = 0.5F;
+ if (this.lidAngle < f2 && f1 >= f2 && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null) {
+ d2 = (double) this.xCoord + 0.5D;
+ double d0 = (double) this.zCoord + 0.5D;
+ this.worldObj.playSoundEffect(d2, (double) this.yCoord + 0.5D, d0, "random.chestclosed", 0.5F,
+ this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
+ }
+
+ if (this.lidAngle < 0.0F) {
+ this.lidAngle = 0.0F;
+ }
+ }
+ }
+
+ /**
+ * Called when a client event is received with the event number and argument,
+ * see World.sendClientEvent
+ */
+ public boolean receiveClientEvent(int p_145842_1_, int p_145842_2_) {
+ if (p_145842_1_ == 1)
+ {
+ this.numPlayersUsing = p_145842_2_;
+ return true;
+ }
+ else
+ {
+ return super.receiveClientEvent(p_145842_1_, p_145842_2_);
+ }
+ }
+
+ /**
+ * invalidates a tile entity
+ */
+ public final void invalidate() {
+ super.invalidate();
+ cachedChestType = 1;
+ this.updateContainingBlockInfo();
+ this.checkForAdjacentChests();
+ }
+
+ private final int updateSlots() {
+ //Have slots changed?
+ if (cachedChestType == 0) {
+ return 0;
+ }
+ ItemUtils.organiseInventory(getInventory());
+ cachedChestType = 0;
+ return cachedChestType;
+
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFirepit.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFirepit.java
new file mode 100644
index 0000000000..49fde8ee64
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFirepit.java
@@ -0,0 +1,39 @@
+package gtPlusPlus.core.tileentities.general;
+
+import java.util.UUID;
+
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+
+public class TileEntityFirepit extends TileEntity{
+
+ private UUID ownerUUID;
+
+ public UUID getOwnerUUID() {
+ return this.ownerUUID;
+ }
+
+ public void setOwnerUUID(final UUID ownerUUID) {
+ this.ownerUUID = ownerUUID;
+ this.markDirty();
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound tagCompound) {
+ super.writeToNBT(tagCompound);
+
+ final UUID ownerUUID = this.getOwnerUUID();
+ if (ownerUUID != null){
+ tagCompound.setLong("OwnerUUIDMost", ownerUUID.getMostSignificantBits());
+ tagCompound.setLong("OwnerUUIDLeast", ownerUUID.getLeastSignificantBits());
+ }
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound tagCompound) {
+ super.readFromNBT(tagCompound);
+
+ this.setOwnerUUID(new UUID(tagCompound.getLong("OwnerUUIDMost"), tagCompound.getLong("OwnerUUIDLeast")));
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFishTrap.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFishTrap.java
new file mode 100644
index 0000000000..beff269428
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFishTrap.java
@@ -0,0 +1,410 @@
+package gtPlusPlus.core.tileentities.general;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+
+import gregtech.api.util.GT_Utility;
+
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.block.ModBlocks;
+import gtPlusPlus.core.inventories.InventoryFishTrap;
+import gtPlusPlus.core.lib.LoadedMods;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import net.minecraftforge.common.FishingHooks;
+
+public class TileEntityFishTrap extends TileEntity implements ISidedInventory {
+
+ private int tickCount = 0;
+ private boolean isInWater = false;
+ private final InventoryFishTrap inventoryContents;
+ private String customName;
+ private int locationX;
+ private int locationY;
+ private int locationZ;
+ private int waterSides = 0;
+ private int baseTickRate = 600 * 5;
+
+ public TileEntityFishTrap() {
+ this.inventoryContents = new InventoryFishTrap();// number of slots -
+ // without product
+ // slot
+ this.setTileLocation();
+ }
+
+ public boolean setTileLocation() {
+ if (this.hasWorldObj()) {
+ if (!this.getWorldObj().isRemote) {
+ this.locationX = this.xCoord;
+ this.locationY = this.yCoord;
+ this.locationZ = this.zCoord;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public final boolean isSurroundedByWater() {
+ this.setTileLocation();
+ final Block[] surroundingBlocks = new Block[6];
+ if (this.hasWorldObj()) {
+ if (!this.getWorldObj().isRemote) {
+ surroundingBlocks[0] = this.worldObj.getBlock(this.locationX, this.locationY + 1, this.locationZ); // Above
+ surroundingBlocks[1] = this.worldObj.getBlock(this.locationX, this.locationY - 1, this.locationZ); // Below
+ surroundingBlocks[2] = this.worldObj.getBlock(this.locationX + 1, this.locationY, this.locationZ);
+ surroundingBlocks[3] = this.worldObj.getBlock(this.locationX - 1, this.locationY, this.locationZ);
+ surroundingBlocks[4] = this.worldObj.getBlock(this.locationX, this.locationY, this.locationZ + 1);
+ surroundingBlocks[5] = this.worldObj.getBlock(this.locationX, this.locationY, this.locationZ - 1);
+ int waterCount = 0;
+ int trapCount = 0;
+ for (final Block checkBlock : surroundingBlocks) {
+ if ((checkBlock == Blocks.water) || (checkBlock == Blocks.flowing_water)
+ || checkBlock.getUnlocalizedName().toLowerCase().contains("water")
+ || (checkBlock == ModBlocks.blockFishTrap)) {
+ if (checkBlock != ModBlocks.blockFishTrap) {
+ waterCount++;
+ }
+ else {
+ waterCount++;
+ trapCount++;
+ }
+ }
+ }
+ if ((waterCount >= 2) && (trapCount <= 4)) {
+ int aCheck = trapCount + waterCount;
+ this.waterSides = MathUtils.balance(aCheck, 0, 6);
+ Logger.MACHINE_INFO("Valid Trap. "+waterCount+" | "+(this.tickCount/20)+"/"+(this.baseTickRate/20));
+ return true;
+ }
+ else if ((waterCount >= 2) && (trapCount > 4)) {
+ Logger.MACHINE_INFO("Too many fish traps surrounding this one.");
+ Logger.MACHINE_INFO("Not adding Loot to the fishtrap at x[" + this.locationX + "] y[" + this.locationY
+ + "] z[" + this.locationZ + "] (Ticking for loot every " + this.baseTickRate + " ticks)");
+ }
+ }
+ }
+ // Utils.LOG_MACHINE_INFO("Error finding water");
+ return false;
+ }
+
+ public InventoryFishTrap getInventory() {
+ return this.inventoryContents;
+ }
+
+ public boolean tryAddLoot() {
+ if (this.getInventory().getInventory() != null) {
+ int checkingSlot = 0;
+ ItemUtils.organiseInventory(getInventory());
+ final ItemStack loot = this.generateLootForFishTrap().copy();
+ try {
+ //Utils.LOG_MACHINE_INFO("Trying to add "+loot.getDisplayName()+" | "+loot.getItemDamage());
+ for (final ItemStack contents : this.getInventory().getInventory()) {
+
+
+ if (GT_Utility.areStacksEqual(loot, contents)){
+ if (contents.stackSize < contents.getMaxStackSize()) {
+ //Utils.LOG_MACHINE_INFO("3-Trying to add one more "+loot.getDisplayName()+"meta: "+loot.getItemDamage()+" to an existing stack of "+contents.getDisplayName()+" with a size of "+contents.stackSize);
+ contents.stackSize++;
+ this.markDirty();
+ return true;
+ }
+ }
+ checkingSlot++;
+ }
+ checkingSlot = 0;
+ for (final ItemStack contents : this.getInventory().getInventory()) {
+ if (contents == null) {
+ //Utils.LOG_MACHINE_INFO("Adding Item To Empty Slot. "+(checkingSlot+1));
+ this.getInventory().setInventorySlotContents(checkingSlot, loot);
+ this.markDirty();
+ return true;
+ }
+ checkingSlot++;
+ }
+ }
+ catch (final NullPointerException n) {
+ }
+ }
+ this.markDirty();
+ return false;
+ }
+
+ private ItemStack generateLootForFishTrap() {
+ final int lootWeight = MathUtils.randInt(0, 100);
+ ItemStack loot;
+ if (lootWeight <= 5) {
+ loot = ItemUtils.getSimpleStack(Items.slime_ball);
+ }
+ else if (lootWeight <= 10) {
+ loot = ItemUtils.getSimpleStack(Items.bone);
+ }
+ else if (lootWeight <= 15) {
+ loot = ItemUtils.getSimpleStack(Blocks.sand);
+ }
+ else if (lootWeight <= 20) {
+ loot = ItemUtils.simpleMetaStack(Items.dye, 0, 1);
+ }
+ // Junk Loot
+ else if (lootWeight <= 23) {
+ if (LoadedMods.PamsHarvestcraft) {
+ loot = ItemUtils.getItemStackOfAmountFromOreDictNoBroken(seaweed, 1);
+ }
+ else {
+ loot = ItemUtils.getSimpleStack(Blocks.dirt);
+ }
+ }
+ // Pam Fish
+ else if (lootWeight <= 99) {
+ final Random xstr = new Random();
+ loot = FishingHooks.getRandomFishable(xstr, 100);
+ }
+
+ else if (lootWeight == 100){
+ final int rareLoot = MathUtils.randInt(1, 10);
+ if (rareLoot <= 4) {
+ loot = ItemUtils.getItemStackOfAmountFromOreDictNoBroken("nuggetIron", 1);
+ if (loot == null){
+ loot = ItemUtils.getItemStackOfAmountFromOreDictNoBroken("ingotIron", 1);
+ }
+ }
+ else if (rareLoot <= 7) {
+ loot = ItemUtils.getItemStackOfAmountFromOreDictNoBroken("nuggetGold", 1);
+ if (loot == null){
+ loot = ItemUtils.getItemStackOfAmountFromOreDictNoBroken("ingotGold", 1);
+ }
+ }
+ else if (rareLoot <= 9){
+ loot = ItemUtils.getSimpleStack(Items.emerald);
+ }
+ else {
+ loot = ItemUtils.getSimpleStack(Items.diamond);
+ }
+ }
+ else {
+ loot = ItemUtils.getSimpleStack(Blocks.diamond_ore);
+ }
+ loot.stackSize=1;
+ Logger.MACHINE_INFO("Adding x"+loot.stackSize+" "+loot.getDisplayName()+".");
+ return loot;
+ }
+
+ @Override
+ public void updateEntity() {
+ try{
+ if (!this.worldObj.isRemote) {
+ this.tickCount++;
+ //Logger.MACHINE_INFO("Ticking "+this.tickCount);
+ // Check if the Tile is within water once per second.
+ if ((this.tickCount % 20) == 0) {
+ this.isInWater = this.isSurroundedByWater();
+ }
+
+ if (this.isInWater) {
+ this.calculateTickrate();
+ }
+
+ // Try add some loot once every 30 seconds.
+ if (this.tickCount >= this.baseTickRate) {
+ if (this.isInWater) {
+ // Add loot
+ Logger.MACHINE_INFO("Adding Loot to the fishtrap at x["+this.locationX+"] y["+this.locationY+"] z["+this.locationZ+"] (Ticking for loot every "+this.baseTickRate+" ticks)");
+
+ int aExtraLootChance = MathUtils.randInt(1, 1000);
+ if (aExtraLootChance >= 999) {
+ this.tryAddLoot();
+ this.tryAddLoot();
+ this.tryAddLoot();
+ }
+ else {
+ this.tryAddLoot();
+ }
+
+ this.markDirty();
+ }
+ else {
+ Logger.MACHINE_INFO("Not in water.");
+ this.markDirty();
+ }
+ this.tickCount = 0;
+ }
+ if (this.tickCount >= (this.baseTickRate + 500)) {
+ Logger.MACHINE_INFO("Resetting tick counter");
+ this.tickCount = 0;
+ }
+
+ }
+ }
+ catch (final Throwable t){}
+ }
+
+ public void calculateTickrate() {
+ int water = this.waterSides;
+ //int variance = (int) ((MathUtils.randInt(-200, 200)/water)*0.5);
+ if (water <= 1) {
+ this.baseTickRate = 0;
+ } else if (water == 2) {
+ this.baseTickRate = 6800;
+ } else if (water == 3) {
+ this.baseTickRate = 5600;
+ } else if (water == 4) {
+ this.baseTickRate = 4400;
+ } else if (water == 5) {
+ this.baseTickRate = 3200;
+ } else {
+ this.baseTickRate = 1750;
+ }
+ if (water > 1) {
+ //this.baseTickRate += variance;
+ }
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ // Utils.LOG_MACHINE_INFO("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.inventoryContents.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ // Utils.LOG_MACHINE_INFO("Trying to read NBT data from TE.");
+ this.inventoryContents.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ }
+
+ final static String prefix = "food";
+ final static String suffix = "raw";
+ final static String seaweed = "cropSeaweed";
+ final static String greenheartFish = "Greenheartfish";
+ private static final String[] harvestcraftFish = { "Anchovy", "Bass", "Carp", "Catfish", "Charr", "Clam", "Crab",
+ "Crayfish", "Eel", "Frog", "Grouper", "Herring", "Jellyfish", "Mudfish", "Octopus", "Perch", "Scallop",
+ "Shrimp", "Snail", "Snapper", "Tilapia", "Trout", "Tuna", "Turtle", "Walleye" };
+
+ public static void pamsHarvestCraftCompat() {
+ for (int i = 0; i < harvestcraftFish.length; i++) {
+
+ }
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.getInventory().getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(final int slot) {
+ return this.getInventory().getStackInSlot(slot);
+ }
+
+ @Override
+ public ItemStack decrStackSize(final int slot, final int count) {
+ return this.getInventory().decrStackSize(slot, count);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(final int slot) {
+ return this.getInventory().getStackInSlotOnClosing(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(final int slot, final ItemStack stack) {
+ this.getInventory().setInventorySlotContents(slot, stack);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.getInventory().getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return this.getInventory().isItemValidForSlot(slot, itemstack);
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int p_94128_1_) {
+ final int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r=0; r<this.getInventory().getSizeInventory(); r++){
+ accessibleSides[r]=r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(final int p_102007_1_, final ItemStack p_102007_2_, final int p_102007_3_) {
+ return false;
+ }
+
+ @Override
+ public boolean canExtractItem(final int p_102008_1_, final ItemStack p_102008_2_, final int p_102008_3_) {
+ return true;
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.fishtrap";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.customName != null) && !this.customName.equals("");
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityHeliumGenerator.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityHeliumGenerator.java
new file mode 100644
index 0000000000..8a2d9d9f51
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityHeliumGenerator.java
@@ -0,0 +1,124 @@
+package gtPlusPlus.core.tileentities.general;
+
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+
+import gregtech.api.enums.GT_Values;
+
+import gtPlusPlus.core.inventories.InventoryHeliumGenerator;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+
+public class TileEntityHeliumGenerator extends TileEntity{
+
+ private int tickCount = 0;
+ private final InventoryHeliumGenerator inventoryContents; //TODO
+ private int locationX;
+ private int locationY;
+ private int locationZ;
+ private int baseTickRate = 1200;
+
+ public TileEntityHeliumGenerator(){
+ this.inventoryContents = new InventoryHeliumGenerator();//number of slots - without product slot
+ this.setTileLocation();
+ }
+
+ public boolean setTileLocation(){
+ if (this.hasWorldObj()){
+ if (!this.getWorldObj().isRemote){
+ this.locationX = this.xCoord;
+ this.locationY = this.yCoord;
+ this.locationZ = this.zCoord;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public InventoryHeliumGenerator getInventory(){
+ return this.inventoryContents;
+ }
+
+ public boolean tryAddLoot(){
+ if (this.getInventory().getInventory() != null){
+ int checkingSlot = 0;
+ final ItemStack loot = this.generateLootForFishTrap();
+ for (final ItemStack contents : this.getInventory().getInventory()){
+ if (contents == null){
+ this.getInventory().setInventorySlotContents(checkingSlot, loot);
+ this.markDirty();
+ return true;
+ }
+ else if (contents.getItem() == loot.getItem()){
+ if (contents.stackSize < contents.getMaxStackSize()){
+ contents.stackSize++;
+ this.markDirty();
+ return true;
+ }
+ else {
+ this.getInventory().setInventorySlotContents(checkingSlot, loot);
+ this.markDirty();
+ return true;
+ }
+ }
+ else {
+
+ }
+ checkingSlot++;
+ }
+ }
+ this.markDirty();
+ return false;
+ }
+
+ private ItemStack generateLootForFishTrap() {
+ final int lootWeight = MathUtils.randInt(0, 1000);
+ ItemStack loot = GT_Values.NI;
+ if (lootWeight > 990){
+ loot = ItemUtils.getSimpleStack(Items.slime_ball);
+ }
+ return loot;
+ }
+
+ @Override
+ public void updateEntity(){
+ if (!this.worldObj.isRemote){
+
+ }
+ }
+
+ public void calculateTickrate(){
+ int calculateTickrate = 0;
+ this.baseTickRate = calculateTickrate;
+ }
+
+ public boolean anyPlayerInRange(){
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag){
+ if(!nbt.hasKey(tag)){
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt){
+ super.writeToNBT(nbt);
+ //Utils.LOG_INFO("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.inventoryContents.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt){
+ super.readFromNBT(nbt);
+ //Utils.LOG_INFO("Trying to read NBT data from TE.");
+ this.inventoryContents.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityInfiniteFluid.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityInfiniteFluid.java
new file mode 100644
index 0000000000..9ddf2065bc
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityInfiniteFluid.java
@@ -0,0 +1,139 @@
+package gtPlusPlus.core.tileentities.general;
+
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.TileEntity;
+
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.*;
+
+public class TileEntityInfiniteFluid extends TileEntity implements IFluidHandler {
+
+ public FluidTank tank = new FluidTank(Integer.MAX_VALUE);
+ private boolean needsUpdate = false;
+ private int updateTimer = 0;
+
+ public TileEntityInfiniteFluid() {
+ }
+
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
+ needsUpdate = true;
+ return this.tank.fill(resource, doFill);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
+ needsUpdate = true;
+ return this.tank.drain(resource.amount, doDrain);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
+ needsUpdate = true;
+ FluidStack fluid = this.tank.getFluid();
+ // return this.tank.drain(maxDrain, doDrain);
+ if (fluid == null) {
+ return null;
+ }
+
+ int drained = maxDrain;
+ if (fluid.amount < drained) {
+ drained = fluid.amount;
+ }
+
+ FluidStack stack = new FluidStack(fluid, drained);
+ if (doDrain) {
+ fluid.amount -= drained;
+ if (fluid.amount <= 0) {
+ fluid = null;
+ }
+
+ if (this != null) {
+ FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(fluid, this.getWorldObj(), this.xCoord,
+ this.yCoord, this.zCoord, this.tank, 0));
+ }
+ }
+ return stack;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid) {
+ return true;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid) {
+ return true;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from) {
+ return new FluidTankInfo[] { this.tank.getInfo() };
+ }
+
+ public float getAdjustedVolume() {
+ needsUpdate = true;
+ float amount = tank.getFluidAmount();
+ float capacity = tank.getCapacity();
+ float volume = (amount / capacity) * 0.8F;
+ return volume;
+ }
+
+ @Override
+ public void updateEntity() {
+
+ if (this.tank.getFluid() != null){
+ FluidStack bigStorage = this.tank.getFluid();
+ bigStorage.amount = this.tank.getCapacity();
+ this.tank.setFluid(bigStorage);
+ }
+
+ if (needsUpdate) {
+
+ if (this.tank.getFluid() != null){
+ FluidStack bigStorage = this.tank.getFluid();
+ bigStorage.amount = this.tank.getCapacity();
+ this.tank.setFluid(bigStorage);
+ }
+
+ if (updateTimer == 0) {
+ updateTimer = 10; // every 10 ticks it will send an update
+ } else {
+ --updateTimer;
+ if (updateTimer == 0) {
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ needsUpdate = false;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound tag) {
+ tank.readFromNBT(tag);
+ super.readFromNBT(tag);
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound tag) {
+ tank.writeToNBT(tag);
+ super.writeToNBT(tag);
+ }
+
+ @Override
+ public Packet getDescriptionPacket() {
+ NBTTagCompound tag = new NBTTagCompound();
+ writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
+ NBTTagCompound tag = pkt.func_148857_g();
+ readFromNBT(tag);
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityPlayerDoorBase.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityPlayerDoorBase.java
new file mode 100644
index 0000000000..48f05fe0fd
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityPlayerDoorBase.java
@@ -0,0 +1,285 @@
+package gtPlusPlus.core.tileentities.general;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.api.objects.minecraft.BlockPos;
+import gtPlusPlus.core.util.minecraft.EntityUtils;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockDoor;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+
+public class TileEntityPlayerDoorBase extends TileEntity {
+
+ public boolean mIsOpen = false;
+ private short mMeta = 0;
+ private long mTickCounter = 0;
+ private final Block mBlockType;
+ private BlockPos mNeighbourDoor;
+
+ public TileEntityPlayerDoorBase(Block aBlock, int meta) {
+ mBlockType = aBlock;
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound aNBT) {
+ super.readFromNBT(aNBT);
+ this.mIsOpen = aNBT.getBoolean("mIsOpen");
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound aNBT) {
+ super.writeToNBT(aNBT);
+ aNBT.setBoolean("mIsOpen", mIsOpen);
+ }
+
+ public int getNeighbourState() {
+
+ if (mNeighbourDoor != null) {
+ World aWorld = this.worldObj;
+ if (aWorld != null) {
+ TileEntity t = aWorld.getTileEntity(mNeighbourDoor.xPos, mNeighbourDoor.yPos, mNeighbourDoor.zPos);
+ // Custom Door
+ if (t != null) {
+ if (t instanceof TileEntityPlayerDoorBase) {
+ TileEntityPlayerDoorBase d = (TileEntityPlayerDoorBase) t;
+ if (d.mIsOpen) {
+ return 100;
+ } else {
+ return -100;
+ }
+ } else
+ return -100;
+ }
+ // Vanilla Door
+ else {
+ Block aBlock = mNeighbourDoor.getBlockAtPos();
+ BlockDoor aDoor = (aBlock instanceof BlockDoor ? (BlockDoor) aBlock : null);
+ if (aDoor != null) {
+ int i1 = aDoor.func_150012_g(mNeighbourDoor.world, mNeighbourDoor.xPos, mNeighbourDoor.yPos,
+ mNeighbourDoor.zPos);
+ if ((i1 & 4) != 0) {
+ return 100;
+ } else {
+ return -100;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ AutoMap<Entity> mNearbyEntityCache = new AutoMap<Entity>();
+
+ @Override
+ public void updateEntity() {
+
+ if (this.getWorldObj().isRemote) {
+ return;
+ }
+
+ // Look For Neighbours
+ if (mTickCounter % 100 == 0 || mTickCounter == 0) {
+ World aWorld = this.getWorldObj();
+ BlockPos aThisPos = new BlockPos(xCoord, yCoord, zCoord, aWorld);
+ BlockPos[] aNeighbors = new BlockPos[4];
+ aNeighbors[0] = aThisPos.getXNeg();
+ aNeighbors[1] = aThisPos.getXPos();
+ aNeighbors[2] = aThisPos.getZNeg();
+ aNeighbors[3] = aThisPos.getZPos();
+ boolean aFoundDoor = false;
+ for (BlockPos b : aNeighbors) {
+ Block aBlock = aWorld.getBlock(b.xPos, b.yPos, b.zPos);
+ BlockDoor aDoor = (aBlock instanceof BlockDoor ? (BlockDoor) aBlock : null);
+ if (aDoor != null) {
+ mNeighbourDoor = b;
+ aFoundDoor = true;
+ if (mMeta == 0) {
+ TileEntity t = aWorld.getTileEntity(b.xPos, b.yPos, b.zPos);
+ if (t != null) {
+ if (t instanceof TileEntityPlayerDoorBase) {
+ TileEntityPlayerDoorBase d = (TileEntityPlayerDoorBase) t;
+ if (d.mMeta != 0) {
+ //Logger.INFO("Found Door with Mode set other than 0, assuming slave role.");
+ mMeta = -1;
+ }
+ else {
+ //Logger.INFO("Found door with no mode set, assuming we are master.");
+ mMeta = 1;
+ }
+ }
+ else {
+ //Logger.INFO("Custom door from another mod, assuming slave role.");
+ mMeta = -1;
+ }
+ }
+ else {
+ //Logger.INFO("No Tile Entity found, Door is probably vanilla, assuming slave role.");
+ mMeta = -1;
+ }
+ }
+ break;
+ }
+ }
+ if (mMeta < 1 && !aFoundDoor) {
+ //Logger.INFO("Found No Valid Doors around, setting this one to master mode.");
+ mMeta = 1;
+ }
+ }
+
+ World aWorld = this.getWorldObj();
+ Block aBlock = aWorld.getBlock(xCoord, yCoord, zCoord);
+ BlockPos aThisPos = new BlockPos(xCoord, yCoord, zCoord, this.worldObj);
+
+ if (mTickCounter % 20 == 0) {
+ int x = 0, y = 0, z = 0;
+ x = this.xCoord;
+ y = this.yCoord;
+ z = this.zCoord;
+ //List aEntityList = aWorld.loadedEntityList;
+ List<Entity> aEntityList = new ArrayList<Entity>();
+ Chunk aThisChunk = aWorld.getChunkFromBlockCoords(x, z);
+ for (List l : aThisChunk.entityLists) {
+ aEntityList.addAll(l);
+ }
+ for (Object o : aEntityList) {
+ if (o != null) {
+ if (o instanceof Entity) {
+ if (o instanceof EntityPlayer) {
+ continue;
+ }
+ else {
+ Entity e = (Entity) o;
+ BlockPos p = EntityUtils.findBlockPosUnderEntity(e);
+ if (p != null) {
+ int newY = p.yPos+1;
+ if (e.getDistance(xCoord, yCoord, zCoord) <= 2){
+ mNearbyEntityCache.put(e);
+ }
+ else if (aThisPos.distanceFrom(p.xPos, newY, p.zPos) <= 2) {
+ mNearbyEntityCache.put(e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mTickCounter % 4 == 0) {
+ for (Entity y : mNearbyEntityCache) {
+ if (y.getDistance(xCoord, yCoord, zCoord) > 2){
+ mNearbyEntityCache.remove(y);
+ }
+ }
+
+ boolean foundMonster = mNearbyEntityCache.size() > 0;
+ int aNeighbourDoorState = 0;
+ if (mNeighbourDoor != null) {
+ aNeighbourDoorState = getNeighbourState();
+ }
+ BlockDoor aDoor = (aBlock instanceof BlockDoor ? (BlockDoor) aBlock : null);
+ boolean aPlayers = checkForPlayers(this.getWorldObj());
+
+ if (aDoor != null) {
+ //If neighbour state != 0 and we are in slave mode
+ if (aNeighbourDoorState != 0 && mMeta == -1) {
+ if (aNeighbourDoorState == 100) {
+ if (!mIsOpen && !foundMonster) {
+ //Logger.INFO("Opening Door (Slave)");
+ aDoor.func_150014_a(aWorld, this.xCoord, this.yCoord, this.zCoord, true);
+ mIsOpen = true;
+ }
+ } else if (aNeighbourDoorState == -100 || foundMonster) {
+ if (mIsOpen) {
+ //Logger.INFO("Closing Door (Slave)");
+ aDoor.func_150014_a(aWorld, this.xCoord, this.yCoord, this.zCoord, false);
+ mIsOpen = false;
+ }
+ }
+ //We are master, proceed
+ } else {
+ //No redstone found, allow automatic handling
+ if (aDoor != null && !hasRedstone()) {
+ //Found a nearby player
+ if (aPlayers) {
+ //If we are closed and there are no monsters nearby, open
+ if (!mIsOpen && !foundMonster) {
+ //Logger.INFO("Opening Door (Mstr)");
+ aDoor.func_150014_a(aWorld, this.xCoord, this.yCoord, this.zCoord, true);
+ mIsOpen = true;
+ } else {
+ // Logger.INFO("Doing Nothing, Door is in correct state.");
+ }
+ //Did not find nearby player
+ } else {
+ //If we are open or there is a monster nearby, close.
+ if (mIsOpen || foundMonster) {
+ //Logger.INFO("Closing Door (Mstr)");
+ aDoor.func_150014_a(aWorld, this.xCoord, this.yCoord, this.zCoord, false);
+ mIsOpen = false;
+ } else {
+ // Logger.INFO("Doing Nothing, Door is in correct state.");
+ }
+ }
+ }
+ }
+ }
+
+ }
+ super.updateEntity();
+ mTickCounter++;
+ }
+
+ @Override
+ public int getBlockMetadata() {
+ return this.mMeta;
+ }
+
+ public boolean hasRedstone() {
+ World aWorld = this.worldObj;
+ if (aWorld != null && !aWorld.isRemote) {
+ return aWorld.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)
+ || aWorld.isBlockIndirectlyGettingPowered(xCoord, yCoord + 1, zCoord);
+ }
+ return false;
+ }
+
+ @Override
+ public Block getBlockType() {
+ return mBlockType;
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return true;
+ }
+
+ private boolean checkForPlayers(World aWorld) {
+ int x = 0, y = 0, z = 0;
+ x = this.xCoord;
+ y = this.yCoord;
+ z = this.zCoord;
+ EntityPlayer aPlayer = aWorld.getClosestPlayer(x, y, z, 3.5D);
+ if (aPlayer != null) {
+ return true;
+ }
+ return false;
+ }
+
+ private short getClosedMeta() {
+ return 0;
+ }
+
+ private short getOpenMeta() {
+ return 1;
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityReverter.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityReverter.java
new file mode 100644
index 0000000000..6e18834786
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityReverter.java
@@ -0,0 +1,312 @@
+package gtPlusPlus.core.tileentities.general;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.init.Blocks;
+import net.minecraft.tileentity.TileEntity;
+
+import gtPlusPlus.core.block.ModBlocks;
+
+
+
+public class TileEntityReverter extends TileEntity
+{
+ private static final int REVERT_CHANCE = 10;
+ public int radius = 16;
+ public int diameter = (8 * this.radius) + 4;
+ public double requiredPlayerRange = 64.0D;
+ public Random rand = new Random();
+ private int tickCount;
+ private boolean slowScan;
+ private int ticksSinceChange;
+ private Block[] blockData;
+ private byte[] metaData;
+
+ @Override
+ public boolean canUpdate(){
+ return true;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ if (this.anyPlayerInRange())
+ {
+ this.tickCount += 1;
+ if (this.worldObj.isRemote)
+ {
+ final double var1 = this.xCoord + this.worldObj.rand.nextFloat();
+ final double var3 = this.yCoord + this.worldObj.rand.nextFloat();
+ final double var5 = this.zCoord + this.worldObj.rand.nextFloat();
+
+ this.worldObj.spawnParticle("enchantmenttable", var1, var3, var5, 0.0D, 0.0D, 0.0D);
+ if (this.rand.nextInt(5) == 0)
+ {
+ this.makeRandomOutline();
+ this.makeRandomOutline();
+ this.makeRandomOutline();
+ }
+ }
+ else
+ {
+ if ((this.blockData == null) || (this.metaData == null))
+ {
+ this.captureBlockData();
+ this.slowScan = true;
+ }
+ if ((!this.slowScan) || ((this.tickCount % 20) == 0)) {
+ if (this.scanAndRevertChanges())
+ {
+ this.slowScan = false;
+ this.ticksSinceChange = 0;
+ }
+ else
+ {
+ this.ticksSinceChange += 1;
+ if (this.ticksSinceChange > 20) {
+ this.slowScan = true;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ this.blockData = null;
+ this.metaData = null;
+
+ this.tickCount = 0;
+ }
+ }
+
+ private void makeRandomOutline()
+ {
+ this.makeOutline(this.rand.nextInt(12));
+ }
+
+ private void makeOutline(final int outline)
+ {
+ double sx = this.xCoord;
+ double sy = this.yCoord;
+ double sz = this.zCoord;
+
+ double dx = this.xCoord;
+ double dy = this.yCoord;
+ double dz = this.zCoord;
+ switch (outline)
+ {
+ case 0:
+ sx -= this.radius;
+ dx -= this.radius;
+ sz -= this.radius;
+ dz += this.radius + 1;
+ case 8:
+ sx -= this.radius;
+ dx += this.radius + 1;
+ sz -= this.radius;
+ dz -= this.radius;
+ break;
+ case 1:
+ case 9:
+ sx -= this.radius;
+ dx -= this.radius;
+ sz -= this.radius;
+ dz += this.radius + 1;
+ break;
+ case 2:
+ case 10:
+ sx -= this.radius;
+ dx += this.radius + 1;
+ sz += this.radius + 1;
+ dz += this.radius + 1;
+ break;
+ case 3:
+ case 11:
+ sx += this.radius + 1;
+ dx += this.radius + 1;
+ sz -= this.radius;
+ dz += this.radius + 1;
+ break;
+ case 4:
+ sx -= this.radius;
+ dx -= this.radius;
+ sz -= this.radius;
+ dz -= this.radius;
+ break;
+ case 5:
+ sx += this.radius + 1;
+ dx += this.radius + 1;
+ sz -= this.radius;
+ dz -= this.radius;
+ break;
+ case 6:
+ sx += this.radius + 1;
+ dx += this.radius + 1;
+ sz += this.radius + 1;
+ dz += this.radius + 1;
+ break;
+ case 7:
+ sx -= this.radius;
+ dx -= this.radius;
+ sz += this.radius + 1;
+ dz += this.radius + 1;
+ }
+ switch (outline)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ sy += this.radius + 1;
+ dy += this.radius + 1;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ sy -= this.radius;
+ dy += this.radius + 1;
+ break;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ sy -= this.radius;
+ dy -= this.radius;
+ }
+ if (this.rand.nextBoolean()) {
+ this.drawParticleLine(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, dx, dy, dz);
+ } else {
+ this.drawParticleLine(sx, sy, sz, this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D);
+ }
+ this.drawParticleLine(sx, sy, sz, dx, dy, dz);
+ }
+
+ protected void drawParticleLine(final double srcX, final double srcY, final double srcZ, final double destX, final double destY, final double destZ)
+ {
+ final int particles = 16;
+ for (int i = 0; i < particles; i++)
+ {
+ final double trailFactor = i / (particles - 1.0D);
+
+ final double tx = srcX + ((destX - srcX) * trailFactor) + (this.rand.nextFloat() * 0.005D);
+ final double ty = srcY + ((destY - srcY) * trailFactor) + (this.rand.nextFloat() * 0.005D);
+ final double tz = srcZ + ((destZ - srcZ) * trailFactor) + (this.rand.nextFloat() * 0.005D);
+ this.worldObj.spawnParticle("portal", tx, ty, tz, 0.0D, 0.0D, 0.0D);
+ }
+ }
+
+ private boolean scanAndRevertChanges()
+ {
+ int index = 0;
+ boolean reverted = false;
+ for (int x = -this.radius; x <= this.radius; x++) {
+ for (int y = -this.radius; y <= this.radius; y++) {
+ for (int z = -this.radius; z <= this.radius; z++)
+ {
+ final Block blockID = this.worldObj.getBlock(this.xCoord + x, this.yCoord + y, this.zCoord + z);
+ final byte meta = (byte)this.worldObj.getBlockMetadata(this.xCoord + x, this.yCoord + y, this.zCoord + z);
+ if (this.blockData[index] != blockID) {
+ if (this.revertBlock(this.xCoord + x, this.yCoord + y, this.zCoord + z, blockID, meta, this.blockData[index], this.metaData[index]))
+ {
+ reverted = true;
+ }
+ else
+ {
+ this.blockData[index] = blockID;
+ this.metaData[index] = meta;
+ }
+ }
+ index++;
+ }
+ }
+ }
+ return reverted;
+ }
+
+ private boolean revertBlock(final int x, final int y, final int z, final Block thereBlockID, final byte thereMeta, final Block replaceBlockID, byte replaceMeta)
+ {
+ /*if ((thereBlockID == Blocks.air) && (!replaceBlockID.getMaterial().blocksMovement()))
+ {
+ System.out.println("Not replacing block " + replaceBlockID + " because it doesn't block movement");
+
+ return false;
+ }*/
+ if (this.isUnrevertable(thereBlockID, thereMeta, replaceBlockID, replaceMeta)) {
+ return false;
+ }
+ if (this.rand.nextInt(5) == 0)
+ {
+ if (replaceBlockID != Blocks.air)
+ {
+ //replaceBlockID = null;
+ replaceMeta = 4;
+ }
+ this.worldObj.setBlock(x, y, z, replaceBlockID, replaceMeta, 2);
+ if (thereBlockID == Blocks.air)
+ {
+ this.worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(replaceBlockID) + (replaceMeta << 12));
+ }
+ else if (replaceBlockID == Blocks.air)
+ {
+ this.worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(thereBlockID) + (thereMeta << 12));
+ thereBlockID.dropBlockAsItem(this.worldObj, x, y, z, thereMeta, 0);
+ }
+ }
+ return true;
+ }
+
+ private boolean isUnrevertable(final Block thereBlockID, final byte thereMeta, final Block replaceBlockID, final byte replaceMeta)
+ {
+ if ((thereBlockID == ModBlocks.blockGriefSaver) || (replaceBlockID == ModBlocks.blockGriefSaver)) {
+ return true;
+ }
+ /*if (((thereBlockID == towerTranslucent) && (thereMeta != 4)) || ((replaceBlockID == towerTranslucent) && (replaceMeta != 4))) {
+ return true;
+ }*/
+ if ((thereBlockID == Blocks.redstone_lamp) && (replaceBlockID == Blocks.lit_redstone_lamp)) {
+ return true;
+ }
+ if ((thereBlockID == Blocks.lit_redstone_lamp) && (replaceBlockID == Blocks.redstone_lamp)) {
+ return true;
+ }
+ /*if ((thereBlockID == Blocks.water) || (replaceBlockID == Blocks.flowing_water)) {
+ return true;
+ }
+ if ((thereBlockID == Blocks.flowing_water) || (replaceBlockID == Blocks.water)) {
+ return true;
+ }*/
+ if (replaceBlockID == Blocks.tnt) {
+ return true;
+ }
+ return false;
+ }
+
+ private void captureBlockData()
+ {
+ this.blockData = new Block[this.diameter * this.diameter * this.diameter];
+ this.metaData = new byte[this.diameter * this.diameter * this.diameter];
+
+ int index = 0;
+ for (int x = -this.radius; x <= this.radius; x++) {
+ for (int y = -this.radius; y <= this.radius; y++) {
+ for (int z = -this.radius; z <= this.radius; z++)
+ {
+ final Block blockID = this.worldObj.getBlock(this.xCoord + x, this.yCoord + y, this.zCoord + z);
+ final int meta = this.worldObj.getBlockMetadata(this.xCoord + x, this.yCoord + y, this.zCoord + z);
+
+ this.blockData[index] = blockID;
+ this.metaData[index] = ((byte)meta);
+
+ index++;
+ }
+ }
+ }
+ }
+
+ public boolean anyPlayerInRange()
+ {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, this.requiredPlayerRange) != null;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityVolumetricFlaskSetter.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityVolumetricFlaskSetter.java
new file mode 100644
index 0000000000..5b837397b1
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityVolumetricFlaskSetter.java
@@ -0,0 +1,403 @@
+package gtPlusPlus.core.tileentities.general;
+
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.core.container.Container_VolumetricFlaskSetter;
+import gtPlusPlus.core.inventories.Inventory_VolumetricFlaskSetter;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.PlayerUtils;
+import gtPlusPlus.xmod.gregtech.common.helpers.VolumetricFlaskHelper;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.fluids.FluidStack;
+
+public class TileEntityVolumetricFlaskSetter extends TileEntity implements ISidedInventory {
+
+ private int tickCount = 0;
+ private final Inventory_VolumetricFlaskSetter inventoryContents;
+ private String customName;
+ public int locationX;
+ public int locationY;
+ public int locationZ;
+ private int aCurrentMode = 0;
+ private short aCustomValue = 1000;
+
+ public TileEntityVolumetricFlaskSetter() {
+ this.inventoryContents = new Inventory_VolumetricFlaskSetter();
+ this.setTileLocation();
+ }
+
+ public short getCustomValue() {
+ //Logger.INFO("Value: "+this.aCustomValue);
+ return this.aCustomValue;
+ }
+
+ public void setCustomValue(int aVal) {
+ Logger.INFO("Old Value: "+this.aCustomValue);
+ this.aCustomValue = (short) MathUtils.balance(aVal, 0, Short.MAX_VALUE);
+ Logger.INFO("New Value: "+this.aCustomValue);
+ markDirty();
+ }
+
+ public boolean setTileLocation() {
+ if (this.hasWorldObj()) {
+ if (!this.getWorldObj().isRemote) {
+ this.locationX = this.xCoord;
+ this.locationY = this.yCoord;
+ this.locationZ = this.zCoord;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //Rename to hasCircuitToConfigure
+ public final boolean hasFlask() {
+ for (int i=0;i<this.getInventory().getInventory().length-1;i++) {
+ if (i == Container_VolumetricFlaskSetter.SLOT_OUTPUT) {
+ continue;
+ }
+ if (this.getInventory().getInventory()[i] != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Inventory_VolumetricFlaskSetter getInventory() {
+ return this.inventoryContents;
+ }
+
+ private int getFlaskType(ItemStack aStack) {
+ if (VolumetricFlaskHelper.isNormalVolumetricFlask(aStack)) {
+ return 1;
+ }
+ else if (VolumetricFlaskHelper.isLargeVolumetricFlask(aStack)) {
+ return 2;
+ }
+ else if (VolumetricFlaskHelper.isGiganticVolumetricFlask(aStack)) {
+ return 3;
+ }
+ return 0;
+ }
+
+ private int getCapacityForSlot(int aSlot) {
+ switch (aSlot) {
+ case 0: //16
+ return 16;
+ case 1: //36
+ return 36;
+ case 2: //144
+ return 144;
+ case 3: //432
+ return 432;
+ case 4: //576
+ return 576;
+ case 5: //720
+ return 720;
+ case 6: //864
+ return 864;
+ case 7: //Custom
+ return getCustomValue();
+ }
+ return 1000;
+ }
+
+ public boolean addOutput() {
+
+ // Don't do anything unless we have items
+ if (!hasFlask()) {
+ Logger.INFO("No Flasks.");
+ return false;
+ }
+
+
+ ItemStack[] aInputs = this.getInventory().getInventory().clone();
+
+
+ //Check if there is output in slot.
+ Boolean hasOutput = false;
+ if (aInputs[Container_VolumetricFlaskSetter.SLOT_OUTPUT] != null) {
+ hasOutput = true;
+ if (aInputs[Container_VolumetricFlaskSetter.SLOT_OUTPUT].stackSize >= 16) {
+ return false;
+ }
+ }
+ AutoMap<Integer> aValidSlots = new AutoMap<Integer>();
+ int aSlotCount = 0;
+ for (ItemStack i : aInputs) {
+ if (i != null) {
+ aValidSlots.put(aSlotCount);
+ }
+ aSlotCount++;
+ }
+ for (int e : aValidSlots) {
+
+ // Skip slot 7 (Custom) unless it has a value > 0
+ if (e == 7 && getCustomValue() <= 0) {
+ Logger.INFO("Skipping Custom slot as value <= 0");
+ continue;
+ }
+ if (e == Container_VolumetricFlaskSetter.SLOT_OUTPUT) {
+ continue;
+ }
+
+ boolean doAdd = false;
+ ItemStack g = this.getStackInSlot(e);
+ FluidStack aInputFluidStack = VolumetricFlaskHelper.getFlaskFluid(g);
+ int aSize = 0;
+ ItemStack aInputStack = null;
+ int aTypeInSlot = getFlaskType(g);
+ if (aTypeInSlot > 0 && g != null) {
+ // No Existing Output
+ if (!hasOutput) {
+ aSize = g.stackSize;
+ doAdd = true;
+ }
+ // Existing Output
+ else {
+ ItemStack f = aInputs[Container_VolumetricFlaskSetter.SLOT_OUTPUT];
+ FluidStack aFluidInCheckedSlot = VolumetricFlaskHelper.getFlaskFluid(f);
+ int aTypeInCheckedSlot = getFlaskType(f);
+ // Check that the Circuit in the Output slot is not null and the same type as the circuit input.
+ if (aTypeInCheckedSlot > 0 && (aTypeInSlot == aTypeInCheckedSlot) && f != null) {
+ if (g.getItem() == f.getItem() && VolumetricFlaskHelper.getFlaskCapacity(f) == getCapacityForSlot(e) && ((aInputFluidStack == null && aFluidInCheckedSlot == null) || aInputFluidStack.isFluidEqual(aFluidInCheckedSlot))) {
+ Logger.INFO("Input Slot Flask Contains: "+(aInputFluidStack != null ? aInputFluidStack.getLocalizedName() : "Empty"));
+ Logger.INFO("Output Slot Flask Contains: "+(aFluidInCheckedSlot != null ? aFluidInCheckedSlot.getLocalizedName() : "Empty"));
+ aSize = f.stackSize + g.stackSize;
+ if (aSize > 16) {
+ aInputStack = g.copy();
+ aInputStack.stackSize = (aSize-16);
+ }
+ doAdd = true;
+ }
+ }
+ }
+ if (doAdd) {
+ // Check Circuit Type
+ ItemStack aOutput;
+ FluidStack aOutputFluid = null;
+ if (!VolumetricFlaskHelper.isFlaskEmpty(g)) {
+ aOutputFluid = aInputFluidStack.copy();
+ }
+ if (aTypeInSlot == 1) {
+ aOutput = VolumetricFlaskHelper.getVolumetricFlask(1);
+ }
+ else if (aTypeInSlot == 2) {
+ aOutput = VolumetricFlaskHelper.getLargeVolumetricFlask(1);
+ }
+ else if (aTypeInSlot == 3) {
+ aOutput = VolumetricFlaskHelper.getGiganticVolumetricFlask(1);
+ }
+ else {
+ aOutput = null;
+ }
+ if (aOutput != null) {
+ aOutput.stackSize = aSize;
+ int aCapacity = getCapacityForSlot(e);
+ VolumetricFlaskHelper.setNewFlaskCapacity(aOutput, aCapacity);
+ if (aOutputFluid != null) {
+ if (aOutputFluid.amount > aCapacity) {
+ aOutputFluid.amount = aCapacity;
+ }
+ VolumetricFlaskHelper.setFluid(aOutput, aOutputFluid);
+ }
+ this.setInventorySlotContents(e, aInputStack);
+ this.setInventorySlotContents(Container_VolumetricFlaskSetter.SLOT_OUTPUT, aOutput);
+ return true;
+ }
+ }
+ }
+ continue;
+ }
+ return false;
+ }
+
+ @Override
+ public void updateEntity() {
+ try{
+ if (!this.worldObj.isRemote) {
+ if (tickCount % 10 == 0) {
+ if (hasFlask()) {
+ this.addOutput();
+ this.markDirty();
+ }
+ }
+ this.tickCount++;
+ }
+ }
+ catch (final Throwable t){}
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ // Utils.LOG_WARNING("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.inventoryContents.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ nbt.setShort("aCustomValue", aCustomValue);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ nbt.setInteger("aCurrentMode", aCurrentMode);
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ // Utils.LOG_WARNING("Trying to read NBT data from TE.");
+ this.inventoryContents.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ this.aCustomValue = nbt.getShort("aCustomValue");
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ aCurrentMode = nbt.getInteger("aCurrentMode");
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.getInventory().getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(final int slot) {
+ return this.getInventory().getStackInSlot(slot);
+ }
+
+ @Override
+ public ItemStack decrStackSize(final int slot, final int count) {
+ return this.getInventory().decrStackSize(slot, count);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(final int slot) {
+ return this.getInventory().getStackInSlotOnClosing(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(final int slot, final ItemStack stack) {
+ this.getInventory().setInventorySlotContents(slot, stack);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.getInventory().getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return this.getInventory().isItemValidForSlot(slot, itemstack);
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int p_94128_1_) {
+ final int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r=0; r<this.getInventory().getSizeInventory(); r++){
+ accessibleSides[r]=r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(final int aSlot, final ItemStack p_102007_2_, final int p_102007_3_) {
+ return aSlot == aCurrentMode;
+ }
+
+ @Override
+ public boolean canExtractItem(final int aSlot, final ItemStack p_102008_2_, final int p_102008_3_) {
+ return aSlot == Container_VolumetricFlaskSetter.SLOT_OUTPUT;
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.VolumetricFlaskSetter";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.customName != null) && !this.customName.equals("");
+ }
+
+ @Override
+ public Packet getDescriptionPacket() {
+ final NBTTagCompound tag = new NBTTagCompound();
+ this.writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public void onDataPacket(final NetworkManager net, final S35PacketUpdateTileEntity pkt) {
+ final NBTTagCompound tag = pkt.func_148857_g();
+ this.readFromNBT(tag);
+ }
+
+ public boolean onScrewdriverRightClick(byte side, EntityPlayer player, int x, int y, int z) {
+
+ if (player.isSneaking()) {
+ PlayerUtils.messagePlayer(player, "Value: "+this.getCustomValue());
+ }
+
+ try {
+ if (aCurrentMode == 7) {
+ aCurrentMode = 0;
+ }
+ else {
+ aCurrentMode++;
+ }
+ PlayerUtils.messagePlayer(player, "Slot "+aCurrentMode+" is now default.");
+ return true;
+ }
+ catch (Throwable t) {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityXpConverter.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityXpConverter.java
new file mode 100644
index 0000000000..2816596515
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityXpConverter.java
@@ -0,0 +1,298 @@
+package gtPlusPlus.core.tileentities.general;
+
+import org.lwjgl.input.Keyboard;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import gtPlusPlus.api.objects.minecraft.BTF_FluidTank;
+import gtPlusPlus.core.tileentities.base.TileBasicTank;
+import gtPlusPlus.core.util.minecraft.EnchantingUtils;
+import gtPlusPlus.core.util.minecraft.PlayerUtils;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.*;
+
+public class TileEntityXpConverter extends TileBasicTank {
+
+ public BTF_FluidTank tankEssence = new BTF_FluidTank((int) (64000*EnchantingUtils.RATIO_MOB_ESSENCE_TO_LIQUID_XP));
+ public BTF_FluidTank tankLiquidXp = new BTF_FluidTank(64000);
+ private boolean mConvertToEssence = true;
+
+ public TileEntityXpConverter() {
+ super (4, 32000);
+ }
+
+ private void changeMode(){
+ if (this.mConvertToEssence){
+ this.mConvertToEssence = false;
+ return;
+ }
+ else {
+ this.mConvertToEssence = true;
+ return;
+ }
+ }
+
+ public float getAdjustedVolume() {
+ if (this.mConvertToEssence){
+ if ((this.tankLiquidXp.getFluid() != null) && (this.tankLiquidXp.getFluidAmount() >= 100) && (this.tankEssence.getFluidAmount() <= (this.tankEssence.getCapacity()-(100*EnchantingUtils.RATIO_MOB_ESSENCE_TO_LIQUID_XP)))){
+ final FluidStack bigStorage = EnchantingUtils.getEssenceFromLiquidXp(100);
+ this.tankEssence.fill(bigStorage, true);
+ this.tankLiquidXp.drain(100, true);
+ return (this.tankEssence.getCapacity()-this.tankEssence.getFluidAmount());
+ }
+ }
+ else {
+ final double rm = EnchantingUtils.RATIO_MOB_ESSENCE_TO_LIQUID_XP;
+ if ((this.tankEssence.getFluid() != null) && (this.tankEssence.getFluidAmount() >= rm) && (this.tankLiquidXp.getFluidAmount() <= (this.tankLiquidXp.getCapacity()-rm))){
+ final FluidStack bigStorage = EnchantingUtils.getLiquidXP(1);
+ this.tankLiquidXp.fill(bigStorage, true);
+ this.tankEssence.drain((int) rm, true);
+ return (this.tankLiquidXp.getCapacity()-this.tankLiquidXp.getFluidAmount());
+ }
+ }
+ return 0f;
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound tag) {
+ this.tankEssence.readFromNBT(tag);
+ this.tankLiquidXp.readFromNBT(tag);
+ this.mConvertToEssence = tag.getBoolean("mConvertToEssence");
+ super.readFromNBT(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound tag) {
+ this.tankEssence.writeToNBT(tag);
+ this.tankLiquidXp.writeToNBT(tag);
+ tag.setBoolean("mConvertToEssence", this.mConvertToEssence);
+ super.writeToNBT(tag);
+ }
+
+ @Override
+ public Packet getDescriptionPacket() {
+ final NBTTagCompound tag = new NBTTagCompound();
+ this.writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public void onDataPacket(final NetworkManager net, final S35PacketUpdateTileEntity pkt) {
+ final NBTTagCompound tag = pkt.func_148857_g();
+ this.readFromNBT(tag);
+ }
+
+ public void onScrewdriverRightClick(final byte aSide, final EntityPlayer aPlayer, final float aX, final float aY, final float aZ) {
+ if (this.isServerSide()){
+ if (this.mConvertToEssence){
+ PlayerUtils.messagePlayer(aPlayer, "Converting from Mob Essence to Liquid Xp.");
+ }
+ else {
+ PlayerUtils.messagePlayer(aPlayer, "Converting from Liquid Xp to Mob Essence.");
+ }
+ //Mode Change
+ this.changeMode();
+ }
+ }
+
+ public void onRightClick(final byte aSide, final EntityPlayer aPlayer, final int aX, final int aY, final int aZ) {
+ if ((Keyboard.isKeyDown(42)) || (Keyboard.isKeyDown(54))) {
+ String mInput;
+ String mOutput;
+
+ if (this.mConvertToEssence){
+ mInput = "Liquid Xp";
+ mOutput = "Mob Essence";
+ }
+ else {
+ mInput = "Mob Essence";
+ mOutput = "Liquid Xp";
+ }
+
+ PlayerUtils.messagePlayer(aPlayer, "Input: "+mInput+".");
+ PlayerUtils.messagePlayer(aPlayer, "Output: "+mOutput+".");
+ }
+ }
+
+ @Override
+ public boolean onPreTick(long aTick) {
+ boolean aSuperResult = super.onPreTick(aTick);
+ long aTankSpaceLeft = 0;
+ double aAmount = 0;
+ int aRuns = 0;
+ if (this.mConvertToEssence) {
+ aTankSpaceLeft = (this.tankEssence.getCapacity()-this.tankEssence.getFluidAmount());
+ aAmount = EnchantingUtils.getEssenceFromLiquidXp(100).amount;
+ }
+ else {
+ aTankSpaceLeft = (this.tankLiquidXp.getCapacity()-this.tankLiquidXp.getFluidAmount());
+ aAmount = EnchantingUtils.RATIO_MOB_ESSENCE_TO_LIQUID_XP;
+ }
+ aRuns = (int) (aTankSpaceLeft / aAmount);
+ for (int i=0;i<aRuns;i++) {
+ if (getAdjustedVolume() == 0) {
+ break;
+ }
+ }
+ return aSuperResult;
+ }
+
+ @Override
+ public boolean isLiquidInput(byte aSide) {
+ if (mConvertToEssence) {
+ if (aSide == 0 || aSide == 1) {
+ return false;
+ }
+ } else {
+ if (aSide == 0 || aSide == 1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isLiquidOutput(byte aSide) {
+ if (mConvertToEssence) {
+ if (aSide == 0 || aSide == 1) {
+ return true;
+ }
+ } else {
+ if (aSide == 0 || aSide == 1) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int fill(ForgeDirection aSide, FluidStack aFluid, boolean doFill) {
+ if (mConvertToEssence) {
+ if (aSide != ForgeDirection.UP && aSide != ForgeDirection.DOWN) {
+ return this.tankLiquidXp.fill(aFluid, doFill);
+ }
+ } else {
+ if (aSide == ForgeDirection.UP || aSide == ForgeDirection.DOWN) {
+ return this.tankEssence.fill(aFluid, doFill);
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, int maxDrain, boolean doDrain) {
+ if (mConvertToEssence) {
+ if (aSide == ForgeDirection.UP || aSide == ForgeDirection.DOWN) {
+ return this.tankEssence.drain(maxDrain, doDrain);
+ }
+ } else {
+ if (aSide != ForgeDirection.UP && aSide != ForgeDirection.DOWN) {
+ return this.tankLiquidXp.drain(maxDrain, doDrain);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection aSide, FluidStack aFluid, boolean doDrain) {
+ if (mConvertToEssence) {
+ if (aSide == ForgeDirection.UP || aSide == ForgeDirection.DOWN) {
+ return this.tankEssence.drain(aFluid, doDrain);
+ }
+ } else {
+ if (aSide != ForgeDirection.UP && aSide != ForgeDirection.DOWN) {
+ return this.tankLiquidXp.drain(aFluid, doDrain);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection aSide, Fluid aFluid) {
+ if (mConvertToEssence) {
+ if (aSide != ForgeDirection.UP && aSide != ForgeDirection.DOWN) {
+ return this.tankLiquidXp.canTankBeFilled();
+ }
+ } else {
+ if (aSide == ForgeDirection.UP || aSide == ForgeDirection.DOWN) {
+ return this.tankEssence.canTankBeFilled();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection aSide, Fluid aFluid) {
+ if (mConvertToEssence) {
+ if (aSide == ForgeDirection.UP || aSide == ForgeDirection.DOWN) {
+ return this.tankEssence.canTankBeEmptied();
+ }
+ } else {
+ if (aSide != ForgeDirection.UP && aSide != ForgeDirection.DOWN) {
+ return this.tankLiquidXp.canTankBeEmptied();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection aSide) {
+ if (aSide == ForgeDirection.UP || aSide == ForgeDirection.DOWN) {
+ return new FluidTankInfo[] { this.tankEssence.getInfo() };
+ } else {
+ return new FluidTankInfo[] { this.tankLiquidXp.getInfo() };
+
+ }
+ }
+
+ @Override
+ public FluidStack getFluid() {
+ if (mConvertToEssence) {
+ return this.tankEssence.getFluid();
+ }
+ else {
+ return this.tankLiquidXp.getFluid();
+ }
+ }
+
+ @Override
+ public int getFluidAmount() {
+ if (mConvertToEssence) {
+ return this.tankEssence.getFluidAmount();
+ }
+ else {
+ return this.tankLiquidXp.getFluidAmount();
+ }
+ }
+
+ @Override
+ public FluidTankInfo getInfo() {
+ if (mConvertToEssence) {
+ return this.tankEssence.getInfo();
+ } else {
+ return this.tankLiquidXp.getInfo();
+ }
+ }
+
+ @Override
+ public int fill(FluidStack resource, boolean doFill) {
+ if (mConvertToEssence) {
+ return this.tankEssence.fill(resource, doFill);
+ } else {
+ return this.tankLiquidXp.fill(resource, doFill);
+ }
+ }
+
+ @Override
+ public FluidStack drain(int maxDrain, boolean doDrain) {
+ if (mConvertToEssence) {
+ return this.tankEssence.drain(maxDrain, doDrain);
+ } else {
+ return this.tankLiquidXp.drain(maxDrain, doDrain);
+ }
+ }
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/general/redstone/TileEntityRedstoneHandler.java b/src/main/java/gtPlusPlus/core/tileentities/general/redstone/TileEntityRedstoneHandler.java
new file mode 100644
index 0000000000..eda0c65e46
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/general/redstone/TileEntityRedstoneHandler.java
@@ -0,0 +1,468 @@
+package gtPlusPlus.core.tileentities.general.redstone;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import gtPlusPlus.api.interfaces.IToolable;
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.api.objects.minecraft.BlockPos;
+import gtPlusPlus.core.util.Utils;
+import gtPlusPlus.core.util.minecraft.EntityUtils;
+import net.minecraft.block.Block;
+import net.minecraft.init.Blocks;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.IIcon;
+import net.minecraft.world.EnumSkyBlock;
+import net.minecraft.world.IBlockAccess;
+
+public abstract class TileEntityRedstoneHandler extends TileEntity implements IToolable {
+
+ private final int mTileType;
+ private BlockPos mTilePos;
+ private boolean mRequiresUpdate = false;
+ private Long mStartTime;
+ private Byte mRedstoneLevel;
+
+ public boolean mLightMode = false;
+ public float mLightValue = 0;
+
+ /**
+ * Sets the Redstone Handler Type.
+ * @param aTileType - A type of the handler designated by an int. 0 = receiver, 1 = emitter, 2 = both, anything else = nothing.
+ */
+ public TileEntityRedstoneHandler(int aTileType) {
+ mTileType = aTileType;
+ registerTileEntity();
+ }
+
+ private void registerTileEntity() {
+ if (!EntityUtils.isTileEntityRegistered(getTileEntityClass(), getTileEntityNameForRegistration())) {
+ GameRegistry.registerTileEntity(getTileEntityClass(), getTileEntityNameForRegistration());
+ }
+ }
+
+ protected abstract Class<? extends TileEntity> getTileEntityClass();
+
+ protected abstract String getTileEntityNameForRegistration();
+
+ public Block getBlock() {
+ return mTilePos != null ? mTilePos.getBlockAtPos() : Blocks.redstone_block;
+ }
+
+ public final boolean isLight() {
+ return mLightMode;
+ }
+
+ public final float getLightBrightness() {
+ if (!isLight()) {
+ return 0;
+ }
+ else {
+ return mLightValue;
+ }
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound aNBT) {
+ mStartTime = aNBT.getLong("mStartTime");
+ mInvName = aNBT.getString("mInvName");
+ mLightValue = aNBT.getFloat("mLightValue");
+ mLightMode = aNBT.getBoolean("mLightMode");
+ mRedstoneLevel = aNBT.getByte("mRedstoneLevel");
+ super.readFromNBT(aNBT);
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound aNBT) {
+ aNBT.setInteger("mTileType", mTileType);
+ aNBT.setLong("mStartTime", mStartTime);
+ aNBT.setString("mInvName", mInvName);
+ aNBT.setFloat("mLightValue", getLightBrightness());
+ aNBT.setBoolean("mLightMode", isLight());
+ aNBT.setByte("mRedstoneLevel", mRedstoneLevel);
+ super.writeToNBT(aNBT);
+ }
+
+
+ private boolean mHasUpdatedRecently = false;
+
+ private final boolean init() {
+ if (mTilePos == null) {
+ try {
+ mTilePos = new BlockPos(this);
+ } catch (Throwable t) {
+ return false;
+ }
+ }
+ if (mStartTime == null) {
+ try {
+ mStartTime = System.currentTimeMillis();
+ } catch (Throwable t) {
+ return false;
+ }
+ }
+ return true;
+ }
+ private Long mLastUpdate;
+ private String mInvName = "";
+
+ @Override
+ public void updateEntity() {
+ //Handle init
+ if (!init()) {
+ return;
+ }
+ if (mRequiresUpdate || mLastUpdate == null) {
+ mRequiresUpdate = false;
+ mHasUpdatedRecently = true;
+ mLastUpdate = System.currentTimeMillis();
+ if (mTilePos.world.getBlockLightValue(xCoord, yCoord, zCoord) != getLightBrightness()/0.0625f) {
+ mTilePos.getBlockAtPos().setLightLevel(getLightBrightness()/0.0625f);
+ mTilePos.world.setLightValue(EnumSkyBlock.Block, xCoord, yCoord, zCoord, (int) (getLightBrightness()/0.0625f));
+ mTilePos.world.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord);
+ Logger.INFO("Updating Light");
+ }
+ mTilePos.world.scheduleBlockUpdate(xCoord, yCoord, zCoord, mTilePos.getBlockAtPos(), 1);
+ markDirty();
+ }
+ if (Utils.getMillisSince(mLastUpdate, System.currentTimeMillis()) >= 5000) {
+ if (mHasUpdatedRecently) {
+ mHasUpdatedRecently = false;
+ this.markForUpdate();
+ }
+ }
+
+ if (Utils.getMillisSince(mStartTime, System.currentTimeMillis()) % 50 == 0) {
+
+ }
+
+
+
+ super.updateEntity();
+ }
+
+ public final void markForUpdate() {
+ mRequiresUpdate = true;
+ }
+
+ public final boolean hasUpdatedRecently() {
+ return mHasUpdatedRecently;
+ }
+
+ @Override
+ public int getBlockMetadata() {
+ return super.getBlockMetadata();
+ }
+
+ @Override
+ public void markDirty() {
+ super.markDirty();
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return true;
+ }
+
+ public void setRedstoneState(boolean aRedstoneActive) {
+
+ }
+
+ public void setCurrentTextureArray(IIcon[] aTextures) {
+
+ }
+
+ /**
+ * Used to see if one of the blocks next to you or your block is getting power from a neighboring block. Used by
+ * items like TNT or Doors so they don't have redstone going straight into them. Args: x, y, z
+ */
+ public boolean isGettingIndirectlyPowered() {
+ if (mTilePos == null) {
+ return false;
+ }
+ return mTilePos.world.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
+ }
+
+ public int getStrongestIndirectPower() {
+ if (mTilePos == null) {
+ return 0;
+ }
+ return mTilePos.world.getStrongestIndirectPower(xCoord, yCoord, zCoord);
+ }
+
+ /**
+ * Gets the power level from a certain block face. Args: x, y, z, direction
+ */
+ public int getIndirectPowerForSide(int aSide) {
+ if (mTilePos == null || aSide <0 || aSide > 5) {
+ return 0;
+ }
+ return mTilePos.world.getIndirectPowerLevelTo(xCoord, yCoord, zCoord, aSide);
+ }
+
+ /**
+ * Returns the highest redstone signal strength powering the given block. Args: X, Y, Z.
+ */
+ public int getBlockPowerInput() {
+ if (mTilePos == null) {
+ return 0;
+ }
+ return mTilePos.world.getBlockPowerInput(xCoord, yCoord, zCoord);
+ }
+
+ /**
+ * Determine if this block can make a redstone connection on the side provided,
+ * Useful to control which sides are inputs and outputs for redstone wires.
+ *
+ * Side:
+ * -1: UP
+ * 0: NORTH
+ * 1: EAST
+ * 2: SOUTH
+ * 3: WEST
+ *
+ * @param world The current world
+ * @param x X Position
+ * @param y Y Position
+ * @param z Z Position
+ * @param side The side that is trying to make the connection
+ * @return True to make the connection
+ */
+ public boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int side) {
+ if (mTilePos == null) {
+ return false;
+ }
+ return canAcceptRedstoneSignal() || canSupplyRedstoneSignal();
+ }
+
+ /**
+ * Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules.
+ * @param world The world
+ * @param x The x position of this block instance
+ * @param y The y position of this block instance
+ * @param z The z position of this block instance
+ * @param side The INPUT side of the block to be powered - ie the opposite of this block's output side
+ * @return Whether Block#isProvidingWeakPower should be called when determining indirect power
+ */
+ public boolean shouldCheckWeakPower(IBlockAccess world, int x, int y, int z, int side) {
+ if (mTilePos == null) {
+ return false;
+ }
+ return getBlock().isNormalCube();
+ }
+
+ /**
+ * If this block should be notified of weak changes.
+ * Weak changes are changes 1 block away through a solid block.
+ * Similar to comparators.
+ *
+ * @param world The current world
+ * @param x X Position
+ * @param y Y position
+ * @param z Z position
+ * @param side The side to check
+ * @return true To be notified of changes
+ */
+ public boolean getWeakChanges(IBlockAccess world, int x, int y, int z) {
+ if (mTilePos == null) {
+ return false;
+ }
+ return false;
+ }
+
+
+ /**
+ * Override this to change the level of redstone output.
+ * @return
+ */
+ public int getRedstoneLevel() {
+ if (mTilePos == null || mRedstoneLevel == null) {
+ return 0;
+ }
+ else {
+ if (canSupplyRedstoneSignal()) {
+ if (this.hasUpdatedRecently()) {
+ int aInputPower = getInputPowerLevel();
+ mRedstoneLevel = (byte) ((aInputPower >= 0 && aInputPower <= 127) ? aInputPower : 0);
+ }
+ return mRedstoneLevel;
+ }
+ }
+ return 0;
+ }
+
+
+ public boolean providesWeakPower() {
+ return isProvidingPower();
+ }
+
+ public boolean providesStrongPower() {
+ return isProvidingPower();
+ }
+
+
+ /**
+ * Returns the amount of week power this block is providing to a side.
+ * @param world
+ * @param x
+ * @param y
+ * @param z
+ * @param side
+ * @return
+ */
+ public int isProvidingWeakPower(IBlockAccess world, int x, int y, int z, int side) {
+ if (!providesWeakPower()) {
+ return 0;
+ }
+ return getOutputPowerLevel();
+ }
+ /**
+ * Returns the amount of strong power this block is providing to a side.
+ * @param world
+ * @param x
+ * @param y
+ * @param z
+ * @param side
+ * @return
+ */
+ public int isProvidingStrongPower(IBlockAccess world, int x, int y, int z, int side) {
+ if (!providesStrongPower()) {
+ return 0;
+ }
+ return getOutputPowerLevel();
+ }
+
+
+
+
+
+
+
+ /*
+ * Alk's Simplified Redstone Handling functions (Fuck redstone)
+ */
+
+ /**
+ *
+ * @return - Does this Block supply redstone signal at all?
+ */
+ public final boolean isPowered() {
+ return canAcceptRedstoneSignal() && getInputPowerLevel() > 0;
+ }
+
+ /**
+ *
+ * @return - Can this Block provide redstone signal at all?
+ */
+ public final boolean isProvidingPower() {
+ return canSupplyRedstoneSignal() && getOutputPowerLevel() > 0;
+ }
+
+ /**
+ *
+ * @return - (0-15) Redstone Output signal level
+ */
+ public final int getOutputPowerLevel() {
+ return getRedstoneLevel();
+ }
+
+ /**
+ *
+ * @return (0-15) Redstone Input Signal level
+ */
+ public final int getInputPowerLevel() {
+ return getBlockPowerInput();
+ }
+
+ /**
+ *
+ * @return - Does this Tile Entity support outputting redstone?
+ */
+ public final boolean canSupplyRedstoneSignal() {
+ return mTileType == 1 || mTileType == 2;
+ }
+
+ /**
+ *
+ * @return - Does this Tile Entity support inputting redstone?
+ */
+ public final boolean canAcceptRedstoneSignal() {
+ return mTileType == 0 || mTileType == 2;
+ }
+
+
+ @Override
+ public boolean isScrewdriverable() {
+ return false;
+ }
+
+
+ @Override
+ public boolean onScrewdriverLMB() {
+ return false;
+ }
+
+
+ @Override
+ public boolean onScrewdriverRMB() {
+ return false;
+ }
+
+
+ @Override
+ public boolean isWrenchable() {
+ return false;
+ }
+
+
+ @Override
+ public boolean onWrenchLMB() {
+ return false;
+ }
+
+
+ @Override
+ public boolean onWrenchRMB() {
+ return false;
+ }
+
+
+ @Override
+ public boolean isMalletable() {
+ return false;
+ }
+
+
+ @Override
+ public boolean onMalletLMB() {
+ return false;
+ }
+
+
+ @Override
+ public boolean onMalletRMB() {
+ return false;
+ }
+
+
+ public void setCustomName(String displayName) {
+ this.mInvName = displayName;
+ }
+
+ public String getCustomName() {
+ return this.mInvName;
+ }
+
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.mInvName : "container.redstone.generic";
+ }
+
+ public boolean hasCustomInventoryName() {
+ return (this.mInvName != null) && !this.mInvName.equals("");
+ }
+
+
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityAdvPooCollector.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityAdvPooCollector.java
new file mode 100644
index 0000000000..6bb4c932dc
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityAdvPooCollector.java
@@ -0,0 +1,155 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.core.item.chemistry.AgriculturalChem;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.passive.EntityAnimal;
+import net.minecraft.entity.passive.EntityChicken;
+import net.minecraft.entity.passive.EntityCow;
+import net.minecraft.entity.passive.EntityHorse;
+import net.minecraft.entity.passive.EntityMooshroom;
+import net.minecraft.entity.passive.EntitySheep;
+import net.minecraft.entity.passive.EntityVillager;
+import net.minecraft.entity.passive.IAnimals;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+
+public class TileEntityAdvPooCollector extends TileEntityBaseFluidCollector {
+
+ public TileEntityAdvPooCollector() {
+ super(18, 128000);
+ }
+
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid) {
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid) {
+ return true;
+ }
+
+ public void onPreLogicTick() {
+
+ }
+
+ public <V> boolean addDrop(V aPooMaker) {
+ int aChance = MathUtils.randInt(0, 50000);
+ if (aChance > 0) {
+ ItemStack aPoop;
+ if (aChance<= 200) {
+ aPoop = ItemUtils.getItemStackOfAmountFromOreDict("dustManureByproducts", 1);
+ }
+ else if (aChance <= 1000) {
+ aPoop = ItemUtils.getItemStackOfAmountFromOreDict("dustSmallManureByproducts", 1);
+ }
+ else if (aChance <= 2000) {
+ aPoop = ItemUtils.getItemStackOfAmountFromOreDict("dustTinyManureByproducts", 1);
+ }
+ else {
+ return false;
+ }
+
+ //Add to inventory if not full, else espawn in world
+ if (!this.mInventory.addItemStack(aPoop)) {
+ EntityItem entity = new EntityItem(worldObj, xCoord, yCoord+1.5, zCoord, aPoop);
+ worldObj.spawnEntityInWorld(entity);
+ }
+
+ }
+
+
+ return false;
+ }
+
+ private static AutoMap<Class> aEntityToDrain = new AutoMap<Class>();
+
+ @Override
+ public AutoMap<Class> aThingsToLookFor() {
+ if (aEntityToDrain.isEmpty()) {
+ aEntityToDrain.add(EntityAnimal.class);
+ aEntityToDrain.add(IAnimals.class);
+ aEntityToDrain.add(EntityVillager.class);
+ aEntityToDrain.add(EntityPlayer.class);
+ }
+ return aEntityToDrain;
+ }
+
+ @Override
+ public <V> int onPostTick(V aPooMaker) {
+ if (this.tank.getFluidAmount() < this.tank.getCapacity()) {
+ int aPooAmount = 0;
+ // Vanilla Animals
+ if (aPooMaker instanceof EntityChicken) {
+ aPooAmount = MathUtils.randInt(1, 40);
+ }
+ else if (aPooMaker instanceof EntityHorse) {
+ aPooAmount = MathUtils.randInt(20, 40);
+ }
+ else if (aPooMaker instanceof EntityCow) {
+ aPooAmount = MathUtils.randInt(18, 45);
+ }
+ else if (aPooMaker instanceof EntityMooshroom) {
+ aPooAmount = 17;
+ }
+ else if (aPooMaker instanceof EntitySheep) {
+ aPooAmount = MathUtils.randInt(8, 30);
+ }
+
+ else {
+ if (aPooMaker instanceof EntityAnimal || aPooMaker instanceof IAnimals) {
+ aPooAmount = MathUtils.randInt(5, 35);
+ }
+ else if (aPooMaker instanceof EntityVillager) {
+ aPooAmount = MathUtils.randInt(25, 30);
+ }
+ else if (aPooMaker instanceof EntityPlayer) {
+ aPooAmount = MathUtils.randInt(1, 3);
+ }
+ else {
+ aPooAmount = MathUtils.randInt(1, 10);
+ }
+ }
+ aPooAmount = Math.max(Math.min(this.tank.getCapacity()-this.tank.getFluidAmount(), aPooAmount), 1);
+ return Math.max(1, (aPooAmount * MathUtils.getRandomFromArray(new int[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4}) / 10));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ @Override
+ public Fluid fluidToProvide() {
+ return AgriculturalChem.PoopJuice;
+ }
+
+ @Override
+ public ItemStack itemToSpawnInWorldIfTankIsFull() {
+ int a = MathUtils.randInt(0, 75);
+ ItemStack aItem = null;
+ if (a <= 30) {
+ aItem = ItemUtils.getSimpleStack(AgriculturalChem.dustDirt);
+ }
+ else if (a <= 40) {
+ aItem = ItemUtils.getItemStackOfAmountFromOreDict("dustManureByproducts", 1);
+ }
+ else if (a <= 55) {
+ aItem = ItemUtils.getItemStackOfAmountFromOreDict("dustSmallManureByproducts", 1);
+ }
+ return aItem;
+ }
+
+ public int getBaseTickRate() {
+ return MathUtils.randInt(50, 200);
+ }
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityBaseFluidCollector.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityBaseFluidCollector.java
new file mode 100644
index 0000000000..cdae4cf829
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityBaseFluidCollector.java
@@ -0,0 +1,238 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.List;
+
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.api.objects.minecraft.BTF_FluidTank;
+import gtPlusPlus.api.objects.minecraft.BlockPos;
+import gtPlusPlus.core.tileentities.base.TileEntityBase;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.FluidUtils;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidEvent;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+
+public abstract class TileEntityBaseFluidCollector extends TileEntityBase implements IFluidHandler {
+
+ public final FluidTank tank;
+ private boolean needsUpdate = false;
+ private int updateTimer = 0;
+ private long internalTickCounter = 0;
+ private BlockPos internalBlockLocation;
+
+ public TileEntityBaseFluidCollector(int aInvSlotCount, int aTankCapcity) {
+ super(aInvSlotCount);
+ tank = new BTF_FluidTank(aTankCapcity);
+ }
+
+ @Override
+ public final int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
+ needsUpdate = true;
+ return this.tank.fill(resource, doFill);
+ }
+
+ @Override
+ public final FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
+ needsUpdate = true;
+ return this.tank.drain(resource.amount, doDrain);
+ }
+
+ @Override
+ public final FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
+ needsUpdate = true;
+ FluidStack fluid = this.tank.getFluid();
+ // return this.tank.drain(maxDrain, doDrain);
+ if (fluid == null) {
+ return null;
+ }
+
+ int drained = maxDrain;
+ if (fluid.amount < drained) {
+ drained = fluid.amount;
+ }
+
+ FluidStack stack = new FluidStack(fluid, drained);
+ if (doDrain) {
+ fluid.amount -= drained;
+ if (fluid.amount <= 0) {
+ fluid = null;
+ }
+
+ if (this != null) {
+ FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(fluid, this.getWorldObj(), this.xCoord,
+ this.yCoord, this.zCoord, this.tank, 0));
+ }
+ }
+ return stack;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid) {
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid) {
+ return true;
+ }
+
+ @Override
+ public final FluidTankInfo[] getTankInfo(ForgeDirection from) {
+ return new FluidTankInfo[] { this.tank.getInfo() };
+ }
+
+ @Override
+ public final void updateEntity() {
+ super.updateEntity();
+ onPreLogicTick();
+ logicTick();
+ if (needsUpdate) {
+ if (updateTimer == 0) {
+ updateTimer = 10; // every 10 ticks it will send an update
+ } else {
+ --updateTimer;
+ if (updateTimer == 0) {
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ needsUpdate = false;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound tag) {
+ tank.readFromNBT(tag);
+ super.readFromNBT(tag);
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound tag) {
+ tank.writeToNBT(tag);
+ super.writeToNBT(tag);
+ }
+
+ @Override
+ public final Packet getDescriptionPacket() {
+ NBTTagCompound tag = new NBTTagCompound();
+ writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public final void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
+ NBTTagCompound tag = pkt.func_148857_g();
+ readFromNBT(tag);
+ }
+
+ public int getBaseTickRate() {
+ return MathUtils.randInt(200, 300);
+ }
+
+ public abstract AutoMap<Class> aThingsToLookFor();
+
+ public abstract void onPreLogicTick();
+
+ public final void logicTick() {
+
+ if (this.worldObj == null || this.worldObj.isRemote) {
+ return;
+ }
+ if (internalTickCounter % getBaseTickRate() == 0) {
+ if (internalBlockLocation == null) {
+ internalBlockLocation = new BlockPos(this);
+ }
+ BlockPos p = internalBlockLocation;
+ if (p != null) {
+ if (p.world != null) {
+ World w = this.worldObj;
+ if (w == null) {
+ return;
+ }
+ Chunk c = w.getChunkFromBlockCoords(p.xPos, p.zPos);
+ if (c != null) {
+ if (c.isChunkLoaded) {
+ int startX = p.xPos - 2;
+ int startY = p.yPos;
+ int startZ = p.zPos - 2;
+ int endX = p.xPos + 3;
+ int endY = p.yPos + 5;
+ int endZ = p.zPos + 3;
+ AxisAlignedBB box = AxisAlignedBB.getBoundingBox(startX, startY, startZ, endX, endY, endZ);
+ if (box != null) {
+ for (Class c2 : aThingsToLookFor()) {
+ tickEntityType(w, box, c2);
+ }
+ } else {
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ internalTickCounter++;
+ }
+
+ @SuppressWarnings("unchecked")
+ public final void tickEntityType(World w, AxisAlignedBB box, Class aClassToFind) {
+ List<?> entities = w.getEntitiesWithinAABB(aClassToFind, box);
+ if (entities != null && !entities.isEmpty()) {
+ interactWithEntities(entities);
+ }
+ }
+
+ public final <V> void interactWithEntities(List<V> entities) {
+ for (V aEntity : entities) {
+ addDrop(aEntity);
+ if (this.tank.getFluidAmount() < this.tank.getCapacity()) {
+ int aFluidAmount = onPostTick(aEntity);
+ aFluidAmount = Math.max(Math.min(this.tank.getCapacity()-this.tank.getFluidAmount(), aFluidAmount), 1);
+ this.tank.fill(FluidUtils.getFluidStack(fluidToProvide(), aFluidAmount), true);
+ }
+ else {
+ ItemStack aDirtStack = ItemUtils.getSimpleStack(itemToSpawnInWorldIfTankIsFull(), 1);
+ if (!ItemUtils.checkForInvalidItems(aDirtStack)) {
+ return;
+ }
+ if (!this.mInventory.addItemStack(aDirtStack)) {
+ EntityItem entity = new EntityItem(worldObj, xCoord, yCoord+1.5, zCoord, aDirtStack);
+ worldObj.spawnEntityInWorld(entity);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Return the amount of fluid for this entity type
+ * @param aEntity
+ * @return
+ */
+ public abstract <V> int onPostTick(V aEntity);
+
+ public abstract <V> boolean addDrop(V aPooMaker);
+
+ public abstract Fluid fluidToProvide();
+
+ public abstract ItemStack itemToSpawnInWorldIfTankIsFull();
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityModularityTable.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityModularityTable.java
new file mode 100644
index 0000000000..8ba43bb197
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityModularityTable.java
@@ -0,0 +1,480 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+import gregtech.api.enums.ItemList;
+
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.api.objects.data.Pair;
+import gtPlusPlus.core.container.Container_ModularityTable;
+import gtPlusPlus.core.inventories.modulartable.InventoryModularMain;
+import gtPlusPlus.core.inventories.modulartable.InventoryModularOutput;
+import gtPlusPlus.core.item.bauble.ModularBauble;
+import gtPlusPlus.core.tileentities.base.TileEntityBase;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import gtPlusPlus.core.util.minecraft.ModularArmourUtils;
+import gtPlusPlus.core.util.minecraft.ModularArmourUtils.BT;
+import gtPlusPlus.core.util.minecraft.ModularArmourUtils.Modifiers;
+
+public class TileEntityModularityTable extends TileEntityBase implements ISidedInventory{
+
+ public InventoryModularMain inventoryGrid;
+ public InventoryModularOutput inventoryOutputs;
+ public InventoryModularOutput mTempRecipeStorage;
+ private Container_ModularityTable container;
+ private String customName;
+ private int mRecipeTimeRemaining = -1;
+
+ public TileEntityModularityTable() {
+ super(16);
+ this.inventoryGrid = new InventoryModularMain();
+ this.inventoryOutputs = new InventoryModularOutput();
+ this.mTempRecipeStorage = new InventoryModularOutput();
+ this.canUpdate();
+ generateAllValidUpgrades();
+ }
+
+ public void setContainer(Container_ModularityTable container_ModularityTable) {
+ this.container = container_ModularityTable;
+ }
+
+ public Container_ModularityTable getContainer() {
+ return this.container;
+ }
+
+ public int getRecipeTime(){
+ return this.mRecipeTimeRemaining;
+ }
+
+ @Override
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ nbt.setInteger("mRecipeTime", this.mRecipeTimeRemaining);
+ this.inventoryOutputs.writeToNBT(this.getTag(nbt, "ContentsOutput"));
+ this.inventoryGrid.writeToNBT(this.getTag(nbt, "ContentsGrid"));
+ this.mTempRecipeStorage.writeToNBT(this.getTag(nbt, "ContentsRecipeTemp"));
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ this.mRecipeTimeRemaining = nbt.getInteger("mRecipeTime");
+ this.inventoryOutputs.readFromNBT(nbt.getCompoundTag("ContentsOutput"));
+ this.inventoryGrid.readFromNBT(nbt.getCompoundTag("ContentsGrid"));
+ this.mTempRecipeStorage.readFromNBT(nbt.getCompoundTag("ContentsRecipeTemp"));
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ }
+
+ protected ItemStack mOutputStack; //Upgraded Bauble
+ protected ItemStack mInputstackA; //Bauble
+ protected ItemStack mInputstackB; //Upgrade
+
+ public ItemStack getPendingOutputItem(){
+ this.mRecipeTimeRemaining--;
+ return this.mOutputStack;
+ }
+
+ public ItemStack[] getCurrentInputItems(){
+ if (this.mRecipeTimeRemaining < 0){
+ return null;
+ }
+ else {
+ return new ItemStack[]{this.mInputstackA, this.mInputstackB};
+ }
+ }
+
+ public boolean setInputStacks(ItemStack tBauble, ItemStack tUpgrade){
+ if (tBauble != null){
+ this.mInputstackA = tBauble;
+ }
+ else {
+ this.mInputstackA = null;
+ }
+ if (tUpgrade != null){
+ this.mInputstackB = tBauble;
+ }
+ else {
+ this.mInputstackB = null;
+ }
+ if (this.mInputstackA != null && this.mInputstackB != null){
+ return true;
+ }
+ return false;
+ }
+
+ public boolean setOutputStack(ItemStack mNewBauble){
+ if (mNewBauble != null){
+ this.mOutputStack = mNewBauble;
+ return true;
+ }
+ else {
+ this.mOutputStack = null;
+ return false;
+ }
+ }
+
+ public boolean clearRecipeData(){
+ this.mInputstackA = null;
+ this.mInputstackB = null;
+ this.mOutputStack = null;
+ return true;
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return true;
+ }
+
+ public static Map<ItemStack, Pair<Modifiers, Integer>> mValidUpgradeList = new HashMap<ItemStack, Pair<Modifiers, Integer>>();
+ public static Map<ItemStack, BT> mValidUpgradeListFormChange = new HashMap<ItemStack, BT>();
+
+ private static boolean generateAllValidUpgrades() {
+
+ // Form Change
+ generateUpgradeFormData(ItemList.Sensor_MV.get(1), BT.TYPE_RING);
+ generateUpgradeFormData(ItemList.Electric_Piston_MV.get(1), BT.TYPE_BELT);
+ generateUpgradeFormData(ItemList.Emitter_MV.get(1), BT.TYPE_AMULET);
+
+ // Damage Boost
+ generateUpgradeData(ItemList.Electric_Motor_LV.get(1), Modifiers.BOOST_DAMAGE, 1);
+ generateUpgradeData(ItemList.Electric_Motor_MV.get(1), Modifiers.BOOST_DAMAGE, 2);
+ generateUpgradeData(ItemList.Electric_Motor_HV.get(1), Modifiers.BOOST_DAMAGE, 3);
+ generateUpgradeData(ItemList.Electric_Motor_EV.get(1), Modifiers.BOOST_DAMAGE, 4);
+ generateUpgradeData(ItemList.Electric_Motor_IV.get(1), Modifiers.BOOST_DAMAGE, 5);
+
+ // Defence Boost
+ generateUpgradeData(ItemUtils.getItemStackOfAmountFromOreDictNoBroken("plateAluminium", 1), Modifiers.BOOST_DEF, 1);
+ generateUpgradeData(ItemUtils.getItemStackOfAmountFromOreDictNoBroken("plateStainlessSteel", 1), Modifiers.BOOST_DEF, 2);
+ generateUpgradeData(ItemUtils.getItemStackOfAmountFromOreDictNoBroken("plateTungsten", 1), Modifiers.BOOST_DEF, 3);
+ generateUpgradeData(ItemUtils.getItemStackOfAmountFromOreDictNoBroken("plateTungstenSteel", 1), Modifiers.BOOST_DEF, 4);
+ generateUpgradeData(ItemUtils.getItemStackOfAmountFromOreDictNoBroken("plateNaquadah", 1), Modifiers.BOOST_DEF, 5);
+
+ // Hp Boost
+ generateUpgradeData(ItemUtils.simpleMetaStack(Items.golden_apple, 0, 1), Modifiers.BOOST_HP, 1);
+ generateUpgradeData(ItemUtils.simpleMetaStack(Items.golden_apple, 1, 1), Modifiers.BOOST_HP, 2);
+ generateUpgradeData(ItemUtils.simpleMetaStack(Items.nether_star, 0, 1), Modifiers.BOOST_HP, 3);
+ generateUpgradeData(ItemUtils.simpleMetaStack("gregtech:gt.metaitem.01:32725", 32725, 1), Modifiers.BOOST_HP,
+ 4);
+ generateUpgradeData(ItemUtils.simpleMetaStack("gregtech:gt.metaitem.01:32726", 32726, 1), Modifiers.BOOST_HP,
+ 5);
+
+ return true;
+ }
+
+ public static boolean generateUpgradeData(ItemStack tStack, Modifiers tMod, int tLevel) {
+ Pair<Modifiers, Integer> tTemp = new Pair<Modifiers, Integer>(tMod, tLevel);
+ if (mValidUpgradeList.put(tStack, tTemp) != null) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean generateUpgradeFormData(ItemStack tStack, BT tMod) {
+ if (mValidUpgradeListFormChange.put(tStack, tMod) != null) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean addUpgrade(ItemStack tStack, ItemStack tBauble) {
+
+ try {
+ Iterator<Entry<ItemStack, BT>> it = mValidUpgradeListFormChange.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<ItemStack, BT> pair = it.next();
+ if (pair.getKey().getItem() == tStack.getItem()
+ && pair.getKey().getItemDamage() == tStack.getItemDamage()) {
+ ModularArmourUtils.setBaubleType(tBauble, pair.getValue());
+ tBauble.setItemDamage(ModularArmourUtils.getBaubleTypeID(tBauble));
+ return true;
+ }
+ }
+ } catch (Throwable t) {
+
+ }
+ try {
+ Iterator<Entry<ItemStack, Pair<Modifiers, Integer>>> it2 = mValidUpgradeList.entrySet().iterator();
+ while (it2.hasNext()) {
+ Entry<ItemStack, Pair<Modifiers, Integer>> pair = it2.next();
+ if (pair.getKey().getItem() == tStack.getItem()
+ && pair.getKey().getItemDamage() == tStack.getItemDamage()) {
+ Pair<Modifiers, Integer> newPair = pair.getValue();
+ ModularArmourUtils.setModifierLevel(tBauble, newPair);
+ return true;
+ }
+ }
+ } catch (Throwable t) {
+
+ }
+ return false;
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return 11;
+ }
+
+ @Override
+ public ItemStack getStackInSlot(int slot) {
+ if (slot >= this.inventoryGrid.getSizeInventory()){
+ return this.inventoryOutputs.getStackInSlot(slot-9);
+ }
+ else if (slot < this.inventoryGrid.getSizeInventory()){
+ return this.inventoryGrid.getStackInSlot(slot);
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public ItemStack decrStackSize(int slot, int count) {
+ if (slot < this.inventoryGrid.getSizeInventory()){
+ return this.inventoryGrid.decrStackSize(slot, count);
+ }
+ else if (slot >= this.inventoryGrid.getSizeInventory()){
+ return this.inventoryOutputs.decrStackSize(slot-9, count);
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int slot) {
+ return this.getStackInSlot(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(int slot, ItemStack stack) {
+ if (slot >= this.inventoryGrid.getSizeInventory()){
+ this.inventoryOutputs.setInventorySlotContents(slot-9, stack);
+ }
+ else if (slot < this.inventoryGrid.getSizeInventory()){
+ this.inventoryGrid.setInventorySlotContents(slot, stack);
+ }
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return 64;
+ }
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer entityplayer) {
+ return true;
+ }
+
+ @Override
+ public void openInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.inventoryGrid.openInventory();
+ this.inventoryOutputs.openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.inventoryGrid.openInventory();
+ this.inventoryOutputs.openInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int slot, ItemStack itemstack) {
+ if (slot >= this.inventoryGrid.getSizeInventory()){
+ return this.inventoryOutputs.isItemValidForSlot(slot-9, itemstack);
+ }
+ else if (slot < this.inventoryGrid.getSizeInventory()){
+ return this.inventoryGrid.isItemValidForSlot(slot, itemstack);
+ }
+ else {
+ return false;
+ }
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int side) {
+ int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r=0; r<this.getSizeInventory(); r++){
+ accessibleSides[r]=r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(int slot, ItemStack item, int side) {
+ Logger.INFO("Slot:"+slot+" | side? "+side);
+
+ /*if (side == 1){
+ return this.inventoryOutputs.isItemValidForSlot(slot-9, item);
+ } */
+ if (slot >= 9){
+ return this.inventoryOutputs.isItemValidForSlot(slot-9, item);
+ }
+ else {
+ return this.inventoryGrid.isItemValidForSlot(slot, item);
+ }
+ }
+
+ @Override
+ public boolean canExtractItem(int slot, ItemStack item, int side) {
+ Logger.INFO("Slot:"+slot+" | side? "+side);
+ if (slot == 11 || slot <= 8){
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ @Override
+ public void setCustomName(String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.fishtrap";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return this.customName != null && !this.customName.equals("");
+ }
+
+ @Override
+ public boolean onPreTick(long aTick) {
+ //Check for active recipe
+ if (this.mRecipeTimeRemaining > -1 || (this.mTempRecipeStorage != null) && (this.mTempRecipeStorage.getRecipeTime() > -1)){
+ if ((this.mTempRecipeStorage != null) && this.mTempRecipeStorage.getRecipeTime() > -1){
+ if (this.mRecipeTimeRemaining < this.mTempRecipeStorage.getRecipeTime()){
+ this.mRecipeTimeRemaining = this.mTempRecipeStorage.getRecipeTime();
+ this.markDirty();
+ }
+ }
+ if (this.mInputstackA != null && this.mInputstackB != null && this.mOutputStack != null){
+ this.mTempRecipeStorage.setInventorySlotContents(0, this.mInputstackA);
+ this.mTempRecipeStorage.setInventorySlotContents(1, this.mInputstackB);
+ this.mTempRecipeStorage.setInventorySlotContents(2, this.mOutputStack);
+ this.mTempRecipeStorage.setRecipeTime(this.mRecipeTimeRemaining);
+ this.markDirty();
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onPostTick(long aTick) {
+ if (mRecipeTimeRemaining == 0){
+ this.inventoryOutputs.setInventorySlotContents(2, this.getPendingOutputItem());
+ clearRecipeData();
+ this.mTempRecipeStorage.setRecipeTime(this.mRecipeTimeRemaining);
+ this.markDirty();
+ }
+ else if (mRecipeTimeRemaining > 0){
+ mRecipeTimeRemaining--;
+ this.mTempRecipeStorage.setRecipeTime(this.mRecipeTimeRemaining);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean processRecipe() {
+ boolean removeInputA = false;
+ boolean removeInputB = false;
+ // Data stick
+ ItemStack tBauble = this.inventoryOutputs.getStackInSlot(0);
+ ItemStack tUpgrade = this.inventoryOutputs.getStackInSlot(1);
+ if (tBauble != null && tUpgrade != null && this.container != null) {
+ if (tBauble.getItem() instanceof ModularBauble && this.mRecipeTimeRemaining == -1) {
+ if (tUpgrade != null && tBauble != null) {
+ removeInputA = true;
+ this.setInputStacks(tBauble, tUpgrade);
+ try {
+ removeInputB = addUpgrade(tUpgrade, tBauble);
+ if (!removeInputB) {
+ }
+ } catch (Throwable t) {
+ }
+ if (removeInputA && removeInputB) {
+ if (this.setOutputStack(tBauble)){
+ if (this.inventoryOutputs.getStackInSlot(1).stackSize > 1) {
+ ItemStack mTempStack = this.inventoryOutputs.getStackInSlot(1);
+ mTempStack.stackSize--;
+ this.inventoryOutputs.setInventorySlotContents(1, mTempStack);
+ } else {
+ this.inventoryOutputs.setInventorySlotContents(1, null);
+ }
+ this.inventoryOutputs.setInventorySlotContents(0, null);
+ this.mRecipeTimeRemaining = 80;
+ this.markDirty();
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean isValidModularPiece(final ItemStack itemstack){
+ if (itemstack.getItem() instanceof ModularBauble){
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isValidUpgrade(final ItemStack itemstack) {
+ boolean isValid = false;
+ if (itemstack != null){
+ Iterator<Entry<ItemStack, BT>> it = mValidUpgradeListFormChange.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<ItemStack, BT> pair = it.next();
+ if (pair.getKey().getItem() == itemstack.getItem()
+ && pair.getKey().getItemDamage() == itemstack.getItemDamage()){
+ isValid = true;
+ }
+ }
+ Iterator<Entry<ItemStack, Pair<Modifiers, Integer>>> it2 = mValidUpgradeList.entrySet().iterator();
+ while (it2.hasNext()) {
+ Entry<ItemStack, Pair<Modifiers, Integer>> pair = it2.next();
+ if (pair.getKey().getItem() == itemstack.getItem()
+ && pair.getKey().getItemDamage() == itemstack.getItemDamage()){
+ isValid = true;
+ }
+ }
+ }
+ return isValid;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPestKiller.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPestKiller.java
new file mode 100644
index 0000000000..012c9f4ff5
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPestKiller.java
@@ -0,0 +1,506 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.api.objects.minecraft.BTF_FluidTank;
+import gtPlusPlus.core.inventories.InventoryPestKiller;
+import gtPlusPlus.core.lib.LoadedMods;
+import gtPlusPlus.core.material.MISC_MATERIALS;
+import gtPlusPlus.core.recipe.common.CI;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.EntityUtils;
+import gtPlusPlus.core.util.minecraft.FluidUtils;
+import gtPlusPlus.core.util.reflect.ReflectionUtils;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.passive.EntityBat;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+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.util.DamageSource;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidEvent;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import net.minecraftforge.oredict.OreDictionary;
+
+public class TileEntityPestKiller extends TileEntity implements ISidedInventory, IFluidHandler {
+
+ private final int mBaseTickRate = 20 * 30;
+ private final InventoryPestKiller mInventory;
+ private final FluidTank mTank;
+ private int mChunkX;
+ private int mChunkZ;
+ private boolean mSet = false;
+
+ private int mTickCounter = 0;
+ private int mUpdateTick = 0;
+ private boolean mNeedsUpdate = false;
+ private String mCustomName;
+
+ private static final AutoMap<Class<?>> mEntityMap = new AutoMap<Class<?>>();
+
+ static {
+ mEntityMap.put(EntityBat.class);
+ if (LoadedMods.Forestry) {
+ mEntityMap.put(ReflectionUtils.getClass("forestry.lepidopterology.entities.EntityButterfly"));
+ }
+ }
+
+ public TileEntityPestKiller() {
+ this.mInventory = new InventoryPestKiller();
+ mTank = new BTF_FluidTank(2000);
+ }
+
+ public InventoryPestKiller getInventory() {
+ return this.mInventory;
+ }
+
+ public FluidTank getTank() {
+ return mTank;
+ }
+
+ private final void setup() {
+ World w = this.worldObj;
+ if (w != null) {
+ Chunk c = w.getChunkFromBlockCoords(this.xCoord, this.zCoord);
+ if (c != null) {
+ mChunkX = c.xPosition;
+ mChunkZ = c.zPosition;
+ mSet = true;
+ }
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public boolean tryKillPests() {
+ int min = 0;
+ int max = 0;
+ switch (getTier()) {
+ case 1:
+ min = -2;
+ max = 3;
+ break;
+ case 2:
+ min = -4;
+ max = 5;
+ break;
+ default:
+ // code block
+ }
+ int aChunkCount = 0;
+ AutoMap<Entity> entities = new AutoMap<Entity>();
+ if (min != 0 && max != 0) {
+ for (int x = min; x < max; x++) {
+ for (int z = min; z < max; z++) {
+ Chunk c = getChunkFromOffsetIfLoaded(x, z);
+ if (c != null) {
+ if (c.hasEntities) {
+ aChunkCount++;
+ List[] lists = c.entityLists;
+ for (List o : lists) {
+ for (Object e : o) {
+ if (e instanceof Entity) {
+ for (Class<?> C : mEntityMap) {
+ if (e.getClass().equals(C) || C.isAssignableFrom(e.getClass())) {
+ entities.put((Entity) e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ Chunk c = getChunkFromOffsetIfLoaded(0, 0);
+ if (c != null) {
+ if (c.hasEntities) {
+ List[] lists = c.entityLists;
+ for (List o : lists) {
+ for (Object e : o) {
+ if (e instanceof Entity) {
+ for (Class<?> C : mEntityMap) {
+ if (e.getClass().equals(C) || C.isAssignableFrom(e.getClass())) {
+ entities.put((Entity) e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ boolean killed = false;
+ if (!entities.isEmpty()) {
+ for (Entity e : entities) {
+ if (e != null) {
+ if (e.isEntityAlive()) {
+ if (this.mTank.getFluidAmount() >= 1 || getTier() == 0) {
+ if (getTier() > 0) {
+ int aChanceToUse = MathUtils.randInt(1, (100 * getTier()));
+ if (aChanceToUse == 1) {
+ this.mTank.drain(1, true);
+ }
+ }
+ e.performHurtAnimation();
+ EntityUtils.doDamage(e, DamageSource.generic, Short.MAX_VALUE);
+ e.setDead();
+ killed = true;
+ }
+ }
+ }
+ }
+ }
+ updateTileEntity();
+ return killed;
+ }
+
+ public Chunk getChunkFromOffsetIfLoaded(int x, int y) {
+ Chunk c = this.worldObj.getChunkFromChunkCoords(mChunkX + x, mChunkZ + y);
+ if (c.isChunkLoaded) {
+ return c;
+ }
+ return null;
+ }
+
+ public int getTier() {
+ if (this.mTank != null) {
+ FluidStack f = mTank.getFluid();
+ if (f != null) {
+ if (f.isFluidEqual(FluidUtils.getWildcardFluidStack("formaldehyde", 1))) {
+ return 1;
+ } else if (f.isFluidEqual(MISC_MATERIALS.HYDROGEN_CYANIDE.getFluidStack(1))) {
+ return 2;
+ }
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public void updateEntity() {
+ if (worldObj.isRemote) {
+ return;
+ }
+ if (!mSet) {
+ setup();
+ }
+ this.mTickCounter++;
+ if (this.mTank != null) {
+ if (this.hasFluidSpace()) {
+ handleInventory();
+ }
+ }
+ if (this.mTickCounter % this.mBaseTickRate == 0) {
+ tryKillPests();
+ }
+ updateTick();
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ mTank.writeToNBT(nbt);
+ super.writeToNBT(nbt);
+ // Utils.LOG_MACHINE_INFO("Trying to write NBT data to TE.");
+ final NBTTagCompound chestData = new NBTTagCompound();
+ this.mInventory.writeToNBT(chestData);
+ nbt.setTag("ContentsChest", chestData);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ mTank.readFromNBT(nbt);
+ super.readFromNBT(nbt);
+ // Utils.LOG_MACHINE_INFO("Trying to read NBT data from TE.");
+ this.mInventory.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return this.getInventory().getSizeInventory();
+ }
+
+ @Override
+ public ItemStack getStackInSlot(final int slot) {
+ return this.getInventory().getStackInSlot(slot);
+ }
+
+ @Override
+ public ItemStack decrStackSize(final int slot, final int count) {
+ return this.getInventory().decrStackSize(slot, count);
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(final int slot) {
+ return this.getInventory().getStackInSlotOnClosing(slot);
+ }
+
+ @Override
+ public void setInventorySlotContents(final int slot, final ItemStack stack) {
+ this.getInventory().setInventorySlotContents(slot, stack);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return this.getInventory().getInventoryStackLimit();
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return this.getInventory().isItemValidForSlot(slot, itemstack);
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int p_94128_1_) {
+ final int[] accessibleSides = new int[this.getSizeInventory()];
+ for (int r = 0; r < this.getInventory().getSizeInventory(); r++) {
+ accessibleSides[r] = r;
+ }
+ return accessibleSides;
+
+ }
+
+ @Override
+ public boolean canInsertItem(final int aSlot, final ItemStack aStack, final int p_102007_3_) {
+ if (this.getInventory().getInventory()[0] == null) {
+ return true;
+ } else if (GT_Utility.areStacksEqual(aStack, this.getInventory().getInventory()[0])) {
+ if (this.getInventory().getInventory()[0].stackSize < 64) {
+ int diff = 64 - this.getInventory().getInventory()[0].stackSize;
+ if (aStack.stackSize <= diff) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canExtractItem(final int aSlot, final ItemStack aStack, final int p_102008_3_) {
+ if (this.getInventory().getInventory()[1] == null) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public String getCustomName() {
+ return this.mCustomName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.mCustomName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.mCustomName : "container.pestkiller";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.mCustomName != null) && !this.mCustomName.equals("");
+ }
+
+ @Override
+ public final int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
+ updateTileEntity();
+ return this.mTank.fill(resource, doFill);
+ }
+
+ @Override
+ public final FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
+ updateTileEntity();
+ return this.mTank.drain(resource.amount, doDrain);
+ }
+
+ @Override
+ public final FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
+ FluidStack fluid = this.mTank.getFluid();
+ // return this.tank.drain(maxDrain, doDrain);
+ if (fluid == null) {
+ return null;
+ }
+
+ int drained = maxDrain;
+ if (fluid.amount < drained) {
+ drained = fluid.amount;
+ }
+
+ FluidStack stack = new FluidStack(fluid, drained);
+ if (doDrain) {
+ fluid.amount -= drained;
+ if (fluid.amount <= 0) {
+ fluid = null;
+ }
+
+ if (this != null) {
+ FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(fluid, this.getWorldObj(), this.xCoord,
+ this.yCoord, this.zCoord, this.mTank, 0));
+ }
+ }
+ updateTileEntity();
+ return stack;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid) {
+ return mTank.getFluid() == null || mTank.getFluid().getFluid().equals(fluid);
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid) {
+ return false;
+ }
+
+ @Override
+ public final FluidTankInfo[] getTankInfo(ForgeDirection from) {
+ return new FluidTankInfo[] { this.mTank.getInfo() };
+ }
+
+ @Override
+ public final Packet getDescriptionPacket() {
+ NBTTagCompound tag = new NBTTagCompound();
+ writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public final void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
+ NBTTagCompound tag = pkt.func_148857_g();
+ readFromNBT(tag);
+ }
+
+
+ public boolean hasFluidSpace() {
+ if (this.mTank.getFluidAmount() <= 1000) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean drainCell() {
+ boolean didFill = false;
+ ItemStack aInput = this.getStackInSlot(0);
+ if (aInput == null) {
+ return false;
+ }
+ aInput = aInput.copy();
+ if (aInput != null && (this.getStackInSlot(1) == null || this.getStackInSlot(1).stackSize < 64)) {
+ ArrayList<ItemStack> t1Cells = OreDictionary.getOres("cellFormaldehyde");
+ ArrayList<ItemStack> t2Cells = OreDictionary.getOres("cellHydrogenCyanide");
+ didFill = addFluid(t1Cells, aInput, FluidUtils.getWildcardFluidStack("formaldehyde", 1000));
+ if (!didFill) {
+ didFill = addFluid(t2Cells, aInput, MISC_MATERIALS.HYDROGEN_CYANIDE.getFluidStack(1000));
+ }
+ }
+
+ return didFill;
+ }
+
+ public boolean handleInventory() {
+ if (this.getInventory() != null && drainCell()) {
+ this.decrStackSize(0, 1);
+ if (this.getStackInSlot(1) == null) {
+ this.setInventorySlotContents(1, CI.emptyCells(1));
+ } else {
+ this.getStackInSlot(1).stackSize++;
+ }
+ this.updateTileEntity();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean addFluid(ArrayList<ItemStack> inputs, ItemStack aInput, FluidStack aFluidForInput) {
+ for (ItemStack a : inputs) {
+ if (GT_Utility.areStacksEqual(a, aInput)) {
+ if (mTank.getFluid() == null || mTank.getFluid()
+ .isFluidEqual(aFluidForInput)) {
+ boolean didFill = fill(ForgeDirection.UNKNOWN, aFluidForInput, true) > 0;
+ return didFill;
+ }
+ } else {
+ continue;
+ }
+ }
+ return false;
+ }
+
+ public void updateTileEntity() {
+ this.getInventory().markDirty();
+ this.markDirty();
+ this.mNeedsUpdate = true;
+ }
+
+ private final void updateTick() {
+ if (mNeedsUpdate) {
+ if (mUpdateTick == 0) {
+ mUpdateTick = 4; // every 4 ticks it will send an update
+ } else {
+ --mUpdateTick;
+ if (mUpdateTick == 0) {
+ markDirty();
+ worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
+ mNeedsUpdate = false;
+ }
+ }
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPooCollector.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPooCollector.java
new file mode 100644
index 0000000000..25348a31f8
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPooCollector.java
@@ -0,0 +1,147 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import gtPlusPlus.api.objects.data.AutoMap;
+import gtPlusPlus.core.item.chemistry.AgriculturalChem;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.passive.EntityAnimal;
+import net.minecraft.entity.passive.EntityChicken;
+import net.minecraft.entity.passive.EntityCow;
+import net.minecraft.entity.passive.EntityHorse;
+import net.minecraft.entity.passive.EntityMooshroom;
+import net.minecraft.entity.passive.EntitySheep;
+import net.minecraft.entity.passive.IAnimals;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+
+public class TileEntityPooCollector extends TileEntityBaseFluidCollector {
+
+ public TileEntityPooCollector() {
+ super(9, 8000);
+ }
+
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid) {
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid) {
+ return true;
+ }
+
+ public void onPreLogicTick() {
+
+ }
+
+ public <V> boolean addDrop(V aPooMaker) {
+ int aChance = MathUtils.randInt(0, 50000);
+ if (aChance > 0) {
+ ItemStack aPoop;
+ if (aChance<= 100) {
+ aPoop = ItemUtils.getItemStackOfAmountFromOreDict("dustManureByproducts", 1);
+ }
+ else if (aChance <= 500) {
+ aPoop = ItemUtils.getItemStackOfAmountFromOreDict("dustSmallManureByproducts", 1);
+ }
+ else if (aChance <= 1250) {
+ aPoop = ItemUtils.getItemStackOfAmountFromOreDict("dustTinyManureByproducts", 1);
+ }
+ else {
+ return false;
+ }
+ if (!ItemUtils.checkForInvalidItems(aPoop)) {
+ return false;
+ }
+
+ //Add poop to world
+ //Logger.INFO("Adding animal waste for "+aPooMaker.getCommandSenderName());
+
+ //Add to inventory if not full, else espawn in world
+ if (!this.mInventory.addItemStack(aPoop)) {
+ EntityItem entity = new EntityItem(worldObj, xCoord, yCoord+1.5, zCoord, aPoop);
+ worldObj.spawnEntityInWorld(entity);
+ }
+
+ }
+
+
+ return false;
+ }
+
+ private static AutoMap<Class> aEntityToDrain = new AutoMap<Class>();
+
+ @Override
+ public AutoMap<Class> aThingsToLookFor() {
+ if (aEntityToDrain.isEmpty()) {
+ aEntityToDrain.add(EntityAnimal.class);
+ aEntityToDrain.add(IAnimals.class);
+ }
+ return aEntityToDrain;
+ }
+
+ @Override
+ public <V> int onPostTick(V aPooMaker) {
+ if (this.tank.getFluidAmount() < this.tank.getCapacity()) {
+ int aPooAmount = 0;
+ // Vanilla Animals
+ if (aPooMaker instanceof EntityChicken) {
+ aPooAmount = MathUtils.randInt(1, 40);
+ }
+ else if (aPooMaker instanceof EntityHorse) {
+ aPooAmount = MathUtils.randInt(20, 40);
+ }
+ else if (aPooMaker instanceof EntityCow) {
+ aPooAmount = MathUtils.randInt(18, 45);
+ }
+ else if (aPooMaker instanceof EntityMooshroom) {
+ aPooAmount = 17;
+ }
+ else if (aPooMaker instanceof EntitySheep) {
+ aPooAmount = MathUtils.randInt(8, 30);
+ }
+
+ else {
+ if (aPooMaker instanceof EntityAnimal || aPooMaker instanceof IAnimals) {
+ aPooAmount = MathUtils.randInt(5, 35);
+ }
+ else {
+ aPooAmount = MathUtils.randInt(1, 10);
+ }
+ }
+ aPooAmount = Math.max((Math.min(this.tank.getCapacity()-this.tank.getFluidAmount(), aPooAmount)/10), 1);
+ return aPooAmount;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ @Override
+ public Fluid fluidToProvide() {
+ return AgriculturalChem.PoopJuice;
+ }
+
+ @Override
+ public ItemStack itemToSpawnInWorldIfTankIsFull() {
+ int a = MathUtils.randInt(0, 100);
+ ItemStack aItem = null;
+ if (a <= 30) {
+ aItem = ItemUtils.getSimpleStack(AgriculturalChem.dustDirt);
+ }
+ else if (a <= 40) {
+ aItem = ItemUtils.getItemStackOfAmountFromOreDict("dustSmallManureByproducts", 1);
+ }
+ else if (a <= 55) {
+ aItem = ItemUtils.getItemStackOfAmountFromOreDict("dustTinyManureByproducts", 1);
+ }
+ return aItem;
+ }
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityProjectTable.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityProjectTable.java
new file mode 100644
index 0000000000..8c87baf6a9
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityProjectTable.java
@@ -0,0 +1,288 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.List;
+import java.util.Vector;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.InventoryCrafting;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+
+import gregtech.api.enums.ItemList;
+import gregtech.common.items.GT_MetaGenerated_Item_01;
+
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.container.Container_ProjectTable;
+import gtPlusPlus.core.inventories.projecttable.InventoryProjectMain;
+import gtPlusPlus.core.inventories.projecttable.InventoryProjectOutput;
+import gtPlusPlus.core.item.bauble.ModularBauble;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import gtPlusPlus.core.util.minecraft.ModularArmourUtils;
+import gtPlusPlus.core.util.minecraft.ModularArmourUtils.BT;
+import gtPlusPlus.core.util.minecraft.ModularArmourUtils.Modifiers;
+import gtPlusPlus.core.util.minecraft.NBTUtils;
+import gtPlusPlus.xmod.gregtech.api.enums.GregtechItemList;
+import gtPlusPlus.xmod.gregtech.common.items.MetaGeneratedGregtechItems;
+import ic2.api.network.INetworkDataProvider;
+import ic2.api.network.INetworkUpdateListener;
+import ic2.api.tile.IWrenchable;
+import ic2.core.IC2;
+
+public class TileEntityProjectTable extends TileEntity implements INetworkDataProvider, INetworkUpdateListener, IWrenchable{
+
+ public InventoryProjectMain inventoryGrid;
+ public InventoryProjectOutput inventoryOutputs;
+
+ /** The crafting matrix inventory (3x3). */
+ public InventoryCrafting craftMatrix;
+ public IInventory craftResult;
+ private Container_ProjectTable container;
+
+ public TileEntityProjectTable(){
+ this.inventoryGrid = new InventoryProjectMain();//number of slots - without product slot
+ this.inventoryOutputs = new InventoryProjectOutput();//number of slots - without product slot
+ this.canUpdate();
+ }
+
+ public void setContainer(Container_ProjectTable container){
+ this.container = container;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag){
+ if(!nbt.hasKey(tag))
+ {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt){
+ super.writeToNBT(nbt);
+ nbt.setShort("facing", this.facing);
+ this.inventoryGrid.writeToNBT(this.getTag(nbt, "ContentsGrid"));
+ this.inventoryOutputs.writeToNBT(this.getTag(nbt, "ContentsOutput"));
+
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt){
+ super.readFromNBT(nbt);
+ this.prevFacing = (this.facing = nbt.getShort("facing"));
+ this.inventoryGrid.readFromNBT(nbt.getCompoundTag("ContentsGrid"));
+ this.inventoryOutputs.readFromNBT(nbt.getCompoundTag("ContentsOutput"));
+ }
+
+ @Override
+ public List<String> getNetworkedFields(){
+ final List<String> ret = new Vector(2);
+ ret.add("facing");
+ return ret;
+ }
+
+
+ @Override
+ public boolean wrenchCanSetFacing(final EntityPlayer entityPlayer, final int side){
+ return false;
+ }
+
+ private short facing = 0;
+ public short prevFacing = 0;
+
+ @Override
+ public void setFacing(final short facing1){
+ this.facing = facing1;
+ if (this.prevFacing != facing1) {
+ IC2.network.get().updateTileEntityField(this, "facing");
+ }
+ this.prevFacing = facing1;
+ }
+
+ @Override
+ public short getFacing(){
+ return this.facing;
+ }
+
+
+ @Override
+ public boolean wrenchCanRemove(final EntityPlayer entityPlayer){
+ return true;
+ }
+
+ @Override
+ public float getWrenchDropRate(){
+ return 1.0F;
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(final EntityPlayer entityPlayer){
+ return new ItemStack(this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord), 1, this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord));
+ }
+
+ @Override
+ public void onNetworkUpdate(final String field) {
+ this.prevFacing = this.facing;
+
+ }
+
+ @Override
+ public void updateEntity() {
+ if (!this.worldObj.isRemote){
+ //Data stick
+ ItemStack dataStick = this.inventoryOutputs.getStackInSlot(0);
+ if (dataStick != null && this.container != null && container.getOutputContent() != null){
+ if ((dataStick.getItem() instanceof GT_MetaGenerated_Item_01 && dataStick.getItemDamage() == 32708)
+ || (dataStick == ItemList.Tool_DataStick.get(1))
+ || (dataStick == GregtechItemList.Old_Tool_DataStick.get(1))
+ || (dataStick.getItem() instanceof MetaGeneratedGregtechItems && dataStick.getItemDamage() == 32208)){
+
+ Logger.INFO("Found Data Stick and valid container.");
+
+
+ ItemStack outputComponent = container.getOutputContent();
+ ItemStack[] craftInputComponent = container.getInputComponents();
+
+
+ ItemStack newStick = NBTUtils.writeItemsToNBT(dataStick, new ItemStack[]{outputComponent}, "Output");
+ newStick = NBTUtils.writeItemsToNBT(newStick, craftInputComponent);
+ NBTUtils.setBookTitle(newStick, "Encrypted Project Data");
+ NBTUtils.setBoolean(newStick, "mEncrypted", true);
+ int slotm=0;
+ Logger.WARNING("Uploading to Data Stick.");
+ for (ItemStack is : NBTUtils.readItemsFromNBT(newStick)){
+ if (is != null){
+ Logger.WARNING("Uploaded "+is.getDisplayName()+" into memory slot "+slotm+".");
+ }
+ else {
+ Logger.WARNING("Left memory slot "+slotm+" blank.");
+ }
+ slotm++;
+ }
+ Logger.WARNING("Encrypting Data Stick.");
+ this.inventoryOutputs.setInventorySlotContents(1, newStick);
+ this.inventoryOutputs.setInventorySlotContents(0, null);
+ }
+ }
+
+ //Utils.LOG_INFO("Doing thing 1");
+ if (dataStick != null)
+ if (dataStick.getItem() instanceof ModularBauble){
+ Logger.INFO("Doing thing 2");
+ ItemStack tBauble = dataStick;
+ dataStick = null;
+ this.inventoryOutputs.setInventorySlotContents(0, dataStick);
+ if (this.inventoryGrid != null){
+ Logger.INFO("Doing things");
+ ItemStack[] tStack = container.getInputComponents();
+ if (tStack != null){
+ //Utils.LOG_INFO(""+tStack.length);
+ if (tBauble != null){
+ for (int i=0;i<tStack.length;i++){
+
+ ItemStack testStack;
+ if ((testStack = container.inventoryGrid.getStackInSlot(i)) != null){
+ Logger.INFO("FOUND: "+testStack.getDisplayName());
+ }
+
+ if (tStack[i] != null){
+ Logger.INFO("found "+tStack[i].getDisplayName());
+ try {
+ if (tStack[i].getItem() == Items.feather){
+ ModularArmourUtils.setBaubleType(tBauble, BT.TYPE_BELT);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ this.inventoryGrid.setInventorySlotContents(i, null);
+ }
+ if (tStack[i].getItem() == Items.bed){
+ ModularArmourUtils.setBaubleType(tBauble, BT.TYPE_RING);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ this.inventoryGrid.setInventorySlotContents(i, null);
+ }
+ if (tStack[i].getItem() == Items.boat){
+ ModularArmourUtils.setBaubleType(tBauble, BT.TYPE_AMULET);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ this.inventoryGrid.setInventorySlotContents(i, null);
+ }
+
+ if (tStack[i].getItem() == Items.egg){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_HOLY, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_HOLY)+1);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ this.inventoryGrid.setInventorySlotContents(i, null);
+ }
+
+ if (tStack[i].getItem() == Items.baked_potato){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_DEF, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_DEF)+1);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ this.inventoryGrid.setInventorySlotContents(i, null);
+ }
+
+ if (tStack[i].getItem() == Items.cooked_beef){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_HP, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_HP)+1);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ this.inventoryGrid.setInventorySlotContents(i, null);
+ }
+
+ if (tStack[i] == ItemUtils.simpleMetaStack("gregtech:gt.metaitem.01:17019", 17019, 1)){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_DEF, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_DEF)+1);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ }
+ if (tStack[i] == ItemList.Electric_Motor_LV.get(1)){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_DAMAGE, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_DAMAGE)+1);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ }
+ else if (tStack[i] == ItemList.Electric_Motor_MV.get(1)){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_DAMAGE, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_DAMAGE)+2);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ }
+ else if (tStack[i] == ItemList.Electric_Motor_HV.get(1)){
+ ModularArmourUtils.setModifierLevel(tBauble, Modifiers.BOOST_DAMAGE, ModularArmourUtils.getModifierLevel(tBauble, Modifiers.BOOST_DAMAGE)+3);
+ Logger.INFO("buffed Modular bauble");
+ tStack[i] = null;
+ container.inventoryGrid.setInventorySlotContents(i, null);
+ }
+ }
+ catch (Throwable t){
+
+ }
+ }
+ }
+ Logger.INFO("set new Modular bauble");
+ this.inventoryOutputs.setInventorySlotContents(1, tBauble);
+ }
+ }
+ }
+ }
+ }
+ super.updateEntity();
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return true;
+ }
+
+
+
+
+
+} \ No newline at end of file
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityRoundRobinator.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityRoundRobinator.java
new file mode 100644
index 0000000000..a220997c84
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityRoundRobinator.java
@@ -0,0 +1,739 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.List;
+
+import gtPlusPlus.GTplusplus;
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.handler.GuiHandler;
+import gtPlusPlus.core.inventories.Inventory_RoundRobinator;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import gtPlusPlus.core.util.minecraft.PlayerUtils;
+import gtPlusPlus.core.util.sys.KeyboardUtils;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockChest;
+import net.minecraft.command.IEntitySelector;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.IHopper;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.tileentity.TileEntityChest;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.Facing;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+
+public class TileEntityRoundRobinator extends TileEntity implements ISidedInventory, IHopper {
+
+ private int tickCount = 0;
+ private final Inventory_RoundRobinator inventoryContents;
+ private String customName;
+ public int locationX;
+ public int locationY;
+ public int locationZ;
+ private int aData = 1111;
+ private int aTier = 1;
+ private int aTickRate = 100;
+
+ public TileEntityRoundRobinator() {
+ this.inventoryContents = new Inventory_RoundRobinator();
+ this.setTileLocation();
+ }
+
+ public boolean setTileLocation() {
+ if (this.hasWorldObj()) {
+ if (!this.getWorldObj().isRemote) {
+ this.locationX = this.xCoord;
+ this.locationY = this.yCoord;
+ this.locationZ = this.zCoord;
+ this.aTier = this.getWorldObj().getBlockMetadata(locationX, locationY, locationZ) + 1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //Rename to hasCircuitToConfigure
+ public final boolean hasInventoryContents() {
+ for (ItemStack i : this.aHopperInventory) {
+ if (i == null) {
+ continue;
+ }
+ else {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Inventory_RoundRobinator getInventory() {
+ return this.inventoryContents;
+ }
+
+ public int getTier() {
+ return this.aTier;
+ }
+
+ public int getTickRate() {
+ return this.aTickRate;
+ }
+
+ @Override
+ public void updateEntity() {
+ try{
+ // TODO
+ if (this.worldObj != null && !this.worldObj.isRemote){
+ setTileLocation();
+ aTickRate = (60-(aTier*10));
+ if (this.getTier() == 1) {
+ // 20 s
+ aTickRate = 400;
+ }
+ else if (this.getTier() == 2) {
+ // 5
+ aTickRate = 100;
+ }
+ else if (this.getTier() == 3) {
+ // 1
+ aTickRate = 20;
+ }
+ else if (this.getTier() == 4) {
+ // 1/5
+ aTickRate = 10;
+ }
+ else if (this.getTier() == 5) {
+ // 1/20
+ aTickRate = 1;
+ }
+ else {
+ aTickRate = 999999;
+ }
+
+ if (tickCount % getTickRate() == 0) {
+ if (hasInventoryContents()) {
+ Logger.WARNING("Trying to move items. "+aTickRate);
+ this.tryProcessItems();
+ }
+ }
+ this.tickCount++;
+ }
+ }
+ catch (final Throwable t){
+ t.printStackTrace();
+ }
+ }
+
+ public boolean anyPlayerInRange() {
+ return this.worldObj.getClosestPlayer(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, 32) != null;
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag) {
+ if (!nbt.hasKey(tag)) {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ if (this.hasCustomInventoryName()) {
+ nbt.setString("CustomName", this.getCustomName());
+ }
+ nbt.setInteger("aCurrentMode", aData);
+ this.writeToNBT2(nbt);
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ if (nbt.hasKey("CustomName", 8)) {
+ this.setCustomName(nbt.getString("CustomName"));
+ }
+ aData = nbt.getInteger("aCurrentMode");
+ this.readFromNBT2(nbt);
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return 64;
+ }
+
+ @Override
+ public boolean isUseableByPlayer(final EntityPlayer entityplayer) {
+ return this.getInventory().isUseableByPlayer(entityplayer);
+ }
+
+ @Override
+ public void openInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ //this.getInventory().openInventory();
+ }
+
+ @Override
+ public void closeInventory() {
+ this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, 1);
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
+ this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType());
+ //this.getInventory().closeInventory();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(final int slot, final ItemStack itemstack) {
+ return true;
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(final int aSide) {
+ return new int[] {0, 1, 2, 3, 4};
+ }
+
+ @Override
+ public boolean canInsertItem(final int aSlot, final ItemStack aStack, final int aSide) {
+ return aSide < 2;
+ }
+
+ @Override
+ public boolean canExtractItem(final int aSlot, final ItemStack aStack, final int aSide) {
+ return false;
+ }
+
+ public String getCustomName() {
+ return this.customName;
+ }
+
+ public void setCustomName(final String customName) {
+ this.customName = customName;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return this.hasCustomInventoryName() ? this.customName : "container.roundrobinator";
+ }
+
+ @Override
+ public boolean hasCustomInventoryName() {
+ return (this.customName != null) && !this.customName.equals("");
+ }
+
+ @Override
+ public Packet getDescriptionPacket() {
+ final NBTTagCompound tag = new NBTTagCompound();
+ this.writeToNBT(tag);
+ return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
+ }
+
+ @Override
+ public void onDataPacket(final NetworkManager net, final S35PacketUpdateTileEntity pkt) {
+ final NBTTagCompound tag = pkt.func_148857_g();
+ this.readFromNBT(tag);
+ }
+
+
+ public boolean onRightClick(byte side, EntityPlayer player, int x, int y, int z) {
+ if (player != null && player.getHeldItem() == null) {
+ if (!player.isSneaking() && !KeyboardUtils.isShiftKeyDown()) {
+ player.openGui(GTplusplus.instance, GuiHandler.GUI16, player.getEntityWorld(), x, y, z);
+ }
+ else {
+ String InventoryContents = ItemUtils.getArrayStackNames(this.aHopperInventory);
+ PlayerUtils.messagePlayer(player, "Contents: "+InventoryContents+" | "+getDataString());
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public boolean onScrewdriverRightClick(byte side, EntityPlayer player, int x, int y, int z) {
+ try {
+ if (side < 2) {
+ // Top/Bottom
+ }
+ else {
+ if (toggleSide(side)) {
+ PlayerUtils.messagePlayer(player, "Enabling side "+side+".");
+ }
+ else {
+ PlayerUtils.messagePlayer(player, "Disabling side "+side+".");
+ }
+ PlayerUtils.messagePlayer(player, "Mode String: "+aData+"");
+ }
+ return true;
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ return false;
+ }
+ }
+
+ public int getDataString() {
+ return aData;
+ }
+
+ public boolean[] getActiveSides() {
+ this.markDirty();
+ String s = String.valueOf(aData);
+ if (s == null || s.length() != 4) {
+ s = "1111";
+ }
+ boolean[] aActiveSides = new boolean[4];
+ for (int i=0;i<4;i++) {
+ char ch = s.charAt(i);
+ if (ch == '1') {
+ aActiveSides[i] = true;
+ }
+ else {
+ aActiveSides[i] = false;
+ }
+ }
+ return aActiveSides;
+ }
+
+ /**
+ * Toggle active state of side
+ * @param aSide - Forge Direction / Side
+ * @return - True if the side is now Active, false if now disabled.
+ */
+ public boolean toggleSide(int aSide) {
+ setSideActive(!getSideActive(aSide), aSide);
+ return getSideActive(aSide);
+ }
+
+
+ public void setSideActive(boolean aActive, int aSide) {
+ try {
+ if (aSide < 2) {
+ }
+ else {
+ if (aData < 1111) {
+ aData = 1111;
+ }
+ else if (aData > 2222) {
+ aData = 2222;
+ }
+ String s = String.valueOf(aData);
+ StringBuilder aDataString = new StringBuilder(s);
+ int aIndex = aSide - 2;
+ if (aActive) {
+ aDataString.setCharAt(aIndex, '1');
+ }
+ else {
+ aDataString.setCharAt(aIndex, '2');
+ }
+ aData = Integer.valueOf(aDataString.toString());
+ this.markDirty();
+ }
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ public boolean getSideActive(int aSide) {
+ this.markDirty();
+ try {
+ if (aSide < 2) {
+ return false;
+ }
+ else {
+ if (aData < 1111) {
+ aData = 1111;
+ }
+ else if (aData > 2222) {
+ aData = 2222;
+ }
+ String s = String.valueOf(aData);
+ int aIndex = aSide - 2;
+ char ch = s.charAt(aIndex);
+ if (ch == '1') {
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ }
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public double getXPos() {
+ return this.locationX;
+ }
+
+ @Override
+ public double getYPos() {
+ return this.locationY;
+ }
+
+ @Override
+ public double getZPos() {
+ return this.locationZ;
+ }
+
+
+
+
+
+
+
+
+ // TODO
+
+
+
+ /*
+ * Hopper Code
+ */
+
+
+ private ItemStack[] aHopperInventory = new ItemStack[5];
+
+ public int getSizeInventory() {
+ return this.aHopperInventory.length;
+ }
+
+ public ItemStack getStackInSlot(int aSlot) {
+ return this.aHopperInventory[aSlot];
+ }
+
+ /**
+ * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a
+ * new stack.
+ */
+ public ItemStack decrStackSize(int aSlot, int aMinimumSizeOfExistingStack)
+ {
+ if (this.aHopperInventory[aSlot] != null)
+ {
+ ItemStack itemstack;
+
+ if (this.aHopperInventory[aSlot].stackSize <= aMinimumSizeOfExistingStack)
+ {
+ itemstack = this.aHopperInventory[aSlot];
+ this.aHopperInventory[aSlot] = null;
+ return itemstack;
+ }
+ else
+ {
+ itemstack = this.aHopperInventory[aSlot].splitStack(aMinimumSizeOfExistingStack);
+
+ if (this.aHopperInventory[aSlot].stackSize == 0)
+ {
+ this.aHopperInventory[aSlot] = null;
+ }
+
+ return itemstack;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
+ * like when you close a workbench GUI.
+ */
+ public ItemStack getStackInSlotOnClosing(int aSlot)
+ {
+ if (this.aHopperInventory[aSlot] != null)
+ {
+ ItemStack itemstack = this.aHopperInventory[aSlot];
+ this.aHopperInventory[aSlot] = null;
+ return itemstack;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
+ */
+ public void setInventorySlotContents(int aSlot, ItemStack aStack)
+ {
+ this.aHopperInventory[aSlot] = aStack;
+
+ if (aStack != null && aStack.stackSize > this.getInventoryStackLimit())
+ {
+ aStack.stackSize = this.getInventoryStackLimit();
+ }
+ }
+
+ public boolean tryProcessItems() {
+ if (this.worldObj != null && !this.worldObj.isRemote) {
+ boolean didSomething = false;
+ if (!this.isEmpty()) {
+ Logger.WARNING("Has Items, Trying to push to all active directions.");
+ didSomething = this.tryPushItemsIntoNeighbours();
+ }
+ if (didSomething) {
+ this.markDirty();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is Empty
+ * @return
+ */
+ private boolean isEmpty() {
+ ItemStack[] aitemstack = this.aHopperInventory;
+ int i = aitemstack.length;
+
+ for (int j = 0; j < i; ++j) {
+ ItemStack itemstack = aitemstack[j];
+
+ if (itemstack != null) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean tryPushItemsIntoNeighbours() {
+
+ boolean aDidPush = false;
+
+ for (int u = 2; u < 6; u++) {
+ if (!this.getSideActive(u)) {
+ Logger.WARNING("Not pushing on side "+u);
+ continue;
+ }
+
+ Logger.WARNING("Pushing on side "+u);
+ IInventory iinventory = this.getInventoryFromFacing(u);
+
+ if (iinventory == null) {
+ Logger.WARNING("No inventory found.");
+ continue;
+ }
+ else {
+
+ int i = Facing.oppositeSide[u];
+ Logger.WARNING("Using Opposite direction: "+i);
+
+ if (this.isInventoryFull(iinventory, i)) {
+ Logger.WARNING("Target is full, skipping.");
+ continue;
+ }
+ else {
+ Logger.WARNING("Target has space, let's move a single item.");
+ for (int j = 0; j < this.getSizeInventory(); ++j) {
+ if (this.getStackInSlot(j) != null) {
+ ItemStack itemstack = this.getStackInSlot(j).copy();
+ ItemStack itemstack1 = setStackInNeighbour(iinventory, this.decrStackSize(j, 1), i);
+ if (itemstack1 == null || itemstack1.stackSize == 0) {
+ iinventory.markDirty();
+ aDidPush = true;
+ continue;
+ }
+ this.setInventorySlotContents(j, itemstack);
+ }
+ }
+ }
+ }
+ }
+
+ return aDidPush;
+ }
+
+ private boolean isInventoryFull(IInventory aInv, int aSide) {
+ if (aInv instanceof ISidedInventory && aSide > -1) {
+ ISidedInventory isidedinventory = (ISidedInventory)aInv;
+ int[] aint = isidedinventory.getAccessibleSlotsFromSide(aSide);
+
+ for (int l = 0; l < aint.length; ++l)
+ {
+ ItemStack itemstack1 = isidedinventory.getStackInSlot(aint[l]);
+
+ if (itemstack1 == null || itemstack1.stackSize != itemstack1.getMaxStackSize())
+ {
+ return false;
+ }
+ }
+ }
+ else {
+ int j = aInv.getSizeInventory();
+
+ for (int k = 0; k < j; ++k)
+ {
+ ItemStack itemstack = aInv.getStackInSlot(k);
+
+ if (itemstack == null || itemstack.stackSize != itemstack.getMaxStackSize())
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static ItemStack setStackInNeighbour(IInventory aNeighbour, ItemStack aStack, int aSide) {
+ if (aNeighbour instanceof ISidedInventory && aSide > -1)
+ {
+ ISidedInventory isidedinventory = (ISidedInventory)aNeighbour;
+ int[] aint = isidedinventory.getAccessibleSlotsFromSide(aSide);
+
+ for (int l = 0; l < aint.length && aStack != null && aStack.stackSize > 0; ++l)
+ {
+ aStack = tryMoveStack(aNeighbour, aStack, aint[l], aSide);
+ }
+ }
+ else
+ {
+ int j = aNeighbour.getSizeInventory();
+
+ for (int k = 0; k < j && aStack != null && aStack.stackSize > 0; ++k)
+ {
+ aStack = tryMoveStack(aNeighbour, aStack, k, aSide);
+ }
+ }
+
+ if (aStack != null && aStack.stackSize == 0)
+ {
+ aStack = null;
+ }
+
+ return aStack;
+ }
+
+ private static boolean canInsertItemIntoNeighbour(IInventory aNeighbour, ItemStack aStack, int aSlot, int aSide) {
+ return !aNeighbour.isItemValidForSlot(aSlot, aStack) ? false : !(aNeighbour instanceof ISidedInventory) || ((ISidedInventory)aNeighbour).canInsertItem(aSlot, aStack, aSide);
+ }
+
+ private static ItemStack tryMoveStack(IInventory aNeighbour, ItemStack aStack, int aSlot, int aSide) {
+ ItemStack itemstack1 = aNeighbour.getStackInSlot(aSlot);
+ if (canInsertItemIntoNeighbour(aNeighbour, aStack, aSlot, aSide)) {
+ boolean aDidSomething = false;
+ if (itemstack1 == null) {
+ //Forge: BUGFIX: Again, make things respect max stack sizes.
+ int max = Math.min(aStack.getMaxStackSize(), aNeighbour.getInventoryStackLimit());
+ if (max >= aStack.stackSize) {
+ aNeighbour.setInventorySlotContents(aSlot, aStack);
+ aStack = null;
+ }
+ else {
+ aNeighbour.setInventorySlotContents(aSlot, aStack.splitStack(max));
+ }
+ aDidSomething = true;
+ }
+ else if (areItemStacksEqual(itemstack1, aStack)) {
+ //Forge: BUGFIX: Again, make things respect max stack sizes.
+ int max = Math.min(aStack.getMaxStackSize(), aNeighbour.getInventoryStackLimit());
+ if (max > itemstack1.stackSize) {
+ int l = Math.min(aStack.stackSize, max - itemstack1.stackSize);
+ aStack.stackSize -= l;
+ itemstack1.stackSize += l;
+ aDidSomething = l > 0;
+ }
+ }
+ if (aDidSomething){
+ aNeighbour.markDirty();
+ }
+ }
+ return aStack;
+ }
+
+ private IInventory getInventoryFromFacing(int aSide)
+ {
+ int i = aSide;
+ return tryFindInvetoryAtXYZ(this.getWorldObj(), (double)(this.xCoord + Facing.offsetsXForSide[i]), (double)(this.yCoord + Facing.offsetsYForSide[i]), (double)(this.zCoord + Facing.offsetsZForSide[i]));
+ }
+
+ public static IInventory tryFindInvetoryAtXYZ(World aWorld, double aX, double aY, double aZ)
+ {
+ IInventory iinventory = null;
+ int sX = MathHelper.floor_double(aX);
+ int sY = MathHelper.floor_double(aY);
+ int sZ = MathHelper.floor_double(aZ);
+ TileEntity tileentity = aWorld.getTileEntity(sX, sY, sZ);
+
+ if (tileentity != null && tileentity instanceof IInventory)
+ {
+ iinventory = (IInventory)tileentity;
+
+ if (iinventory instanceof TileEntityChest)
+ {
+ Block block = aWorld.getBlock(sX, sY, sZ);
+
+ if (block instanceof BlockChest)
+ {
+ iinventory = ((BlockChest)block).func_149951_m(aWorld, sX, sY, sZ);
+ }
+ }
+ }
+
+ if (iinventory == null)
+ {
+ List list = aWorld.getEntitiesWithinAABBExcludingEntity((Entity)null, AxisAlignedBB.getBoundingBox(aX, aY, aZ, aX + 1.0D, aY + 1.0D, aZ + 1.0D), IEntitySelector.selectInventories);
+
+ if (list != null && list.size() > 0)
+ {
+ iinventory = (IInventory)list.get(aWorld.rand.nextInt(list.size()));
+ }
+ }
+
+ return iinventory;
+ }
+
+ private static boolean areItemStacksEqual(ItemStack aStack, ItemStack aStack2) {
+ return aStack.getItem() != aStack2.getItem() ? false : (aStack.getItemDamage() != aStack2.getItemDamage() ? false : (aStack.stackSize > aStack.getMaxStackSize() ? false : ItemStack.areItemStackTagsEqual(aStack, aStack2)));
+ }
+
+ public void readFromNBT2(NBTTagCompound p_145839_1_) {
+ super.readFromNBT(p_145839_1_);
+ NBTTagList nbttaglist = p_145839_1_.getTagList("Items", 10);
+ this.aHopperInventory = new ItemStack[this.getSizeInventory()];
+ for (int i = 0; i < nbttaglist.tagCount(); ++i) {
+ NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
+ byte b0 = nbttagcompound1.getByte("Slot");
+ if (b0 >= 0 && b0 < this.aHopperInventory.length) {
+ this.aHopperInventory[b0] = ItemStack.loadItemStackFromNBT(
+ nbttagcompound1
+ );
+ }
+ }
+ }
+
+ public void writeToNBT2(NBTTagCompound aNBT) {
+ super.writeToNBT(aNBT);
+ NBTTagList nbttaglist = new NBTTagList();
+ for (int i = 0; i < this.aHopperInventory.length; ++i) {
+ if (this.aHopperInventory[i] != null) {
+ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
+ nbttagcompound1.setByte("Slot", (byte) i);
+ this.aHopperInventory[i].writeToNBT(nbttagcompound1);
+ nbttaglist.appendTag(nbttagcompound1);
+ }
+ }
+ aNBT.setTag("Items", nbttaglist);
+ }
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityTradeTable.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityTradeTable.java
new file mode 100644
index 0000000000..ad7ec3d0b3
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityTradeTable.java
@@ -0,0 +1,133 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+import gtPlusPlus.core.container.Container_TradeTable;
+import gtPlusPlus.core.inventories.tradetable.InventoryTradeMain;
+import gtPlusPlus.core.inventories.tradetable.InventoryTradeOutput;
+import gtPlusPlus.core.tileentities.base.TileEntityBase;
+import gtPlusPlus.core.util.minecraft.NBTUtils;
+
+public class TileEntityTradeTable extends TileEntityBase {
+
+ public InventoryTradeMain inventoryGrid;
+ public InventoryTradeOutput inventoryOutputs;
+
+ private Container_TradeTable container;
+
+ public TileEntityTradeTable(){
+ super(2);
+ this.inventoryGrid = new InventoryTradeMain();//number of slots - without product slot
+ this.inventoryOutputs = new InventoryTradeOutput();//number of slots - without product slot
+ }
+
+ public void setContainer(Container_TradeTable container_TradeTable){
+ this.container = container_TradeTable;
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt){
+ super.writeToNBT(nbt);
+ this.inventoryGrid.writeToNBT(this.getTag(nbt, "ContentsGrid"));
+ this.inventoryOutputs.writeToNBT(this.getTag(nbt, "ContentsOutput"));
+
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt){
+ this.inventoryGrid.readFromNBT(nbt);
+ this.inventoryOutputs.readFromNBT(nbt);
+ super.readFromNBT(nbt);
+ }
+
+ @Override
+ public void updateEntity() {
+ if (!this.worldObj.isRemote){
+ ItemStack slot0;
+ try{
+
+ slot0 = this.inventoryOutputs.getStackInSlot(0);
+ if (slot0 != null && slot0.hasTagCompound()){
+ NBTUtils.tryIterateNBTData(slot0);
+ this.inventoryOutputs.setInventorySlotContents(0, null);
+ this.inventoryOutputs.setInventorySlotContents(1, slot0);
+ }
+
+ }
+ catch (Throwable t){
+ t.printStackTrace();
+ this.inventoryOutputs.setInventorySlotContents(0, null);
+ }
+
+ }
+ super.updateEntity();
+ }
+
+ @Override
+ public int getSizeInventory() {
+ return 0;
+ }
+
+ @Override
+ public ItemStack getStackInSlot(int p_70301_1_) {
+ return null;
+ }
+
+ @Override
+ public ItemStack decrStackSize(int p_70298_1_, int p_70298_2_) {
+ return null;
+ }
+
+ @Override
+ public ItemStack getStackInSlotOnClosing(int p_70304_1_) {
+ return null;
+ }
+
+ @Override
+ public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_) {
+
+ }
+
+ @Override
+ public int getInventoryStackLimit() {
+ return 64;
+ }
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer p_70300_1_) {
+ return true;
+ }
+
+ @Override
+ public void openInventory() {
+
+ }
+
+ @Override
+ public void closeInventory() {
+
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) {
+ return false;
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int p_94128_1_) {
+ return new int[] {};
+ }
+
+ @Override
+ public boolean canInsertItem(int p_102007_1_, ItemStack p_102007_2_, int p_102007_3_) {
+ return false;
+ }
+
+ @Override
+ public boolean canExtractItem(int p_102008_1_, ItemStack p_102008_2_, int p_102008_3_) {
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbench.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbench.java
new file mode 100644
index 0000000000..a2db2326a9
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbench.java
@@ -0,0 +1,172 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.List;
+import java.util.Vector;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.InventoryCraftResult;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.tileentity.TileEntity;
+
+import gtPlusPlus.core.inventories.InventoryWorkbenchChest;
+import gtPlusPlus.core.inventories.InventoryWorkbenchHoloSlots;
+import gtPlusPlus.core.inventories.InventoryWorkbenchTools;
+import ic2.api.network.INetworkDataProvider;
+import ic2.api.network.INetworkUpdateListener;
+import ic2.api.tile.IWrenchable;
+import ic2.core.IC2;
+
+public class TileEntityWorkbench extends TileEntity implements INetworkDataProvider, INetworkUpdateListener, IWrenchable{
+
+ //Credit to NovaViper in http://www.minecraftforge.net/forum/index.php?topic=26439.0 - Helped me restructure my Inventory system and now the crafting matrix works better.
+
+ public InventoryWorkbenchChest inventoryChest;
+ public InventoryWorkbenchTools inventoryTool;
+ public InventoryWorkbenchHoloSlots inventoryHolo;
+ //public InventoryWorkbenchHoloCrafting inventoryCrafting;
+
+ public IInventory inventoryCraftResult = new InventoryCraftResult();
+
+ public TileEntityWorkbench(){
+ this.inventoryTool = new InventoryWorkbenchTools();//number of slots - without product slot
+ this.inventoryChest = new InventoryWorkbenchChest();//number of slots - without product slot
+ this.inventoryHolo = new InventoryWorkbenchHoloSlots();
+ //this.inventoryCrafting = new InventoryWorkbenchHoloCrafting();
+ this.canUpdate();
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag)
+ {
+ if(!nbt.hasKey(tag))
+ {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+
+ nbt.setShort("facing", this.facing);
+
+ this.inventoryChest.writeToNBT(this.getTag(nbt, "ContentsChest"));
+ this.inventoryTool.writeToNBT(this.getTag(nbt, "ContentsTools"));
+ //inventoryCrafting.writeToNBT(getTag(nbt, "ContentsCrafting"));
+ this.inventoryHolo.writeToNBT(this.getTag(nbt, "ContentsHolo"));
+
+ // Write Crafting Matrix to NBT
+ final NBTTagList craftingTag = new NBTTagList();
+ /*for (int currentIndex = 0; currentIndex < this.inventoryCrafting.getSizeInventory(); ++currentIndex) {
+ if (this.inventoryCrafting.getStackInSlot(currentIndex) != null) {
+ final NBTTagCompound tagCompound = new NBTTagCompound();
+ tagCompound.setByte("Slot", (byte) currentIndex);
+ this.inventoryCrafting.getStackInSlot(currentIndex).writeToNBT(tagCompound);
+ craftingTag.appendTag(tagCompound);
+ }
+ }*/
+
+ nbt.setTag("CraftingMatrix", craftingTag);
+ // Write craftingResult to NBT
+ if (this.inventoryCraftResult.getStackInSlot(0) != null) {
+ nbt.setTag("CraftingResult", this.inventoryCraftResult.getStackInSlot(0).writeToNBT(new NBTTagCompound()));
+ }
+
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+
+ this.prevFacing = (this.facing = nbt.getShort("facing"));
+
+ this.inventoryChest.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ this.inventoryTool.readFromNBT(nbt.getCompoundTag("ContentsTools"));
+ //inventoryCrafting.readFromNBT(nbt.getCompoundTag("ContentsCrafting"));
+ this.inventoryHolo.readFromNBT(nbt.getCompoundTag("ContentsHolo"));
+
+ // Read in the Crafting Matrix from NBT
+ final NBTTagList craftingTag = nbt.getTagList("CraftingMatrix", 10);
+ /*this.inventoryCrafting = new InventoryWorkbenchHoloCrafting(); //TODO: magic number
+ for (int i = 0; i < craftingTag.tagCount(); ++i) {
+ final NBTTagCompound tagCompound = craftingTag.getCompoundTagAt(i);
+ final byte slot = tagCompound.getByte("Slot");
+ if ((slot >= 0) && (slot < this.inventoryCrafting.getSizeInventory())) {
+ this.inventoryCrafting.setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(tagCompound));
+ }
+ }*/
+
+
+ // Read craftingResult from NBT
+ final NBTTagCompound tagCraftResult = nbt.getCompoundTag("CraftingResult");
+ this.inventoryCraftResult.setInventorySlotContents(0, ItemStack.loadItemStackFromNBT(tagCraftResult));
+
+ }
+
+ @Override
+ public List<String> getNetworkedFields(){
+ final List<String> ret = new Vector(2);
+ ret.add("facing");
+ return ret;
+ }
+
+
+ @Override
+ public boolean wrenchCanSetFacing(final EntityPlayer entityPlayer, final int side)
+ {
+ return false;
+ }
+
+ private short facing = 0;
+ public short prevFacing = 0;
+
+ @Override
+ public void setFacing(final short facing1)
+ {
+ this.facing = facing1;
+ if (this.prevFacing != facing1) {
+ IC2.network.get().updateTileEntityField(this, "facing");
+ }
+ this.prevFacing = facing1;
+ }
+
+ @Override
+ public short getFacing()
+ {
+ return this.facing;
+ }
+
+
+ @Override
+ public boolean wrenchCanRemove(final EntityPlayer entityPlayer)
+ {
+ return true;
+ }
+
+ @Override
+ public float getWrenchDropRate()
+ {
+ return 1.0F;
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(final EntityPlayer entityPlayer)
+ {
+ return new ItemStack(this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord), 1, this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord));
+ }
+
+ @Override
+ public void onNetworkUpdate(final String field) {
+
+ this.prevFacing = this.facing;
+
+ }
+
+
+
+} \ No newline at end of file
diff --git a/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbenchAdvanced.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbenchAdvanced.java
new file mode 100644
index 0000000000..264323388f
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityWorkbenchAdvanced.java
@@ -0,0 +1,245 @@
+package gtPlusPlus.core.tileentities.machines;
+
+import java.util.List;
+import java.util.Vector;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.InventoryCraftResult;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.tileentity.TileEntity;
+
+import gtPlusPlus.core.inventories.*;
+import ic2.api.energy.event.EnergyTileLoadEvent;
+import ic2.api.energy.event.EnergyTileUnloadEvent;
+import ic2.api.energy.tile.IEnergySink;
+import ic2.api.network.INetworkDataProvider;
+import ic2.api.network.INetworkUpdateListener;
+import ic2.api.tile.IWrenchable;
+import ic2.core.IC2;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class TileEntityWorkbenchAdvanced extends TileEntity implements IEnergySink, INetworkDataProvider, INetworkUpdateListener, IWrenchable{
+
+ //Credit to NovaViper in http://www.minecraftforge.net/forum/index.php?topic=26439.0 - Helped me restructure my Inventory system and now the crafting matrix works better.
+
+ public InventoryWorkbenchChest inventoryChest;
+ public InventoryWorkbenchToolsElectric inventoryTool;
+ public InventoryWorkbenchHoloSlots inventoryHolo;
+ public InventoryWorkbenchHoloCrafting inventoryCrafting;
+
+ public IInventory inventoryCraftResult = new InventoryCraftResult();
+
+ //Wrench Code
+ private short facing = 0;
+ public short prevFacing = 0;
+
+ //E-Net Code
+ public double energy = 0.0D;
+ public int maxEnergy;
+ private boolean addedToEnergyNet = false;
+ private int tier;
+ private float guiChargeLevel;
+
+
+ public TileEntityWorkbenchAdvanced(final int maxenergy, final int tier1){
+ this.inventoryTool = new InventoryWorkbenchToolsElectric();//number of slots - without product slot
+ this.inventoryChest = new InventoryWorkbenchChest();//number of slots - without product slot
+ this.inventoryHolo = new InventoryWorkbenchHoloSlots();
+ this.inventoryCrafting = new InventoryWorkbenchHoloCrafting();
+ this.canUpdate();
+
+ //Electric Stats
+ this.maxEnergy = maxenergy;
+ this.tier = tier1;
+
+ }
+
+ public NBTTagCompound getTag(final NBTTagCompound nbt, final String tag)
+ {
+ if(!nbt.hasKey(tag))
+ {
+ nbt.setTag(tag, new NBTTagCompound());
+ }
+ return nbt.getCompoundTag(tag);
+ }
+
+ @Override
+ public void writeToNBT(final NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+ nbt.setDouble("energy", this.energy);
+ nbt.setShort("facing", this.facing);
+
+ this.inventoryChest.writeToNBT(this.getTag(nbt, "ContentsChest"));
+ this.inventoryTool.writeToNBT(this.getTag(nbt, "ContentsTools"));
+ //inventoryCrafting.writeToNBT(getTag(nbt, "ContentsCrafting"));
+ this.inventoryHolo.writeToNBT(this.getTag(nbt, "ContentsHolo"));
+
+ // Write Crafting Matrix to NBT
+ final NBTTagList craftingTag = new NBTTagList();
+ for (int currentIndex = 0; currentIndex < this.inventoryCrafting.getSizeInventory(); ++currentIndex) {
+ if (this.inventoryCrafting.getStackInSlot(currentIndex) != null) {
+ final NBTTagCompound tagCompound = new NBTTagCompound();
+ tagCompound.setByte("Slot", (byte) currentIndex);
+ this.inventoryCrafting.getStackInSlot(currentIndex).writeToNBT(tagCompound);
+ craftingTag.appendTag(tagCompound);
+ }
+ }
+
+ nbt.setTag("CraftingMatrix", craftingTag);
+ // Write craftingResult to NBT
+ if (this.inventoryCraftResult.getStackInSlot(0) != null) {
+ nbt.setTag("CraftingResult", this.inventoryCraftResult.getStackInSlot(0).writeToNBT(new NBTTagCompound()));
+ }
+
+ }
+
+ @Override
+ public void readFromNBT(final NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+ this.energy = nbt.getDouble("energy");
+
+ this.prevFacing = (this.facing = nbt.getShort("facing"));
+
+ this.inventoryChest.readFromNBT(nbt.getCompoundTag("ContentsChest"));
+ this.inventoryTool.readFromNBT(nbt.getCompoundTag("ContentsTools"));
+ //inventoryCrafting.readFromNBT(nbt.getCompoundTag("ContentsCrafting"));
+ this.inventoryHolo.readFromNBT(nbt.getCompoundTag("ContentsHolo"));
+
+ // Read in the Crafting Matrix from NBT
+ final NBTTagList craftingTag = nbt.getTagList("CraftingMatrix", 10);
+ this.inventoryCrafting = new InventoryWorkbenchHoloCrafting(); //TODO: magic number
+ for (int i = 0; i < craftingTag.tagCount(); ++i) {
+ final NBTTagCompound tagCompound = craftingTag.getCompoundTagAt(i);
+ final byte slot = tagCompound.getByte("Slot");
+ if ((slot >= 0) && (slot < this.inventoryCrafting.getSizeInventory())) {
+ this.inventoryCrafting.setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(tagCompound));
+ }
+ }
+
+
+ // Read craftingResult from NBT
+ final NBTTagCompound tagCraftResult = nbt.getCompoundTag("CraftingResult");
+ this.inventoryCraftResult.setInventorySlotContents(0, ItemStack.loadItemStackFromNBT(tagCraftResult));
+
+ }
+
+ @Override
+ public boolean acceptsEnergyFrom(final TileEntity emitter, final ForgeDirection direction)
+ {
+ return true;
+ }
+
+ @Override
+ public double getDemandedEnergy()
+ {
+ return this.maxEnergy - this.energy;
+ }
+
+ @Override
+ public int getSinkTier()
+ {
+ return this.tier;
+ }
+
+ @Override
+ public double injectEnergy(final ForgeDirection directionFrom, final double amount, final double voltage)
+ {
+ if (this.energy >= this.maxEnergy) {
+ return amount;
+ }
+ this.energy += amount;
+ return 0.0D;
+ }
+
+ public final float getChargeLevel()
+ {
+ return this.guiChargeLevel;
+ }
+
+ public void setTier(final int tier1)
+ {
+ if (this.tier == tier1) {
+ return;
+ }
+ final boolean addedToENet = this.addedToEnergyNet;
+ if (addedToENet)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
+ this.addedToEnergyNet = false;
+ }
+ this.tier = tier1;
+
+ for (int i=0; i<this.inventoryTool.getSizeInventory(); i++){
+ //this.inventoryTool..setTier(tier1); TODO
+ }
+
+ if (addedToENet)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
+ this.addedToEnergyNet = true;
+ }
+ }
+
+ @Override
+ public List<String> getNetworkedFields(){
+ final List<String> ret = new Vector(2);
+ ret.add("facing");
+ return ret;
+ }
+
+
+ @Override
+ public boolean wrenchCanSetFacing(final EntityPlayer entityPlayer, final int side)
+ {
+ return false;
+ }
+
+ @Override
+ public void setFacing(final short facing1)
+ {
+ this.facing = facing1;
+ if (this.prevFacing != facing1) {
+ IC2.network.get().updateTileEntityField(this, "facing");
+ }
+ this.prevFacing = facing1;
+ }
+
+ @Override
+ public short getFacing()
+ {
+ return this.facing;
+ }
+
+
+ @Override
+ public boolean wrenchCanRemove(final EntityPlayer entityPlayer)
+ {
+ return true;
+ }
+
+ @Override
+ public float getWrenchDropRate()
+ {
+ return 1.0F;
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(final EntityPlayer entityPlayer)
+ {
+ return new ItemStack(this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord), 1, this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord));
+ }
+
+ @Override
+ public void onNetworkUpdate(final String field) {
+
+ this.prevFacing = this.facing;
+
+ }
+
+} \ No newline at end of file