diff options
author | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
---|---|---|
committer | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
commit | 6d1b2216464d4dad449ac6fcfec476832224a55e (patch) | |
tree | 526a0c15f7056313c80e6c0386e025e9b3f61781 /src/main/java/gtPlusPlus/core/tileentities | |
parent | b5d35f40afa606ed1b07061dad82e0521a59c186 (diff) | |
download | GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.gz GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.bz2 GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.zip |
Merge addon sources
Diffstat (limited to 'src/main/java/gtPlusPlus/core/tileentities')
12 files changed, 4211 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..56cf2fdbab --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/ModTileEntities.java @@ -0,0 +1,35 @@ +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.tileentities.general.TileEntityCircuitProgrammer; +import gtPlusPlus.core.tileentities.general.TileEntityDecayablesChest; +import gtPlusPlus.core.tileentities.general.TileEntityFishTrap; +import gtPlusPlus.core.tileentities.general.TileEntityInfiniteFluid; +import gtPlusPlus.core.tileentities.general.TileEntityVolumetricFlaskSetter; +import gtPlusPlus.core.tileentities.machines.TileEntityAdvPooCollector; +import gtPlusPlus.core.tileentities.machines.TileEntityPestKiller; +import gtPlusPlus.core.tileentities.machines.TileEntityPooCollector; +import gtPlusPlus.core.tileentities.machines.TileEntityProjectTable; + +public class ModTileEntities { + + public static void init() { + Logger.INFO("Registering Tile Entities."); + GameRegistry.registerTileEntity(TileEntityPooCollector.class, "TileEntityPooCollector"); + GameRegistry.registerTileEntity(TileEntityAdvPooCollector.class, "TileEntityAdvPooCollector"); + GameRegistry.registerTileEntity(TileEntityFishTrap.class, "TileFishTrap"); + GameRegistry.registerTileEntity(TileEntityInfiniteFluid.class, "TileInfiniteFluid"); + GameRegistry.registerTileEntity(TileEntityProjectTable.class, "TileProjectTable"); + GameRegistry.registerTileEntity(TileEntityCircuitProgrammer.class, "TileCircuitProgrammer"); + GameRegistry.registerTileEntity(TileEntityDecayablesChest.class, "TileDecayablesChest"); + GameRegistry.registerTileEntity(TileEntitySuperJukebox.class, "TileEntitySuperJukebox"); + GameRegistry.registerTileEntity(TileEntitySuperLight.class, "TileEntitySuperLight"); + GameRegistry.registerTileEntity(TileEntityPestKiller.class, "TileEntityPestKiller"); + + GameRegistry.registerTileEntity(TileEntityVolumetricFlaskSetter.class, "TileEntityVolumetricFlaskSetter"); + } + +} 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..98f1d67439 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/base/TileEntityBase.java @@ -0,0 +1,1419 @@ +package gtPlusPlus.core.tileentities.base; + +import java.util.UUID; + +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 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_OreDictUnificator; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.ISerializableObject; +import gregtech.common.covers.CoverInfo; +import gtPlusPlus.api.interfaces.ILazyCoverable; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.minecraft.BTF_Inventory; +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; + } + } + } + + @Override + public boolean isServerSide() { + if (this.hasWorldObj()) { + if (!this.getWorldObj().isRemote) { + return true; + } + } + return false; + } + + @Override + 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 ordinalSide) { + final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide); + CoverInfo coverInfo = getCoverInfoAtSide(side); + if (canAccessData() && (coverInfo.letsItemsOut(-1) || coverInfo.letsItemsIn(-1))) + return mInventory.getAccessibleSlotsFromSide(ordinalSide); + return new int[0]; + } + + /** + * Can put aStack into Slot at Side + */ + @Override + public boolean canInsertItem(int aIndex, ItemStack aStack, int ordinalSide) { + final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide); + return canAccessData() && (mRunningThroughTick || !mInputDisabled) + && getCoverInfoAtSide(side).letsItemsIn(aIndex) + && mInventory.canInsertItem(aIndex, aStack, ordinalSide); + } + + /** + * Can pull aStack out of Slot from Side + */ + @Override + public boolean canExtractItem(int aIndex, ItemStack aStack, int ordinalSide) { + final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide); + return canAccessData() && (mRunningThroughTick || !mOutputDisabled) + && getCoverInfoAtSide(side).letsItemsOut(aIndex) + && mInventory.canExtractItem(aIndex, aStack, ordinalSide); + } + + @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(ForgeDirection side) { + this.issueClientUpdate(); + } + + @Override + public void receiveCoverData(ForgeDirection coverSide, int coverID, int coverData) { + if (coverSide != ForgeDirection.UNKNOWN && (mCoverSides[coverSide.ordinal()] == coverID)) + setCoverDataAtSide(coverSide, coverData); + } + + @Override + public long getTimer() { + return this.mTickTimer; + } + + @Override + public long getOutputAmperage() { + return this.canAccessData() && this.mMetaTileEntity.isElectric() ? this.mMetaTileEntity.maxAmperesOut() : 0L; + } + + @Override + public long getOutputVoltage() { + return this.canAccessData() && this.mMetaTileEntity.isElectric() && this.mMetaTileEntity.isEnetOutput() + ? this.mMetaTileEntity.maxEUOutput() + : 0L; + } + + @Override + public long getInputAmperage() { + return this.canAccessData() && this.mMetaTileEntity.isElectric() ? this.mMetaTileEntity.maxAmperesIn() : 0L; + } + + @Override + 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(ForgeDirection side) { + return side == ForgeDirection.UNKNOWN ? true + : (!this.isServerSide() ? this.isEnergyInputSide(side) + : side != ForgeDirection.UNKNOWN && this.mActiveEUInputs[side.ordinal()] && !this.mReleaseEnergy); + } + + @Override + public boolean outputsEnergyTo(ForgeDirection side) { + return side == ForgeDirection.UNKNOWN ? true + : (!this.isServerSide() ? this.isEnergyOutputSide(side) + : side != ForgeDirection.UNKNOWN && this.mActiveEUOutputs[side.ordinal()] || this.mReleaseEnergy); + } + + private boolean isEnergyInputSide(ForgeDirection side) { + if (side != ForgeDirection.UNKNOWN) { + if (!this.getCoverInfoAtSide(side) + .letsEnergyIn()) { + return false; + } + + if (this.isInvalid() || this.mReleaseEnergy) { + return false; + } + + if (this.canAccessData() && this.mMetaTileEntity.isElectric() && this.mMetaTileEntity.isEnetInput()) { + return this.mMetaTileEntity.isInputFacing(side); + } + } + + return false; + } + + private boolean isEnergyOutputSide(ForgeDirection side) { + if (side != ForgeDirection.UNKNOWN) { + if (!this.getCoverInfoAtSide(side) + .letsEnergyOut()) { + return false; + } + + if (this.isInvalid() || this.mReleaseEnergy) { + return this.mReleaseEnergy; + } + + if (this.canAccessData() && this.mMetaTileEntity.isElectric() && this.mMetaTileEntity.isEnetOutput()) { + return this.mMetaTileEntity.isOutputFacing(side); + } + } + + return false; + } + + public boolean isOutputFacing(ForgeDirection side) { + return false; + } + + public boolean isInputFacing(ForgeDirection side) { + return false; + } + + private final TileEntity[] mBufferedTileEntities = new TileEntity[6]; + public boolean ignoreUnloadedChunks = true; + public boolean isDead = false; + + private 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; + } + } + + @Override + public final World getWorld() { + return this.worldObj; + } + + @Override + public final int getXCoord() { + return this.xCoord; + } + + @Override + public final short getYCoord() { + return (short) this.yCoord; + } + + @Override + public final int getZCoord() { + return this.zCoord; + } + + @Override + public final int getOffsetX(ForgeDirection side, int aMultiplier) { + return this.xCoord + side.offsetX * aMultiplier; + } + + @Override + public final short getOffsetY(ForgeDirection side, int aMultiplier) { + return (short) (this.yCoord + side.offsetY * aMultiplier); + } + + @Override + public final int getOffsetZ(ForgeDirection side, int aMultiplier) { + return this.zCoord + side.offsetZ * aMultiplier; + } + + @Override + public final int getRandomNumber(int aRange) { + return this.worldObj.rand.nextInt(aRange); + } + + @Override + public final BiomeGenBase getBiome(int aX, int aZ) { + return this.worldObj.getBiomeGenForCoords(aX, aZ); + } + + @Override + public final BiomeGenBase getBiome() { + return this.getBiome(this.xCoord, this.zCoord); + } + + @Override + public final Block getBlockOffset(int aX, int aY, int aZ) { + return this.getBlock(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final Block getBlockAtSide(ForgeDirection side) { + return this.getBlockAtSideAndDistance(side, 1); + } + + @Override + public final Block getBlockAtSideAndDistance(ForgeDirection side, int aDistance) { + return this.getBlock( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final byte getMetaIDOffset(int aX, int aY, int aZ) { + return this.getMetaID(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final byte getMetaIDAtSide(ForgeDirection side) { + return this.getMetaIDAtSideAndDistance(side, 1); + } + + @Override + public final byte getMetaIDAtSideAndDistance(ForgeDirection side, int aDistance) { + return this.getMetaID( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final byte getLightLevelOffset(int aX, int aY, int aZ) { + return this.getLightLevel(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final byte getLightLevelAtSide(ForgeDirection side) { + return this.getLightLevelAtSideAndDistance(side, 1); + } + + @Override + public final byte getLightLevelAtSideAndDistance(ForgeDirection side, int aDistance) { + return this.getLightLevel( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final boolean getOpacityOffset(int aX, int aY, int aZ) { + return this.getOpacity(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final boolean getOpacityAtSide(ForgeDirection side) { + return this.getOpacityAtSideAndDistance(side, 1); + } + + @Override + public final boolean getOpacityAtSideAndDistance(ForgeDirection side, int aDistance) { + return this.getOpacity( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final boolean getSkyOffset(int aX, int aY, int aZ) { + return this.getSky(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final boolean getSkyAtSide(ForgeDirection side) { + return this.getSkyAtSideAndDistance(side, 1); + } + + @Override + public final boolean getSkyAtSideAndDistance(ForgeDirection side, int aDistance) { + return this.getSky( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final boolean getAirOffset(int aX, int aY, int aZ) { + return this.getAir(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final boolean getAirAtSide(ForgeDirection side) { + return this.getAirAtSideAndDistance(side, 1); + } + + @Override + public final boolean getAirAtSideAndDistance(ForgeDirection side, int aDistance) { + return this.getAir( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final TileEntity getTileEntityOffset(int aX, int aY, int aZ) { + return this.getTileEntity(this.xCoord + aX, this.yCoord + aY, this.zCoord + aZ); + } + + @Override + public final TileEntity getTileEntityAtSideAndDistance(ForgeDirection side, int aDistance) { + return aDistance == 1 ? this.getTileEntityAtSide(side) + : this.getTileEntity( + this.getOffsetX(side, aDistance), + this.getOffsetY(side, aDistance), + this.getOffsetZ(side, aDistance)); + } + + @Override + public final IInventory getIInventory(int aX, int aY, int aZ) { + TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ); + return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null; + } + + @Override + public final IInventory getIInventoryOffset(int aX, int aY, int aZ) { + TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ); + return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null; + } + + @Override + public final IInventory getIInventoryAtSide(ForgeDirection side) { + TileEntity tTileEntity = this.getTileEntityAtSide(side); + return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null; + } + + @Override + public final IInventory getIInventoryAtSideAndDistance(ForgeDirection side, int aDistance) { + TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(side, aDistance); + return tTileEntity instanceof IInventory ? (IInventory) tTileEntity : null; + } + + @Override + public final IFluidHandler getITankContainer(int aX, int aY, int aZ) { + TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ); + return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null; + } + + @Override + public final IFluidHandler getITankContainerOffset(int aX, int aY, int aZ) { + TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ); + return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null; + } + + @Override + public final IFluidHandler getITankContainerAtSide(ForgeDirection side) { + TileEntity tTileEntity = this.getTileEntityAtSide(side); + return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null; + } + + @Override + public final IFluidHandler getITankContainerAtSideAndDistance(ForgeDirection side, int aDistance) { + TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(side, aDistance); + return tTileEntity instanceof IFluidHandler ? (IFluidHandler) tTileEntity : null; + } + + @Override + public final IGregTechTileEntity getIGregTechTileEntity(int aX, int aY, int aZ) { + TileEntity tTileEntity = this.getTileEntity(aX, aY, aZ); + return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null; + } + + @Override + public final IGregTechTileEntity getIGregTechTileEntityOffset(int aX, int aY, int aZ) { + TileEntity tTileEntity = this.getTileEntityOffset(aX, aY, aZ); + return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null; + } + + @Override + public final IGregTechTileEntity getIGregTechTileEntityAtSide(ForgeDirection side) { + TileEntity tTileEntity = this.getTileEntityAtSide(side); + return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null; + } + + @Override + public final IGregTechTileEntity getIGregTechTileEntityAtSideAndDistance(ForgeDirection side, int aDistance) { + TileEntity tTileEntity = this.getTileEntityAtSideAndDistance(side, aDistance); + return tTileEntity instanceof IGregTechTileEntity ? (IGregTechTileEntity) tTileEntity : null; + } + + @Override + 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); + } + + @Override + 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); + } + + @Override + 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)); + } + + @Override + 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); + } + + @Override + 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); + } + + @Override + 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); + } + + @Override + 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); + } + + @Override + public final TileEntity getTileEntityAtSide(ForgeDirection side) { + final int ordinalSide = side.ordinal(); + if (side != ForgeDirection.UNKNOWN && this.mBufferedTileEntities[ordinalSide] != this) { + int tX = this.getOffsetX(side, 1); + short tY = this.getOffsetY(side, 1); + int tZ = this.getOffsetZ(side, 1); + if (this.crossedChunkBorder(tX, tZ)) { + this.mBufferedTileEntities[ordinalSide] = null; + if (this.ignoreUnloadedChunks && !this.worldObj.blockExists(tX, tY, tZ)) { + return null; + } + } + + if (this.mBufferedTileEntities[ordinalSide] == null) { + this.mBufferedTileEntities[ordinalSide] = this.worldObj.getTileEntity(tX, tY, tZ); + if (this.mBufferedTileEntities[ordinalSide] == null) { + this.mBufferedTileEntities[ordinalSide] = this; + return null; + } else { + return this.mBufferedTileEntities[ordinalSide]; + } + } else if (this.mBufferedTileEntities[ordinalSide].isInvalid()) { + this.mBufferedTileEntities[ordinalSide] = null; + return this.getTileEntityAtSide(side); + } else { + return this.mBufferedTileEntities[ordinalSide].xCoord == tX + && this.mBufferedTileEntities[ordinalSide].yCoord == tY + && this.mBufferedTileEntities[ordinalSide].zCoord == tZ ? this.mBufferedTileEntities[ordinalSide] + : null; + } + } else { + return null; + } + } + + @Override + public boolean isDead() { + return this.isDead || this.isInvalidTileEntity(); + } + + @Override + public void validate() { + this.clearNullMarkersFromTileEntityBuffer(); + super.validate(); + } + + @Override + public void invalidate() { + this.clearNullMarkersFromTileEntityBuffer(); + super.invalidate(); + } + + @Override + public void onChunkUnload() { + this.clearNullMarkersFromTileEntityBuffer(); + super.onChunkUnload(); + this.isDead = true; + } + + public final void onAdjacentBlockChange(int aX, int aY, int aZ) { + this.clearNullMarkersFromTileEntityBuffer(); + } + + @Override + 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); + } + + @Override + public byte getInternalInputRedstoneSignal(ForgeDirection side) { + return (byte) (getCoverBehaviorAtSide(side).getRedstoneInput( + side, + getInputRedstoneSignal(side), + getCoverIDAtSide(side), + getCoverDataAtSide(side), + this) & 15); + } + + @Override + public byte getInputRedstoneSignal(ForgeDirection side) { + return (byte) (worldObj + .getIndirectPowerLevelTo(getOffsetX(side, 1), getOffsetY(side, 1), getOffsetZ(side, 1), side.ordinal()) + & 15); + } + + @Override + public byte getOutputRedstoneSignal(ForgeDirection side) { + return getCoverBehaviorAtSide(side) + .manipulatesSidedRedstoneOutput(side, getCoverIDAtSide(side), getCoverDataAtSide(side), this) + ? mSidedRedstone[side.ordinal()] + : getGeneralRS(side); + } + + public boolean allowGeneralRedstoneOutput() { + return false; + } + + @Override + public byte getGeneralRS(ForgeDirection side) { + return allowGeneralRedstoneOutput() ? mSidedRedstone[side.ordinal()] : 0; + } + + @Override + public void setInternalOutputRedstoneSignal(ForgeDirection side, byte aStrength) { + if (!getCoverBehaviorAtSide(side) + .manipulatesSidedRedstoneOutput(side, getCoverIDAtSide(side), getCoverDataAtSide(side), this)) + setOutputRedstoneSignal(side, aStrength); + } + + @Override + public void setOutputRedstoneSignal(ForgeDirection side, byte aStrength) { + aStrength = (byte) Math.min(Math.max(0, aStrength), 15); + if (side != ForgeDirection.UNKNOWN && mSidedRedstone[side.ordinal()] != aStrength) { + mSidedRedstone[side.ordinal()] = aStrength; + issueBlockUpdate(); + } + } + + @Override + public boolean hasInventoryBeenModified() { + return mInventoryChanged; + } + + @Override + public void setGenericRedstoneOutput(boolean aOnOff) { + mRedstone = aOnOff; + } + + @Override + public GT_CoverBehavior getCoverBehaviorAtSide(ForgeDirection side) { + return side != ForgeDirection.UNKNOWN ? mCoverBehaviors[side.ordinal()] : GregTech_API.sNoBehavior; + } + + @Override + public void setCoverIDAtSide(ForgeDirection side, int aID) { + if (setCoverIDAtSideNoUpdate(side, aID)) { + issueCoverUpdate(side); + issueBlockUpdate(); + } + } + + @Override + public boolean setCoverIDAtSideNoUpdate(ForgeDirection side, int aID) { + if (side != ForgeDirection.UNKNOWN) { + final int ordinalSide = side.ordinal(); + mCoverSides[ordinalSide] = aID; + mCoverData[ordinalSide] = 0; + mCoverBehaviors[ordinalSide] = (GT_CoverBehavior) GregTech_API.getCoverBehaviorNew(aID); + return true; + } + return false; + } + + @Override + public void setCoverIdAndDataAtSide(ForgeDirection side, int aId, ISerializableObject aData) { + setCoverIDAtSide(side, aId); + setCoverDataAtSide(side, aData); + } + + @Override + public void setCoverItemAtSide(ForgeDirection side, ItemStack aCover) { + GregTech_API.getCoverBehaviorNew(aCover) + .placeCover(side, aCover, this); + } + + @Override + public int getCoverIDAtSide(ForgeDirection side) { + if (side != ForgeDirection.UNKNOWN) return mCoverSides[side.ordinal()]; + return 0; + } + + @Override + public ItemStack getCoverItemAtSide(ForgeDirection side) { + return GT_Utility.intToStack(getCoverIDAtSide(side)); + } + + @Override + public boolean canPlaceCoverIDAtSide(ForgeDirection side, int aID) { + return getCoverIDAtSide(side) == 0; + } + + @Override + public boolean canPlaceCoverItemAtSide(ForgeDirection side, ItemStack aCover) { + return getCoverIDAtSide(side) == 0; + } + + @Override + public void setCoverDataAtSide(ForgeDirection side, int aData) { + if (side != ForgeDirection.UNKNOWN) mCoverData[side.ordinal()] = aData; + } + + @Override + public int getCoverDataAtSide(ForgeDirection side) { + if (side != ForgeDirection.UNKNOWN) return mCoverData[side.ordinal()]; + 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(ForgeDirection side, ForgeDirection droppedSide, boolean aForced) { + if (getCoverBehaviorAtSide(side) + .onCoverRemoval(side, getCoverIDAtSide(side), mCoverData[side.ordinal()], this, aForced) || aForced) { + ItemStack tStack = getCoverBehaviorAtSide(side) + .getDrop(side, getCoverIDAtSide(side), getCoverDataAtSide(side), this); + if (tStack != null) { + tStack.setTagCompound(null); + EntityItem tEntity = new EntityItem( + worldObj, + getOffsetX(droppedSide, 1) + 0.5, + getOffsetY(droppedSide, 1) + 0.5, + getOffsetZ(droppedSide, 1) + 0.5, + tStack); + tEntity.motionX = 0; + tEntity.motionY = 0; + tEntity.motionZ = 0; + worldObj.spawnEntityInWorld(tEntity); + } + setCoverIDAtSide(side, 0); + if (mMetaTileEntity.hasSidedRedstoneOutputBehavior()) { + setOutputRedstoneSignal(side, (byte) 0); + } else { + setOutputRedstoneSignal(side, (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(ForgeDirection side) { + return canAccessData() ? mMetaTileEntity.getComparatorValue(side) : 0; + } + + @Override + public byte getStrongOutputRedstoneSignal(ForgeDirection side) { + final int ordinalSide = side.ordinal(); + return side != ForgeDirection.UNKNOWN && (mStrongRedstone & (1 << ordinalSide)) != 0 + ? (byte) (mSidedRedstone[ordinalSide] & 15) + : 0; + } + + @Override + public void setStrongOutputRedstoneSignal(ForgeDirection side, byte aStrength) { + mStrongRedstone |= (1 << side.ordinal()); + setOutputRedstoneSignal(side, aStrength); + } + + @Override + public long injectEnergyUnits(ForgeDirection side, long aVoltage, long aAmperage) { + if (!canAccessData() || !mMetaTileEntity.isElectric() + || !inputEnergyFrom(side) + || 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(ForgeDirection side, long aVoltage, long aAmperage) { + if (!canAccessData() || !mMetaTileEntity.isElectric() + || !outputsEnergyTo(side) + || 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 side) { + return false; + } + + public double demandedEnergyUnits() { + if (mReleaseEnergy || !canAccessData() || !mMetaTileEntity.isEnetInput()) return 0; + return getEUCapacity() - getStoredEU(); + } + + public double injectEnergyUnits(ForgeDirection aDirection, double aAmount) { + return injectEnergyUnits(aDirection, (int) aAmount, 1) > 0 ? 0 : aAmount; + } + + public boolean acceptsEnergyFrom(TileEntity aEmitter, ForgeDirection aDirection) { + return inputEnergyFrom(aDirection); + } + + public boolean emitsEnergyTo(TileEntity aReceiver, ForgeDirection aDirection) { + return outputsEnergyTo(aDirection); + } + + 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(aForgeDirection, 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(aDirection.toForgeDirection(), aAmount, 1) > 0 ? 0 : aAmount; + } + + public boolean acceptsEnergyFrom(TileEntity aReceiver, Direction aDirection) { + return inputEnergyFrom(aDirection.toForgeDirection()); + } + + public boolean emitsEnergyTo(TileEntity aReceiver, Direction aDirection) { + return outputsEnergyTo(aDirection.toForgeDirection()); + } + + @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; + } + + @Override + public long getStoredEU() { + return this.canAccessData() ? Math.min(this.mMetaTileEntity.getEUVar(), this.getEUCapacity()) : 0L; + } + + @Override + 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/general/TileEntityCircuitProgrammer.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityCircuitProgrammer.java new file mode 100644 index 0000000000..0be6959b8f --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityCircuitProgrammer.java @@ -0,0 +1,313 @@ +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<>(); + 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..b641f2e99e --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityDecayablesChest.java @@ -0,0 +1,378 @@ +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.tileentity.TileEntity; +import net.minecraft.world.World; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.inventories.Inventory_DecayablesChest; +import gtPlusPlus.core.item.materials.DustDecayable; +import gtPlusPlus.core.util.minecraft.ItemUtils; + +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 D) { + 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 + */ + @Override + 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 + */ + @Override + 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 + */ + @Override + public final void invalidate() { + super.invalidate(); + cachedChestType = 1; + this.updateContainingBlockInfo(); + this.checkForAdjacentChests(); + } + + private 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/TileEntityFishTrap.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFishTrap.java new file mode 100644 index 0000000000..1a09b6b423 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityFishTrap.java @@ -0,0 +1,294 @@ +package gtPlusPlus.core.tileentities.general; + +import static gregtech.api.enums.Mods.PamsHarvestCraft; + +import java.util.Random; + +import javax.annotation.Nullable; + +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 net.minecraftforge.common.FishingHooks; + +import gregtech.api.enums.Materials; +import gregtech.api.util.GT_Utility; +import gtPlusPlus.core.block.ModBlocks; +import gtPlusPlus.core.inventories.InventoryFishTrap; +import gtPlusPlus.core.util.math.MathUtils; +import gtPlusPlus.core.util.minecraft.ItemUtils; + +public class TileEntityFishTrap extends TileEntity implements ISidedInventory { + + private int tickCount = 0; + private final InventoryFishTrap inventoryContents; + private String customName; + // The number of water blocks is used as an index to get the tick rate. + private final static short[] waterBlocksToTickRate = new short[] { 0, 0, 5600, 4400, 3200, 2000, 1750 }; + private int surroundingWaterBlocks = 0; + + public TileEntityFishTrap() { + this.inventoryContents = new InventoryFishTrap(); + } + + private int getNumberOfSurroundingWater() { + if (!this.hasWorldObj() || this.getWorldObj().isRemote) { + return 0; + } + final Block[] surroundingBlocks = new Block[6]; + surroundingBlocks[0] = this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord); // Above + surroundingBlocks[1] = this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord); // Below + surroundingBlocks[2] = this.worldObj.getBlock(this.xCoord + 1, this.yCoord, this.zCoord); + surroundingBlocks[3] = this.worldObj.getBlock(this.xCoord - 1, this.yCoord, this.zCoord); + surroundingBlocks[4] = this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord + 1); + surroundingBlocks[5] = this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord - 1); + int waterCount = 0; + int trapCount = 0; + for (final Block checkBlock : surroundingBlocks) { + if (checkBlock == ModBlocks.blockFishTrap) { + trapCount++; + } else if ((checkBlock == Blocks.water) || (checkBlock == Blocks.flowing_water)) { + waterCount++; + } + } + // Explicitly check for at least 2 water blocks. + if (waterCount < 2) { + return 0; + } + // Only allow the first four traps to count towards valid neighbor blocks. + return waterCount + Math.min(trapCount, 4); + } + + public InventoryFishTrap getInventory() { + return this.inventoryContents; + } + + private void tryAddLoot() { + ItemUtils.organiseInventory(getInventory()); + final ItemStack loot = this.generateLootForFishTrap(); + if (loot == null) { + return; + } + for (final ItemStack contents : this.getInventory() + .getInventory()) { + if (GT_Utility.areStacksEqual(loot, contents)) { + if (contents.stackSize < contents.getMaxStackSize()) { + contents.stackSize++; + this.markDirty(); + return; + } + } + } + int checkingSlot = 0; + for (final ItemStack contents : this.getInventory() + .getInventory()) { + if (contents == null) { + this.getInventory() + .setInventorySlotContents(checkingSlot, loot); + this.markDirty(); + return; + } + checkingSlot++; + } + } + + @Nullable + private ItemStack generateLootForFishTrap() { + final int lootWeight = MathUtils.randInt(0, 100); + ItemStack loot = null; + 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 (PamsHarvestCraft.isModLoaded()) { + loot = ItemUtils.getItemStackOfAmountFromOreDictNoBroken("cropSeaweed", 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 = Materials.Iron.getNuggets(1); + } else if (rareLoot <= 7) { + loot = ItemUtils.getSimpleStack(Items.gold_nugget); + } else if (rareLoot <= 9) { + loot = ItemUtils.getSimpleStack(Items.emerald); + } else { + loot = ItemUtils.getSimpleStack(Items.diamond); + } + } + if (loot != null) { + loot.stackSize = 1; + } + return loot; + } + + @Override + public void updateEntity() { + if (this.worldObj.isRemote) { + return; + } + + this.tickCount++; + // Only recalculate the amount of neighboring water/trap blocks every 20 ticks. + if ((this.tickCount % 20) == 0) { + this.surroundingWaterBlocks = getNumberOfSurroundingWater(); + } + + if ((waterBlocksToTickRate[this.surroundingWaterBlocks] != 0) + && this.tickCount > waterBlocksToTickRate[this.surroundingWaterBlocks]) { + int aExtraLootChance = MathUtils.randInt(1, 1000); + if (aExtraLootChance >= 999) { + this.tryAddLoot(); + this.tryAddLoot(); + this.tryAddLoot(); + } else { + this.tryAddLoot(); + } + this.markDirty(); + + this.tickCount = 0; + } + } + + @Override + public void writeToNBT(final NBTTagCompound nbt) { + super.writeToNBT(nbt); + 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); + 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() { + 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.isEmpty(); + } +} 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..fd528c589d --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityInfiniteFluid.java @@ -0,0 +1,148 @@ +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.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 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/TileEntityVolumetricFlaskSetter.java b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityVolumetricFlaskSetter.java new file mode 100644 index 0000000000..a9bc2b0049 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/general/TileEntityVolumetricFlaskSetter.java @@ -0,0 +1,418 @@ +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 net.minecraftforge.fluids.FluidStack; + +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; + +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 int aCustomValue = 1000; + + public TileEntityVolumetricFlaskSetter() { + this.inventoryContents = new Inventory_VolumetricFlaskSetter(); + this.setTileLocation(); + } + + public int getCustomValue() { + // Logger.INFO("Value: "+this.aCustomValue); + return this.aCustomValue; + } + + public void setCustomValue(int aVal) { + log("Old Value: " + this.aCustomValue); + this.aCustomValue = (short) MathUtils.balance(aVal, 0, Short.MAX_VALUE); + log("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) { + return switch (aSlot) { + case 0 -> // 16 + 16; + case 1 -> // 36 + 36; + case 2 -> // 144 + 144; + case 3 -> // 432 + 432; + case 4 -> // 576 + 576; + case 5 -> // 720 + 720; + case 6 -> // 864 + 864; + case 7 -> // Custom + getCustomValue(); + default -> 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<>(); + 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) { + log("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))) { + log( + "Input Slot Flask Contains: " + + (aInputFluidStack != null ? aInputFluidStack.getLocalizedName() : "Empty")); + log( + "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.setInteger("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.getInteger("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; + } + } + + public void log(String aString) { + Logger.INFO("[Flask-Tile] " + aString); + } +} 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..5e0aaf8370 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityAdvPooCollector.java @@ -0,0 +1,140 @@ +package gtPlusPlus.core.tileentities.machines; + +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; + +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.core.item.chemistry.AgriculturalChem; +import gtPlusPlus.core.util.math.MathUtils; +import gtPlusPlus.core.util.minecraft.ItemUtils; + +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; + } + + @Override + public void onPreLogicTick() {} + + @Override + 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<>(); + + @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; + } + + @Override + 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..6340415e82 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityBaseFluidCollector.java @@ -0,0 +1,241 @@ +package gtPlusPlus.core.tileentities.machines; + +import java.util.List; + +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; + +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; + +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/TileEntityPestKiller.java b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPestKiller.java new file mode 100644 index 0000000000..dfdb7104b0 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPestKiller.java @@ -0,0 +1,532 @@ +package gtPlusPlus.core.tileentities.machines; + +import static gregtech.api.enums.Mods.Forestry; + +import java.util.ArrayList; +import java.util.List; + +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; + +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.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; + +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<>(); + + static { + mEntityMap.put(EntityBat.class); + if (Forestry.isModLoaded()) { + 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 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; + } + case 2 -> { + min = -4; + max = 5; + } + default -> {} + // code block + } + int aChunkCount = 0; + AutoMap<Entity> entities = new AutoMap<>(); + 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); + } + } + 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 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..d0d4ee3661 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityPooCollector.java @@ -0,0 +1,128 @@ +package gtPlusPlus.core.tileentities.machines; + +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; + +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.core.item.chemistry.AgriculturalChem; +import gtPlusPlus.core.util.math.MathUtils; +import gtPlusPlus.core.util.minecraft.ItemUtils; + +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; + } + + @Override + public void onPreLogicTick() {} + + @Override + 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<>(); + + @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..7c90ddc1c2 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/tileentities/machines/TileEntityProjectTable.java @@ -0,0 +1,165 @@ +package gtPlusPlus.core.tileentities.machines; + +import java.util.List; +import java.util.Vector; + +import net.minecraft.entity.player.EntityPlayer; +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.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; + + 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); + } + } + + } + super.updateEntity(); + } + + @Override + public boolean canUpdate() { + return true; + } +} |