/*
* Copyright (c) CovertJaguar, 2014 http://railcraft.info
*
* This code is the property of CovertJaguar
* and may only be used with explicit written
* permission unless otherwise specified on the
* license page at http://railcraft.info/wiki/info:license.
*/
package mods.railcraft.common.carts;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import mods.railcraft.api.carts.CartTools;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import mods.railcraft.api.carts.IExplosiveCart;
import mods.railcraft.common.gui.EnumGui;
import mods.railcraft.common.gui.GuiHandler;
import mods.railcraft.common.items.firestone.ItemFirestoneRefined;
import mods.railcraft.common.util.misc.Game;
import mods.railcraft.common.util.network.IGuiReturnHandler;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.util.DamageSource;
public abstract class CartExplosiveBase extends CartBase implements IExplosiveCart, IGuiReturnHandler {
private static final byte FUSE_DATA_ID = 25;
private static final byte BLAST_DATA_ID = 26;
private static final byte PRIMED_DATA_ID = 27;
private final static float BLAST_RADIUS_BYTE_MULTIPLIER = 0.5f;
private final static float BLAST_RADIUS_MIN = 2;
private final static float BLAST_RADIUS_MAX = 6;
private final static float BLAST_RADIUS_MAX_BONUS = 5;
public static final short MAX_FUSE = 500;
public static final short MIN_FUSE = 0;
private boolean isExploding;
public CartExplosiveBase(World world) {
super(world);
}
public CartExplosiveBase(World world, double x, double y, double z) {
super(world, x, y, z);
}
@Override
protected void entityInit() {
super.entityInit();
dataWatcher.addObject(FUSE_DATA_ID, Short.valueOf((short) 80));
dataWatcher.addObject(BLAST_DATA_ID, Byte.valueOf((byte) 8));
dataWatcher.addObject(PRIMED_DATA_ID, Byte.valueOf((byte) 0));
}
@Override
public Block func_145820_n() {
return Blocks.tnt;
}
@Override
public void onUpdate() {
super.onUpdate();
if (this.isCollidedHorizontally) {
double d0 = this.motionX * this.motionX + this.motionZ * this.motionZ;
if (d0 >= 0.01) {
explode(getBlastRadiusWithSpeedModifier());
}
}
if (isPrimed()) {
setFuse((short) (getFuse() - 1));
if (getFuse() <= 0) {
explode();
} else {
worldObj.spawnParticle("smoke", posX, posY + 0.8D, posZ, 0.0D, 0.0D, 0.0D);
}
}
}
@Override
public void explode() {
explode(getBlastRadius());
}
protected void explode(float blastRadius) {
isExploding = true;
if (Game.isHost(getWorld())) {
worldObj.createExplosion(this, posX, posY, posZ, blastRadius, true);
setDead();
}
}
@Override
public void killMinecart(DamageSource damageSource) {
if (isDead || isExploding) {
return;
}
double speedSq = this.motionX * this.motionX + this.motionZ * this.motionZ;
if (damageSource.isFireDamage() || damageSource.isExplosion() || speedSq >= 0.01D) {
explode(getBlastRadiusWithSpeedModifier());
} else {
super.killMinecart(damageSource);
}
}
protected float getBlastRadiusWithSpeedModifier() {
double blast = Math.min(CartTools.getCartSpeedUncapped(this), getMaxBlastRadiusBonus());
return (float) (getBlastRadius() + rand.nextDouble() * 1.5 * blast);
}
protected float getBlastRadiusWithFallModifier(float distance) {
double blast = Math.min(distance / 10.0, getMaxBlastRadiusBonus());
return (float) (getBlastRadius() + rand.nextDouble() * 1.5 * blast);
}
@Override
public void onActivatorRailPass(int x, int y, int z, boolean powered) {
setPrimed(powered);
}
@Override
protected void fall(float distance) {
if (distance >= 3.0F) {
explode(getBlastRadiusWithFallModifier(distance));
}
super.fall(distance);
}
@Override
public boolean doInteract(EntityPlayer player) {
ItemStack stack = player.inventory.getCurrentItem();
if (stack != null) {
if (stack.getItem() == Items.flint_and_steel
|| stack.getItem() instanceof ItemFirestoneRefined) {
setPrimed(true);
stack.damageItem(1, player);
} else if (stack.getItem() == Items.string) {
player.inventory.decrStackSize(player.inventory.currentItem, 1);
GuiHandler.openGui(EnumGui.CART_TNT_FUSE, player, worldObj, this);
} else if (stack.getItem() == Items.gunpowder) {
player.inventory.decrStackSize(player.inventory.currentItem, 1);
GuiHandler.openGui(EnumGui.CART_TNT_BLAST, player, worldObj, this);
}
}
return true;
}
@Override
public boolean canBeRidden() {
return false;
}
@Override
public boolean isPrimed() {
return dataWatcher.getWatchableObjectByte(PRIMED_DATA_ID) != 0;
}
@Override
public void setPrimed(boolean primed) {
if (Game.isHost(worldObj) && isPrimed() != primed) {
if (primed) {
worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 1.0F);
}
dataWatcher.updateObject(PRIMED_DATA_ID, primed ? Byte.valueOf((byte) 1) : Byte.valueOf((byte) 0));
}
}
@Override
public int getFuse() {
return dataWatcher.getWatchableObjectShort(FUSE_DATA_ID);
}
@Override
public void setFuse(int f) {
f = (short) Math.max(f, MIN_FUSE);
f = (short) Math.min(f, MAX_FUSE);
dataWatcher.updateObject(FUSE_DATA_ID, (short) f);
}
protected float getMinBlastRadius() {
return BLAST_RADIUS_MIN;
}
protected float getMaxBlastRadius() {
return BLAST_RADIUS_MAX;
}
protected float getMaxBlastRadiusBonus() {
return BLAST_RADIUS_MAX_BONUS;
}
@Override
public float getBlastRadius() {
return dataWatcher.getWatchableObjectByte(BLAST_DATA_ID) * BLAST_RADIUS_BYTE_MULTIPLIER;
}
@Override
public void setBlastRadius(float b) {
b = Math.max(b, getMinBlastRadius());
b = Math.min(b, getMaxBlastRadius());
b /= BLAST_RADIUS_BYTE_MULTIPLIER;
dataWatcher.updateObject(BLAST_DATA_ID, Byte.valueOf((byte) b));
}
@Override
protected void writeEntityToNBT(NBTTagCompound data) {
super.writeEntityToNBT(data);
data.setShort("Fuse", (short) getFuse());
data.setByte("blastRadius", dataWatcher.getWatchableObjectByte(BLAST_DATA_ID));
data.setBoolean("Primed", isPrimed());
}
@Override
protected void readEntityFromNBT(NBTTagCompound data) {
super.readEntityFromNBT(data);
setFuse(data.getShort("Fuse"));
setBlastRadius(data.getByte("blastRadius"));
setPrimed(data.getBoolean("Primed"));
}
@Override
public void writeGuiData(DataOutputStream data) throws IOException {
data.writeShort(getFuse());
data.writeByte(dataWatcher.getWatchableObjectByte(BLAST_DATA_ID));
}
@Override
public void readGuiData(DataInputStream data, EntityPlayer sender) throws IOException {
setFuse(data.readShort());
setBlastRadius(data.readByte());
}
@Override
public World getWorld() {
return worldObj;
}
@Override
public double getDrag() {
return CartConstants.STANDARD_DRAG;
}
}