package crazypants.enderio.machine.capbank;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
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.AxisAlignedBB;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import com.enderio.core.api.client.gui.IAdvancedTooltipProvider;
import com.enderio.core.client.handlers.SpecialTooltipHandler;
import com.enderio.core.common.TileEntityEnder;
import com.enderio.core.common.util.Util;
import com.enderio.core.common.vecmath.Vector3d;
import cpw.mods.fml.common.network.IGuiHandler;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import crazypants.enderio.BlockEio;
import crazypants.enderio.EnderIO;
import crazypants.enderio.GuiHandler;
import crazypants.enderio.ModObject;
import crazypants.enderio.api.redstone.IRedstoneConnectable;
import crazypants.enderio.machine.IoMode;
import crazypants.enderio.machine.capbank.network.CapBankClientNetwork;
import crazypants.enderio.machine.capbank.network.ICapBankNetwork;
import crazypants.enderio.machine.capbank.network.NetworkUtil;
import crazypants.enderio.machine.capbank.packet.PacketGuiChange;
import crazypants.enderio.machine.capbank.packet.PacketNetworkEnergyRequest;
import crazypants.enderio.machine.capbank.packet.PacketNetworkEnergyResponse;
import crazypants.enderio.machine.capbank.packet.PacketNetworkIdRequest;
import crazypants.enderio.machine.capbank.packet.PacketNetworkIdResponse;
import crazypants.enderio.machine.capbank.packet.PacketNetworkStateRequest;
import crazypants.enderio.machine.capbank.packet.PacketNetworkStateResponse;
import crazypants.enderio.machine.power.PowerDisplayUtil;
import crazypants.enderio.network.PacketHandler;
import crazypants.enderio.power.PowerHandlerUtil;
import crazypants.enderio.tool.ToolUtil;
import crazypants.enderio.waila.IWailaInfoProvider;
public class BlockCapBank extends BlockEio implements IGuiHandler, IAdvancedTooltipProvider, IWailaInfoProvider, IRedstoneConnectable {
public static int renderId = -1;
public static BlockCapBank create() {
PacketHandler.INSTANCE.registerMessage(PacketNetworkStateResponse.class, PacketNetworkStateResponse.class, PacketHandler.nextID(), Side.CLIENT);
PacketHandler.INSTANCE.registerMessage(PacketNetworkStateRequest.class, PacketNetworkStateRequest.class, PacketHandler.nextID(), Side.SERVER);
PacketHandler.INSTANCE.registerMessage(PacketNetworkIdRequest.class, PacketNetworkIdRequest.class, PacketHandler.nextID(), Side.SERVER);
PacketHandler.INSTANCE.registerMessage(PacketNetworkIdResponse.class, PacketNetworkIdResponse.class, PacketHandler.nextID(), Side.CLIENT);
PacketHandler.INSTANCE.registerMessage(PacketNetworkEnergyRequest.class, PacketNetworkEnergyRequest.class, PacketHandler.nextID(), Side.SERVER);
PacketHandler.INSTANCE.registerMessage(PacketNetworkEnergyResponse.class, PacketNetworkEnergyResponse.class, PacketHandler.nextID(), Side.CLIENT);
PacketHandler.INSTANCE.registerMessage(PacketGuiChange.class, PacketGuiChange.class, PacketHandler.nextID(), Side.SERVER);
BlockCapBank res = new BlockCapBank();
res.init();
return res;
}
@SideOnly(Side.CLIENT)
private IIcon gaugeIcon;
@SideOnly(Side.CLIENT)
private IIcon fillBarIcon;
@SideOnly(Side.CLIENT)
private IIcon[] blockIcons;
@SideOnly(Side.CLIENT)
private IIcon[] borderIcons;
@SideOnly(Side.CLIENT)
private IIcon[] inputIcons;
@SideOnly(Side.CLIENT)
private IIcon[] outputIcons;
@SideOnly(Side.CLIENT)
private IIcon[] lockedIcons;
@SideOnly(Side.CLIENT)
private IIcon infoPanelIcon;
protected BlockCapBank() {
super(ModObject.blockCapBank.unlocalisedName, TileCapBank.class);
setHardness(2.0F);
}
@Override
protected void init() {
GameRegistry.registerBlock(this, BlockItemCapBank.class, name);
if(teClass != null) {
GameRegistry.registerTileEntity(teClass, name + "TileEntity");
}
EnderIO.guiHandler.registerGuiHandler(GuiHandler.GUI_ID_CAP_BANK, this);
setLightOpacity(255);
}
@Override
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item p_149666_1_, CreativeTabs p_149666_2_, List list) {
int meta = 0;
for (CapBankType type : CapBankType.types()) {
if(type.isCreative()) {
list.add(BlockItemCapBank.createItemStackWithPower(meta, type.getMaxEnergyStored() / 2));
} else {
list.add(BlockItemCapBank.createItemStackWithPower(meta, 0));
list.add(BlockItemCapBank.createItemStackWithPower(meta, type.getMaxEnergyStored()));
}
meta++;
}
}
@Override
public int damageDropped(int par1) {
return par1;
}
@Override
@SideOnly(Side.CLIENT)
public void addCommonEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) {
}
@Override
@SideOnly(Side.CLIENT)
public void addBasicEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) {
list.add(PowerDisplayUtil.formatStoredPower(PowerHandlerUtil.getStoredEnergyForItem(itemstack), CapBankType.getTypeFromMeta(itemstack.getItemDamage())
.getMaxEnergyStored()));
if(itemstack.stackTagCompound != null && itemstack.stackTagCompound.hasKey("Items")) {
NBTTagList itemList = (NBTTagList) itemstack.stackTagCompound.getTag("Items");
String msg = EnderIO.lang.localizeExact("tile.blockCapBank.tooltip.hasItems");
list.add(EnumChatFormatting.GOLD + MessageFormat.format(msg, itemList.tagCount()));
}
}
@Override
@SideOnly(Side.CLIENT)
public void addDetailedEntries(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) {
SpecialTooltipHandler.addDetailedTooltipFromResources(list, itemstack);
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float par7, float par8, float par9) {
TileEntity te = world.getTileEntity(x, y, z);
if(!(te instanceof TileCapBank)) {
return false;
}
TileCapBank tcb = (TileCapBank) te;
ForgeDirection faceHit = ForgeDirection.getOrientation(side);
if(entityPlayer.isSneaking() && entityPlayer.getCurrentEquippedItem() == null && faceHit.offsetY == 0) {
InfoDisplayType newDisplayType = tcb.getDisplayType(faceHit).next();
if(newDisplayType == InfoDisplayType.NONE) {
tcb.setDefaultIoMode(faceHit);
} else {
tcb.setIoMode(faceHit, IoMode.DISABLED);
}
tcb.setDisplayType(faceHit, newDisplayType);
return true;
}
if(!entityPlayer.isSneaking() && ToolUtil.isToolEquipped(entityPlayer)) {
IoMode ioMode = tcb.getIoMode(faceHit);
if(faceHit.offsetY == 0) {
if(ioMode == IoMode.DISABLED) {
InfoDisplayType newDisplayType = tcb.getDisplayType(faceHit).next();
tcb.setDisplayType(faceHit, newDisplayType);
if(newDisplayType == InfoDisplayType.NONE) {
tcb.setDefaultIoMode(faceHit);
}
} else {
tcb.toggleIoModeForFace(faceHit);
}
} else {
tcb.toggleIoModeForFace(faceHit);
}
if(world.isRemote) {
world.markBlockForUpdate(x, y, z);
} else {
world.notifyBlocksOfNeighborChange(x, y, z, EnderIO.blockCapBank);
world.markBlockForUpdate(x, y, z);
}
return true;
}
return super.onBlockActivated(world, x, y, z, entityPlayer, side, par7, par8, par9);
}
@Override
public boolean doNormalDrops(World world, int x, int y, int z) {
return false;
}
@Override
protected boolean openGui(World world, int x, int y, int z, EntityPlayer entityPlayer, int side) {
if(!world.isRemote) {
entityPlayer.openGui(EnderIO.instance, GuiHandler.GUI_ID_CAP_BANK, world, x, y, z);
}
return true;
}
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof TileCapBank) {
return new ContainerCapBank(player.inventory, (TileCapBank) te);
}
return null;
}
@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof TileCapBank) {
return new GuiCapBank(player, player.inventory, (TileCapBank) te);
}
return null;
}
@SideOnly(Side.CLIENT)
@Override
public void registerBlockIcons(IIconRegister IIconRegister) {
blockIcon = IIconRegister.registerIcon("enderio:capacitorBank");
gaugeIcon = IIconRegister.registerIcon("enderio:capacitorBankOverlays");
fillBarIcon = IIconRegister.registerIcon("enderio:capacitorBankFillBar");
infoPanelIcon = IIconRegister.registerIcon("enderio:capBankInfoPanel");
blockIcons = new IIcon[CapBankType.types().size()];
borderIcons = new IIcon[CapBankType.types().size()];
inputIcons = new IIcon[CapBankType.types().size()];
outputIcons = new IIcon[CapBankType.types().size()];
lockedIcons = new IIcon[CapBankType.types().size()];
int index = 0;
for (CapBankType type : CapBankType.types()) {
blockIcons[index] = IIconRegister.registerIcon(type.getIcon());
borderIcons[index] = IIconRegister.registerIcon(type.getBorderIcon());
inputIcons[index] = IIconRegister.registerIcon(type.getInputIcon());
outputIcons[index] = IIconRegister.registerIcon(type.getOutputIcon());
lockedIcons[index] = IIconRegister.registerIcon(type.getLockedIcon());
++index;
}
}
@Override
public int getRenderType() {
return renderId;
}
@Override
public boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side) {
return true;
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public boolean renderAsNormalBlock() {
return false;
}
@Override
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) {
Block i1 = par1IBlockAccess.getBlock(par2, par3, par4);
return i1 == this ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5);
}
@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(int side, int meta) {
meta = MathHelper.clamp_int(meta, 0, blockIcons.length - 1);
return blockIcons[meta];
}
@SideOnly(Side.CLIENT)
public IIcon getBorderIcon(int side, int meta) {
meta = MathHelper.clamp_int(meta, 0, blockIcons.length - 1);
return borderIcons[meta];
}
@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(IBlockAccess ba, int x, int y, int z, int side) {
TileEntity te = ba.getTileEntity(x, y, z);
if(!(te instanceof TileCapBank)) {
return blockIcons[0];
}
// if(true) {
// return IconUtil.blankTexture;
// }
TileCapBank cb = (TileCapBank) te;
ForgeDirection face = ForgeDirection.values()[side];
int meta = ba.getBlockMetadata(x, y, z);
meta = MathHelper.clamp_int(meta, 0, CapBankType.types().size() - 1);
IoMode mode = cb.getIoMode(face);
if(mode == null || mode == IoMode.NONE || cb.getDisplayType(face) != InfoDisplayType.NONE) {
return blockIcons[meta];
}
if(mode == IoMode.PULL) {
return inputIcons[meta];
}
if(mode == IoMode.PUSH) {
return outputIcons[meta];
}
return lockedIcons[meta];
}
@SideOnly(Side.CLIENT)
public IIcon getGaugeIcon() {
return gaugeIcon;
}
@SideOnly(Side.CLIENT)
public IIcon getFillBarIcon() {
return fillBarIcon;
}
@SideOnly(Side.CLIENT)
public IIcon getInfoPanelIcon() {
return infoPanelIcon;
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block blockId) {
if(world.isRemote) {
return;
}
TileEntity tile = world.getTileEntity(x, y, z);
if(tile instanceof TileCapBank) {
TileCapBank te = (TileCapBank) tile;
te.onNeighborBlockChange(blockId);
}
}
@Override
public int quantityDropped(Random r) {
return 0;
}
@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) {
super.onBlockPlacedBy(world, x, y, z, player, stack);
TileCapBank cb = getTileEntity(world, x, y, z);
if(cb == null) {
return;
}
if(stack.stackTagCompound != null) {
cb.readCommonNBT(stack.stackTagCompound);
}
Collection<TileCapBank> neigbours = NetworkUtil.getNeigbours(cb);
if(neigbours.isEmpty()) {
int heading = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3;
ForgeDirection dir = getDirForHeading(heading);
cb.setDisplayType(dir, InfoDisplayType.LEVEL_BAR);
} else {
boolean modifiedDisplayType;
modifiedDisplayType = setDisplayToVerticalFillBar(cb, getTileEntity(world, x, y - 1, z));
modifiedDisplayType |= setDisplayToVerticalFillBar(cb, getTileEntity(world, x, y + 1, z));
if(modifiedDisplayType) {
cb.validateDisplayTypes();
}
}
if(world.isRemote) {
return;
}
world.markBlockForUpdate(x, y, z);
}
protected boolean setDisplayToVerticalFillBar(TileCapBank cb, TileCapBank capBank) {
boolean modifiedDisplayType = false;
if(capBank != null) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
if(dir.offsetY == 0 && capBank.getDisplayType(dir) == InfoDisplayType.LEVEL_BAR && capBank.getType() == cb.getType()) {
cb.setDisplayType(dir, InfoDisplayType.LEVEL_BAR);
modifiedDisplayType = true;
}
}
}
return modifiedDisplayType;
}
private TileCapBank getTileEntity(World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof TileCapBank) {
return (TileCapBank) te;
}
return null;
}
protected ForgeDirection getDirForHeading(int heading) {
switch (heading) {
case 0:
return ForgeDirection.values()[2];
case 1:
return ForgeDirection.values()[5];
case 2:
return ForgeDirection.values()[3];
case 3:
default:
return ForgeDirection.values()[4];
}
}
@Override
public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z, boolean doHarvest) {
if(!world.isRemote && (!player.capabilities.isCreativeMode)) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof TileCapBank) {
TileCapBank cb = (TileCapBank) te;
cb.moveInventoryToNetwork();
}
}
return super.removedByPlayer(world, player, x, y, z, doHarvest);
}
@Override
protected void processDrop(World world, int x, int y, int z, TileEntityEnder te, ItemStack drop) {
drop.stackTagCompound = new NBTTagCompound();
if(te != null) {
((TileCapBank) te).writeCommonNBT(drop.stackTagCompound);
}
}
@Override
public void breakBlock(World world, int x, int y, int z, Block par5, int par6) {
if(!world.isRemote) {
TileEntity te = world.getTileEntity(x, y, z);
if(!(te instanceof TileCapBank)) {
return;
}
TileCapBank cb = (TileCapBank) te;
cb.onBreakBlock();
}
super.breakBlock(world, x, y, z, par5, par6);
}
@Override
@SideOnly(Side.CLIENT)
public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(!(te instanceof TileCapBank)) {
return super.getSelectedBoundingBoxFromPool(world, x, y, z);
}
TileCapBank tr = (TileCapBank) te;
ICapBankNetwork network = tr.getNetwork();
if(!tr.getType().isMultiblock() || network == null) {
return super.getSelectedBoundingBoxFromPool(world, x, y, z);
}
Vector3d min = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
Vector3d max = new Vector3d(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
for (TileCapBank bc : network.getMembers()) {
min.x = Math.min(min.x, bc.xCoord);
max.x = Math.max(max.x, bc.xCoord + 1);
min.y = Math.min(min.y, bc.yCoord);
max.y = Math.max(max.y, bc.yCoord + 1);
min.z = Math.min(min.z, bc.zCoord);
max.z = Math.max(max.z, bc.zCoord + 1);
}
return AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z);
}
@Override
public boolean hasComparatorInputOverride() {
return true;
}
@Override
public int getComparatorInputOverride(World w, int x, int y, int z, int side) {
TileEntity te = w.getTileEntity(x, y, z);
if(te instanceof TileCapBank) {
return ((TileCapBank) te).getComparatorOutput();
}
return 0;
}
@Override
public void getWailaInfo(List<String> tooltip, EntityPlayer player, World world, int x, int y, int z) {
TileEntity te = world.getTileEntity(x, y, z);
if(te instanceof TileCapBank) {
TileCapBank cap = (TileCapBank) te;
if(cap.getNetwork() != null) {
if(world.isRemote && shouldDoWorkThisTick(world, x, y, z, 20)) {
PacketHandler.INSTANCE.sendToServer(new PacketNetworkStateRequest(cap));
}
ICapBankNetwork nw = cap.getNetwork();
if(world.isRemote) {
((CapBankClientNetwork) nw).requestPowerUpdate(cap, 2);
}
if(SpecialTooltipHandler.showAdvancedTooltips()) {
String format = Util.TAB + Util.ALIGNRIGHT + EnumChatFormatting.WHITE;
String suffix = Util.TAB + Util.ALIGNRIGHT + PowerDisplayUtil.abrevation() + PowerDisplayUtil.perTickStr();
tooltip.add(String.format("%s : %s%s%s", EnderIO.lang.localize("capbank.maxIO"), format, PowerDisplayUtil.formatPower(nw.getMaxIO()), suffix));
tooltip.add(String.format("%s : %s%s%s", EnderIO.lang.localize("capbank.maxIn"), format, PowerDisplayUtil.formatPower(nw.getMaxInput()), suffix));
tooltip.add(String.format("%s : %s%s%s", EnderIO.lang.localize("capbank.maxOut"), format, PowerDisplayUtil.formatPower(nw.getMaxOutput()), suffix));
tooltip.add("");
}
long stored = nw.getEnergyStoredL();
long max = nw.getMaxEnergyStoredL();
tooltip.add(String.format("%s%s%s / %s%s%s %s", EnumChatFormatting.WHITE, PowerDisplayUtil.formatPower(stored), EnumChatFormatting.RESET,
EnumChatFormatting.WHITE, PowerDisplayUtil.formatPower(max), EnumChatFormatting.RESET, PowerDisplayUtil.abrevation()));
int change = Math.round(nw.getAverageChangePerTick());
String color = EnumChatFormatting.WHITE.toString();
if(change > 0) {
color = EnumChatFormatting.GREEN.toString() + "+";
} else if(change < 0) {
color = EnumChatFormatting.RED.toString();
}
tooltip.add(String.format("%s%s%s", color, PowerDisplayUtil.formatPowerPerTick(change), " " + EnumChatFormatting.RESET.toString()));
}
}
}
@Override
public int getDefaultDisplayMask(World world, int x, int y, int z) {
return IWailaInfoProvider.BIT_DETAILED;
}
/* IRedstoneConnectable */
@Override
public boolean shouldRedstoneConduitConnect(World world, int x, int y, int z, ForgeDirection from) {
return true;
}
}