diff options
author | Johann Bernhardt <johann.bernhardt@tum.de> | 2021-12-12 19:38:06 +0100 |
---|---|---|
committer | Johann Bernhardt <johann.bernhardt@tum.de> | 2021-12-12 19:38:06 +0100 |
commit | 311ab89f93558233a40079f7cb16605b141b5346 (patch) | |
tree | c5f44ef47f441a57c5f57aa801f639c7879ed760 /src/main/java/gtPlusPlus/core/tileentities | |
parent | 896143b96132f5ac54aa8d8f7386f27487e5e530 (diff) | |
download | GT5-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')
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 |