package micdoodle8.mods.galacticraft.core.tile;
import micdoodle8.mods.galacticraft.api.item.IKeyable;
import micdoodle8.mods.galacticraft.core.Constants;
import micdoodle8.mods.galacticraft.core.GalacticraftCore;
import micdoodle8.mods.galacticraft.core.network.PacketSimple;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import micdoodle8.mods.miccore.Annotations;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryLargeChest;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.Iterator;
import java.util.List;
public class TileEntityTreasureChest extends TileEntityAdvanced implements ITickable, IInventory, IKeyable
{
private ItemStack[] chestContents = new ItemStack[27];
public boolean adjacentChestChecked;
public float lidAngle;
public float prevLidAngle;
public int numPlayersUsing;
private int ticksSinceSync;
private AxisAlignedBB renderAABB;
@Annotations.NetworkedField(targetSide = Side.CLIENT)
public boolean locked = true;
public int tier = 1;
public TileEntityTreasureChest()
{
this(1);
}
public TileEntityTreasureChest(int tier)
{
this.tier = tier;
}
/**
* Returns the number of slots in the inventory.
*/
@Override
public int getSizeInventory()
{
return 27;
}
/**
* Returns the stack in slot i
*/
@Override
public ItemStack getStackInSlot(int index)
{
return this.chestContents[index];
}
/**
* Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a
* new stack.
*/
@Override
public ItemStack decrStackSize(int index, int count)
{
if (this.chestContents[index] != null)
{
ItemStack itemstack;
if (this.chestContents[index].stackSize <= count)
{
itemstack = this.chestContents[index];
this.chestContents[index] = null;
this.markDirty();
return itemstack;
}
else
{
itemstack = this.chestContents[index].splitStack(count);
if (this.chestContents[index].stackSize == 0)
{
this.chestContents[index] = null;
}
this.markDirty();
return itemstack;
}
}
else
{
return null;
}
}
/**
* When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
* like when you close a workbench GUI.
*/
@Override
public ItemStack removeStackFromSlot(int index)
{
if (this.chestContents[index] != null)
{
ItemStack itemstack = this.chestContents[index];
this.chestContents[index] = null;
return itemstack;
}
else
{
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{
this.chestContents[index] = stack;
if (stack != null && stack.stackSize > this.getInventoryStackLimit())
{
stack.stackSize = this.getInventoryStackLimit();
}
this.markDirty();
}
/**
* Gets the name of this command sender (usually username, but possibly "Rcon")
*/
@Override
public String getName()
{
return GCCoreUtil.translate("container.treasurechest.name");
}
/**
* Returns true if this thing is named
*/
@Override
public boolean hasCustomName()
{
return false;
}
public void setCustomName(String name)
{
}
@Override
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.locked = compound.getBoolean("isLocked");
this.tier = compound.getInteger("tier");
NBTTagList nbttaglist = compound.getTagList("Items", 10);
this.chestContents = new ItemStack[this.getSizeInventory()];
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
int j = nbttagcompound1.getByte("Slot") & 255;
if (j >= 0 && j < this.chestContents.length)
{
this.chestContents[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
}
@Override
public void writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setBoolean("isLocked", this.locked);
compound.setInteger("tier", this.tier);
NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < this.chestContents.length; ++i)
{
if (this.chestContents[i] != null)
{
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte) i);
this.chestContents[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
compound.setTag("Items", nbttaglist);
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
* this more of a set than a get?*
*/
@Override
public int getInventoryStackLimit()
{
return 64;
}
/**
* Do not make give this method the name canInteractWith because it clashes with Container
*/
@Override
public boolean isUseableByPlayer(EntityPlayer player)
{
return this.worldObj.getTileEntity(this.pos) != this ? false : player.getDistanceSq((double) this.pos.getX() + 0.5D, (double) this.pos.getY() + 0.5D, (double) this.pos.getZ() + 0.5D) <= 64.0D;
}
@Override
public void updateContainingBlockInfo()
{
super.updateContainingBlockInfo();
this.adjacentChestChecked = false;
}
/**
* Updates the JList with a new model.
*/
@Override
public void update()
{
int i = this.pos.getX();
int j = this.pos.getY();
int k = this.pos.getZ();
++this.ticksSinceSync;
float f;
if (this.locked)
{
this.numPlayersUsing = 0;
}
if (!this.worldObj.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + i + j + k) % 200 == 0)
{
this.numPlayersUsing = 0;
f = 5.0F;
List list = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double) ((float) i - f), (double) ((float) j - f), (double) ((float) k - f), (double) ((float) (i + 1) + f), (double) ((float) (j + 1) + f), (double) ((float) (k + 1) + f)));
Iterator iterator = list.iterator();
while (iterator.hasNext())
{
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
if (entityplayer.openContainer instanceof ContainerChest)
{
IInventory iinventory = ((ContainerChest) entityplayer.openContainer).getLowerChestInventory();
if (iinventory == this || iinventory instanceof InventoryLargeChest && ((InventoryLargeChest) iinventory).isPartOfLargeChest(this))
{
++this.numPlayersUsing;
}
}
}
}
this.prevLidAngle = this.lidAngle;
f = 0.1F;
double d2;
if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F)
{
double d1 = (double) i + 0.5D;
d2 = (double) k + 0.5D;
this.worldObj.playSoundEffect(d1, (double) j + 0.5D, d2, "random.chestopen", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
}
if (((this.numPlayersUsing == 0 || this.locked) && this.lidAngle > 0.0F) || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
{
float f1 = this.lidAngle;
if (this.numPlayersUsing == 0 || this.locked)
{
this.lidAngle -= f;
}
else
{
this.lidAngle += f;
}
if (this.lidAngle > 1.0F)
{
this.lidAngle = 1.0F;
}
float f2 = 0.5F;
if (this.lidAngle < f2 && f1 >= f2)
{
d2 = (double) i + 0.5D;
double d0 = (double) k + 0.5D;
this.worldObj.playSoundEffect(d2, (double) j + 0.5D, d0, "random.chestclosed", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
}
if (this.lidAngle < 0.0F)
{
this.lidAngle = 0.0F;
}
}
super.update();
}
@Override
public boolean receiveClientEvent(int id, int type)
{
if (id == 1)
{
this.numPlayersUsing = type;
return true;
}
else
{
return super.receiveClientEvent(id, type);
}
}
@Override
public void openInventory(EntityPlayer player)
{
if (!player.isSpectator())
{
if (this.numPlayersUsing < 0)
{
this.numPlayersUsing = 0;
}
++this.numPlayersUsing;
this.worldObj.addBlockEvent(this.pos, this.getBlockType(), 1, this.numPlayersUsing);
this.worldObj.notifyNeighborsOfStateChange(this.pos, this.getBlockType());
this.worldObj.notifyNeighborsOfStateChange(this.pos.down(), this.getBlockType());
}
}
@Override
public void closeInventory(EntityPlayer player)
{
if (!player.isSpectator())
{
// --this.numPlayersUsing;
// this.worldObj.addBlockEvent(this.pos, this.getBlockType(), 1, this.numPlayersUsing);
// this.worldObj.notifyNeighborsOfStateChange(this.pos, this.getBlockType());
// this.worldObj.notifyNeighborsOfStateChange(this.pos.down(), this.getBlockType());
}
}
/**
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot.
*/
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{
return true;
}
/**
* invalidates a tile entity
*/
@Override
public void invalidate()
{
super.invalidate();
this.updateContainingBlockInfo();
}
public String getGuiID()
{
return "minecraft:chest";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
return new ContainerChest(playerInventory, this, playerIn);
}
@Override
public int getField(int id)
{
return 0;
}
@Override
public void setField(int id, int value)
{
}
@Override
public int getFieldCount()
{
return 0;
}
@Override
public void clear()
{
for (int i = 0; i < this.chestContents.length; ++i)
{
this.chestContents[i] = null;
}
}
@Override
public IChatComponent getDisplayName()
{
return (IChatComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatComponentTranslation(this.getName(), new Object[0]));
}
@Override
public double getPacketRange()
{
return 20.0D;
}
@Override
public int getPacketCooldown()
{
return 3;
}
@Override
public boolean isNetworkedTile()
{
return true;
}
@Override
public int getTierOfKeyRequired()
{
return this.tier;
}
@Override
public boolean onValidKeyActivated(EntityPlayer player, ItemStack key, EnumFacing face)
{
if (this.locked)
{
this.locked = false;
if (this.worldObj.isRemote)
{
// player.playSound("galacticraft.player.unlockchest", 1.0F,
// 1.0F);
}
else
{
if (!player.capabilities.isCreativeMode && --player.inventory.getCurrentItem().stackSize == 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, null);
}
return true;
}
}
return false;
}
@Override
public boolean onActivatedWithoutKey(EntityPlayer player, EnumFacing face)
{
if (this.locked)
{
if (player.worldObj.isRemote)
{
GalacticraftCore.packetPipeline.sendToServer(new PacketSimple(PacketSimple.EnumSimplePacket.S_ON_FAILED_CHEST_UNLOCK, GCCoreUtil.getDimensionID(this.worldObj), new Object[] { this.getTierOfKeyRequired() }));
}
return true;
}
return false;
}
@Override
public boolean canBreak()
{
return false;
}
public static TileEntityTreasureChest findClosest(Entity entity, int tier)
{
double distance = Double.MAX_VALUE;
TileEntityTreasureChest chest = null;
for (final TileEntity tile : entity.worldObj.loadedTileEntityList)
{
if (tile instanceof TileEntityTreasureChest && ((TileEntityTreasureChest) tile).getTierOfKeyRequired() == tier)
{
double dist = entity.getDistanceSq(tile.getPos().getX() + 0.5, tile.getPos().getY() + 0.5, tile.getPos().getZ() + 0.5);
if (dist < distance)
{
distance = dist;
chest = (TileEntityTreasureChest) tile;
}
}
}
if (chest != null)
{
System.out.println("Found chest to generate boss loot in: " + chest.pos);
}
else
{
System.out.println("Could not find chest to generate boss loot in!");
}
return chest;
}
@Override
@SideOnly(Side.CLIENT)
public AxisAlignedBB getRenderBoundingBox()
{
if (this.renderAABB == null)
{
this.renderAABB = new AxisAlignedBB(pos, pos.add(1, 2, 1));
}
return this.renderAABB;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared()
{
return Constants.RENDERDISTANCE_MEDIUM;
}
}