/*******************************************************************************
* AbyssalCraft
* Copyright (c) 2012 - 2017 Shinoow.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Contributors:
* Shinoow - implementation
******************************************************************************/
package com.shinoow.abyssalcraft.common.blocks.tile;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import com.shinoow.abyssalcraft.api.AbyssalCraftAPI;
import com.shinoow.abyssalcraft.api.energy.IEnergyContainer;
import com.shinoow.abyssalcraft.api.energy.IEnergyContainerItem;
import com.shinoow.abyssalcraft.api.entity.IAntiEntity;
import com.shinoow.abyssalcraft.api.entity.ICoraliumEntity;
import com.shinoow.abyssalcraft.api.entity.IDreadEntity;
import com.shinoow.abyssalcraft.api.item.ACItems;
import com.shinoow.abyssalcraft.lib.ACLib;
import com.shinoow.abyssalcraft.lib.util.blocks.ISingletonInventory;
import com.shinoow.abyssalcraft.lib.util.items.IStaffOfRending;
public class TileEntityRendingPedestal extends TileEntity implements IEnergyContainer, ITickable, ISidedInventory, ISingletonInventory {
private float energy;
private NonNullList<ItemStack> containerItemStacks = NonNullList.withSize(6, ItemStack.EMPTY);
int ticksExisted, shadowEnergy, abyssalEnergy, dreadEnergy, omotholEnergy;
@Override
public void readFromNBT(NBTTagCompound nbttagcompound)
{
super.readFromNBT(nbttagcompound);
energy = nbttagcompound.getFloat("PotEnergy");
containerItemStacks = NonNullList.withSize(getSizeInventory(), ItemStack.EMPTY);
ItemStackHelper.loadAllItems(nbttagcompound, containerItemStacks);
shadowEnergy = nbttagcompound.getInteger("energyShadow");
abyssalEnergy = nbttagcompound.getInteger("energyAbyssal");
dreadEnergy = nbttagcompound.getInteger("energyDread");
omotholEnergy = nbttagcompound.getInteger("energyOmothol");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
nbttagcompound.setFloat("PotEnergy", energy);
ItemStackHelper.saveAllItems(nbttagcompound, containerItemStacks);
nbttagcompound.setInteger("energyShadow", shadowEnergy);
nbttagcompound.setInteger("energyAbyssal", abyssalEnergy);
nbttagcompound.setInteger("energyDread", dreadEnergy);
nbttagcompound.setInteger("energyOmothol", omotholEnergy);
return nbttagcompound;
}
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
return new SPacketUpdateTileEntity(pos, 1, getUpdateTag());
}
@Override
public NBTTagCompound getUpdateTag()
{
return writeToNBT(new NBTTagCompound());
}
@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet)
{
readFromNBT(packet.getNbtCompound());
}
@Override
public void update() {
++ticksExisted;
ItemStack input = getStackInSlot(0);
if(!input.isEmpty())
if(input.getItem() instanceof IEnergyContainerItem)
if(!world.isRemote && ((IEnergyContainerItem) input.getItem()).canTransferPE(input) && canAcceptPE())
addEnergy(((IEnergyContainerItem) input.getItem()).consumeEnergy(input, 1));
ItemStack stack = getStackInSlot(1);
if(!stack.isEmpty())
if(stack.getItem() instanceof IStaffOfRending)
if(ticksExisted % 40 == 0 && !world.isRemote){
IStaffOfRending staff = (IStaffOfRending)stack.getItem();
if(staff.getEnergy(stack, "Shadow") > 0){
increaseEnergy(0, staff.getEnergy(stack, "Shadow"));
staff.setEnergy(0, stack, "Shadow");
}
if(staff.getEnergy(stack, "Abyssal") > 0){
increaseEnergy(1, staff.getEnergy(stack, "Abyssal"));
staff.setEnergy(0, stack, "Abyssal");
}
if(staff.getEnergy(stack, "Dread") > 0){
increaseEnergy(2, staff.getEnergy(stack, "Dread"));
staff.setEnergy(0, stack, "Dread");
}
if(staff.getEnergy(stack, "Omothol") > 0){
increaseEnergy(3, staff.getEnergy(stack, "Omothol"));
staff.setEnergy(0, stack, "Omothol");
}
for(EntityLivingBase target : world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(pos).expand(15, 3, 15)))
if(target.getCreatureAttribute() == AbyssalCraftAPI.SHADOW && target.isNonBoss()){
if(!target.isDead && getContainedEnergy() >= target.getMaxHealth()/2)
if(target.attackEntityFrom(DamageSource.MAGIC, staff.getDrainAmount(stack))){
consumeEnergy(target.getMaxHealth()/2);
increaseEnergy(0, staff.getDrainAmount(stack));
}
} else if(world.provider.getDimension() == ACLib.abyssal_wasteland_id && target instanceof ICoraliumEntity &&
target.isNonBoss()){
if(!target.isDead && getContainedEnergy() >= target.getMaxHealth()/2)
if(target.attackEntityFrom(DamageSource.MAGIC, staff.getDrainAmount(stack))){
consumeEnergy(target.getMaxHealth()/2);
increaseEnergy(1, staff.getDrainAmount(stack));
}
} else if(world.provider.getDimension() == ACLib.dreadlands_id && target instanceof IDreadEntity &&
target.isNonBoss()){
if(!target.isDead && getContainedEnergy() >= target.getMaxHealth()/2)
if(target.attackEntityFrom(DamageSource.MAGIC, staff.getDrainAmount(stack))){
consumeEnergy(target.getMaxHealth()/2);
increaseEnergy(2, staff.getDrainAmount(stack));
}
} else if(world.provider.getDimension() == ACLib.omothol_id && target instanceof ICoraliumEntity
&& target instanceof IDreadEntity && target instanceof IAntiEntity &&
target.getCreatureAttribute() != AbyssalCraftAPI.SHADOW && target.isNonBoss())
if(!target.isDead && getContainedEnergy() >= target.getMaxHealth()/2)
if(target.attackEntityFrom(DamageSource.MAGIC, staff.getDrainAmount(stack))){
consumeEnergy(target.getMaxHealth()/2);
increaseEnergy(3, staff.getDrainAmount(stack));
}
}
if(getEnergy(0) >= 200){
setEnergy(0, 0);
ItemStack output = getStackInSlot(2);
if(!output.isEmpty() && output.getItem() == ACItems.shadow_gem)
output.grow(1);
else setInventorySlotContents(2, new ItemStack(ACItems.shadow_gem));
}
if(getEnergy(1) >= 100){
setEnergy(1, 0);
ItemStack output = getStackInSlot(3);
if(!output.isEmpty() && output.getItem() == ACItems.essence && output.getItemDamage() == 0)
output.grow(1);
else setInventorySlotContents(3, new ItemStack(ACItems.essence, 1, 0));
}
if(getEnergy(2) >= 100){
setEnergy(2, 0);
ItemStack output = getStackInSlot(4);
if(!output.isEmpty() && output.getItem() == ACItems.essence && output.getItemDamage() == 1)
output.grow(1);
else setInventorySlotContents(4, new ItemStack(ACItems.essence, 1, 1));
}
if(getEnergy(3) >= 100){
setEnergy(3, 0);
ItemStack output = getStackInSlot(5);
if(!output.isEmpty() && output.getItem() == ACItems.essence && output.getItemDamage() == 2)
output.grow(1);
else setInventorySlotContents(5, new ItemStack(ACItems.essence, 1, 2));
}
}
@Override
public float getContainedEnergy() {
return energy;
}
@Override
public int getMaxEnergy() {
return 5000;
}
@Override
public void addEnergy(float energy) {
this.energy += energy;
if(this.energy > getMaxEnergy()) this.energy = getMaxEnergy();
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 2);
}
@Override
public float consumeEnergy(float energy) {
if(energy < this.energy){
this.energy -= energy;
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 2);
return energy;
} else {
float ret = this.energy;
this.energy = 0;
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 2);
return ret;
}
}
@Override
public boolean canAcceptPE() {
return getContainedEnergy() < getMaxEnergy();
}
@Override
public boolean canTransferPE() {
return false;
}
@Override
public TileEntity getContainerTile() {
return this;
}
public int getEnergy(int type){
switch(type){
case 0:
return shadowEnergy;
case 1:
return abyssalEnergy;
case 2:
return dreadEnergy;
case 3:
return omotholEnergy;
default:
return 0;
}
}
public void increaseEnergy(int type, int amount){
switch(type){
case 0:
shadowEnergy += amount;
break;
case 1:
abyssalEnergy += amount;
break;
case 2:
dreadEnergy += amount;
break;
case 3:
omotholEnergy += amount;
break;
}
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 2);
}
public void setEnergy(int type, int amount){
switch(type){
case 0:
shadowEnergy = amount;
break;
case 1:
abyssalEnergy = amount;
break;
case 2:
dreadEnergy = amount;
break;
case 3:
omotholEnergy = amount;
break;
}
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 2);
}
@Override
public String getName() {
return "container.abyssalcraft.rendingpedestal";
}
@Override
public boolean hasCustomName() {
return false;
}
@Override
public ITextComponent getDisplayName() {
return new TextComponentTranslation(getName());
}
@Override
public int getSizeInventory() {
return containerItemStacks.size();
}
@Override
public ItemStack getStackInSlot(int index) {
return containerItemStacks.get(index);
}
@Override
public ItemStack decrStackSize(int var1, int var2) {
return ItemStackHelper.getAndSplit(containerItemStacks, var1, var2);
}
@Override
public ItemStack removeStackFromSlot(int index) {
return ItemStackHelper.getAndRemove(containerItemStacks, index);
}
@Override
public void setInventorySlotContents(int index, ItemStack stack) {
containerItemStacks.set(index, stack);
if(!stack.isEmpty() && stack.getCount() > getInventoryStackLimit())
stack.setCount(getInventoryStackLimit());
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public boolean isUsableByPlayer(EntityPlayer player) {
return world.getTileEntity(pos) != this ? false : player.getDistanceSq(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D) <= 64.0D;
}
@Override
public void openInventory(EntityPlayer player) {}
@Override
public void closeInventory(EntityPlayer player) {}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
switch(index){
case 0:
return stack.getItem() instanceof IEnergyContainerItem;
case 1:
return stack.getItem() instanceof IStaffOfRending;
default:
return false;
}
}
@Override
public int[] getSlotsForFace(EnumFacing side) {
return side == EnumFacing.DOWN ? new int[]{2, 3, 4, 5} : new int[0];
}
@Override
public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction) {
return false;
}
@Override
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) {
return direction == EnumFacing.DOWN && index > 1;
}
@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() {
}
net.minecraftforge.items.IItemHandler handlerBottom = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN);
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing)
{
if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
if (facing == EnumFacing.DOWN)
return (T) handlerBottom;
return super.getCapability(capability, facing);
}
@Override
public ItemStack getItem() {
return getStackInSlot(1);
}
@Override
public void setItem(ItemStack item) {
setInventorySlotContents(1, item);
}
@Override
public int getRotation() {
return 0;
}
@Override
public boolean isEmpty() {
for (ItemStack itemstack : containerItemStacks)
if (!itemstack.isEmpty())
return false;
return true;
}
}