package shedar.mods.ic2.nuclearcontrol.tileentities; import ic2.api.energy.event.EnergyTileLoadEvent; import ic2.api.energy.event.EnergyTileUnloadEvent; import ic2.api.energy.tile.IEnergySink; import ic2.api.item.ElectricItem; import ic2.api.item.IC2Items; import ic2.api.item.IElectricItem; import ic2.api.reactor.IReactor; import ic2.core.IC2; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ChunkCoordinates; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.ForgeDirection; import shedar.mods.ic2.nuclearcontrol.IC2NuclearControl; import shedar.mods.ic2.nuclearcontrol.IRotation; import shedar.mods.ic2.nuclearcontrol.ISlotItemFilter; import shedar.mods.ic2.nuclearcontrol.items.ItemCard55Reactor; import shedar.mods.ic2.nuclearcontrol.items.ItemCardReactorSensorLocation; import shedar.mods.ic2.nuclearcontrol.items.ItemUpgrade; import shedar.mods.ic2.nuclearcontrol.panel.CardWrapperImpl; import shedar.mods.ic2.nuclearcontrol.utils.BlockDamages; import shedar.mods.ic2.nuclearcontrol.utils.NuclearHelper; import java.util.List; import cpw.mods.fml.common.FMLLog; public class TileEntityRemoteThermo extends TileEntityThermo implements IEnergySink, ISlotItemFilter, IRotation, IInventory{ public static final int SLOT_CHARGER = 0; public static final int SLOT_CARD = 1; private static final double BASE_PACKET_SIZE = 32.0D; private static final int BASE_STORAGE = 600; private static final int STORAGE_PER_UPGRADE = 10000; private static final int ENERGY_SU_BATTERY = 1000; private static final int LOCATION_RANGE = 8; private int deltaX; private int deltaY; private int deltaZ; private double prevMaxStorage; public double maxStorage; public double prevMaxPacketSize; public double maxPacketSize; private int prevTier; public int tier; public int rotation; public int prevRotation; public double energy; private boolean addedToEnergyNet; private ItemStack inventory[]; public TileEntityRemoteThermo() { super(); inventory = new ItemStack[5];// battery + card + 3 overclockers addedToEnergyNet = false; maxStorage = BASE_STORAGE; maxPacketSize = BASE_PACKET_SIZE; tier = 1; deltaX = 0; deltaY = 0; deltaZ = 0; energy = 0; prevRotation = 0; rotation = 0; } @Override public List<String> getNetworkedFields() { List<String> list = super.getNetworkedFields(); list.add("maxStorage"); list.add("tier"); list.add("maxPacketSize"); list.add("rotation"); return list; } @Override protected void checkStatus() { if (!addedToEnergyNet) { EnergyTileLoadEvent event = new EnergyTileLoadEvent(this); MinecraftForge.EVENT_BUS.post(event); addedToEnergyNet = true; } markDirty(); int fire; if (energy >= IC2NuclearControl.instance.remoteThermalMonitorEnergyConsumption){ IReactor reactor = NuclearHelper.getReactorAt(worldObj, xCoord + deltaX, yCoord + deltaY, zCoord + deltaZ); //UUID cardType = null; if(reactor == null){ if (inventory[SLOT_CARD] != null){ ChunkCoordinates target = new CardWrapperImpl(inventory[SLOT_CARD], SLOT_CARD).getTarget(); if(target != null){ int x = target.posX; int y = target.posY; int z = target.posZ; reactor = ItemCard55Reactor.getReactor(worldObj, x, y, z); } } } if (reactor != null){ if (tickRate == -1){ tickRate = reactor.getTickRate() / 2; if (tickRate == 0) tickRate = 1; updateTicker = tickRate; } int reactorHeat = reactor.getHeat(); fire = reactorHeat; }else{ fire = -1; } }else{ fire = -2; } if (fire != getOnFire()){ setOnFire(fire); worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, worldObj.getBlock(xCoord, yCoord, zCoord)); } } public double getEnergy(){ return energy; } public void setEnergy(double value) { energy = value; } public void setTier(int value) { tier = value; if (tier != prevTier) { IC2.network.get().updateTileEntityField(this, "tier"); } prevTier = tier; } @Override public void setRotation(int value) { rotation = value; if (rotation != prevRotation) { IC2.network.get().updateTileEntityField(this, "rotation"); } prevRotation = rotation; } public void setMaxPacketSize(double value) { maxPacketSize = value; if (maxPacketSize != prevMaxPacketSize) { IC2.network.get().updateTileEntityField(this, "maxPacketSize"); } prevMaxPacketSize = maxPacketSize; } public void setMaxStorage(double value) { maxStorage = value; if (maxStorage != prevMaxStorage) { IC2.network.get().updateTileEntityField(this, "maxStorage"); } prevMaxStorage = maxStorage; } @Override public void updateEntity() { super.updateEntity(); if (!worldObj.isRemote) { //If is server int consumption = IC2NuclearControl.instance.remoteThermalMonitorEnergyConsumption; if (inventory[SLOT_CHARGER] != null) { if (energy < maxStorage) { if (inventory[SLOT_CHARGER].getItem() instanceof IElectricItem) { IElectricItem ielectricitem = (IElectricItem) inventory[SLOT_CHARGER].getItem(); if (ielectricitem.canProvideEnergy(inventory[SLOT_CHARGER])) { double k = ElectricItem.manager.discharge(inventory[SLOT_CHARGER], maxStorage - energy, tier, false, false, false); energy += k; } }else if (Item.getIdFromItem(inventory[SLOT_CHARGER].getItem()) == Item.getIdFromItem((IC2Items.getItem("suBattery")).getItem())){ if (ENERGY_SU_BATTERY <= maxStorage - energy || energy == 0) { inventory[SLOT_CHARGER].stackSize--; if (inventory[SLOT_CHARGER].stackSize <= 0) { inventory[SLOT_CHARGER] = null; } energy += ENERGY_SU_BATTERY; if (energy > maxStorage) energy = maxStorage; } } } } if (energy >= consumption) { energy -= consumption; }else{ energy = 0; } setEnergy(energy); } } @Override public void readFromNBT(NBTTagCompound nbttagcompound) { super.readFromNBT(nbttagcompound); energy = nbttagcompound.getDouble("energy"); //I'm not sure why it was getInt instead of double... if (nbttagcompound.hasKey("rotation")) { prevRotation = rotation = nbttagcompound.getInteger("rotation"); } NBTTagList nbttaglist = nbttagcompound.getTagList("Items", Constants.NBT.TAG_COMPOUND); inventory = new ItemStack[getSizeInventory()]; for (int i = 0; i < nbttaglist.tagCount(); i++) { NBTTagCompound compound = nbttaglist.getCompoundTagAt(i); byte slotNum = compound.getByte("Slot"); if (slotNum >= 0 && slotNum < inventory.length) { inventory[slotNum] = ItemStack.loadItemStackFromNBT(compound); } } markDirty(); } @Override public void writeToNBT(NBTTagCompound nbttagcompound) { super.writeToNBT(nbttagcompound); nbttagcompound.setDouble("energy", energy); nbttagcompound.setInteger("rotation", rotation); NBTTagList nbttaglist = new NBTTagList(); for (int i = 0; i < inventory.length; i++) { if (inventory[i] != null) { NBTTagCompound compound = new NBTTagCompound(); compound.setByte("Slot", (byte) i); inventory[i].writeToNBT(compound); nbttaglist.appendTag(compound); } } nbttagcompound.setTag("Items", nbttaglist); } @Override public void onNetworkUpdate(String field) { super.onNetworkUpdate(field); if (field.equals("rotation") && prevRotation != rotation) { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); prevRotation = rotation; } } @Override public void invalidate() { if (!worldObj.isRemote && addedToEnergyNet) { EnergyTileUnloadEvent event = new EnergyTileUnloadEvent(this); MinecraftForge.EVENT_BUS.post(event); addedToEnergyNet = false; } super.invalidate(); } @Override public int getSizeInventory() { return inventory.length; } @Override public ItemStack getStackInSlot(int slotNum) { return inventory[slotNum]; } @Override public ItemStack decrStackSize(int slotNum, int amount) { if (inventory[slotNum] != null) { if (inventory[slotNum].stackSize <= amount) { ItemStack itemStack = inventory[slotNum]; inventory[slotNum] = null; return itemStack; } ItemStack taken = inventory[slotNum].splitStack(amount); if (inventory[slotNum].stackSize == 0) { inventory[slotNum] = null; } return taken; } return null; } @Override public ItemStack getStackInSlotOnClosing(int var1) { return null; } @Override public void setInventorySlotContents(int slotNum, ItemStack itemStack) { inventory[slotNum] = itemStack; if (itemStack != null && itemStack.stackSize > getInventoryStackLimit()) { itemStack.stackSize = getInventoryStackLimit(); } } @Override public String getInventoryName(){ return "block.RemoteThermo"; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return worldObj.getTileEntity(xCoord, yCoord, zCoord) == this && player.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64D; } @Override public void openInventory(){} @Override public void closeInventory(){} @Override public void markDirty() { super.markDirty(); int upgradeCountTransormer = 0; int upgradeCountStorage = 0; int upgradeCountRange = 0; for (int i = 2; i < 5; i++) { ItemStack itemStack = inventory[i]; if (itemStack == null) { continue; } if (itemStack.isItemEqual(IC2Items.getItem("transformerUpgrade"))) { upgradeCountTransormer += itemStack.stackSize; }else if (itemStack.isItemEqual(IC2Items.getItem("energyStorageUpgrade"))) { upgradeCountStorage += itemStack.stackSize; }else if (itemStack.getItem() instanceof ItemUpgrade && itemStack.getItemDamage() == ItemUpgrade.DAMAGE_RANGE) { upgradeCountRange += itemStack.stackSize; } } if (inventory[SLOT_CARD] != null) { ChunkCoordinates target = new CardWrapperImpl(inventory[SLOT_CARD], SLOT_CARD).getTarget(); if (target != null) { deltaX = target.posX - xCoord; deltaY = target.posY - yCoord; deltaZ = target.posZ - zCoord; if (upgradeCountRange > 7) upgradeCountRange = 7; int range = LOCATION_RANGE * (int) Math.pow(2, upgradeCountRange); if (Math.abs(deltaX) > range || Math.abs(deltaY) > range || Math.abs(deltaZ) > range) { deltaX = deltaY = deltaZ = 0; } }else{ deltaX = 0; deltaY = 0; deltaZ = 0; } }else{ deltaX = 0; deltaY = 0; deltaZ = 0; } upgradeCountTransormer = Math.min(upgradeCountTransormer, 4); if (worldObj != null && !worldObj.isRemote) { tier = upgradeCountTransormer + 1; setTier(tier); maxPacketSize = BASE_PACKET_SIZE * Math.pow(4D, upgradeCountTransormer); setMaxPacketSize(maxPacketSize); maxStorage = BASE_STORAGE + STORAGE_PER_UPGRADE * upgradeCountStorage; setMaxStorage(maxStorage); if (energy > maxStorage) energy = maxStorage; setEnergy(energy); } } @Override public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction) { return true; } @Override public double getDemandedEnergy() { return maxStorage - energy; } @Override public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage) { energy += amount; double left = 0.0; if (energy > maxStorage) { left = energy - maxStorage; energy = maxStorage; } setEnergy(energy); return left; } @Override public boolean isItemValid(int slotIndex, ItemStack itemstack) { switch (slotIndex) { case SLOT_CHARGER: if (Item.getIdFromItem(itemstack.getItem()) == Item.getIdFromItem(IC2Items.getItem("suBattery").getItem())) return true; if (itemstack.getItem() instanceof IElectricItem) { IElectricItem item = (IElectricItem) itemstack.getItem(); if (item.canProvideEnergy(itemstack) && item.getTier(itemstack) <= tier) { return true; } } return false; case SLOT_CARD: return itemstack.getItem() instanceof ItemCardReactorSensorLocation || itemstack.getItem() instanceof ItemCard55Reactor; default: return itemstack.isItemEqual(IC2Items.getItem("transformerUpgrade")) || itemstack.isItemEqual(IC2Items.getItem("energyStorageUpgrade")) || (itemstack.getItem() instanceof ItemUpgrade && itemstack.getItemDamage() == ItemUpgrade.DAMAGE_RANGE); } } @Override public boolean wrenchCanSetFacing(EntityPlayer entityPlayer, int face) { return !entityPlayer.isSneaking() && getFacing() != face; } @Override public boolean wrenchCanRemove(EntityPlayer entityPlayer) { return !entityPlayer.isSneaking(); } @Override public int modifyTextureIndex(int texture) { return texture; } @Override public void rotate() { int r; switch (rotation) { case 0: r = 1; break; case 1: r = 3; break; case 3: r = 2; break; case 2: r = 0; break; default: r = 0; break; } setRotation(r); } @Override public int getRotation() { return rotation; } @Override public ItemStack getWrenchDrop(EntityPlayer entityPlayer) { return new ItemStack(IC2NuclearControl.blockNuclearControlMain, 1, BlockDamages.DAMAGE_REMOTE_THERMO); } @Override public int getSinkTier() { return tier; } @Override public boolean hasCustomInventoryName() { return false; } @Override public boolean isItemValidForSlot(int slot, ItemStack itemstack) { return isItemValid(slot, itemstack); } }