Guest User

EntityArrow.java

a guest
May 3rd, 2013
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 50.50 KB | None | 0 0
  1. package net.minecraft.entity.projectile;
  2.  
  3. import cpw.mods.fml.common.FMLCommonHandler;
  4. import cpw.mods.fml.common.network.PacketDispatcher;
  5. import cpw.mods.fml.common.network.Player;
  6. import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
  7. import cpw.mods.fml.relauncher.Side;
  8. import cpw.mods.fml.relauncher.SideOnly;
  9.  
  10. import java.io.ByteArrayOutputStream;
  11. import java.io.DataOutputStream;
  12. import java.util.ArrayList;
  13. import java.util.EmptyStackException;
  14. import java.util.Iterator;
  15. import java.util.List;
  16.  
  17. import com.google.common.io.ByteArrayDataInput;
  18. import com.google.common.io.ByteArrayDataOutput;
  19.  
  20. import quivermod.QuiverMod;
  21. import quivermod.TileEntityTorch;
  22. import net.minecraft.block.Block;
  23. import net.minecraft.block.StepSound;
  24. import net.minecraft.block.material.Material;
  25. import net.minecraft.client.multiplayer.WorldClient;
  26. import net.minecraft.enchantment.EnchantmentThorns;
  27. import net.minecraft.entity.Entity;
  28. import net.minecraft.entity.EntityLiving;
  29. import net.minecraft.entity.IProjectile;
  30. import net.minecraft.entity.monster.EntityEnderman;
  31. import net.minecraft.entity.player.EntityPlayer;
  32. import net.minecraft.entity.player.EntityPlayerMP;
  33. import net.minecraft.item.Item;
  34. import net.minecraft.item.ItemStack;
  35. import net.minecraft.nbt.NBTTagCompound;
  36. import net.minecraft.network.packet.Packet;
  37. import net.minecraft.network.packet.Packet250CustomPayload;
  38. import net.minecraft.network.packet.Packet60Explosion;
  39. import net.minecraft.network.packet.Packet70GameEvent;
  40. import net.minecraft.potion.PotionEffect;
  41. import net.minecraft.tileentity.TileEntity;
  42. import net.minecraft.util.AxisAlignedBB;
  43. import net.minecraft.util.DamageSource;
  44. import net.minecraft.util.EnumMovingObjectType;
  45. import net.minecraft.util.MathHelper;
  46. import net.minecraft.util.MovingObjectPosition;
  47. import net.minecraft.util.Vec3;
  48. import net.minecraft.world.ChunkCoordIntPair;
  49. import net.minecraft.world.Explosion;
  50. import net.minecraft.world.World;
  51. import net.minecraft.world.WorldServer;
  52. import net.minecraft.world.chunk.Chunk;
  53. import net.minecraft.world.chunk.IChunkProvider;
  54. import net.minecraft.world.gen.ChunkProviderServer;
  55. import net.minecraftforge.common.ForgeChunkManager;
  56. import net.minecraftforge.common.ForgeChunkManager.Ticket;
  57.  
  58. public class EntityArrow extends Entity implements IProjectile, IEntityAdditionalSpawnData
  59. {
  60.     private float gravity = -0.05F;
  61.    
  62.     public float slowmo = 5;
  63.     public float actualTicks = -1;
  64.     public float prevYawForSlowmo = 0;
  65.     public float prevPitchForSlowmo = 0;
  66.    
  67.     MovingObjectPosition lastHitMOP = null;
  68.    
  69.     protected int xTile = -1;
  70.     protected int yTile = -1;
  71.     protected int zTile = -1;
  72.     protected int hitSide = -1;
  73.     protected int inTile = 0;
  74.     protected int inData = 0;
  75.     protected boolean inGround = false;
  76.    
  77.     public AxisAlignedBB headBoundingBox;
  78.     double headWidth = 0.1;
  79.  
  80.     /** != 0 if the player can pick up the arrow */
  81.     public int canBePickedUp = 0;
  82.     private ItemStack pickupItemStack = new ItemStack(Item.arrow);
  83.     public float arrowLength = 1;
  84.  
  85.     /** Timer for arrow shake animation and picking up the arrow. */
  86.     public int arrowShake = 0;
  87.  
  88.     /** The owner of this arrow. */
  89.     public Entity shootingEntity;
  90.     private int shootingEntityID = -1;
  91.     private String shootingPlayerName = null;
  92.     protected int ticksInGround;
  93.     protected int ticksInAir = 0;
  94.     protected double damage = 2.0D;
  95.  
  96.     /** The amount of knockback an arrow applies when it hits a mob. */
  97.     protected int knockbackStrength;
  98.    
  99.     public int ticks = 0;
  100.    
  101.     private int setFireTicks = -1;
  102.    
  103.     public boolean exploded = false;
  104.     public float explosionSize = 0;
  105.     public boolean explosionBurn = false;
  106.     public int explosionTime = -1;
  107.     public boolean explodeInWater = false;
  108.    
  109.     public int breakGlass = 0;
  110.     public double breakGlassVel = 0;
  111.  
  112.     public boolean teleportShooter = false;
  113.     public Ticket chunkLoader = null;
  114.    
  115.     public boolean placeTorch = false;
  116.    
  117.     public ArrayList<PotionEffect> effects;
  118.    
  119.     private int smokeParticlesPerBlock = 4;
  120.  
  121.     public EntityArrow(World world)
  122.     {
  123.         super(world);
  124.         this.renderDistanceWeight = 10.0D;
  125.         this.setSize(0.5F, 0.5F);
  126.     }
  127.  
  128.     public EntityArrow(World world, double x, double y, double z)
  129.     {
  130.         super(world);
  131.         this.renderDistanceWeight = 10.0D;
  132.         this.setSize(0.5F, 0.5F);
  133.         this.setPosition(x, y, z);
  134.         this.yOffset = 0.0F;
  135.     }
  136.  
  137.     public EntityArrow(World world, EntityLiving shooter, EntityLiving target, float speed, float deviation)
  138.     {
  139.         super(world);
  140.         this.renderDistanceWeight = 10.0D;
  141.         this.shootingEntity = shooter;
  142.  
  143.         if (shooter instanceof EntityPlayer)
  144.         {
  145.             this.canBePickedUp = 1;
  146.         }
  147.  
  148.         this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.1;
  149.        
  150.         double initVecX = target.posX - shooter.posX;
  151.         double initVecY = target.boundingBox.minY + (target.height / 2) - this.posY;
  152.         double initVecZ = target.posZ - shooter.posZ;
  153.  
  154.         double vecX = initVecX;
  155.         double vecY = initVecY;
  156.         double vecZ = initVecZ;
  157.        
  158.         double distance = 0;
  159.         double flightTicks = 0;
  160.         double approxSpeed = speed;
  161.  
  162.         double moveX = target.posX - target.lastTickPosX;
  163.         double moveY = target.posY - target.lastTickPosY;
  164.         double moveZ = target.posZ - target.lastTickPosZ;
  165.        
  166.         System.out.println("x " + moveX + " y " + moveY + " z " + moveZ);
  167.        
  168.         int passes = 4;
  169.  
  170.         for (int i = 0; i <= passes; i++)
  171.         {
  172.             distance = (double)MathHelper.sqrt_double(vecX * vecX + vecY * vecY + vecZ * vecZ);
  173.             flightTicks = distance / approxSpeed;
  174.            
  175.             if (i < passes)
  176.             {
  177.                 if (worldObj.difficultySetting >= 2)
  178.                 {
  179.                     vecX = initVecX + moveX * flightTicks;
  180.                     vecY = initVecY + moveY * flightTicks;
  181.                     vecZ = initVecZ + moveZ * flightTicks;
  182.                 }
  183.                
  184.                 approxSpeed = speed * Math.pow(0.99, flightTicks);
  185.             }
  186.         }
  187.        
  188.         double antiGrav = 0.5F * gravity * flightTicks * flightTicks;
  189.         vecY -= antiGrav;
  190.        
  191.         double horizDistance = (double)MathHelper.sqrt_double(vecX * vecX + vecZ * vecZ);
  192.  
  193.         if (horizDistance >= 1.0E-7D)
  194.         {
  195.             float yaw = (float)(Math.atan2(vecZ, vecX) * 180.0D / Math.PI) - 90.0F;
  196.             float pitch = (float)(-(Math.atan2(vecY, horizDistance) * 180.0D / Math.PI));
  197.             double offsetX = vecX / horizDistance;
  198.             double offsetY = vecY / horizDistance;
  199.             double offsetZ = vecZ / horizDistance;
  200.             this.setLocationAndAngles(shooter.posX + offsetX, this.posY + offsetY, shooter.posZ + offsetZ, yaw, pitch);
  201.             this.yOffset = 0.0F;
  202.             this.setThrowableHeading(vecX, vecY, vecZ, speed, deviation);
  203.         }
  204.     }
  205.  
  206.     public EntityArrow(World world, EntityLiving shooter, float speed)
  207.     {
  208.         super(world);
  209.         this.renderDistanceWeight = 10.0D;
  210.         this.shootingEntity = shooter;
  211.  
  212.         if (shooter instanceof EntityPlayer)
  213.         {
  214.             this.canBePickedUp = 1;
  215.         }
  216.  
  217.         this.setSize(0.5F, 0.5F);
  218.         this.setLocationAndAngles(shooter.posX, shooter.posY + (double)shooter.getEyeHeight(), shooter.posZ, shooter.rotationYaw, shooter.rotationPitch);
  219.         this.posX -= (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F);
  220.         this.posY -= 0.1;
  221.         this.posZ -= (double)(MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F);
  222.         this.setPosition(this.posX, this.posY, this.posZ);
  223.         this.yOffset = 0.0F;
  224.         this.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI));
  225.         this.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI));
  226.         this.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI));
  227.         this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, speed * 1.5F, 1.0F);
  228.     }
  229.  
  230.     protected void entityInit()
  231.     {
  232.         this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
  233.     }
  234.  
  235.     /**
  236.      * Similar to setArrowHeading, it's point the throwable entity to a x, y, z direction.
  237.      */
  238.     public void setThrowableHeading(double vecX, double vecY, double vecZ, float speed, float deviation)
  239.     {
  240.         float distance = MathHelper.sqrt_double(vecX * vecX + vecY * vecY + vecZ * vecZ);
  241.         vecX /= (double)distance;
  242.         vecY /= (double)distance;
  243.         vecZ /= (double)distance;
  244.         vecX += this.rand.nextGaussian() * (double)(this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double)deviation;
  245.         vecY += this.rand.nextGaussian() * (double)(this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double)deviation;
  246.         vecZ += this.rand.nextGaussian() * (double)(this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double)deviation;
  247.         vecX *= (double)speed;
  248.         vecY *= (double)speed;
  249.         vecZ *= (double)speed;
  250.         this.motionX = vecX;
  251.         this.motionY = vecY;
  252.         this.motionZ = vecZ;
  253.         double horizDistance = MathHelper.sqrt_double(vecX * vecX + vecZ * vecZ);
  254.         this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(vecX, vecZ) * 180.0D / Math.PI);
  255.         this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(vecY, (double)horizDistance) * 180.0D / Math.PI);
  256.         this.ticksInGround = 0;
  257.     }
  258.    
  259.     public static double degreesToRad = Math.PI / 180;
  260.    
  261.     protected Vec3 getTipCoords(float length)
  262.     {
  263.         float pitch = (float)(rotationPitch * degreesToRad);
  264.         float yaw = (float)((rotationYaw - 90) * degreesToRad);
  265.        
  266.         float x = (float)posX + (length * (float)Math.cos(pitch) * (float)Math.cos(yaw));
  267.         float y = (float)posY + (length * (float)Math.sin(pitch));
  268.         float z = (float)posZ + (-length * (float)Math.cos(pitch) * (float)Math.sin(yaw));
  269.        
  270.         return worldObj.getWorldVec3Pool().getVecFromPool(x, y, z);
  271.     }
  272.    
  273.     protected void setHeadBounds()
  274.     {
  275.         if (headBoundingBox == null)
  276.             headBoundingBox = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
  277.        
  278.         Vec3 headCoords = getTipCoords(0.4F);
  279.        
  280.         headBoundingBox.setBounds(headCoords.xCoord - headWidth, headCoords.yCoord - headWidth, headCoords.zCoord - headWidth,
  281.                 headCoords.xCoord + headWidth, headCoords.yCoord + headWidth, headCoords.zCoord + headWidth);
  282.     }
  283.    
  284.     protected void setBounds()
  285.     {
  286.         setHeadBounds();
  287.  
  288.         Vec3 headCoords = getTipCoords(0.15F);
  289.         Vec3 tailCoords = getTipCoords(-0.6F);
  290.        
  291.         boundingBox.setBounds(headCoords.xCoord, headCoords.yCoord, headCoords.zCoord,
  292.                 headCoords.xCoord, headCoords.yCoord, headCoords.zCoord);
  293.         AxisAlignedBB newBoundingBox = boundingBox.addCoord(tailCoords.xCoord - headCoords.xCoord,
  294.                 tailCoords.yCoord - headCoords.yCoord,
  295.                 tailCoords.zCoord - headCoords.zCoord).expand(0.15, 0.15, 0.15);
  296.         boundingBox.setBB(newBoundingBox);
  297.     }
  298.    
  299.     public void setPosition(double par1, double par3, double par5)
  300.     {
  301.         super.setPosition(par1, par3, par5);
  302.         setBounds();
  303.     }
  304.    
  305.     protected void setRotation(float yaw, float pitch)
  306.     {
  307.         super.setRotation(yaw, pitch);
  308.         setBounds();
  309.     }
  310.  
  311.     @SideOnly(Side.CLIENT)
  312.  
  313.     /**
  314.      * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
  315.      * posY, posZ, yaw, pitch
  316.      */
  317.     public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
  318.     {
  319.         this.setPosition(par1, par3, par5);
  320.         this.setRotation(par7, par8);
  321.     }
  322.  
  323.     @SideOnly(Side.CLIENT)
  324.  
  325.     /**
  326.      * Sets the velocity to the args. Args: x, y, z
  327.      */
  328.     public void setVelocity(double par1, double par3, double par5)
  329.     {
  330.         this.motionX = par1;
  331.         this.motionY = par3;
  332.         this.motionZ = par5;
  333.  
  334.         if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F)
  335.         {
  336.             float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5);
  337.             this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(par1, par5) * 180.0D / Math.PI);
  338.             this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(par3, (double)var7) * 180.0D / Math.PI);
  339.             this.prevRotationPitch = this.rotationPitch;
  340.             this.prevRotationYaw = this.rotationYaw;
  341.             this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
  342.             this.ticksInGround = 0;
  343.         }
  344.     }
  345.    
  346.     public void setPickupItemStack(ItemStack itemStack)
  347.     {
  348.         pickupItemStack = itemStack;
  349.     }
  350.    
  351.     public void setExplosive(float size)
  352.     {
  353.         explosionSize = size;
  354.     }
  355.    
  356.     public void setExplosionBurn(boolean burn)
  357.     {
  358.         explosionBurn = burn;
  359.     }
  360.    
  361.     public void setExplosionTimer(int time)
  362.     {
  363.         explosionTime = time;
  364.     }
  365.    
  366.     public void setExplodeWhileInWater(boolean explode)
  367.     {
  368.         explodeInWater = true;
  369.     }
  370.    
  371.     public void setTeleportShooter(boolean teleport)
  372.     {
  373.         teleportShooter = teleport;
  374.        
  375.         chunkLoader = ForgeChunkManager.requestTicket(QuiverMod.instance, worldObj, ForgeChunkManager.Type.ENTITY);
  376.        
  377.         if (chunkLoader != null)
  378.         {
  379.             chunkLoader.bindEntity(this);
  380.             chunkLoader.setChunkListDepth(chunkLoader.getMaxChunkListDepth());
  381.         }
  382.     }
  383.    
  384.     public void setPlaceTorch(boolean place)
  385.     {
  386.         placeTorch = place;
  387.     }
  388.    
  389.     public void setPotionEffects(ArrayList<PotionEffect> newEffects)
  390.     {
  391.         effects = newEffects;
  392.     }
  393.    
  394.     private void getShooter()
  395.     {
  396.         if (actualTicks < 5)
  397.         {
  398.             if (shootingEntity == null)
  399.             {
  400.                 if (shootingEntityID != -1)
  401.                 {
  402.                     shootingEntity = worldObj.getEntityByID(shootingEntityID);
  403.                 }
  404.                 else if (shootingPlayerName != null)
  405.                 {
  406.                     shootingEntity = worldObj.getPlayerEntityByName(shootingPlayerName);
  407.                 }
  408.             }
  409.            
  410.             /*if (worldObj.isRemote && shootingEntity == null && QuiverMod.proxy.mc != null && QuiverMod.proxy.mc.isSingleplayer())
  411.             {
  412.                 shootingEntity = QuiverMod.proxy.mc.thePlayer;
  413.             }*/
  414.         }
  415.     }
  416.    
  417.     private int[] getPos()
  418.     {
  419.         int[] pos = new int[3];
  420.        
  421.         if (inGround)
  422.         {
  423.             int x = xTile;
  424.             int y = yTile;
  425.             int z = zTile;
  426.            
  427.             if (x == 0 && y == 0 && z == 0)
  428.             {
  429.                 x = (int)posX;
  430.                 y = (int)posY;
  431.                 z = (int)posZ;
  432.             }
  433.            
  434.             if (hitSide == 0)
  435.               y--;
  436.             else if (hitSide == 1)
  437.               y++;
  438.             else if (hitSide == 2)
  439.               z--;
  440.             else if (hitSide == 3)
  441.               z++;
  442.             else if (hitSide == 4)
  443.               x--;
  444.             else if (hitSide == 5)
  445.               x++;
  446.            
  447.             pos[0] = x;
  448.             pos[1] = y;
  449.             pos[2] = z;
  450.         }
  451.         else
  452.         {
  453.             pos[0] = (int)posX;
  454.             pos[1] = (int)posY;
  455.             pos[2] = (int)posZ;
  456.         }
  457.        
  458.         return pos;
  459.     }
  460.    
  461.     private Vec3 getTeleportPos(MovingObjectPosition mop)
  462.     {
  463.         Vec3 out = worldObj.getWorldVec3Pool().getVecFromPool(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
  464.        
  465.         if (shootingEntity != null)
  466.         {
  467.             if (mop.sideHit == 0)
  468.             {
  469.                 out.yCoord -= shootingEntity.height;
  470.             }
  471.             else if (mop.sideHit == 2)
  472.             {
  473.                 out.zCoord -= 0.5;
  474.             }
  475.             else if (mop.sideHit == 3)
  476.             {
  477.                 out.zCoord += 0.5;
  478.             }
  479.             else if (mop.sideHit == 4)
  480.             {
  481.                 out.xCoord -= 0.5;
  482.             }
  483.             else if (mop.sideHit == 5)
  484.             {
  485.                 out.xCoord += 0.5;
  486.             }
  487.         }
  488.        
  489.         return out;
  490.     }
  491.    
  492.     private boolean tryExplodeNoDeath(double x, double y, double z)
  493.     {
  494.         if (explosionSize > 0 && !exploded)
  495.         {
  496.             int id = worldObj.getBlockId((int)x, (int)y, (int)z);
  497.            
  498.             if (explodeInWater || (id != Block.waterStill.blockID && id != Block.waterMoving.blockID))
  499.             {
  500.                 if (!worldObj.isRemote)
  501.                 {
  502.                     Explosion explosion = new Explosion(worldObj, this, x, y, z, explosionSize);
  503.                     explosion.indirectExploder = shootingEntity;
  504.                     explosion.isFlaming = explosionBurn || isBurning();
  505.                     explosion.isSmoking = true;
  506.                     explosion.doExplosionA();
  507.                     explosion.doExplosionB(true);
  508.  
  509.                     Iterator playerIter = worldObj.playerEntities.iterator();
  510.  
  511.                     while (playerIter.hasNext())
  512.                     {
  513.                         ((EntityPlayerMP)playerIter.next()).playerNetServerHandler.sendPacketToPlayer(new Packet60Explosion(x, y, z, explosionSize, explosion.affectedBlockPositions, null));
  514.                     }
  515.                 }
  516.                
  517.                 exploded = true;
  518.                 return true;
  519.             }
  520.         }
  521.        
  522.         return false;
  523.     }
  524.    
  525.     private void explode(double x, double y, double z)
  526.     {
  527.         if (tryExplodeNoDeath(x, y, z))
  528.             setDead();
  529.     }
  530.    
  531.     private void explode(Vec3 pos)
  532.     {
  533.         explode(pos.xCoord, pos.yCoord, pos.zCoord);
  534.     }
  535.    
  536.     private void explode(int x, int y, int z)
  537.     {
  538.         explode((double)x, (double)y, (double)z);
  539.     }
  540.    
  541.     private void teleportParticles()
  542.     {
  543.         if (shootingEntity != null)
  544.         {
  545.             for (int i = 0; i < 40; i++)
  546.             {
  547.                 worldObj.spawnParticle("portal", shootingEntity.posX, shootingEntity.posY - 2 + rand.nextDouble() * 2.0, shootingEntity.posZ, rand.nextGaussian(), 0, rand.nextGaussian());
  548.             }
  549.         }
  550.     }
  551.    
  552.     private boolean teleport(double x, double y, double z)
  553.     {
  554.         if (teleportShooter && shootingEntity != null && shootingEntity instanceof EntityPlayerMP)
  555.         {
  556.             EntityPlayerMP shooter = ((EntityPlayerMP)shootingEntity);
  557.            
  558.             worldObj.playSoundEffect(shooter.posX, shooter.posY, shooter.posZ, "mob.endermen.portal", 1.0F, 1.0F);
  559.            
  560.             shooter.setPositionAndUpdate(x, y, z);
  561.             shooter.fallDistance = 0;
  562.             shooter.attackEntityFrom(DamageSource.fall, 5);
  563.            
  564.             teleportShooter = false;
  565.             return true;
  566.         }
  567.        
  568.         return false;
  569.     }
  570.  
  571.     private boolean teleport(Vec3 pos)
  572.     {
  573.         return teleport(pos.xCoord, pos.yCoord, pos.zCoord);
  574.     }
  575.    
  576.     public static AxisAlignedBB createBoundingBox(Vec3 vec1, Vec3 vec2)
  577.     {
  578.         AxisAlignedBB out = AxisAlignedBB.getAABBPool().getAABB(0, 0, 0, 0, 0, 0);
  579.        
  580.         if (vec1.xCoord < vec2.xCoord)
  581.         {
  582.             out.minX = vec1.xCoord;
  583.             out.maxX = vec2.xCoord;
  584.         }
  585.         else
  586.         {
  587.             out.minX = vec2.xCoord;
  588.             out.maxX = vec1.xCoord;
  589.         }
  590.        
  591.         if (vec1.yCoord < vec2.yCoord)
  592.         {
  593.             out.minY = vec1.yCoord;
  594.             out.maxY = vec2.yCoord;
  595.         }
  596.         else
  597.         {
  598.             out.minY = vec2.yCoord;
  599.             out.maxY = vec1.yCoord;
  600.         }
  601.        
  602.         if (vec1.zCoord < vec2.zCoord)
  603.         {
  604.             out.minZ = vec1.zCoord;
  605.             out.maxZ = vec2.zCoord;
  606.         }
  607.         else
  608.         {
  609.             out.minZ = vec2.zCoord;
  610.             out.maxZ = vec1.zCoord;
  611.         }
  612.        
  613.         return out;
  614.     }
  615.    
  616.     private void onGroundImpact(MovingObjectPosition mop)
  617.     {
  618.         Vec3 teleportPos = getTeleportPos(mop);
  619.  
  620.         if (!worldObj.isRemote && teleport(teleportPos))
  621.         {
  622.             setDead();
  623.         }
  624.        
  625.         int[] posInt = getPos();
  626.         int intX = posInt[0];
  627.         int intY = posInt[1];
  628.         int intZ = posInt[2];
  629.         int blockID = worldObj.getBlockId(intX, intY, intZ);
  630.        
  631.         if (inGround && explosionTime < 0)
  632.         {
  633.             explode(mop.hitVec);
  634.         }
  635.        
  636.         if (placeTorch)
  637.         {
  638.             intY = (int)mop.hitVec.yCoord;
  639.            
  640.             if (!worldObj.isRemote)
  641.                 QuiverMod.entityTorchBlock.tryPlace(worldObj, intX, intY, intZ, mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord, mop.sideHit);
  642.            
  643.             placeTorch = false;
  644.         }
  645.     }
  646.    
  647.     private boolean canAttackEntity(Entity entity)
  648.     {
  649.         if (entity == null ||
  650.                 entity instanceof EntityEnderman)
  651.             return false;
  652.        
  653.         return true;
  654.     }
  655.    
  656.     /**
  657.      * Called to update the entity's position/logic.
  658.      */
  659.     public synchronized void onUpdate()
  660.     {
  661.         actualTicks++;
  662.        
  663.         if (slowmo > 0)
  664.         {
  665.             prevRotationYaw = prevYawForSlowmo;
  666.             prevRotationPitch = prevPitchForSlowmo;
  667.         }
  668.        
  669.         if (slowmo < 1 || actualTicks % slowmo == 0)
  670.         {
  671.             getShooter();
  672.            
  673.             if (chunkLoader != null)
  674.             {
  675.                 Chunk currentChunk;
  676.                 ChunkCoordIntPair chunkPos;
  677.                 int size = 25;
  678.                 int skip = 5;
  679.                
  680.                 for (int x = -size; x <= size; x += skip)
  681.                 {
  682.                     for (int z = -size; z <= size; z += skip)
  683.                     {
  684.                         if (x != 0 || z != 0)
  685.                         {
  686.                             currentChunk = worldObj.getChunkFromBlockCoords((int)(posX + x), (int)(posZ + z));
  687.                             chunkPos = currentChunk.getChunkCoordIntPair();
  688.                            
  689.                             ForgeChunkManager.forceChunk(chunkLoader, chunkPos);
  690.                         }
  691.                     }
  692.                 }
  693.                
  694.                 currentChunk = worldObj.getChunkFromBlockCoords((int)posX, (int)posZ);
  695.                 chunkPos = currentChunk.getChunkCoordIntPair();
  696.                
  697.                 ForgeChunkManager.forceChunk(chunkLoader, chunkPos);
  698.             }
  699.  
  700.             double thePrevX = prevPosX;
  701.             double thePrevY = prevPosY;
  702.             double thePrevZ = prevPosZ;
  703.            
  704.             super.onUpdate();
  705.            
  706.             ticks++;
  707.             EntityPlayer player;
  708.    
  709.             if (prevRotationPitch == 0 && prevRotationYaw == 0)
  710.             {
  711.                 float motion = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
  712.                 prevRotationYaw = rotationYaw = (float)(Math.atan2(motionX, motionZ) * 180.0D / Math.PI);
  713.                 prevRotationPitch = rotationPitch = (float)(Math.atan2(motionY, (double)motion) * 180.0D / Math.PI);
  714.             }
  715.    
  716.             int inBlockID = worldObj.getBlockId(xTile, yTile, zTile);
  717.    
  718.             if (inBlockID > 0)
  719.             {
  720.                 Block.blocksList[inBlockID].setBlockBoundsBasedOnState(worldObj, xTile, yTile, zTile);
  721.                 AxisAlignedBB bounds = Block.blocksList[inBlockID].getCollisionBoundingBoxFromPool(worldObj, xTile, yTile, zTile);
  722.    
  723.                 if (bounds != null && bounds.isVecInside(worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ)))
  724.                 {
  725.                     inGround = true;
  726.                 }
  727.             }
  728.    
  729.             if (arrowShake > 0)
  730.             {
  731.                 --arrowShake;
  732.             }
  733.            
  734.             float motion1;
  735.             float motion2;
  736.            
  737.             if (lastHitMOP != null)
  738.             {
  739.                 System.out.println(FMLCommonHandler.instance().getEffectiveSide() + " calculations " + lastHitMOP.hitVec.xCoord + ", " + lastHitMOP.hitVec.yCoord + ", " + lastHitMOP.hitVec.zCoord);
  740.                 motion1 = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);
  741.                
  742.                 if (lastHitMOP.typeOfHit == EnumMovingObjectType.ENTITY)
  743.                 {
  744.                     int hitDamage = MathHelper.ceiling_double_int((double)motion1 * damage);
  745.  
  746.                     if (getIsCritical())
  747.                     {
  748.                         hitDamage += rand.nextInt(hitDamage / 2 + 2);
  749.                     }
  750.  
  751.                     DamageSource damageSource = null;
  752.  
  753.                     if (shootingEntity == null)
  754.                     {
  755.                         damageSource = DamageSource.causeArrowDamage(this, this);
  756.                     }
  757.                     else
  758.                     {
  759.                         damageSource = DamageSource.causeArrowDamage(this, shootingEntity);
  760.                     }
  761.  
  762.                     if (isBurning())
  763.                     {
  764.                         lastHitMOP.entityHit.setFire(5);
  765.                     }
  766.  
  767.                     if (explosionTime < 0 && lastHitMOP.entityHit.attackEntityFrom(damageSource, hitDamage))
  768.                     {
  769.                         if (lastHitMOP.entityHit instanceof EntityLiving)
  770.                         {
  771.                             EntityLiving entityLiving = (EntityLiving)lastHitMOP.entityHit;
  772.  
  773.                             if (!worldObj.isRemote)
  774.                             {
  775.                                 entityLiving.setArrowCountInEntity(entityLiving.getArrowCountInEntity() + 1);
  776.                             }
  777.  
  778.                             if (knockbackStrength > 0)
  779.                             {
  780.                                 motion2 = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
  781.  
  782.                                 if (motion2 > 0.0F)
  783.                                 {
  784.                                     lastHitMOP.entityHit.addVelocity(motionX * (double)knockbackStrength * 0.6 / (double)motion2, 0.1, motionZ * (double)knockbackStrength * 0.6 / (double)motion2);
  785.                                 }
  786.                             }
  787.  
  788.                             if (shootingEntity != null)
  789.                             {
  790.                                 EnchantmentThorns.func_92096_a(shootingEntity, entityLiving, rand);
  791.                             }
  792.  
  793.                             if (shootingEntity != null && lastHitMOP.entityHit != shootingEntity && lastHitMOP.entityHit instanceof EntityPlayer && shootingEntity instanceof EntityPlayerMP)
  794.                             {
  795.                                 ((EntityPlayerMP)shootingEntity).playerNetServerHandler.sendPacketToPlayer(new Packet70GameEvent(6, 0));
  796.                             }
  797.                         }
  798.  
  799.                         playSound("random.bowhit", 1.0F, 1.2F / (rand.nextFloat() * 0.2F + 0.9F));
  800.  
  801.                         tryExplodeNoDeath(lastHitMOP.hitVec.xCoord, lastHitMOP.hitVec.yCoord, lastHitMOP.hitVec.zCoord);
  802.                        
  803.                         if (lastHitMOP.entityHit instanceof EntityLiving && effects != null)
  804.                         {
  805.                             EntityLiving entityHitLiving = (EntityLiving)lastHitMOP.entityHit;
  806.                            
  807.                             for (PotionEffect effect : effects)
  808.                             {
  809.                                 entityHitLiving.addPotionEffect(effect);
  810.                             }
  811.                         }
  812.                        
  813.                         teleport(lastHitMOP.hitVec.xCoord, lastHitMOP.hitVec.yCoord, lastHitMOP.hitVec.zCoord);
  814.                        
  815.                         setDead();
  816.                     }
  817.                     else if (lastHitMOP.entityHit != shootingEntity)
  818.                     {
  819.                         float diffX = (float)(posX - lastHitMOP.entityHit.posX);
  820.                         float diffY = (float)(posY - lastHitMOP.entityHit.posY);
  821.                         float diffZ = (float)(posZ - lastHitMOP.entityHit.posZ);
  822.                         float distance = MathHelper.sqrt_float(diffX * diffX + diffY * diffY + diffZ * diffZ);
  823.                         diffX /= distance;
  824.                         diffY /= distance;
  825.                         diffZ /= distance;
  826.                         distance = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ) / 3;
  827.                         motionX += diffX;
  828.                         motionY += diffY;
  829.                         motionZ += diffZ;
  830.                         float newDistance = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);
  831.                         motionX /= newDistance;
  832.                         motionY /= newDistance;
  833.                         motionZ /= newDistance;
  834.                         motionX *= distance;
  835.                         motionY *= distance;
  836.                         motionZ *= distance;
  837.                         lastHitMOP.entityHit.motionX -= diffX / 5D;
  838.                         lastHitMOP.entityHit.motionY -= diffY / 5D;
  839.                         lastHitMOP.entityHit.motionZ -= diffZ / 5D;
  840.                     }
  841.                 }
  842.                 else    // TILE
  843.                 {
  844.                     inGround = true;
  845.                     xTile = lastHitMOP.blockX;
  846.                     yTile = lastHitMOP.blockY;
  847.                     zTile = lastHitMOP.blockZ;
  848.                     hitSide = lastHitMOP.sideHit;
  849.                     inTile = worldObj.getBlockId(xTile, yTile, zTile);
  850.                     inData = worldObj.getBlockMetadata(xTile, yTile, zTile);
  851.                    
  852.                     setIsCritical(false);
  853.                    
  854.                     arrowShake = 7;
  855.                    
  856.                     float volume = motion1 / 3;
  857.                    
  858.                     /*if (volMult > 1.5F)
  859.                         volMult = 1.5F;
  860.                     else */if (volume < 0.25F)
  861.                         volume = 0.25F;
  862.                    
  863.                     playSound("random.bowhit", volume, 1.2F / (rand.nextFloat() * 0.2F + 0.9F));
  864.                     playSound(Block.blocksList[inTile].stepSound.getPlaceSound(), volume, 1.2F / (rand.nextFloat() * 0.2F + 0.9F));
  865.  
  866.                     if (inTile != 0)
  867.                     {
  868.                         Block.blocksList[inTile].onEntityCollidedWithBlock(worldObj, xTile, yTile, zTile, this);
  869.                     }
  870.                    
  871.                     onGroundImpact(lastHitMOP);
  872.                 }
  873.                
  874.                 lastHitMOP = null;
  875.                 //motionX *= 0.001;
  876.                 //motionY *= 0.001;
  877.                 //motionZ *= 0.001;
  878.             }
  879.            
  880.             float distance = 0;
  881.    
  882.             if (this.inGround)
  883.             {
  884.                 int blockID = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile);
  885.                 int metadata = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile);
  886.    
  887.                 if (blockID == this.inTile && metadata == this.inData)
  888.                 {
  889.                     ++this.ticksInGround;
  890.    
  891.                     if (this.ticksInGround >= 1200)
  892.                     {
  893.                         this.setDead();
  894.                     }
  895.                 }
  896.                 else
  897.                 {
  898.                     inGround = false;
  899.                     double vecX = posX - (xTile + 0.5);
  900.                     double vecY = posY - (yTile + 0.5);
  901.                     double vecZ = posZ - (zTile + 0.5);
  902.                     motionX = vecX * 0.2F;
  903.                     motionY = vecY * 0.2F;
  904.                     motionZ = vecZ * 0.2F;
  905.                    
  906.                     ticksInGround = 0;
  907.                     ticksInAir = 0;
  908.                 }
  909.             }
  910.             else
  911.             {
  912.                 ++this.ticksInAir;
  913.                 Vec3 fromVec = null;
  914.                 Vec3 toVec = null;
  915.                 MovingObjectPosition mop = null;
  916.                
  917.                 double motion = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);
  918.                
  919.                 while (fromVec == null || mop != null)
  920.                 {
  921.                     fromVec = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
  922.                     toVec = worldObj.getWorldVec3Pool().getVecFromPool(posX + motionX, posY + motionY, posZ + motionZ);
  923.                     mop = worldObj.rayTraceBlocks_do_do(fromVec, toVec, false, true);
  924.                    
  925.                     if (mop != null)
  926.                     {
  927.                         int id = worldObj.getBlockId(mop.blockX, mop.blockY, mop.blockZ);
  928.                        
  929.                         if (breakGlass > 0 && motion > breakGlassVel && (id == Block.glass.blockID || id == Block.thinGlass.blockID || id == Block.glowStone.blockID))
  930.                         {
  931.                             worldObj.setBlock(mop.blockX, mop.blockY, mop.blockZ, 0);
  932.                            
  933.                             breakGlass--;
  934.                             motionX *= 0.25;
  935.                             motionY *= 0.25;
  936.                             motionZ *= 0.25;
  937.                         }
  938.                         else
  939.                         {
  940.                             break;
  941.                         }
  942.                     }
  943.                 }
  944.                
  945.                 fromVec = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
  946.                 toVec = worldObj.getWorldVec3Pool().getVecFromPool(posX + motionX, posY + motionY, posZ + motionZ);
  947.                
  948.                 //fromVec = worldObj.getWorldVec3Pool().getVecFromPool(thePrevX, thePrevY, thePrevZ);
  949.                 //toVec = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
  950.                
  951.                 if (mop != null)
  952.                 {
  953.                     toVec = worldObj.getWorldVec3Pool().getVecFromPool(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
  954.                 }
  955.                
  956.                 Vec3 diffVec = fromVec.subtract(toVec);
  957.                 List entityList = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
  958.                 //List entityList = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(diffVec.xCoord, diffVec.yCoord, diffVec.zCoord).expand(1.0D, 1.0D, 1.0D));
  959.                 //AxisAlignedBB hitBounds = createBoundingBox(fromVec, toVec).expand(width + 1, width + 1, width + 1);
  960.                 //List entityList = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, hitBounds);
  961.  
  962.                 float expand = 0.3F;
  963.                
  964.                 Entity hitEntity = null;
  965.                 double entityDist = -1;
  966.                 MovingObjectPosition entityIntercept = null;
  967.    
  968.                 for (int i = 0; i < entityList.size(); ++i)
  969.                 {
  970.                     Entity curEntity = (Entity)entityList.get(i);
  971.    
  972.                     if (curEntity.canBeCollidedWith() && (curEntity != this.shootingEntity || this.ticksInAir >= 5))
  973.                     {
  974.                         AxisAlignedBB entityBounds = curEntity.boundingBox.expand((double)expand, (double)expand, (double)expand);
  975.                         MovingObjectPosition intercept = entityBounds.calculateIntercept(fromVec, toVec);
  976.    
  977.                         if (intercept != null)
  978.                         {
  979.                             double curDist = fromVec.distanceTo(intercept.hitVec);
  980.    
  981.                             if (entityDist == -1 || curDist < entityDist)
  982.                             {
  983.                                 hitEntity = curEntity;
  984.                                 entityDist = curDist;
  985.                                 entityIntercept = intercept;
  986.                             }
  987.                         }
  988.                     }
  989.                 }
  990.                
  991.                 if (hitEntity != null)
  992.                 {
  993.                     mop = new MovingObjectPosition(hitEntity);
  994.                     mop.hitVec = worldObj.getWorldVec3Pool().getVecFromPool(entityIntercept.hitVec.xCoord, entityIntercept.hitVec.yCoord, entityIntercept.hitVec.zCoord);
  995.                     mop.sideHit = entityIntercept.sideHit;
  996.                 }
  997.    
  998.                 if (mop != null && mop.entityHit != null && mop.entityHit instanceof EntityPlayer)
  999.                 {
  1000.                     EntityPlayer entityplayer = (EntityPlayer)mop.entityHit;
  1001.    
  1002.                     if (entityplayer.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer)this.shootingEntity).func_96122_a(entityplayer))
  1003.                     {
  1004.                         mop = null;
  1005.                     }
  1006.                 }
  1007.    
  1008.                 if (mop != null && hitEntity != null)
  1009.                 {
  1010.                     if (getIsCritical())
  1011.                     {
  1012.                         double velX = entityIntercept.hitVec.xCoord - hitEntity.posX;
  1013.                         double velZ = entityIntercept.hitVec.zCoord - hitEntity.posZ;
  1014.                         double hitDistSqr = velX * velX + velZ * velZ;
  1015.                         velX /= hitDistSqr;
  1016.                         velZ /= hitDistSqr;
  1017.                        
  1018.                         for (int i = 0; i < 32; i++)
  1019.                         {
  1020.                             worldObj.spawnParticle("crit", (hitEntity.posX + entityIntercept.hitVec.xCoord) / 2, entityIntercept.hitVec.yCoord, (hitEntity.posZ + entityIntercept.hitVec.zCoord) / 2,
  1021.                                     velX + (rand.nextDouble() - 0.5) * 0.5, rand.nextDouble(), velZ + (rand.nextDouble() - 0.5) * 0.5);
  1022.                         }
  1023.                     }
  1024.                 }
  1025.                
  1026.                 if (mop != null && (mop.typeOfHit == EnumMovingObjectType.ENTITY ? canAttackEntity(mop.entityHit) : true))
  1027.                 {
  1028.                     Vec3 hitVec = mop.hitVec;
  1029.                    
  1030.                     if (mop.entityHit != null)
  1031.                     {
  1032.                         /*AxisAlignedBB entityBB = mop.entityHit.boundingBox;
  1033.                         Vec3 newHitVec;
  1034.  
  1035.                         if (mop.sideHit <= 1)
  1036.                         {
  1037.                             System.out.println("y");
  1038.                             newHitVec = fromVec.getIntermediateWithYValue(toVec, (entityBB.maxY - entityBB.minY) / 2);
  1039.                         }
  1040.                         else if (mop.sideHit <= 3)
  1041.                         {
  1042.                             System.out.println("z");
  1043.                             newHitVec = fromVec.getIntermediateWithZValue(toVec, (entityBB.maxZ - entityBB.minZ) / 2);
  1044.                         }
  1045.                         else
  1046.                         {
  1047.                             System.out.println("x");
  1048.                             newHitVec = fromVec.getIntermediateWithXValue(toVec, (entityBB.maxX - entityBB.minX) / 2);
  1049.                         }
  1050.                        
  1051.                         if (newHitVec != null)
  1052.                         {
  1053.                             hitVec = newHitVec;
  1054.                         }*/
  1055.                     }
  1056.                     else
  1057.                     {
  1058.                         motionX = hitVec.xCoord - posX;
  1059.                         motionY = hitVec.yCoord - posY;
  1060.                         motionZ = hitVec.zCoord - posZ;
  1061.                         /*motionDist = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
  1062.                         posX -= motionX / motionDist * 0.05000000074505806D;
  1063.                         posY -= motionY / motionDist * 0.05000000074505806D;
  1064.                         posZ -= motionZ / motionDist * 0.05000000074505806D;*/
  1065.                     }
  1066.                    
  1067.                     lastHitMOP = mop;
  1068.                    
  1069.                     System.out.println(FMLCommonHandler.instance().getEffectiveSide() + " pre " + lastHitMOP.hitVec.xCoord + ", " + lastHitMOP.hitVec.yCoord + ", " + lastHitMOP.hitVec.zCoord);
  1070.                 }
  1071.    
  1072.                 posX += this.motionX;
  1073.                 posY += this.motionY;
  1074.                 posZ += this.motionZ;
  1075.                 motion1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
  1076.                 rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
  1077.                
  1078.                 double posDiffX = posX - prevPosX;
  1079.                 double posDiffY = posY - prevPosY;
  1080.                 double posDiffZ = posZ - prevPosZ;
  1081.                 distance = MathHelper.sqrt_double(posDiffX * posDiffX + posDiffY * posDiffY + posDiffZ * posDiffZ);
  1082.    
  1083.                 if (this.getIsCritical())
  1084.                 {
  1085.                     for (int i = 0; i < distance; ++i)
  1086.                     {
  1087.                         worldObj.spawnParticle("crit", posX + motionX * (double)i / distance, posY + motionY * (double)i / distance, posZ + motionZ * (double)i / distance, -motionX, -motionY + 0.2D, -motionZ);
  1088.                     }
  1089.                 }
  1090.                
  1091.                 float targetPitch = (float)(Math.atan2(this.motionY, (double)motion1) * 180.0D / Math.PI);
  1092.                 float pitchDiff = rotationPitch - targetPitch;
  1093.                 float maxRotSpeed = 10;
  1094.                
  1095.                 if (pitchDiff > maxRotSpeed)
  1096.                     pitchDiff = maxRotSpeed;
  1097.                 if (pitchDiff < -maxRotSpeed)
  1098.                     pitchDiff = -maxRotSpeed;
  1099.                
  1100.                 rotationPitch -= pitchDiff;
  1101.                
  1102.                 /*for (this.rotationPitch = (float)(Math.atan2(this.motionY, (double)motionDist) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F)
  1103.                 {
  1104.                     ;
  1105.                 }
  1106.    
  1107.                 while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
  1108.                 {
  1109.                     this.prevRotationPitch += 360.0F;
  1110.                 }
  1111.    
  1112.                 while (this.rotationYaw - this.prevRotationYaw < -180.0F)
  1113.                 {
  1114.                     this.prevRotationYaw -= 360.0F;
  1115.                 }
  1116.    
  1117.                 while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
  1118.                 {
  1119.                     this.prevRotationYaw += 360.0F;
  1120.                 }*/
  1121.    
  1122.                 //this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
  1123.                
  1124.                 rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
  1125.                
  1126.                 float slowdown = 0.99F;
  1127.    
  1128.                 if (this.isInWater())
  1129.                 {
  1130.                     for (int var25 = 0; var25 < 4; ++var25)
  1131.                     {
  1132.                         motion2 = 0.25F;
  1133.                         this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double)motion2, this.posY - this.motionY * (double)motion2, this.posZ - this.motionZ * (double)motion2, this.motionX, this.motionY, this.motionZ);
  1134.                     }
  1135.    
  1136.                     slowdown = 0.8F;
  1137.                 }
  1138.    
  1139.                 this.motionX *= (double)slowdown;
  1140.                 this.motionY *= (double)slowdown;
  1141.                 this.motionZ *= (double)slowdown;
  1142.                 this.motionY += (double)gravity;
  1143.                 this.setPosition(this.posX, this.posY, this.posZ);
  1144.                 this.doBlockCollisions();
  1145.             }
  1146.            
  1147.             int[] pos = getPos();
  1148.             int x = pos[0];
  1149.             int y = pos[1];
  1150.             int z = pos[2];
  1151.             int blockID = worldObj.getBlockId(x, y, z);
  1152.            
  1153.             if ((ticks > explosionTime && explosionTime > 0) || blockID == Block.lavaStill.blockID || blockID == Block.lavaMoving.blockID)
  1154.             {
  1155.                 explode(posX, posY, posZ);
  1156.             }
  1157.            
  1158.             if (isBurning())
  1159.             {
  1160.                 if (QuiverMod.proxy.mc != null && QuiverMod.proxy.mc.gameSettings.particleSetting <= 1)
  1161.                 {
  1162.                     int particles = (int)(smokeParticlesPerBlock * distance);
  1163.                    
  1164.                     if (particles <= 0)
  1165.                         particles = 1;
  1166.  
  1167.                     double moveX = posX - prevPosX;
  1168.                     double moveY = posY - prevPosY;
  1169.                     double moveZ = posZ - prevPosZ;
  1170.                    
  1171.                     double mult;
  1172.                    
  1173.                     for (int i = 0; i < particles; i++)
  1174.                     {
  1175.                         mult = (i / (float)particles);  // Multiplier for current position's weight for interpolation
  1176.                         worldObj.spawnParticle("smoke", posX + (moveX * mult) + ((rand.nextDouble() - 0.5) * 0.25),
  1177.                                 posY + (moveY * mult) + ((rand.nextDouble() - 0.5) * 0.25),
  1178.                                 posZ + (moveZ * mult) + ((rand.nextDouble() - 0.5) * 0.25), 0, 0, 0);
  1179.                     }
  1180.                 }
  1181.                
  1182.                 if (!inGround)
  1183.                 {
  1184.                     setFireTicks = -1;
  1185.                 }
  1186.                
  1187.                 if (!worldObj.isRemote && inGround && ticksInGround > 25 && setFireTicks == -1)
  1188.                 {
  1189.                     boolean replace = false;
  1190.                    
  1191.                     if (worldObj.isAirBlock(x, y, z))
  1192.                     {
  1193.                         replace = true;
  1194.                     }
  1195.                     else
  1196.                     {
  1197.                         Block block = Block.blocksList[worldObj.getBlockId(x, y, z)];
  1198.                        
  1199.                         if (block != null)
  1200.                         {
  1201.                             replace = block.blockMaterial.isReplaceable() && !block.blockMaterial.isLiquid();
  1202.                         }
  1203.                     }
  1204.                    
  1205.                     if (replace)
  1206.                         worldObj.setBlock(x, y, z, Block.fire.blockID);
  1207.                    
  1208.                     setFireTicks = ticksInGround;
  1209.                 }
  1210.                
  1211.                 if (setFireTicks >= 0 && ticksInGround - setFireTicks > 50)
  1212.                 {
  1213.                     setDead();
  1214.                 }
  1215.             }
  1216.            
  1217.             if (lastHitMOP != null)
  1218.             {
  1219.                 System.out.println(FMLCommonHandler.instance().getEffectiveSide() + " afterSetPrevMOP " + lastHitMOP.hitVec.xCoord + ", " + lastHitMOP.hitVec.yCoord + ", " + lastHitMOP.hitVec.zCoord);
  1220.             }
  1221.         }
  1222.        
  1223.         if (slowmo > 0)
  1224.         {
  1225.             prevYawForSlowmo = prevRotationYaw;
  1226.             prevPitchForSlowmo = prevRotationPitch;
  1227.         }
  1228.        
  1229.         if (lastHitMOP != null)
  1230.         {
  1231.             System.out.println(FMLCommonHandler.instance().getEffectiveSide() + " endrealtick " + lastHitMOP.hitVec.xCoord + ", " + lastHitMOP.hitVec.yCoord + ", " + lastHitMOP.hitVec.zCoord);
  1232.         }
  1233.        
  1234.         /*}
  1235.         else
  1236.         {
  1237.             this.prevRotationPitch = rotationPitch;
  1238.             this.prevRotationYaw = rotationYaw;
  1239.             this.rotationPitch += 1;
  1240.             this.rotationYaw += 1;
  1241.            
  1242.             rotationPitch = rotationPitch % 360;
  1243.             rotationYaw = rotationYaw % 360;
  1244.            
  1245.             ticks++;
  1246.         }*/
  1247.     }
  1248.  
  1249.     public void setDead()
  1250.     {
  1251.         if (teleportShooter)
  1252.         {
  1253.             if (chunkLoader != null)
  1254.             {
  1255.                 Iterator chunkIter = chunkLoader.getChunkList().iterator();
  1256.                
  1257.                 while (chunkIter.hasNext())
  1258.                 {
  1259.                     ChunkCoordIntPair chunk = (ChunkCoordIntPair)chunkIter.next();
  1260.                     ForgeChunkManager.unforceChunk(chunkLoader, chunk);
  1261.                 }
  1262.             }
  1263.            
  1264.             teleportParticles();
  1265.         }
  1266.        
  1267.         super.setDead();
  1268.     }
  1269.  
  1270.     public void writeSpawnData(ByteArrayDataOutput data) {
  1271.         data.writeInt(ticks);
  1272.  
  1273.         data.writeInt(breakGlass);
  1274.         data.writeDouble(breakGlassVel);
  1275.        
  1276.         data.writeBoolean(exploded);
  1277.         data.writeFloat(explosionSize);
  1278.         data.writeBoolean(explosionBurn);
  1279.         data.writeInt(explosionTime);
  1280.         data.writeBoolean(explodeInWater);
  1281.        
  1282.         data.writeBoolean(teleportShooter);
  1283.        
  1284.         data.writeBoolean(placeTorch);
  1285.        
  1286.         if (shootingEntity != null)
  1287.             data.writeInt(shootingEntity.entityId);
  1288.         else
  1289.             data.writeInt(-1);
  1290.     }
  1291.  
  1292.     public void readSpawnData(ByteArrayDataInput data) {
  1293.         ticks = data.readInt();
  1294.  
  1295.         breakGlass = data.readInt();
  1296.         breakGlassVel = data.readDouble();
  1297.        
  1298.         exploded = data.readBoolean();
  1299.         explosionSize = data.readFloat();
  1300.         explosionBurn = data.readBoolean();
  1301.         explosionTime = data.readInt();
  1302.         explodeInWater = data.readBoolean();
  1303.        
  1304.         teleportShooter = data.readBoolean();
  1305.        
  1306.         placeTorch = data.readBoolean();
  1307.        
  1308.         shootingEntityID = data.readInt();
  1309.     }
  1310.  
  1311.     /**
  1312.      * (abstract) Protected helper method to write subclass entity data to NBT.
  1313.      */
  1314.     public void writeEntityToNBT(NBTTagCompound tagCompound)
  1315.     {
  1316.         tagCompound.setShort("xTile", (short)this.xTile);
  1317.         tagCompound.setShort("yTile", (short)this.yTile);
  1318.         tagCompound.setShort("zTile", (short)this.zTile);
  1319.         tagCompound.setByte("inTile", (byte)this.inTile);
  1320.         tagCompound.setByte("inData", (byte)this.inData);
  1321.         tagCompound.setByte("shake", (byte)this.arrowShake);
  1322.         tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
  1323.         tagCompound.setByte("pickup", (byte)this.canBePickedUp);
  1324.         tagCompound.setCompoundTag("pickupItemStack", pickupItemStack.writeToNBT(new NBTTagCompound()));
  1325.         tagCompound.setDouble("damage", this.damage);
  1326.  
  1327.         tagCompound.setInteger("ticks", ticks);
  1328.         tagCompound.setInteger("ticksInAir", ticksInAir);
  1329.         tagCompound.setInteger("ticksInGround", ticksInGround);
  1330.         tagCompound.setInteger("setFireTicks", setFireTicks);
  1331.        
  1332.         tagCompound.setBoolean("exploded", exploded);
  1333.         tagCompound.setFloat("explosionSize", explosionSize);
  1334.         tagCompound.setInteger("explosionTime", explosionTime);
  1335.         tagCompound.setBoolean("explodeInWater", explodeInWater);
  1336.  
  1337.         tagCompound.setBoolean("teleportShooter", teleportShooter);
  1338.        
  1339.         if (shootingEntity != null && shootingEntity instanceof EntityPlayer)
  1340.         {
  1341.             String entName = ((EntityPlayer)shootingEntity).getEntityName();
  1342.             tagCompound.setString("shootingEntityName", entName);
  1343.         }
  1344.     }
  1345.  
  1346.     /**
  1347.      * (abstract) Protected helper method to read subclass entity data from NBT.
  1348.      */
  1349.     public void readEntityFromNBT(NBTTagCompound tagCompound)
  1350.     {
  1351.         this.xTile = tagCompound.getShort("xTile");
  1352.         this.yTile = tagCompound.getShort("yTile");
  1353.         this.zTile = tagCompound.getShort("zTile");
  1354.         this.inTile = tagCompound.getByte("inTile") & 255;
  1355.         this.inData = tagCompound.getByte("inData") & 255;
  1356.         this.arrowShake = tagCompound.getByte("shake") & 255;
  1357.         this.inGround = tagCompound.getByte("inGround") == 1;
  1358.  
  1359.         if (tagCompound.hasKey("damage"))
  1360.         {
  1361.             this.damage = tagCompound.getDouble("damage");
  1362.         }
  1363.  
  1364.         if (tagCompound.hasKey("pickup"))
  1365.         {
  1366.             this.canBePickedUp = tagCompound.getByte("pickup");
  1367.         }
  1368.         else if (tagCompound.hasKey("player"))
  1369.         {
  1370.             this.canBePickedUp = tagCompound.getBoolean("player") ? 1 : 0;
  1371.         }
  1372.        
  1373.         pickupItemStack = ItemStack.loadItemStackFromNBT(tagCompound.getCompoundTag("pickupItemStack"));
  1374.  
  1375.         ticks = tagCompound.getInteger("ticks");
  1376.         ticksInAir = tagCompound.getInteger("ticksInAir");
  1377.         ticksInGround = tagCompound.getInteger("ticksInGround");
  1378.         setFireTicks = tagCompound.getInteger("setFireTicks");
  1379.        
  1380.         exploded = tagCompound.getBoolean("exploded");
  1381.         explosionSize = tagCompound.getFloat("explosionSize");
  1382.         explosionTime = tagCompound.getInteger("explosionTime");
  1383.         explodeInWater = tagCompound.getBoolean("explodeInWater");
  1384.  
  1385.         teleportShooter = tagCompound.getBoolean("teleportShooter");
  1386.        
  1387.         if (tagCompound.hasKey("shootingEntityName"))
  1388.         {
  1389.             String entName = tagCompound.getString("shootingEntityName");
  1390.             shootingPlayerName = entName;
  1391.             System.out.println("Loaded shooting entity ID " + shootingPlayerName);
  1392.         }
  1393.         else
  1394.         {
  1395.             System.out.println("Loaded arrow with no shooting entity");
  1396.         }
  1397.     }
  1398.  
  1399.     /**
  1400.      * Called by a player entity when they collide with an entity
  1401.      */
  1402.     public void onCollideWithPlayer(EntityPlayer player)
  1403.     {
  1404.         if (!this.worldObj.isRemote && this.inGround && this.arrowShake <= 0)
  1405.         {
  1406.             boolean var2 = this.canBePickedUp == 1 || this.canBePickedUp == 2;
  1407.    
  1408.             if (this.canBePickedUp == 1 && !player.inventory.addItemStackToInventory(pickupItemStack))
  1409.             {
  1410.                 var2 = false;
  1411.             }
  1412.    
  1413.             if (var2)
  1414.             {
  1415.                 this.playSound("random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F);
  1416.                 player.onItemPickup(this, 1);
  1417.                 this.setDead();
  1418.             }
  1419.         }
  1420.     }
  1421.  
  1422.     /**
  1423.      * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
  1424.      * prevent them from trampling crops
  1425.      */
  1426.     protected boolean canTriggerWalking()
  1427.     {
  1428.         return false;
  1429.     }
  1430.  
  1431.     @SideOnly(Side.CLIENT)
  1432.     public float getShadowSize()
  1433.     {
  1434.         return 0.0F;
  1435.     }
  1436.  
  1437.     public void setDamage(double par1)
  1438.     {
  1439.         this.damage = par1;
  1440.     }
  1441.  
  1442.     public double getDamage()
  1443.     {
  1444.         return this.damage;
  1445.     }
  1446.  
  1447.     /**
  1448.      * Sets the amount of knockback the arrow applies when it hits a mob.
  1449.      */
  1450.     public void setKnockbackStrength(int par1)
  1451.     {
  1452.         this.knockbackStrength = par1;
  1453.     }
  1454.  
  1455.     /**
  1456.      * If returns false, the item will not inflict any damage against entities.
  1457.      */
  1458.     public boolean canAttackWithItem()
  1459.     {
  1460.         return false;
  1461.     }
  1462.  
  1463.     /**
  1464.      * Whether the arrow has a stream of critical hit particles flying behind it.
  1465.      */
  1466.     public void setIsCritical(boolean par1)
  1467.     {
  1468.         byte var2 = this.dataWatcher.getWatchableObjectByte(16);
  1469.  
  1470.         if (par1)
  1471.         {
  1472.             this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 1)));
  1473.         }
  1474.         else
  1475.         {
  1476.             this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -2)));
  1477.         }
  1478.     }
  1479.  
  1480.     /**
  1481.      * Whether the arrow has a stream of critical hit particles flying behind it.
  1482.      */
  1483.     public boolean getIsCritical()
  1484.     {
  1485.         byte var1 = this.dataWatcher.getWatchableObjectByte(16);
  1486.         return (var1 & 1) != 0;
  1487.     }
  1488. }
Advertisement
Add Comment
Please, Sign In to add comment