package openblocks.common.tileentity;
import java.lang.ref.WeakReference;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler;
import openblocks.OpenBlocks;
import openblocks.common.LiquidXpUtils;
import openmods.OpenMods;
import openmods.tileentity.OpenTileEntity;
import openmods.utils.EnchantmentUtils;
public class TileEntityXPDrain extends OpenTileEntity {
private WeakReference<TileEntity> targetTank;
@Override
public void updateEntity() {
super.updateEntity();
if (OpenMods.proxy.getTicks(worldObj) % 100 == 0) {
searchForTank();
}
if (targetTank != null) {
TileEntity tile = targetTank.get();
if (!(tile instanceof IFluidHandler) || tile.isInvalid()) {
targetTank = null;
} else {
if (!worldObj.isRemote) {
IFluidHandler tank = (IFluidHandler)tile;
for (EntityXPOrb orb : getXPOrbsOnGrid())
tryConsumeOrb(tank, orb);
for (EntityPlayer player : getPlayersOnGrid())
tryDrainPlayer(tank, player);
}
}
}
}
protected void tryDrainPlayer(IFluidHandler tank, EntityPlayer player) {
int playerXP = EnchantmentUtils.getPlayerXP(player);
if (playerXP <= 0) return;
int maxDrainedXp = Math.min(4, playerXP);
int xpAmount = LiquidXpUtils.xpToLiquidRatio(maxDrainedXp);
FluidStack xpStack = new FluidStack(OpenBlocks.Fluids.xpJuice, xpAmount);
int maxAcceptedLiquid = tank.fill(ForgeDirection.UP, xpStack, false);
// rounding down, so we only use as much as we can
int acceptedXP = LiquidXpUtils.liquidToXpRatio(maxAcceptedLiquid);
int acceptedLiquid = LiquidXpUtils.xpToLiquidRatio(acceptedXP);
xpStack.amount = acceptedLiquid;
int finallyAcceptedLiquid = tank.fill(ForgeDirection.UP, xpStack, true);
if (finallyAcceptedLiquid <= 0) return;
if (OpenMods.proxy.getTicks(worldObj) % 4 == 0) {
worldObj.playSoundEffect(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "random.orb", 0.1F, 0.5F * ((worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.7F + 1.8F));
}
EnchantmentUtils.addPlayerXP(player, -acceptedXP);
}
protected void tryConsumeOrb(IFluidHandler tank, EntityXPOrb orb) {
if (!orb.isDead) {
int xpAmount = LiquidXpUtils.xpToLiquidRatio(orb.getXpValue());
FluidStack xpStack = new FluidStack(OpenBlocks.Fluids.xpJuice, xpAmount);
int filled = tank.fill(ForgeDirection.UP, xpStack, false);
if (filled == xpStack.amount) {
tank.fill(ForgeDirection.UP, xpStack, true);
orb.setDead();
}
}
}
public void searchForTank() {
targetTank = null;
for (int y = yCoord - 1; y > 0; y--) {
boolean isAir = worldObj.isAirBlock(xCoord, y, zCoord);
if (!isAir) {
TileEntity te = worldObj.getTileEntity(xCoord, y, zCoord);
if (!(te instanceof IFluidHandler) && te != null) {
Block block = te.getBlockType();
if (block.isOpaqueCube()) { return; }
} else {
targetTank = new WeakReference<TileEntity>(te);
return;
}
}
}
}
@SuppressWarnings("unchecked")
protected List<EntityPlayer> getPlayersOnGrid() {
AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 1, zCoord + 1);
return worldObj.getEntitiesWithinAABB(EntityPlayer.class, bb);
}
@SuppressWarnings("unchecked")
protected List<EntityXPOrb> getXPOrbsOnGrid() {
AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 0.3, zCoord + 1);
return worldObj.getEntitiesWithinAABB(EntityXPOrb.class, bb);
}
}