package mcjty.rftools.blocks.dimletconstruction;
import mcjty.lib.entity.GenericTileEntity;
import mcjty.lib.varia.Coordinate;
import mcjty.rftools.items.dimlets.DimletKey;
import mcjty.rftools.items.dimlets.DimletObjectMapping;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.S29PacketSoundEffect;
import net.minecraft.util.ChunkCoordinates;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.*;
public class LiquidAbsorberTileEntity extends GenericTileEntity {
private static final int ABSORB_SPEED = 2;
private int absorbing = 0;
private int blockID = -1;
private int timer = ABSORB_SPEED;
private Set<Coordinate> toscan = new HashSet<Coordinate>();
@Override
protected void checkStateClient() {
if (absorbing > 0) {
Random rand = worldObj.rand;
double u = rand.nextFloat() * 2.0f - 1.0f;
double v = (float) (rand.nextFloat() * 2.0f * Math.PI);
double x = Math.sqrt(1 - u * u) * Math.cos(v);
double y = Math.sqrt(1 - u * u) * Math.sin(v);
double z = u;
double r = 1.0f;
worldObj.spawnParticle("portal", xCoord + 0.5f + x * r, yCoord + 0.5f + y * r, zCoord + 0.5f + z * r, -x, -y, -z);
}
}
private void checkBlock(Coordinate c, ForgeDirection direction) {
Coordinate c2 = c.addDirection(direction);
Block block = blockMatches(c2);
if (block != null) {
toscan.add(c2);
}
}
private Block blockMatches(Coordinate c2) {
Block block = isValidSourceBlock(c2);
if (block == null) {
return null;
}
int id = Block.blockRegistry.getIDForObject(block);
return id == blockID ? block : null;
}
private Block isValidSourceBlock(Coordinate coordinate) {
Block block = worldObj.getBlock(coordinate.getX(), coordinate.getY(), coordinate.getZ());
if (block == null || block.getMaterial() == Material.air) {
return null;
}
int meta = worldObj.getBlockMetadata(coordinate.getX(), coordinate.getY(), coordinate.getZ());
if (meta != 0) {
return null;
}
boolean ok = isValidDimletLiquid(block);
return ok ? block : null;
}
// Server side: play a sound to all nearby players
private void playSound(String soundName, double x, double y, double z, double volume, double pitch) {
S29PacketSoundEffect soundEffect = new S29PacketSoundEffect(soundName, x, y, z, (float) volume, (float) pitch);
for (int j = 0; j < worldObj.playerEntities.size(); ++j) {
EntityPlayerMP entityplayermp = (EntityPlayerMP)worldObj.playerEntities.get(j);
ChunkCoordinates chunkcoordinates = entityplayermp.getPlayerCoordinates();
double d7 = x - chunkcoordinates.posX;
double d8 = y - chunkcoordinates.posY;
double d9 = z - chunkcoordinates.posZ;
double d10 = d7 * d7 + d8 * d8 + d9 * d9;
if (d10 <= 256.0D) {
entityplayermp.playerNetServerHandler.sendPacket(soundEffect);
}
}
}
@Override
protected void checkStateServer() {
if (absorbing > 0 || blockID == -1) {
timer--;
if (timer <= 0) {
timer = ABSORB_SPEED;
Block b = isValidSourceBlock(new Coordinate(xCoord, yCoord - 1, zCoord));
if (b != null) {
int id = Block.blockRegistry.getIDForObject(b);
if (blockID == -1) {
absorbing = DimletConstructionConfiguration.maxLiquidAbsorbtion;
blockID = id;
toscan.clear();
toscan.add(new Coordinate(xCoord, yCoord - 1, zCoord));
} else if (id == blockID) {
toscan.add(new Coordinate(xCoord, yCoord - 1, zCoord));
}
}
if (!toscan.isEmpty()) {
int r = worldObj.rand.nextInt(toscan.size());
Iterator<Coordinate> iterator = toscan.iterator();
Coordinate c = null;
for (int i = 0 ; i <= r ; i++) {
c = iterator.next();
}
toscan.remove(c);
checkBlock(c, ForgeDirection.DOWN);
checkBlock(c, ForgeDirection.UP);
checkBlock(c, ForgeDirection.EAST);
checkBlock(c, ForgeDirection.WEST);
checkBlock(c, ForgeDirection.SOUTH);
checkBlock(c, ForgeDirection.NORTH);
Block block = blockMatches(c);
if (block != null) {
playSound(block.stepSound.getBreakSound(), xCoord, yCoord, zCoord, 1.0f, 1.0f);
worldObj.setBlockToAir(c.getX(), c.getY(), c.getZ());
absorbing--;
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
}
markDirty();
}
}
private boolean isValidDimletLiquid(Block block) {
boolean ok = false;
for (Map.Entry<DimletKey, Block> entry : DimletObjectMapping.idToFluid.entrySet()) {
if (entry.getValue() == block) {
ok = true;
break;
}
}
return ok;
}
@Override
public void writeToNBT(NBTTagCompound tagCompound) {
super.writeToNBT(tagCompound);
int[] x = new int[toscan.size()];
int[] y = new int[toscan.size()];
int[] z = new int[toscan.size()];
int i = 0;
for (Coordinate c : toscan) {
x[i] = c.getX();
y[i] = c.getY();
z[i] = c.getZ();
i++;
}
tagCompound.setIntArray("toscanx", x);
tagCompound.setIntArray("toscany", y);
tagCompound.setIntArray("toscanz", z);
}
@Override
public void writeRestorableToNBT(NBTTagCompound tagCompound) {
super.writeRestorableToNBT(tagCompound);
tagCompound.setInteger("absorbing", absorbing);
tagCompound.setInteger("liquid", blockID);
}
@Override
public void readFromNBT(NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
int[] x = tagCompound.getIntArray("toscanx");
int[] y = tagCompound.getIntArray("toscany");
int[] z = tagCompound.getIntArray("toscanz");
toscan.clear();
for (int i = 0 ; i < x.length ; i++) {
toscan.add(new Coordinate(x[i], y[i], z[i]));
}
}
@Override
public void readRestorableFromNBT(NBTTagCompound tagCompound) {
super.readRestorableFromNBT(tagCompound);
absorbing = tagCompound.getInteger("absorbing");
blockID = tagCompound.getInteger("liquid");
}
}