package pneumaticCraft.common.tileentity; import java.util.Iterator; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemFood; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import pneumaticCraft.common.PneumaticCraftAPIHandler; import pneumaticCraft.common.block.Blockss; import pneumaticCraft.common.item.ItemMachineUpgrade; import pneumaticCraft.common.item.Itemss; import pneumaticCraft.common.network.GuiSynced; import pneumaticCraft.common.util.PneumaticCraftUtils; import pneumaticCraft.lib.ModIds; import pneumaticCraft.lib.PneumaticValues; import cofh.api.energy.EnergyStorage; import cofh.api.energy.IEnergyContainerItem; import cofh.api.energy.IEnergyReceiver; import cofh.api.tileentity.IEnergyInfo; import com.mojang.authlib.GameProfile; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Optional; @Optional.InterfaceList({@Optional.Interface(iface = "cofh.api.energy.IEnergyReceiver", modid = ModIds.COFH_CORE), @Optional.Interface(iface = "cofh.api.tileentity.IEnergyInfo", modid = ModIds.COFH_CORE)}) public class TileEntityAerialInterface extends TileEntityPneumaticBase implements ISidedInventory, IFluidHandler, IMinWorkingPressure, IRedstoneControl, IEnergyReceiver, IEnergyInfo{ private ItemStack[] inventory; private final int INVENTORY_SIZE = 4; private static final int UPGRADE_SLOT_START = 0; private static final int UPGRADE_SLOT_END = 3; @GuiSynced public String playerName = ""; public String playerUUID = ""; private Fluid curXpFluid; @GuiSynced public int redstoneMode; @GuiSynced public int feedMode; private boolean oldRedstoneStatus; private boolean updateNeighbours; @GuiSynced public boolean isConnectedToPlayer; private boolean dispenserUpgradeInserted; public TileEntityAerialInterface(){ super(PneumaticValues.DANGER_PRESSURE_AERIAL_INTERFACE, PneumaticValues.MAX_PRESSURE_AERIAL_INTERFACE, PneumaticValues.VOLUME_AERIAL_INTERFACE); inventory = new ItemStack[INVENTORY_SIZE]; setUpgradeSlots(new int[]{UPGRADE_SLOT_START, 1, 2, UPGRADE_SLOT_END}); if(isRFAvailable()) initRF(); } public void setPlayer(GameProfile gameProfile){ setPlayer(gameProfile.getName(), gameProfile.getId() != null ? gameProfile.getId().toString() : ""); } public void setPlayer(String username, String uuid){ playerName = username; playerUUID = uuid; updateNeighbours = true; } @Override public void updateEntity(){ if(!worldObj.isRemote && updateNeighbours) { updateNeighbours = false; updateNeighbours(); } if(!worldObj.isRemote) { if(getPressure(ForgeDirection.UNKNOWN) > PneumaticValues.MIN_PRESSURE_AERIAL_INTERFACE && isConnectedToPlayer) { if(energyRF != null) tickRF(); addAir(-PneumaticValues.USAGE_AERIAL_INTERFACE, ForgeDirection.UNKNOWN); if(worldObj.getTotalWorldTime() % 40 == 0) dispenserUpgradeInserted = getUpgrades(ItemMachineUpgrade.UPGRADE_DISPENSER_DAMAGE) > 0; if(worldObj.getTotalWorldTime() % 20 == 0) { EntityPlayer player = getPlayer(); if(player != null && player.getAir() <= 280) { player.setAir(player.getAir() + 20); addAir(-4000, null); } } } if(worldObj.getTotalWorldTime() % 20 == 0) getPlayerInventory(); } if(oldRedstoneStatus != shouldEmitRedstone()) { oldRedstoneStatus = shouldEmitRedstone(); updateNeighbours = true; } super.updateEntity(); } @Override public void handleGUIButtonPress(int buttonID, EntityPlayer player){ if(buttonID == 0) { redstoneMode++; if(redstoneMode > 1) redstoneMode = 0; // updateNeighbours(); } else if(buttonID >= 1 && buttonID < 4) { feedMode = buttonID - 1; } } public boolean shouldEmitRedstone(){ // if(!worldObj.isRemote) System.out.println("redstone mode: " + // redstoneMode + ", charging: " + charging + ",discharging: " + // disCharging); switch(redstoneMode){ case 0: return false; case 1: return isConnectedToPlayer; } return false; } private InventoryPlayer getPlayerInventory(){ EntityPlayer player = getPlayer(); return player != null ? player.inventory : null; } private EntityPlayer getPlayer(){ if(worldObj != null && !worldObj.isRemote) { EntityPlayer player = PneumaticCraftUtils.getPlayerFromId(playerUUID); isConnectedToPlayer = player != null; return player; } return null; } @Override public boolean hasCustomInventoryName(){ return false; } /** * Returns the number of slots in the inventory. */ @Override public int getSizeInventory(){ InventoryPlayer inventoryPlayer = getPlayerInventory(); return inventory.length + (inventoryPlayer != null ? inventoryPlayer.getSizeInventory() + (dispenserUpgradeInserted ? 1 : 0) : 0); } /** * Returns the stack in slot i */ @Override public ItemStack getStackInSlot(int slot){ if(slot < 4) { return inventory[slot]; } else { InventoryPlayer inventoryPlayer = getPlayerInventory(); return inventoryPlayer != null ? slot == inventory.length + inventoryPlayer.getSizeInventory() ? null : inventoryPlayer.getStackInSlot(slot - 4) : null; } } @Override public ItemStack decrStackSize(int slot, int amount){ if(slot < 4) { ItemStack itemStack = getStackInSlot(slot); if(itemStack != null) { if(itemStack.stackSize <= amount) { setInventorySlotContents(slot, null); } else { itemStack = itemStack.splitStack(amount); if(itemStack.stackSize == 0) { setInventorySlotContents(slot, null); } } } return itemStack; } else { InventoryPlayer inventoryPlayer = getPlayerInventory(); return inventoryPlayer != null ? inventoryPlayer.decrStackSize(slot - 4, amount) : null; } } @Override public ItemStack getStackInSlotOnClosing(int slot){ if(slot < 4) { ItemStack itemStack = getStackInSlot(slot); if(itemStack != null) { setInventorySlotContents(slot, null); } return itemStack; } else { InventoryPlayer inventoryPlayer = getPlayerInventory(); return inventoryPlayer != null ? inventoryPlayer.getStackInSlotOnClosing(slot - 4) : null; } } @Override public void setInventorySlotContents(int slot, ItemStack itemStack){ if(slot < 4) { inventory[slot] = itemStack; if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) { itemStack.stackSize = getInventoryStackLimit(); } } else { EntityPlayer player = getPlayer(); if(dispenserUpgradeInserted) { if(itemStack != null) { int startValue = itemStack.stackSize; while(itemStack.stackSize > 0) { ItemStack remainingItem = itemStack.onFoodEaten(player.worldObj, player); remainingItem = ForgeEventFactory.onItemUseFinish(player, itemStack, 0, remainingItem); if(remainingItem != null && remainingItem.stackSize > 0 && (remainingItem != itemStack || remainingItem.stackSize != startValue)) { if(!player.inventory.addItemStackToInventory(remainingItem) && remainingItem.stackSize > 0) { player.dropPlayerItemWithRandomChoice(remainingItem, false); } } if(itemStack.stackSize == startValue) break; } } } else { InventoryPlayer inventoryPlayer = player != null ? player.inventory : null; if(inventoryPlayer != null) { inventoryPlayer.setInventorySlotContents(slot - 4, itemStack); } else if(worldObj != null && !worldObj.isRemote) { EntityItem item = new EntityItem(worldObj, xCoord, yCoord, zCoord, itemStack); worldObj.spawnEntityInWorld(item); } } } } @Override public String getInventoryName(){ return Blockss.aerialInterface.getUnlocalizedName(); } @Override public int getInventoryStackLimit(){ return 64; } @Override public void readFromNBT(NBTTagCompound tag){ super.readFromNBT(tag); // Read in the ItemStacks in the inventory from NBT redstoneMode = tag.getInteger("redstoneMode"); feedMode = tag.getInteger("feedMode"); setPlayer(tag.getString("playerName"), tag.getString("playerUUID")); isConnectedToPlayer = tag.getBoolean("connected"); if(tag.hasKey("curXpFluid")) curXpFluid = FluidRegistry.getFluid(tag.getString("curXpFluid")); if(energyRF != null) readRF(tag); NBTTagList tagList = tag.getTagList("Items", 10); inventory = new ItemStack[4]; for(int i = 0; i < tagList.tagCount(); ++i) { NBTTagCompound tagCompound = tagList.getCompoundTagAt(i); byte slot = tagCompound.getByte("Slot"); if(slot >= 0 && slot < inventory.length) { inventory[slot] = ItemStack.loadItemStackFromNBT(tagCompound); } } dispenserUpgradeInserted = getUpgrades(ItemMachineUpgrade.UPGRADE_DISPENSER_DAMAGE) > 0; } @Override public void writeToNBT(NBTTagCompound tag){ super.writeToNBT(tag); // Write the ItemStacks in the inventory to NBT tag.setInteger("redstoneMode", redstoneMode); tag.setInteger("feedMode", feedMode); tag.setString("playerName", playerName); tag.setString("playerUUID", playerUUID); if(curXpFluid != null) tag.setString("curXpFluid", curXpFluid.getName()); if(energyRF != null) saveRF(tag); tag.setBoolean("connected", isConnectedToPlayer); NBTTagList tagList = new NBTTagList(); for(int currentIndex = 0; currentIndex < inventory.length; ++currentIndex) { if(inventory[currentIndex] != null) { NBTTagCompound tagCompound = new NBTTagCompound(); tagCompound.setByte("Slot", (byte)currentIndex); inventory[currentIndex].writeToNBT(tagCompound); tagList.appendTag(tagCompound); } } tag.setTag("Items", tagList); } @Override public boolean isItemValidForSlot(int i, ItemStack itemstack){ return i >= 4 || itemstack != null && itemstack.getItem() == Itemss.machineUpgrade; } @Override // upgrades in bottom, fuel in the rest. public int[] getAccessibleSlotsFromSide(int var1){ if(ForgeDirection.getOrientation(var1) == ForgeDirection.UP) { return new int[]{0, 1, 2, 3}; } else if(getPlayerInventory() == null) { return new int[0]; } else if(ForgeDirection.getOrientation(var1) == ForgeDirection.DOWN) { return new int[]{40, 41, 42, 43}; } else if(dispenserUpgradeInserted) { return new int[]{44}; } else { int[] mainInv = new int[36]; for(int i = 0; i < 36; i++) { mainInv[i] = i + 4; } return mainInv; } } @Override public boolean canInsertItem(int i, ItemStack itemstack, int j){ if(i < 4) return true; EntityPlayer player = getPlayer(); if(player == null) return false; if(getPressure(ForgeDirection.UNKNOWN) > PneumaticValues.MIN_PRESSURE_AERIAL_INTERFACE) { if(!dispenserUpgradeInserted || i >= 40 && i <= 43) { return i < 40 || itemstack != null && itemstack.getItem() instanceof ItemArmor && ((ItemArmor)itemstack.getItem()).armorType == 43 - i; } else { if(i == 4 + player.inventory.getSizeInventory() && getFoodValue(itemstack) > 0) { int foodValue = getFoodValue(itemstack); int curFoodLevel = player.getFoodStats().getFoodLevel(); int feedMode = this.feedMode; if(feedMode == 2) { feedMode = player.getMaxHealth() - player.getHealth() > 0 ? 1 : 0; } switch(feedMode){ case 0: return 20 - curFoodLevel >= foodValue * itemstack.stackSize; case 1: return 20 - curFoodLevel >= foodValue * (itemstack.stackSize - 1) + 1; } } return false; } } else { return false; } } @Override public boolean canExtractItem(int i, ItemStack itemstack, int j){ return i < 4 || getPressure(ForgeDirection.UNKNOWN) > PneumaticValues.MIN_PRESSURE_AERIAL_INTERFACE; } @Override public boolean isUseableByPlayer(EntityPlayer var1){ return isGuiUseableByPlayer(var1); } @Override public void openInventory(){} @Override public void closeInventory(){} private int getFoodValue(ItemStack item){ return item != null && item.getItem() instanceof ItemFood ? ((ItemFood)item.getItem()).func_150905_g(item) : 0; } /* * * ------------------------ Liquid XP handling * */ @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill){ if(resource != null && canFill(from, resource.getFluid())) { EntityPlayer player = getPlayer(); if(player != null) { int liquidToXP = PneumaticCraftAPIHandler.getInstance().liquidXPs.get(resource.getFluid()); int xpPoints = resource.amount / liquidToXP; if(doFill) { player.addExperience(xpPoints); curXpFluid = resource.getFluid(); } return xpPoints * liquidToXP; } } return 0; } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain){ if(resource != null && canDrain(from, resource.getFluid())) { EntityPlayer player = getPlayer(); if(player != null) { int liquidToXP = PneumaticCraftAPIHandler.getInstance().liquidXPs.get(resource.getFluid()); int pointsDrained = Math.min(getPlayerXP(player), resource.amount / liquidToXP); if(doDrain) addPlayerXP(player, -pointsDrained); return new FluidStack(resource.getFluid(), pointsDrained * liquidToXP); } } return null; } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain){ updateXpFluid(); if(curXpFluid == null) return null; return drain(from, new FluidStack(curXpFluid, maxDrain), doDrain); } private void updateXpFluid(){ if(curXpFluid == null) { Iterator<Fluid> fluids = PneumaticCraftAPIHandler.getInstance().liquidXPs.keySet().iterator(); if(fluids.hasNext()) curXpFluid = fluids.next(); } } @Override public boolean canFill(ForgeDirection from, Fluid fluid){ return fluid != null && PneumaticCraftAPIHandler.getInstance().liquidXPs.containsKey(fluid) && getPlayer() != null && getPressure(ForgeDirection.UNKNOWN) > PneumaticValues.MIN_PRESSURE_AERIAL_INTERFACE && dispenserUpgradeInserted; } @Override public boolean canDrain(ForgeDirection from, Fluid fluid){ return (fluid == null || PneumaticCraftAPIHandler.getInstance().liquidXPs.containsKey(fluid)) && getPlayer() != null && getPressure(ForgeDirection.UNKNOWN) > PneumaticValues.MIN_PRESSURE_AERIAL_INTERFACE && dispenserUpgradeInserted; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from){ updateXpFluid(); if(curXpFluid != null) { EntityPlayer player = getPlayer(); if(player != null) { return new FluidTankInfo[]{new FluidTankInfo(new FluidStack(curXpFluid, getPlayerXP(player) * PneumaticCraftAPIHandler.getInstance().liquidXPs.get(curXpFluid)), Integer.MAX_VALUE)}; } } return null; } /** * This method is copied from OpenMods' OpenModsLib * https://github.com/OpenMods/OpenModsLib/blob/master/src/main/java/openmods/utils/EnchantmentUtils.java * @param player * @return */ private static int getPlayerXP(EntityPlayer player){ return (int)(getExperienceForLevel(player.experienceLevel) + player.experience * player.xpBarCap()); } /** * This method is copied from OpenMods' OpenModsLib * https://github.com/OpenMods/OpenModsLib/blob/master/src/main/java/openmods/utils/EnchantmentUtils.java * @param player * @return */ private static int getExperienceForLevel(int level){ if(level == 0) { return 0; } if(level > 0 && level < 16) { return level * 17; } else if(level > 15 && level < 31) { return (int)(1.5 * Math.pow(level, 2) - 29.5 * level + 360); } else { return (int)(3.5 * Math.pow(level, 2) - 151.5 * level + 2220); } } /** * This method is copied from OpenMods' OpenModsLib * https://github.com/OpenMods/OpenModsLib/blob/master/src/main/java/openmods/utils/EnchantmentUtils.java * @param player * @return */ private static void addPlayerXP(EntityPlayer player, int amount){ int experience = getPlayerXP(player) + amount; player.experienceTotal = experience; player.experienceLevel = getLevelForExperience(experience); int expForLevel = getExperienceForLevel(player.experienceLevel); player.experience = (float)(experience - expForLevel) / (float)player.xpBarCap(); } /** * This method is copied from OpenMods' OpenModsLib * https://github.com/OpenMods/OpenModsLib/blob/master/src/main/java/openmods/utils/EnchantmentUtils.java * @param player * @return */ private static int getLevelForExperience(int experience){ int i = 0; while(getExperienceForLevel(i) <= experience) { i++; } return i - 1; } @Override public float getMinWorkingPressure(){ return PneumaticValues.MIN_PRESSURE_AERIAL_INTERFACE; } @Override public int getRedstoneMode(){ return redstoneMode; } /** * RF integration */ private Object energyRF; private static final int RF_PER_TICK = 1000; private boolean isRFAvailable(){ return Loader.isModLoaded(ModIds.COFH_CORE); } private void initRF(){ energyRF = new EnergyStorage(100000); } private void saveRF(NBTTagCompound tag){ getEnergy().writeToNBT(tag); } private void readRF(NBTTagCompound tag){ getEnergy().readFromNBT(tag); } private void tickRF(){ if(getEnergyStored(null) > 0) { InventoryPlayer inv = getPlayerInventory(); if(inv != null) { for(int i = 0; i < inv.getSizeInventory(); i++) { ItemStack stack = inv.getStackInSlot(i); if(stack != null && stack.getItem() instanceof IEnergyContainerItem) { IEnergyContainerItem chargingItem = (IEnergyContainerItem)stack.getItem(); int energyLeft = getEnergyStored(null); if(energyLeft > 0) { getEnergy().extractEnergy(chargingItem.receiveEnergy(stack, energyLeft, false), false); } else { break; } } } } } } @Optional.Method(modid = ModIds.COFH_CORE) private EnergyStorage getEnergy(){ return (EnergyStorage)energyRF; } @Override public boolean canConnectEnergy(ForgeDirection from){ return true; } @Override public int getInfoEnergyPerTick(){ return RF_PER_TICK; } @Override public int getInfoMaxEnergyPerTick(){ return RF_PER_TICK; } @Override public int getInfoEnergyStored(){ return getEnergy().getEnergyStored(); } @Override public int getInfoMaxEnergyStored(){ return getEnergy().getMaxEnergyStored(); } @Override public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate){ return getEnergy().receiveEnergy(maxReceive, simulate); } @Override public int getEnergyStored(ForgeDirection from){ return getEnergy().getEnergyStored(); } @Override public int getMaxEnergyStored(ForgeDirection from){ return getEnergy().getMaxEnergyStored(); } }