package net.tropicraft.entity.projectile; import java.util.List; import CoroUtil.packet.PacketHelper; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IProjectile; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.S2BPacketChangeGameState; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.tropicraft.Tropicraft; import net.tropicraft.entity.damage.TCDamageSource; import net.tropicraft.util.EffectHelper; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class EntityDart extends Entity implements IProjectile { /** Number of seconds desired * number of ticks per second = number of ticks total 8) */ private static final short MAX_HIT_TIME = 10 * 20; private int ticksInGround; private int ticksInAir; public Entity shootingEntity; private short dartType; private boolean inGround; public boolean doesDartBelongToPlayer; public int dartShake; private boolean hasRidden; public static int[] potions; public EntityDart(World world) { super(world); this.renderDistanceWeight = 10.0D; this.setSize(0.5F, 0.5F); } public EntityDart(World world, double x, double y, double z) { super(world); this.renderDistanceWeight = 10.0D; this.setSize(0.5F, 0.5F); this.setPosition(x, y, z); this.yOffset = 0.0F; this.ticksInAir = 0; this.ticksInGround = 0; } public EntityDart(World world, Entity shooter, float derp, short damage) { this(world); this.shootingEntity = shooter; this.dartType = damage; this.setLocationAndAngles(shooter.posX, shooter.posY + (double)shooter.getEyeHeight(), shooter.posZ, shooter.rotationYaw, shooter.rotationPitch); this.posX -= (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F); this.posY -= 0.10000000149011612D; this.posZ -= (double)(MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F); this.setPosition(this.posX, this.posY, this.posZ); this.yOffset = 0.0F; this.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI)); this.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI)); this.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI)); this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, derp * 1.5F, 1.0F); } @Override public void setThrowableHeading(double x, double y, double z, float rotation1, float rotation2) { // Vector normalization float f2 = MathHelper.sqrt_double(x * x + y * y + z * z); x /= (double)f2; y /= (double)f2; z /= (double)f2; // Add some random x += this.rand.nextGaussian() * (double)(this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double)rotation2; y += this.rand.nextGaussian() * (double)(this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double)rotation2; z += this.rand.nextGaussian() * (double)(this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double)rotation2; x *= (double)rotation1; y *= (double)rotation1; z *= (double)rotation1; this.motionX = x; this.motionY = y; this.motionZ = z; float f3 = MathHelper.sqrt_double(x * x + z * z); this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(x, z) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(y, (double)f3) * 180.0D / Math.PI); this.ticksInGround = 0; } /** * NOTE: Mostly taken from EntityArrow.onUpdate (1.7.2) */ @Override public void onUpdate() { super.onUpdate(); if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(this.motionY, (double)f) * 180.0D / Math.PI); } if (this.dartShake > 0) { --this.dartShake; } if (!worldObj.isRemote) { //System.out.println("motion: " + motionX + " - " + motionZ); } if (this.inGround) { this.setDead(); } else { ++this.ticksInAir; Vec3 vec31 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); Vec3 vec3 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); MovingObjectPosition movingobjectposition = this.worldObj.func_147447_a(vec31, vec3, false, true, false); vec31 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); vec3 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); if (movingobjectposition != null) { vec3 = Vec3.createVectorHelper(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); } Entity entity = null; List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); double d0 = 0.0D; int i; float f1; for (i = 0; i < list.size(); ++i) { Entity entity1 = (Entity)list.get(i); if (entity1.canBeCollidedWith() && (entity1 != this.shootingEntity || this.ticksInAir >= 5)) { f1 = 0.3F; AxisAlignedBB axisalignedbb1 = entity1.boundingBox.expand((double)f1, (double)f1, (double)f1); MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec31, vec3); if (movingobjectposition1 != null) { double d1 = vec31.distanceTo(movingobjectposition1.hitVec); if (d1 < d0 || d0 == 0.0D) { entity = entity1; d0 = d1; } } } } if (entity != null) { movingobjectposition = new MovingObjectPosition(entity); } if (movingobjectposition != null && movingobjectposition.entityHit != null && movingobjectposition.entityHit instanceof EntityPlayer) { EntityPlayer entityplayer = (EntityPlayer)movingobjectposition.entityHit; if (entityplayer.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer)this.shootingEntity).canAttackPlayer(entityplayer)) { movingobjectposition = null; } } float f2; float f4; if (movingobjectposition != null) { if (movingobjectposition.entityHit != null) { f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); DamageSource damagesource = null; if (this.shootingEntity == null) { damagesource = TCDamageSource.causeDartDamage(this, this); } else { damagesource = TCDamageSource.causeDartDamage(this, this.shootingEntity); } if (movingobjectposition.entityHit.attackEntityFrom(damagesource, (float)2)) { if (movingobjectposition.entityHit instanceof EntityLivingBase) { EntityLivingBase entitylivingbase = (EntityLivingBase)movingobjectposition.entityHit; if (!this.worldObj.isRemote) { if (this.dartType == 0) { System.out.println("client?: " + worldObj.isRemote); //do custom paralyse if (entitylivingbase instanceof EntityPlayerMP) { //Player, send to client NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("packetCommand", "effectAdd"); nbt.setInteger("effectID", this.dartType); nbt.setInteger("effectTime", 100); Tropicraft.eventChannel.sendTo(PacketHelper.getNBTPacket(nbt, Tropicraft.eventChannelName), (EntityPlayerMP) entitylivingbase); } else { //AI EffectHelper.addEntry(entitylivingbase, 100); } } else { entitylivingbase.addPotionEffect(new PotionEffect(potions[this.dartType], MAX_HIT_TIME, 1)); } } if (this.shootingEntity != null && movingobjectposition.entityHit != this.shootingEntity && movingobjectposition.entityHit instanceof EntityPlayer && this.shootingEntity instanceof EntityPlayerMP) { ((EntityPlayerMP)this.shootingEntity).playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(6, 0.0F)); } } this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } else { this.motionX *= -0.10000000149011612D; this.motionY *= -0.10000000149011612D; this.motionZ *= -0.10000000149011612D; this.rotationYaw += 180.0F; this.prevRotationYaw += 180.0F; this.ticksInAir = 0; } } else { Block block = this.worldObj.getBlock(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); if (block.getMaterial() != Material.air) { this.setDead(); } } } this.posX += this.motionX; this.posY += this.motionY; this.posZ += this.motionZ; f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); for (this.rotationPitch = (float)(Math.atan2(this.motionY, (double)f2) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { ; } while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { this.prevRotationPitch += 360.0F; } while (this.rotationYaw - this.prevRotationYaw < -180.0F) { this.prevRotationYaw -= 360.0F; } while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { this.prevRotationYaw += 360.0F; } this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; float f3 = 0.99F; f1 = 0.05F; if (this.isInWater()) { for (int l = 0; l < 4; ++l) { f4 = 0.25F; this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double)f4, this.posY - this.motionY * (double)f4, this.posZ - this.motionZ * (double)f4, this.motionX, this.motionY, this.motionZ); } f3 = 0.8F; } if (this.isWet()) { this.extinguish(); } this.motionX *= (double)f3; this.motionY *= (double)f3; this.motionZ *= (double)f3; this.motionY -= (double)f1; this.setPosition(this.posX, this.posY, this.posZ); this.func_145775_I(); } } @Override public void setDead() { // TODO Auto-generated method stub super.setDead(); } @Override @SideOnly(Side.CLIENT) public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { this.setPosition(par1, par3, par5); this.setRotation(par7, par8); } @Override @SideOnly(Side.CLIENT) public void setVelocity(double par1, double par3, double par5) { this.motionX = par1; this.motionY = par3; this.motionZ = par5; if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { float f = MathHelper.sqrt_double(par1 * par1 + par5 * par5); this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(par1, par5) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(par3, (double)f) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch; this.prevRotationYaw = this.rotationYaw; this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); this.ticksInGround = 0; } } public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { } @Override protected boolean canTriggerWalking() { return false; } @Override @SideOnly(Side.CLIENT) public float getShadowSize() { return 0.0F; } @Override protected void entityInit() { potions = new int[]{Potion.blindness.id, Potion.poison.id, Potion.moveSlowdown.id, Potion.harm.id, Potion.confusion.id, Potion.hunger.id, Potion.weakness.id}; dataWatcher.addObject(17, new Short(MAX_HIT_TIME)); dataWatcher.addObject(18, new Byte((byte) 0)); } @Override public void writeEntityToNBT(NBTTagCompound nbttagcompound) { nbttagcompound.setByte("shake", (byte) dartShake); nbttagcompound.setByte("inGround", (byte) (inGround ? 1 : 0)); nbttagcompound.setBoolean("player", doesDartBelongToPlayer); nbttagcompound.setBoolean("hit", getIsHit()); nbttagcompound.setShort("hitTime", (short) getHitTimer()); nbttagcompound.setShort("dartType", dartType); } @Override public void readEntityFromNBT(NBTTagCompound nbttagcompound) { dartShake = nbttagcompound.getByte("shake") & 0xff; inGround = nbttagcompound.getByte("inGround") == 1; doesDartBelongToPlayer = nbttagcompound.getBoolean("player"); setIsHit(nbttagcompound.getBoolean("hit")); setHitTimer(nbttagcompound.getShort("hitTime")); dartType = nbttagcompound.getShort("dartType"); } public void setIsHit(boolean set) { dataWatcher.updateObject(18, new Byte((byte) (set ? 1 : 0))); } public boolean getIsHit() { return dataWatcher.getWatchableObjectByte(18) == 1; } public void setHitTimer(short hitTime) { dataWatcher.updateObject(17, new Short(hitTime)); } public int getHitTimer() { return dataWatcher.getWatchableObjectShort(17); } }