package mekanism.generators.common.item;
import ic2.api.item.IElectricItemManager;
import ic2.api.item.ISpecialElectricItem;
import java.util.List;
import mekanism.api.EnumColor;
import mekanism.api.MekanismConfig.general;
import mekanism.api.energy.IEnergizedItem;
import mekanism.client.MekKeyHandler;
import mekanism.client.MekanismKeyHandler;
import mekanism.common.base.ISustainedData;
import mekanism.common.base.ISustainedInventory;
import mekanism.common.base.ISustainedTank;
import mekanism.common.integration.IC2ItemManager;
import mekanism.common.security.ISecurityItem;
import mekanism.common.security.ISecurityTile;
import mekanism.common.security.ISecurityTile.SecurityMode;
import mekanism.common.tile.TileEntityBasicBlock;
import mekanism.common.tile.TileEntityElectricBlock;
import mekanism.common.util.ItemDataUtils;
import mekanism.common.util.LangUtils;
import mekanism.common.util.MekanismUtils;
import mekanism.common.util.SecurityUtils;
import mekanism.generators.common.block.states.BlockStateGenerator.GeneratorType;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.Optional.Interface;
import net.minecraftforge.fml.common.Optional.InterfaceList;
import net.minecraftforge.fml.common.Optional.Method;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import cofh.api.energy.IEnergyContainerItem;
/**
* Item class for handling multiple generator block IDs.
* 0: Heat Generator
* 1: Solar Generator
* 3: Hydrogen Generator
* 4: Bio-Generator
* 5: Advanced Solar Generator
* 6: Wind Generator
* 7: Turbine Rotor
* 8: Rotational Complex
* 9: Electromagnetic Coil
* 10: Turbine Casing
* 11: Turbine Valve
* 12: Turbine Vent
* 13: Saturating Condenser
* @author AidanBrady
*
*/
@InterfaceList({
@Interface(iface = "ic2.api.item.ISpecialElectricItem", modid = "IC2")
})
public class ItemBlockGenerator extends ItemBlock implements IEnergizedItem, ISpecialElectricItem, ISustainedInventory, ISustainedTank, IEnergyContainerItem, ISecurityItem
{
public Block metaBlock;
public ItemBlockGenerator(Block block)
{
super(block);
metaBlock = block;
setHasSubtypes(true);
}
@Override
public int getItemStackLimit(ItemStack stack)
{
GeneratorType type = GeneratorType.get(stack);
if(type.maxEnergy == -1)
{
return 64;
}
else {
return 1;
}
}
@Override
public int getMetadata(int i)
{
return i;
}
@Override
public String getUnlocalizedName(ItemStack itemstack)
{
if(GeneratorType.get(itemstack) == null)
{
return "KillMe!";
}
return getUnlocalizedName() + "." + GeneratorType.get(itemstack).name;
}
@Override
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag)
{
GeneratorType type = GeneratorType.get(itemstack);
if(type.maxEnergy > -1)
{
if(!MekKeyHandler.getIsKeyPressed(MekanismKeyHandler.sneakKey))
{
list.add(LangUtils.localize("tooltip.hold") + " " + EnumColor.INDIGO + GameSettings.getKeyDisplayString(MekanismKeyHandler.sneakKey.getKeyCode()) + EnumColor.GREY + " " + LangUtils.localize("tooltip.forDetails") + ".");
list.add(LangUtils.localize("tooltip.hold") + " " + EnumColor.AQUA + GameSettings.getKeyDisplayString(MekanismKeyHandler.sneakKey.getKeyCode()) + EnumColor.GREY + " " + LangUtils.localize("tooltip.and") + " " + EnumColor.AQUA + GameSettings.getKeyDisplayString(MekanismKeyHandler.modeSwitchKey.getKeyCode()) + EnumColor.GREY + " " + LangUtils.localize("tooltip.forDesc") + ".");
}
else if(!MekKeyHandler.getIsKeyPressed(MekanismKeyHandler.modeSwitchKey))
{
if(hasSecurity(itemstack))
{
list.add(SecurityUtils.getOwnerDisplay(entityplayer.getName(), getOwner(itemstack)));
list.add(EnumColor.GREY + LangUtils.localize("gui.security") + ": " + SecurityUtils.getSecurityDisplay(itemstack, Side.CLIENT));
if(SecurityUtils.isOverridden(itemstack, Side.CLIENT))
{
list.add(EnumColor.RED + "(" + LangUtils.localize("gui.overridden") + ")");
}
}
list.add(EnumColor.BRIGHT_GREEN + LangUtils.localize("tooltip.storedEnergy") + ": " + EnumColor.GREY + MekanismUtils.getEnergyDisplay(getEnergy(itemstack)));
if(hasTank(itemstack))
{
if(getFluidStack(itemstack) != null)
{
list.add(EnumColor.PINK + FluidRegistry.getFluidName(getFluidStack(itemstack)) + ": " + EnumColor.GREY + getFluidStack(itemstack).amount + "mB");
}
}
list.add(EnumColor.AQUA + LangUtils.localize("tooltip.inventory") + ": " + EnumColor.GREY + LangUtils.transYesNo(getInventory(itemstack) != null && getInventory(itemstack).tagCount() != 0));
}
else {
list.addAll(MekanismUtils.splitTooltip(type.getDescription(), itemstack));
}
}
else {
if(!MekKeyHandler.getIsKeyPressed(MekanismKeyHandler.sneakKey))
{
list.add(LangUtils.localize("tooltip.hold") + " " + EnumColor.INDIGO + GameSettings.getKeyDisplayString(MekanismKeyHandler.sneakKey.getKeyCode()) + EnumColor.GREY + " " + LangUtils.localize("tooltip.forDetails") + ".");
}
else {
list.addAll(MekanismUtils.splitTooltip(type.getDescription(), itemstack));
}
}
}
@Override
public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, IBlockState state)
{
boolean place = true;
Block block = world.getBlockState(pos).getBlock();
if(stack.getItemDamage() == GeneratorType.ADVANCED_SOLAR_GENERATOR.meta)
{
if(!(block.isReplaceable(world, pos) && world.isAirBlock(pos.add(0, 1, 0))))
{
return false;
}
outer:
for(int xPos = -1; xPos <= 1; xPos++)
{
for(int zPos =- 1; zPos <= 1; zPos++)
{
if(!world.isAirBlock(pos.add(xPos, 2, zPos)) || pos.getY()+2 > 255)
{
place = false;
break outer;
}
}
}
}
else if(stack.getItemDamage() == GeneratorType.WIND_GENERATOR.meta)
{
if(!block.isReplaceable(world, pos))
{
return false;
}
outer:
for(int yPos = 1; yPos <= 4; yPos++)
{
if(!world.isAirBlock(pos.add(0, yPos, 0)) || pos.getY()+yPos > 255)
{
place = false;
break outer;
}
}
}
if(place && super.placeBlockAt(stack, player, world, pos, side, hitX, hitY, hitZ, state))
{
TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getTileEntity(pos);
if(tileEntity instanceof ISecurityTile)
{
ISecurityTile security = (ISecurityTile)tileEntity;
security.getSecurity().setOwner(getOwner(stack));
if(hasSecurity(stack))
{
security.getSecurity().setMode(getSecurity(stack));
}
if(getOwner(stack) == null)
{
security.getSecurity().setOwner(player.getName());
}
}
if(tileEntity instanceof TileEntityElectricBlock)
{
((TileEntityElectricBlock)tileEntity).electricityStored = getEnergy(stack);
}
if(tileEntity instanceof ISustainedInventory)
{
((ISustainedInventory)tileEntity).setInventory(getInventory(stack));
}
if(tileEntity instanceof ISustainedData)
{
if(stack.getTagCompound() != null)
{
((ISustainedData)tileEntity).readSustainedData(stack);
}
}
if(tileEntity instanceof ISustainedTank)
{
if(hasTank(stack) && getFluidStack(stack) != null)
{
((ISustainedTank)tileEntity).setFluidStack(getFluidStack(stack), stack);
}
}
return true;
}
return false;
}
@Override
public void setInventory(NBTTagList nbtTags, Object... data)
{
if(data[0] instanceof ItemStack)
{
ItemDataUtils.setList((ItemStack)data[0], "Items", nbtTags);
}
}
@Override
public NBTTagList getInventory(Object... data)
{
if(data[0] instanceof ItemStack)
{
return ItemDataUtils.getList((ItemStack)data[0], "Items");
}
return null;
}
@Override
public void setFluidStack(FluidStack fluidStack, Object... data)
{
if(data[0] instanceof ItemStack)
{
ItemStack itemStack = (ItemStack)data[0];
if(fluidStack == null || fluidStack.amount == 0 || fluidStack.getFluid() == null)
{
ItemDataUtils.removeData(itemStack, "fluidTank");
}
else {
ItemDataUtils.setCompound(itemStack, "fluidTank", fluidStack.writeToNBT(new NBTTagCompound()));
}
}
}
@Override
public FluidStack getFluidStack(Object... data)
{
if(data[0] instanceof ItemStack)
{
ItemStack itemStack = (ItemStack)data[0];
if(!ItemDataUtils.hasData(itemStack, "fluidTank"))
{
return null;
}
return FluidStack.loadFluidStackFromNBT(ItemDataUtils.getCompound(itemStack, "fluidTank"));
}
return null;
}
@Override
public boolean hasTank(Object... data)
{
return data[0] instanceof ItemStack && ((ItemStack)data[0]).getItem() instanceof ISustainedTank && (((ItemStack)data[0]).getItemDamage() == 2);
}
@Override
public double getEnergy(ItemStack itemStack)
{
return ItemDataUtils.getDouble(itemStack, "energyStored");
}
@Override
public void setEnergy(ItemStack itemStack, double amount)
{
ItemDataUtils.setDouble(itemStack, "energyStored", Math.max(Math.min(amount, getMaxEnergy(itemStack)), 0));
}
@Override
public double getMaxEnergy(ItemStack itemStack)
{
return GeneratorType.get(itemStack).maxEnergy;
}
@Override
public double getMaxTransfer(ItemStack itemStack)
{
return getMaxEnergy(itemStack)*0.005;
}
@Override
public boolean canReceive(ItemStack itemStack)
{
return false;
}
@Override
public boolean canSend(ItemStack itemStack)
{
return GeneratorType.get(itemStack).maxEnergy != -1;
}
@Override
public int receiveEnergy(ItemStack theItem, int energy, boolean simulate)
{
if(canReceive(theItem))
{
double energyNeeded = getMaxEnergy(theItem)-getEnergy(theItem);
double toReceive = Math.min(energy*general.FROM_RF, energyNeeded);
if(!simulate)
{
setEnergy(theItem, getEnergy(theItem) + toReceive);
}
return (int)Math.round(toReceive*general.TO_RF);
}
return 0;
}
@Override
public int extractEnergy(ItemStack theItem, int energy, boolean simulate)
{
if(canSend(theItem))
{
double energyRemaining = getEnergy(theItem);
double toSend = Math.min((energy*general.FROM_RF), energyRemaining);
if(!simulate)
{
setEnergy(theItem, getEnergy(theItem) - toSend);
}
return (int)Math.round(toSend*general.TO_RF);
}
return 0;
}
@Override
public int getEnergyStored(ItemStack theItem)
{
return (int)(getEnergy(theItem)*general.TO_RF);
}
@Override
public int getMaxEnergyStored(ItemStack theItem)
{
return (int)(getMaxEnergy(theItem)*general.TO_RF);
}
@Override
@Method(modid = "IC2")
public IElectricItemManager getManager(ItemStack itemStack)
{
return IC2ItemManager.getManager(this);
}
@Override
public String getOwner(ItemStack stack)
{
if(ItemDataUtils.hasData(stack, "owner"))
{
return ItemDataUtils.getString(stack, "owner");
}
return null;
}
@Override
public void setOwner(ItemStack stack, String owner)
{
if(owner == null || owner.isEmpty())
{
ItemDataUtils.removeData(stack, "owner");
return;
}
ItemDataUtils.setString(stack, "owner", owner);
}
@Override
public SecurityMode getSecurity(ItemStack stack)
{
if(!general.allowProtection)
{
return SecurityMode.PUBLIC;
}
return SecurityMode.values()[ItemDataUtils.getInt(stack, "security")];
}
@Override
public void setSecurity(ItemStack stack, SecurityMode mode)
{
ItemDataUtils.setInt(stack, "security", mode.ordinal());
}
@Override
public boolean hasSecurity(ItemStack stack)
{
GeneratorType type = GeneratorType.get(stack);
return type.hasModel;
}
@Override
public boolean hasOwner(ItemStack stack)
{
return hasSecurity(stack);
}
}