/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [Aug 16, 2015, 3:56:14 PM (GMT)]
*/
package vazkii.botania.common.entity;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import vazkii.botania.api.sound.BotaniaSoundEvents;
import vazkii.botania.common.Botania;
import vazkii.botania.common.core.helper.PlayerHelper;
import vazkii.botania.common.core.helper.Vector3;
import vazkii.botania.common.item.ModItems;
import vazkii.botania.common.item.equipment.tool.ToolCommons;
import vazkii.botania.common.item.relic.ItemKingKey;
public class EntityBabylonWeapon extends EntityThrowableCopy {
private static final String TAG_CHARGING = "charging";
private static final String TAG_VARIETY = "variety";
private static final String TAG_CHARGE_TICKS = "chargeTicks";
private static final String TAG_LIVE_TICKS = "liveTicks";
private static final String TAG_DELAY = "delay";
private static final String TAG_ROTATION = "rotation";
private static final DataParameter<Boolean> CHARGING = EntityDataManager.createKey(EntityBabylonWeapon.class, DataSerializers.BOOLEAN);
private static final DataParameter<Integer> VARIETY = EntityDataManager.createKey(EntityBabylonWeapon.class, DataSerializers.VARINT);
private static final DataParameter<Integer> CHARGE_TICKS = EntityDataManager.createKey(EntityBabylonWeapon.class, DataSerializers.VARINT);
private static final DataParameter<Integer> LIVE_TICKS = EntityDataManager.createKey(EntityBabylonWeapon.class, DataSerializers.VARINT);
private static final DataParameter<Integer> DELAY = EntityDataManager.createKey(EntityBabylonWeapon.class, DataSerializers.VARINT);
private static final DataParameter<Float> ROTATION = EntityDataManager.createKey(EntityBabylonWeapon.class, DataSerializers.FLOAT);
public EntityBabylonWeapon(World world) {
super(world);
}
public EntityBabylonWeapon(World world, EntityLivingBase thrower) {
super(world, thrower);
}
@Override
protected void entityInit() {
super.entityInit();
setSize(0F, 0F);
dataManager.register(CHARGING, false);
dataManager.register(VARIETY, 0);
dataManager.register(CHARGE_TICKS, 0);
dataManager.register(LIVE_TICKS, 0);
dataManager.register(DELAY, 0);
dataManager.register(ROTATION, 0F);
}
@Override
public boolean isImmuneToExplosions() {
return true;
}
@Override
public void onUpdate() {
EntityLivingBase thrower = getThrower();
if(!world.isRemote && (thrower == null || !(thrower instanceof EntityPlayer) || thrower.isDead)) {
setDead();
return;
}
EntityPlayer player = (EntityPlayer) thrower;
boolean charging = isCharging();
if(!world.isRemote) {
ItemStack stack = player == null ? ItemStack.EMPTY : PlayerHelper.getFirstHeldItem(player, ModItems.kingKey);
boolean newCharging = !stack.isEmpty() && ItemKingKey.isCharging(stack);
if(charging != newCharging) {
setCharging(newCharging);
charging = newCharging;
}
}
double x = motionX;
double y = motionY;
double z = motionZ;
int liveTime = getLiveTicks();
int delay = getDelay();
charging &= liveTime == 0;
if(charging) {
motionX = 0;
motionY = 0;
motionZ = 0;
int chargeTime = getChargeTicks();
setChargeTicks(chargeTime + 1);
if(world.rand.nextInt(20) == 0)
world.playSound(null, posX, posY, posZ, BotaniaSoundEvents.babylonSpawn, SoundCategory.PLAYERS, 0.1F, 1F + world.rand.nextFloat() * 3F);
} else {
if(liveTime < delay) {
motionX = 0;
motionY = 0;
motionZ = 0;
} else if (liveTime == delay && player != null) {
Vector3 playerLook;
RayTraceResult lookat = ToolCommons.raytraceFromEntity(world, player, true, 64);
if(lookat == null)
playerLook = new Vector3(player.getLookVec()).multiply(64).add(Vector3.fromEntity(player));
else playerLook = new Vector3(lookat.getBlockPos().getX() + 0.5, lookat.getBlockPos().getY() + 0.5, lookat.getBlockPos().getZ() + 0.5);
Vector3 thisVec = Vector3.fromEntityCenter(this);
Vector3 motionVec = playerLook.subtract(thisVec).normalize().multiply(2);
x = motionVec.x;
y = motionVec.y;
z = motionVec.z;
world.playSound(null, posX, posY, posZ, BotaniaSoundEvents.babylonAttack, SoundCategory.PLAYERS, 2F, 0.1F + world.rand.nextFloat() * 3F);
}
setLiveTicks(liveTime + 1);
if(!world.isRemote) {
AxisAlignedBB axis = new AxisAlignedBB(posX, posY, posZ, lastTickPosX, lastTickPosY, lastTickPosZ).expand(2, 2, 2);
List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, axis);
for(EntityLivingBase living : entities) {
if(living == thrower)
continue;
if(living.hurtTime == 0) {
if(player != null)
living.attackEntityFrom(DamageSource.causePlayerDamage(player), 20);
else living.attackEntityFrom(DamageSource.GENERIC, 20);
onImpact(new RayTraceResult(living));
return;
}
}
}
}
super.onUpdate();
motionX = x;
motionY = y;
motionZ = z;
if(liveTime > delay)
Botania.proxy.wispFX(posX, posY, posZ, 1F, 1F, 0F, 0.3F, 0F);
if(liveTime > 200 + delay)
setDead();
}
@Override
protected void onImpact(RayTraceResult pos) {
EntityLivingBase thrower = getThrower();
if(pos.entityHit == null || pos.entityHit != thrower) {
world.createExplosion(this, posX, posY, posZ, 3F, false);
setDead();
}
}
@Override
public void writeEntityToNBT(@Nonnull NBTTagCompound cmp) {
super.writeEntityToNBT(cmp);
cmp.setBoolean(TAG_CHARGING, isCharging());
cmp.setInteger(TAG_VARIETY, getVariety());
cmp.setInteger(TAG_CHARGE_TICKS, getChargeTicks());
cmp.setInteger(TAG_LIVE_TICKS, getLiveTicks());
cmp.setInteger(TAG_DELAY, getDelay());
cmp.setFloat(TAG_ROTATION, getRotation());
}
@Override
public void readEntityFromNBT(@Nonnull NBTTagCompound cmp) {
super.readEntityFromNBT(cmp);
setCharging(cmp.getBoolean(TAG_CHARGING));
setVariety(cmp.getInteger(TAG_VARIETY));
setChargeTicks(cmp.getInteger(TAG_CHARGE_TICKS));
setLiveTicks(cmp.getInteger(TAG_LIVE_TICKS));
setDelay(cmp.getInteger(TAG_DELAY));
setRotation(cmp.getFloat(TAG_ROTATION));
}
public boolean isCharging() {
return dataManager.get(CHARGING);
}
public void setCharging(boolean charging) {
dataManager.set(CHARGING, charging);
}
public int getVariety() {
return dataManager.get(VARIETY);
}
public void setVariety(int var) {
dataManager.set(VARIETY, var);
}
public int getChargeTicks() {
return dataManager.get(CHARGE_TICKS);
}
public void setChargeTicks(int ticks) {
dataManager.set(CHARGE_TICKS, ticks);
}
public int getLiveTicks() {
return dataManager.get(LIVE_TICKS);
}
public void setLiveTicks(int ticks) {
dataManager.set(LIVE_TICKS, ticks);
}
public int getDelay() {
return dataManager.get(DELAY);
}
public void setDelay(int delay) {
dataManager.set(DELAY, delay);
}
public float getRotation() {
return dataManager.get(ROTATION);
}
public void setRotation(float rot) {
dataManager.set(ROTATION, rot);
}
}