package micdoodle8.mods.galacticraft.core.entities;
import io.netty.buffer.ByteBuf;
import micdoodle8.mods.galacticraft.api.entity.IDockable;
import micdoodle8.mods.galacticraft.api.tile.IFuelDock;
import micdoodle8.mods.galacticraft.core.Constants;
import micdoodle8.mods.galacticraft.core.GCItems;
import micdoodle8.mods.galacticraft.core.GalacticraftCore;
import micdoodle8.mods.galacticraft.core.TransformerHooks;
import micdoodle8.mods.galacticraft.core.inventory.IInventoryDefaults;
import micdoodle8.mods.galacticraft.core.network.*;
import micdoodle8.mods.galacticraft.core.network.PacketEntityUpdate.IEntityFullSync;
import micdoodle8.mods.galacticraft.core.tick.KeyHandlerClient;
import micdoodle8.mods.galacticraft.core.tile.TileEntityBuggyFueler;
import micdoodle8.mods.galacticraft.core.util.FluidUtil;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class EntityBuggy extends Entity implements IInventoryDefaults, IPacketReceiver, IDockable, IControllableEntity, IEntityFullSync
{
public static final int tankCapacity = 1000;
public FluidTank buggyFuelTank = new FluidTank(this.tankCapacity);
protected long ticks = 0;
public int buggyType;
public int currentDamage;
public int timeSinceHit;
public int rockDirection;
public double speed;
public float wheelRotationZ;
public float wheelRotationX;
float maxSpeed = 0.5F;
float accel = 0.2F;
float turnFactor = 3.0F;
public String texture;
ItemStack[] cargoItems = new ItemStack[60];
public double boatX;
public double boatY;
public double boatZ;
public double boatYaw;
public double boatPitch;
public int boatPosRotationIncrements;
private IFuelDock landingPad;
private int timeClimbing;
private boolean shouldClimb;
public EntityBuggy(World var1)
{
super(var1);
this.setSize(0.98F, 1.4F);
this.currentDamage = 18;
this.timeSinceHit = 19;
this.rockDirection = 20;
this.speed = 0.0D;
this.preventEntitySpawning = true;
this.dataWatcher.addObject(this.currentDamage, new Integer(0));
this.dataWatcher.addObject(this.timeSinceHit, new Integer(0));
this.dataWatcher.addObject(this.rockDirection, new Integer(1));
this.ignoreFrustumCheck = true;
this.isImmuneToFire = true;
if (var1 != null && var1.isRemote)
{
GalacticraftCore.packetPipeline.sendToServer(new PacketDynamic(this));
}
}
public EntityBuggy(World var1, double var2, double var4, double var6, int type)
{
this(var1);
this.setPosition(var2, var4, var6);
this.setBuggyType(type);
this.cargoItems = new ItemStack[this.buggyType * 18];
}
public int getScaledFuelLevel(int i)
{
final double fuelLevel = this.buggyFuelTank.getFluid() == null ? 0 : this.buggyFuelTank.getFluid().amount;
return (int) (fuelLevel * i / this.tankCapacity);
}
public ModelBase getModel()
{
return null;
}
@Override
public ItemStack getPickedResult(MovingObjectPosition target)
{
return new ItemStack(GCItems.buggy, 1, this.buggyType);
}
public int getType()
{
return this.buggyType;
}
@Override
protected void entityInit()
{
}
@Override
protected boolean canTriggerWalking()
{
return false;
}
@Override
public boolean canBePushed()
{
return false;
}
@Override
public double getMountedYOffset()
{
return this.height - 3.0D;
}
@Override
public boolean canBeCollidedWith()
{
return !this.isDead;
}
public void setBuggyType(int par1)
{
this.buggyType = par1;
}
@Override
public void updateRiderPosition()
{
if (this.riddenByEntity != null)
{
final double var1 = Math.cos(this.rotationYaw / Constants.RADIANS_TO_DEGREES_D + 114.8) * -0.5D;
final double var3 = Math.sin(this.rotationYaw / Constants.RADIANS_TO_DEGREES_D + 114.8) * -0.5D;
this.riddenByEntity.setPosition(this.posX + var1, this.posY + 0.4F + this.riddenByEntity.getYOffset(), this.posZ + var3);
}
}
@Override
public void setPositionRotationAndMotion(double x, double y, double z, float yaw, float pitch, double motX, double motY, double motZ, boolean onGround)
{
if (this.worldObj.isRemote)
{
this.boatX = x;
this.boatY = y;
this.boatZ = z;
this.boatYaw = yaw;
this.boatPitch = pitch;
this.motionX = motX;
this.motionY = motY;
this.motionZ = motZ;
this.boatPosRotationIncrements = 5;
}
else
{
this.setPosition(x, y, z);
this.setRotation(yaw, pitch);
this.motionX = motX;
this.motionY = motY;
this.motionZ = motZ;
}
}
@Override
public void performHurtAnimation()
{
this.dataWatcher.updateObject(this.rockDirection, Integer.valueOf(-this.dataWatcher.getWatchableObjectInt(this.rockDirection)));
this.dataWatcher.updateObject(this.timeSinceHit, Integer.valueOf(10));
this.dataWatcher.updateObject(this.currentDamage, Integer.valueOf(this.dataWatcher.getWatchableObjectInt(this.currentDamage) * 5));
}
@Override
public boolean attackEntityFrom(DamageSource var1, float var2)
{
if (this.isDead || var1.equals(DamageSource.cactus))
{
return true;
}
else
{
Entity e = var1.getEntity();
boolean flag = var1.getEntity() instanceof EntityPlayer && ((EntityPlayer) var1.getEntity()).capabilities.isCreativeMode;
if (this.isEntityInvulnerable(var1) || (e instanceof EntityLivingBase && !(e instanceof EntityPlayer)))
{
return false;
}
else
{
this.dataWatcher.updateObject(this.rockDirection, Integer.valueOf(-this.dataWatcher.getWatchableObjectInt(this.rockDirection)));
this.dataWatcher.updateObject(this.timeSinceHit, Integer.valueOf(10));
this.dataWatcher.updateObject(this.currentDamage, Integer.valueOf((int) (this.dataWatcher.getWatchableObjectInt(this.currentDamage) + var2 * 10)));
this.setBeenAttacked();
if (e instanceof EntityPlayer && ((EntityPlayer) e).capabilities.isCreativeMode)
{
this.dataWatcher.updateObject(this.currentDamage, 100);
}
if (flag || this.dataWatcher.getWatchableObjectInt(this.currentDamage) > 2)
{
if (this.riddenByEntity != null)
{
this.riddenByEntity.mountEntity(this);
}
if (!this.worldObj.isRemote)
{
if (this.riddenByEntity != null)
{
this.riddenByEntity.mountEntity(this);
}
}
if (flag)
{
this.setDead();
}
else
{
this.setDead();
if (!this.worldObj.isRemote)
{
this.dropBuggyAsItem();
}
}
this.setDead();
}
return true;
}
}
}
public void dropBuggyAsItem()
{
List<ItemStack> dropped = this.getItemsDropped();
if (dropped == null)
{
return;
}
for (final ItemStack item : dropped)
{
EntityItem entityItem = this.entityDropItem(item, 0);
if (item.hasTagCompound())
{
entityItem.getEntityItem().setTagCompound((NBTTagCompound) item.getTagCompound().copy());
}
}
}
public List<ItemStack> getItemsDropped()
{
final List<ItemStack> items = new ArrayList<ItemStack>();
ItemStack buggy = new ItemStack(GCItems.buggy, 1, this.buggyType);
buggy.setTagCompound(new NBTTagCompound());
buggy.getTagCompound().setInteger("BuggyFuel", this.buggyFuelTank.getFluidAmount());
items.add(buggy);
for (ItemStack item : this.cargoItems)
{
if (item != null)
{
items.add(item);
}
}
return items;
}
@Override
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean b)
{
if (this.riddenByEntity != null)
{
if (this.riddenByEntity instanceof EntityPlayer && FMLClientHandler.instance().getClient().thePlayer.equals(this.riddenByEntity))
{
}
else
{
this.boatPosRotationIncrements = posRotationIncrements + 5;
this.boatX = x;
this.boatY = y + (this.riddenByEntity == null ? 1 : 0);
this.boatZ = z;
this.boatYaw = yaw;
this.boatPitch = pitch;
}
}
}
@Override
public void onUpdate()
{
this.ticks++;
super.onUpdate();
if (this.worldObj.isRemote)
{
this.wheelRotationX += Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ) * 150.0F * (this.speed < 0 ? 1 : -1);
this.wheelRotationX %= 360;
this.wheelRotationZ = Math.max(-30.0F, Math.min(30.0F, this.wheelRotationZ * 0.9F));
}
if (this.worldObj.isRemote && !FMLClientHandler.instance().getClient().thePlayer.equals(this.worldObj.getClosestPlayerToEntity(this, -1)))
{
double x;
double y;
double var12;
double z;
if (this.boatPosRotationIncrements > 0)
{
x = this.posX + (this.boatX - this.posX) / this.boatPosRotationIncrements;
y = this.posY + (this.boatY - this.posY) / this.boatPosRotationIncrements;
z = this.posZ + (this.boatZ - this.posZ) / this.boatPosRotationIncrements;
var12 = MathHelper.wrapAngleTo180_double(this.boatYaw - this.rotationYaw);
this.rotationYaw = (float) (this.rotationYaw + var12 / this.boatPosRotationIncrements);
this.rotationPitch = (float) (this.rotationPitch + (this.boatPitch - this.rotationPitch) / this.boatPosRotationIncrements);
--this.boatPosRotationIncrements;
this.setPosition(x, y, z);
this.setRotation(this.rotationYaw, this.rotationPitch);
}
else
{
x = this.posX + this.motionX;
y = this.posY + this.motionY;
z = this.posZ + this.motionZ;
if (this.riddenByEntity != null)
{
this.setPosition(x, y, z);
}
if (this.onGround)
{
this.motionX *= 0.5D;
this.motionY *= 0.5D;
this.motionZ *= 0.5D;
}
this.motionX *= 0.9900000095367432D;
this.motionY *= 0.949999988079071D;
this.motionZ *= 0.9900000095367432D;
}
return;
}
if (this.dataWatcher.getWatchableObjectInt(this.timeSinceHit) > 0)
{
this.dataWatcher.updateObject(this.timeSinceHit, Integer.valueOf(this.dataWatcher.getWatchableObjectInt(this.timeSinceHit) - 1));
}
if (this.dataWatcher.getWatchableObjectInt(this.currentDamage) > 0)
{
this.dataWatcher.updateObject(this.currentDamage, Integer.valueOf(this.dataWatcher.getWatchableObjectInt(this.currentDamage) - 1));
}
if (!this.onGround)
{
this.motionY -= TransformerHooks.getGravityForEntity(this) * 0.5D;
}
if (this.inWater && this.speed > 0.2D)
{
this.worldObj.playSoundEffect((float) this.posX, (float) this.posY, (float) this.posZ, "random.fizz", 0.5F, 2.6F + (this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.8F);
}
this.speed *= 0.98D;
if (this.speed > this.maxSpeed)
{
this.speed = this.maxSpeed;
}
if (this.isCollidedHorizontally && this.shouldClimb)
{
this.speed *= 0.9;
this.motionY = 0.15D * ((-Math.pow((this.timeClimbing) - 1, 2)) / 250.0F) + 0.15F;
this.motionY = Math.max(-0.15, this.motionY);
this.shouldClimb = false;
}
if ((this.motionX == 0 || this.motionZ == 0) && !this.onGround)
{
this.timeClimbing++;
}
else
{
this.timeClimbing = 0;
}
if (this.worldObj.isRemote && this.buggyFuelTank.getFluid() != null && this.buggyFuelTank.getFluid().amount > 0)
{
this.motionX = -(this.speed * Math.cos((this.rotationYaw - 90F) / Constants.RADIANS_TO_DEGREES_D));
this.motionZ = -(this.speed * Math.sin((this.rotationYaw - 90F) / Constants.RADIANS_TO_DEGREES_D));
}
if (this.worldObj.isRemote)
{
this.moveEntity(this.motionX, this.motionY, this.motionZ);
}
if (!this.worldObj.isRemote && Math.abs(this.motionX * this.motionZ) > 0.000001)
{
double d = this.motionX * this.motionX + this.motionZ * this.motionZ;
if (d != 0 && this.ticks % (MathHelper.floor_double(2 / d) + 1) == 0)
{
this.removeFuel(1);
}
}
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.worldObj.isRemote)
{
GalacticraftCore.packetPipeline.sendToServer(new PacketEntityUpdate(this));
}
else if (this.ticks % 5 == 0)
{
GalacticraftCore.packetPipeline.sendToAllAround(new PacketEntityUpdate(this), new TargetPoint(GCCoreUtil.getDimensionID(this.worldObj), this.posX, this.posY, this.posZ, 50.0D));
GalacticraftCore.packetPipeline.sendToAllAround(new PacketDynamic(this), new TargetPoint(GCCoreUtil.getDimensionID(this.worldObj), this.posX, this.posY, this.posZ, 50.0D));
}
}
@Override
public void getNetworkedData(ArrayList<Object> sendData)
{
if (this.worldObj.isRemote)
{
return;
}
sendData.add(this.buggyType);
sendData.add(this.buggyFuelTank);
}
@Override
public void decodePacketdata(ByteBuf buffer)
{
this.buggyType = buffer.readInt();
try
{
this.buggyFuelTank = NetworkUtil.readFluidTank(buffer);
}
catch (IOException e)
{
e.printStackTrace();
}
}
@Override
protected void readEntityFromNBT(NBTTagCompound var1)
{
this.buggyType = var1.getInteger("buggyType");
final NBTTagList var2 = var1.getTagList("Items", 10);
this.cargoItems = new ItemStack[this.getSizeInventory()];
if (var1.hasKey("fuelTank"))
{
this.buggyFuelTank.readFromNBT(var1.getCompoundTag("fuelTank"));
}
for (int var3 = 0; var3 < var2.tagCount(); ++var3)
{
final NBTTagCompound var4 = var2.getCompoundTagAt(var3);
final int var5 = var4.getByte("Slot") & 255;
if (var5 < this.cargoItems.length)
{
this.cargoItems[var5] = ItemStack.loadItemStackFromNBT(var4);
}
}
}
@Override
protected void writeEntityToNBT(NBTTagCompound var1)
{
var1.setInteger("buggyType", this.buggyType);
final NBTTagList var2 = new NBTTagList();
if (this.buggyFuelTank.getFluid() != null)
{
var1.setTag("fuelTank", this.buggyFuelTank.writeToNBT(new NBTTagCompound()));
}
for (int var3 = 0; var3 < this.cargoItems.length; ++var3)
{
if (this.cargoItems[var3] != null)
{
final NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte) var3);
this.cargoItems[var3].writeToNBT(var4);
var2.appendTag(var4);
}
}
var1.setTag("Items", var2);
}
@Override
public int getSizeInventory()
{
return this.buggyType * 18;
}
@Override
public ItemStack getStackInSlot(int var1)
{
return this.cargoItems[var1];
}
@Override
public ItemStack decrStackSize(int var1, int var2)
{
if (this.cargoItems[var1] != null)
{
ItemStack var3;
if (this.cargoItems[var1].stackSize <= var2)
{
var3 = this.cargoItems[var1];
this.cargoItems[var1] = null;
return var3;
}
else
{
var3 = this.cargoItems[var1].splitStack(var2);
if (this.cargoItems[var1].stackSize == 0)
{
this.cargoItems[var1] = null;
}
return var3;
}
}
else
{
return null;
}
}
@Override
public ItemStack removeStackFromSlot(int var1)
{
if (this.cargoItems[var1] != null)
{
final ItemStack var2 = this.cargoItems[var1];
this.cargoItems[var1] = null;
return var2;
}
else
{
return null;
}
}
@Override
public void setInventorySlotContents(int var1, ItemStack var2)
{
this.cargoItems[var1] = var2;
if (var2 != null && var2.stackSize > this.getInventoryStackLimit())
{
var2.stackSize = this.getInventoryStackLimit();
}
}
@Override
public String getName()
{
return "Buggy";
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1)
{
return !this.isDead && var1.getDistanceSqToEntity(this) <= 64.0D;
}
@Override
public void markDirty()
{
}
@Override
public boolean interactFirst(EntityPlayer var1)
{
if (this.worldObj.isRemote)
{
if (this.riddenByEntity == null)
{
var1.addChatMessage(new ChatComponentText(GameSettings.getKeyDisplayString(KeyHandlerClient.leftKey.getKeyCode()) + " / " + GameSettings.getKeyDisplayString(KeyHandlerClient.rightKey.getKeyCode()) + " - " + GCCoreUtil.translate("gui.buggy.turn.name")));
var1.addChatMessage(new ChatComponentText(GameSettings.getKeyDisplayString(KeyHandlerClient.accelerateKey.getKeyCode()) + " - " + GCCoreUtil.translate("gui.buggy.accel.name")));
var1.addChatMessage(new ChatComponentText(GameSettings.getKeyDisplayString(KeyHandlerClient.decelerateKey.getKeyCode()) + " - " + GCCoreUtil.translate("gui.buggy.decel.name")));
var1.addChatMessage(new ChatComponentText(GameSettings.getKeyDisplayString(KeyHandlerClient.openFuelGui.getKeyCode()) + " - " + GCCoreUtil.translate("gui.buggy.inv.name")));
}
return true;
}
else
{
if (this.riddenByEntity != null)
{
if (this.riddenByEntity == var1)
var1.mountEntity(null);
return true;
}
else
{
var1.mountEntity(this);
return true;
}
}
}
@Override
public boolean pressKey(int key)
{
if (this.worldObj.isRemote && (key == 6 || key == 8 || key == 9))
{
GalacticraftCore.packetPipeline.sendToServer(new PacketSimple(PacketSimple.EnumSimplePacket.S_CONTROL_ENTITY, GCCoreUtil.getDimensionID(this.worldObj), new Object[] { key }));
return true;
}
switch (key)
{
case 0: // Accelerate
this.speed += this.accel / 20D;
this.shouldClimb = true;
return true;
case 1: // Deccelerate
this.speed -= this.accel / 20D;
this.shouldClimb = true;
return true;
case 2: // Left
this.rotationYaw -= 0.5F * this.turnFactor;
this.wheelRotationZ = Math.max(-30.0F, Math.min(30.0F, this.wheelRotationZ + 0.5F));
return true;
case 3: // Right
this.rotationYaw += 0.5F * this.turnFactor;
this.wheelRotationZ = Math.max(-30.0F, Math.min(30.0F, this.wheelRotationZ - 0.5F));
return true;
}
return false;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return false;
}
@Override
public int addFuel(FluidStack liquid, boolean doDrain)
{
if (this.landingPad != null)
{
return FluidUtil.fillWithGCFuel(this.buggyFuelTank, liquid, doDrain);
}
return 0;
}
@Override
public FluidStack removeFuel(int amount)
{
return this.buggyFuelTank.drain(amount, true);
}
@Override
public EnumCargoLoadingState addCargo(ItemStack stack, boolean doAdd)
{
if (this.buggyType == 0)
{
return EnumCargoLoadingState.NOINVENTORY;
}
int count = 0;
for (count = 0; count < this.cargoItems.length; count++)
{
ItemStack stackAt = this.cargoItems[count];
if (stackAt != null && stackAt.getItem() == stack.getItem() && stackAt.getItemDamage() == stack.getItemDamage() && stackAt.stackSize < stackAt.getMaxStackSize())
{
if (stackAt.stackSize + stack.stackSize <= stackAt.getMaxStackSize())
{
if (doAdd)
{
this.cargoItems[count].stackSize += stack.stackSize;
this.markDirty();
}
return EnumCargoLoadingState.SUCCESS;
}
else
{
//Part of the stack can fill this slot but there will be some left over
int origSize = stackAt.stackSize;
int surplus = origSize + stack.stackSize - stackAt.getMaxStackSize();
if (doAdd)
{
this.cargoItems[count].stackSize = stackAt.getMaxStackSize();
this.markDirty();
}
stack.stackSize = surplus;
if (this.addCargo(stack, doAdd) == EnumCargoLoadingState.SUCCESS)
{
return EnumCargoLoadingState.SUCCESS;
}
this.cargoItems[count].stackSize = origSize;
return EnumCargoLoadingState.FULL;
}
}
}
for (count = 0; count < this.cargoItems.length; count++)
{
ItemStack stackAt = this.cargoItems[count];
if (stackAt == null)
{
if (doAdd)
{
this.cargoItems[count] = stack;
this.markDirty();
}
return EnumCargoLoadingState.SUCCESS;
}
}
return EnumCargoLoadingState.FULL;
}
@Override
public RemovalResult removeCargo(boolean doRemove)
{
for (int i = 0; i < this.cargoItems.length; i++)
{
ItemStack stackAt = this.cargoItems[i];
if (stackAt != null)
{
ItemStack resultStack = stackAt.copy();
resultStack.stackSize = 1;
if (doRemove && --stackAt.stackSize <= 0)
{
this.cargoItems[i] = null;
}
if (doRemove)
{
this.markDirty();
}
return new RemovalResult(EnumCargoLoadingState.SUCCESS, resultStack);
}
}
return new RemovalResult(EnumCargoLoadingState.EMPTY, null);
}
@Override
public void setPad(IFuelDock pad)
{
this.landingPad = pad;
}
@Override
public IFuelDock getLandingPad()
{
return this.landingPad;
}
@Override
public void onPadDestroyed()
{
}
@Override
public boolean isDockValid(IFuelDock dock)
{
return dock instanceof TileEntityBuggyFueler;
}
@Override
public boolean hasCustomName()
{
return true;
}
@Override
public UUID getOwnerUUID()
{
if (this.riddenByEntity != null && !(this.riddenByEntity instanceof EntityPlayer))
{
return null;
}
return this.riddenByEntity != null ? ((EntityPlayer) this.riddenByEntity).getPersistentID() : null;
}
}