package com.austinv11.peripheralsplusplus.entities;
import com.austinv11.peripheralsplusplus.PeripheralsPlusPlus;
import com.austinv11.peripheralsplusplus.network.RidableTurtlePacket;
import com.austinv11.peripheralsplusplus.reference.Config;
import com.austinv11.peripheralsplusplus.turtles.TurtleRidable;
import com.austinv11.peripheralsplusplus.utils.ReflectionHelper;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleAnimation;
import dan200.computercraft.api.turtle.TurtleSide;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
import org.lwjgl.input.Keyboard;
public class EntityRidableTurtle extends Entity {
private ITurtleAccess turtle = null;
private int queuedActionCode = -1;
private int tick = 0;
private boolean canPerformAction = true;
private int[] turtleLastPos;
public EntityRidableTurtle(World world) {
super(world);
this.setSize(1, 1);
}
@Override
protected void entityInit() {}
@Override
protected void readEntityFromNBT(NBTTagCompound nbtTagCompound) {
turtleLastPos = nbtTagCompound.getIntArray("turtleLastPos");
}
@Override
protected void writeEntityToNBT(NBTTagCompound nbtTagCompound) {
if (turtle != null)
nbtTagCompound.setIntArray("turtleLastPos", new int[]{turtle.getPosition().posX, turtle.getPosition().posY,
turtle.getPosition().posZ});
}
@Override
public void setPositionAndRotation2(double x, double y, double z, float pitch, float yaw, int par) {
this.setPosition(x, y, z);
this.setRotation(pitch, yaw);
}
@Override
public boolean canBeCollidedWith() {
return this.worldObj.isRemote && (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) ||
playerIsHoldingRideEnablingItem());
}
private boolean playerIsHoldingRideEnablingItem() {
if (!this.worldObj.isRemote) {
return false;
}
ItemStack item = Minecraft.getMinecraft().thePlayer.getHeldItem();
return item != null && (item.isItemEqual(new ItemStack(Items.carrot_on_a_stick)) || item.isItemEqual(new ItemStack(Items.stick)));
}
@Override
public boolean interactFirst(EntityPlayer player) {
if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer &&
this.riddenByEntity != player) {
return true;
} else if (this.riddenByEntity != null && this.riddenByEntity != player) {
return false;
} else {
if (!this.worldObj.isRemote) {
player.mountEntity(this);
}
return true;
}
}
@Override
public void onUpdate() {
checkRemove();
checkMovementQueue();
checkPlayerMovementRequest();
checkLocation();
updateTick();
}
private void checkRemove() {
if (turtleLastPos != null) {
try {
TileEntity turtleTile = this.worldObj.getTileEntity(turtleLastPos[0], turtleLastPos[1], turtleLastPos[2]);
this.turtle = ReflectionHelper.getTurtle(turtleTile);
} catch (Exception ignored) {}
turtleLastPos = null;
}
if (!this.worldObj.isRemote && ((turtle == null || !isTurleInWorld()) || !turtleHasUpgrade())) {
this.worldObj.removeEntity(this);
}
}
private boolean turtleHasUpgrade()
{
return this.turtle.getUpgrade(TurtleSide.Left) instanceof TurtleRidable || this.turtle.getUpgrade(TurtleSide.Right) instanceof TurtleRidable;
}
private boolean isTurleInWorld() {
TileEntity turtleTile = this.worldObj.getTileEntity(turtle.getPosition().posX, turtle.getPosition().posY, turtle.getPosition().posZ);
return turtleTile != null;
}
private void updateTick() {
if (canPerformAction) {
return;
}
if (tick < 10) { // ~.5 second
tick++;
} else {
tick = 0;
canPerformAction = true;
}
}
private void checkLocation() {
if (this.worldObj.isRemote || turtle == null || turtle.getPosition().equals(new ChunkCoordinates(
(int)Math.floor(this.posX), (int)Math.floor(this.posY), (int)Math.floor(this.posZ)))) {
return;
}
this.setPosition(turtle.getPosition().posX + 0.5, turtle.getPosition().posY, turtle.getPosition().posZ + 0.5);
}
private void checkMovementQueue() {
if ((!canPerformAction) || this.worldObj.isRemote || queuedActionCode < 0
|| queuedActionCode > RidableTurtlePacket.MovementCode.values().length - 1 || turtle == null) {
return;
}
RidableTurtlePacket.MovementCode which = RidableTurtlePacket.MovementCode.values()[queuedActionCode];
switch (which) {
case FORWARD:
moveTurtle(0);
break;
case TURN_LEFT:
turnTurtle("left");
break;
case TURN_RIGHT:
turnTurtle("right");
break;
case DESCEND:
moveTurtle(1);
break;
case ASCEND:
moveTurtle(2);
break;
}
queuedActionCode = -1;
canPerformAction = false;
}
private void turnTurtle(String turnTo) {
int[] directions = {2, 5, 3, 4};
int index = 0;
for (int i = 0; i < directions.length; i++) {
if (directions[i] == turtle.getDirection()) {
index = i;
break;
}
}
if (turnTo.equalsIgnoreCase("left")) {
index--;
} else {
index++;
}
if (index < 0) {
index = directions.length - 1;
}
if (index >= directions.length) {
index = 0;
}
turtle.setDirection(directions[index]);
if (turnTo.equalsIgnoreCase("left")) {
turtle.playAnimation(TurtleAnimation.TurnLeft);
} else {
turtle.playAnimation(TurtleAnimation.TurnRight);
}
}
private void moveTurtle(int direction) {
int x = turtle.getPosition().posX;
int y = turtle.getPosition().posY;
int z = turtle.getPosition().posZ;
TurtleAnimation animation = TurtleAnimation.None;
switch (direction) {
case 0: // Forward
switch (turtle.getDirection()) {
case 2: // North
z--;
break;
case 5: // East
x++;
break;
case 3: // South
z++;
break;
case 4: // West
x--;
break;
}
animation = TurtleAnimation.MoveForward;
break;
case 1: // Descend
y--;
animation = TurtleAnimation.MoveDown;
break;
case 2: // Ascend
y++;
animation = TurtleAnimation.MoveUp;
break;
}
if (this.worldObj.isAirBlock(x, y, z) && (turtle.getFuelLevel() >= Config.fuelPerTurtleMovement || !turtle.isFuelNeeded())) {
turtle.playAnimation(animation);
turtle.teleportTo(turtle.getWorld(), x, y, z);
turtle.consumeFuel(Config.fuelPerTurtleMovement);
}
}
private void checkPlayerMovementRequest() {
if (this.worldObj.isRemote && this.riddenByEntity != null &&
this.riddenByEntity == Minecraft.getMinecraft().thePlayer) {
if (Keyboard.isKeyDown(Keyboard.KEY_W)) { // TODO Forge keybinds
PeripheralsPlusPlus.NETWORK.sendToServer(new RidableTurtlePacket(this.getEntityId(),
RidableTurtlePacket.MovementCode.FORWARD.code, this.dimension));
} else if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
PeripheralsPlusPlus.NETWORK.sendToServer(new RidableTurtlePacket(this.getEntityId(),
RidableTurtlePacket.MovementCode.TURN_RIGHT.code, this.dimension));
} else if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
PeripheralsPlusPlus.NETWORK.sendToServer(new RidableTurtlePacket(this.getEntityId(),
RidableTurtlePacket.MovementCode.TURN_LEFT.code, this.dimension));
} else if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
PeripheralsPlusPlus.NETWORK.sendToServer(new RidableTurtlePacket(this.getEntityId(),
RidableTurtlePacket.MovementCode.DESCEND.code, this.dimension));
} else if (Keyboard.isKeyDown(Keyboard.KEY_X)) {
PeripheralsPlusPlus.NETWORK.sendToServer(new RidableTurtlePacket(this.getEntityId(),
RidableTurtlePacket.MovementCode.ASCEND.code, this.dimension));
}
}
}
public void setTurtle(ITurtleAccess turtle) {
this.turtle = turtle;
}
public void queueAction(int movementCode) {
if (canPerformAction) {
this.queuedActionCode = movementCode;
}
}
public boolean canMoveUp() {
return (this.worldObj.isAirBlock(turtle.getPosition().posX, turtle.getPosition().posY + 1,
turtle.getPosition().posZ) && (turtle.getFuelLevel() >= Config.fuelPerTurtleMovement
|| !turtle.isFuelNeeded()));
}
}