package com.amadornes.framez.block;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;
import uk.co.qmunity.lib.misc.Pair;
import uk.co.qmunity.lib.vec.Vec3d;
import uk.co.qmunity.lib.vec.Vec3i;
import com.amadornes.framez.Framez;
import com.amadornes.framez.api.Priority;
import com.amadornes.framez.api.Priority.PriorityEnum;
import com.amadornes.framez.api.movement.BlockMovementType;
import com.amadornes.framez.api.movement.IMovable;
import com.amadornes.framez.api.movement.IMovement;
import com.amadornes.framez.api.movement.IMovingBlock;
import com.amadornes.framez.movement.MovingBlock;
import com.amadornes.framez.movement.MovingStructure;
import com.amadornes.framez.network.PacketSingleBlockSync;
import com.amadornes.framez.ref.References;
import com.amadornes.framez.tile.TileMoving;
import com.amadornes.framez.world.FakeWorld;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockMoving extends BlockContainer implements IMovable {
public BlockMoving() {
super(Material.rock);
setBlockName(References.Block.MOVING);
setHardness(-1);
setResistance(-1);
MinecraftForge.EVENT_BUS.register(this);
}
@Override
public TileEntity createNewTileEntity(World w, int meta) {
return new TileMoving();
}
private TileMoving get(IBlockAccess w, int x, int y, int z) {
TileEntity te = w.getTileEntity(x, y, z);
if (te != null && te instanceof TileMoving)
return (TileMoving) te;
return null;
}
@SuppressWarnings("rawtypes")
@Override
public void addCollisionBoxesToList(World w, int x, int y, int z, AxisAlignedBB aabb, List l, Entity e) {
TileMoving te = get(w, x, y, z);
if (te == null)
return;
te.addCollisionBoxesToList(aabb, l, e);
}
@Override
@SideOnly(Side.CLIENT)
public AxisAlignedBB getSelectedBoundingBoxFromPool(World w, int x, int y, int z) {
TileMoving te = get(w, x, y, z);
if (te == null)
return AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
return te.getSelectedBoundingBox();
}
@Override
public MovingObjectPosition collisionRayTrace(World w, int x, int y, int z, Vec3 start, Vec3 end) {
TileMoving te = get(w, x, y, z);
if (te == null)
return null;
MovingObjectPosition mop = te.rayTrace(new Vec3d(start), new Vec3d(end));
if (mop != null)
mop.hitInfo = ((Pair<?, ?>) mop.hitInfo).getValue();
return mop;
}
@Override
@SideOnly(Side.CLIENT)
public int getRenderType() {
return -1;
}
@Override
public boolean isNormalCube() {
return false;
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public boolean renderAsNormalBlock() {
return false;
}
@Override
public boolean onBlockActivated(World w, int x, int y, int z, EntityPlayer p, int side, float subX, float subY, float subZ) {
TileMoving te = get(w, x, y, z);
if (te == null)
return false;
return te.onBlockActivated(p);
}
@Override
public void updateTick(World w, int x, int y, int z, Random rnd) {
TileMoving te = get(w, x, y, z);
if (te == null)
return;
if (te.getBlockA() == null)
return;
te.getBlockA().getBlock().updateTick(FakeWorld.getFakeWorld(te.getBlockA()), x, y, z, rnd);
}
@Override
public int getLightValue(IBlockAccess w, int x, int y, int z) {
TileMoving te = get(w, x, y, z);
if (te == null)
return 0;
return te.getLightValue();
}
@Override
public int getLightOpacity(IBlockAccess w, int x, int y, int z) {
return 0;
// TileMoving te = get(w, x, y, z);
// if (te == null)
// return 0;
// return te.getLightOpacity();
}
@Override
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) {
TileMoving te = get(world, x, y, z);
if (te == null)
return null;
return te.getPickBlock(target, player);
}
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World w, int x, int y, int z, Random rnd) {
TileMoving te = get(w, x, y, z);
if (te == null)
return;
te.randomDisplayTick(rnd);
}
@Override
public void onBlockExploded(World world, int x, int y, int z, Explosion explosion) {
}
@Override
public boolean canEntityDestroy(IBlockAccess world, int x, int y, int z, Entity entity) {
return false;
}
@Override
public boolean canDropFromExplosion(Explosion p_149659_1_) {
return false;
}
@SuppressWarnings("deprecation")
@Override
public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) {
TileMoving te = get(world, x, y, z);
if (te == null)
return false;
MovingObjectPosition mop = te.rayTrace(player);
if (mop != null) {
MovingBlock b = (MovingBlock) ((Entry<?, ?>) mop.hitInfo).getKey();
boolean result = b.getBlock().removedByPlayer(FakeWorld.getFakeWorld(b), player, b.getX(), b.getY(), b.getZ());
com.amadornes.framez.network.NetworkHandler.instance().sendToAllAround(
new PacketSingleBlockSync(b.getStructure().getMotor(), b), world, 64);
return result;
}
return false;
}
@Override
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister p_149651_1_) {
}
private boolean drawingHighlight = false;
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onDrawHighlight(DrawBlockHighlightEvent event) {
if (event == null || event.context == null || event.currentItem == null || event.player == null || event.target == null
|| event.target.typeOfHit != MovingObjectType.BLOCK)
return;
if (drawingHighlight)
return;
drawingHighlight = true;
try {
TileMoving te = get(event.player.worldObj, event.target.blockX, event.target.blockY, event.target.blockZ);
if (te != null) {
MovingObjectPosition mop = te.rayTrace(event.player);
if (mop != null && mop.typeOfHit == MovingObjectType.BLOCK) {
DrawBlockHighlightEvent ev = new DrawBlockHighlightEvent(event.context, event.player, mop, mop.subHit,
event.currentItem, event.partialTicks);
World world = event.player.worldObj;
World w = null;
MovingBlock a = te.getBlockA();
MovingBlock b = te.getBlockB();
Vec3i pos = null;
MovingStructure structure = null;
if (a != null) {
w = a.getRenderList() > 0 ? FakeWorld.getFakeWorld(a) : null;
pos = new Vec3i(a);
structure = a.getStructure();
} else if (b != null) {
w = b.getRenderList() > 0 ? FakeWorld.getFakeWorld(b) : null;
pos = new Vec3i(a);
structure = b.getStructure();
}
if (w != null) {
event.player.worldObj = w;
GL11.glPushMatrix();
{
GL11.glTranslated(-pos.getX(), -pos.getY(), -pos.getZ());
Vec3d t = structure.getMovement().transform(new Vec3d(pos.getX(), pos.getY(), pos.getZ()),
structure.getInterpolatedProgress(Framez.proxy.getFrame() - 1));
GL11.glTranslated(t.getX(), t.getY(), t.getZ());
MinecraftForge.EVENT_BUS.post(ev);
}
GL11.glPopMatrix();
if (ev.isCanceled())
event.setCanceled(true);
event.player.worldObj = world;
}
}
}
} catch (Exception ex) {
event.setCanceled(false);
}
drawingHighlight = false;
}
@Override
@Priority(PriorityEnum.OVERRIDE)
public BlockMovementType getMovementType(World world, int x, int y, int z, ForgeDirection side, IMovement movement) {
return BlockMovementType.UNMOVABLE;
}
@Override
public boolean startMoving(IMovingBlock block) {
return false;
}
@Override
public boolean finishMoving(IMovingBlock block) {
return false;
}
@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(IBlockAccess world, int x, int y, int z, int face) {
TileMoving te = get(world, x, y, z);
if (te == null)
return null;
if (te.getBlockA() != null)
return te
.getBlockA()
.getBlock()
.getIcon(FakeWorld.getFakeWorld(te.getBlockA()), te.getBlockA().getX(), te.getBlockA().getY(), te.getBlockA().getZ(),
face);
if (te.getBlockB() != null)
return te
.getBlockB()
.getBlock()
.getIcon(FakeWorld.getFakeWorld(te.getBlockB()), te.getBlockB().getX(), te.getBlockB().getY(), te.getBlockB().getZ(),
face);
return null;
}
}