Advertisement
grossik

Untitled

Aug 14th, 2016
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.71 KB | None | 0 0
  1. package com.example.examplemod;
  2.  
  3. import java.util.List;
  4.  
  5. import javax.annotation.Nullable;
  6.  
  7. import com.google.common.collect.Lists;
  8.  
  9. import net.minecraft.block.BlockLiquid;
  10. import net.minecraft.block.BlockPlanks;
  11. import net.minecraft.block.material.Material;
  12. import net.minecraft.block.state.IBlockState;
  13. import net.minecraft.entity.Entity;
  14. import net.minecraft.entity.EntityLivingBase;
  15. import net.minecraft.entity.passive.EntityAnimal;
  16. import net.minecraft.entity.passive.EntityWaterMob;
  17. import net.minecraft.entity.player.EntityPlayer;
  18. import net.minecraft.init.Blocks;
  19. import net.minecraft.init.Items;
  20. import net.minecraft.item.Item;
  21. import net.minecraft.item.ItemStack;
  22. import net.minecraft.nbt.NBTTagCompound;
  23. import net.minecraft.network.datasync.DataParameter;
  24. import net.minecraft.network.datasync.DataSerializers;
  25. import net.minecraft.network.datasync.EntityDataManager;
  26. import net.minecraft.network.play.client.CPacketSteerBoat;
  27. import net.minecraft.util.DamageSource;
  28. import net.minecraft.util.EntityDamageSourceIndirect;
  29. import net.minecraft.util.EntitySelectors;
  30. import net.minecraft.util.EnumFacing;
  31. import net.minecraft.util.EnumHand;
  32. import net.minecraft.util.math.AxisAlignedBB;
  33. import net.minecraft.util.math.BlockPos;
  34. import net.minecraft.util.math.MathHelper;
  35. import net.minecraft.util.math.Vec3d;
  36. import net.minecraft.world.IBlockAccess;
  37. import net.minecraft.world.World;
  38. import net.minecraftforge.fml.relauncher.Side;
  39. import net.minecraftforge.fml.relauncher.SideOnly;
  40.  
  41. public class EntityVehicle extends Entity
  42. {
  43. private static final DataParameter<Integer> TIME_SINCE_HIT = EntityDataManager.<Integer>createKey(EntityVehicle.class, DataSerializers.VARINT);
  44. private static final DataParameter<Integer> FORWARD_DIRECTION = EntityDataManager.<Integer>createKey(EntityVehicle.class, DataSerializers.VARINT);
  45. private static final DataParameter<Float> DAMAGE_TAKEN = EntityDataManager.<Float>createKey(EntityVehicle.class, DataSerializers.FLOAT);
  46. private static final DataParameter<Integer> BOAT_TYPE = EntityDataManager.<Integer>createKey(EntityVehicle.class, DataSerializers.VARINT);
  47. private static final DataParameter<Boolean>[] DATA_ID_PADDLE = new DataParameter[] {EntityDataManager.createKey(EntityVehicle.class, DataSerializers.BOOLEAN), EntityDataManager.createKey(EntityVehicle.class, DataSerializers.BOOLEAN)};
  48. private final float[] paddlePositions;
  49. /** How much of current speed to retain. Value zero to one. */
  50. private float momentum;
  51. private float outOfControlTicks;
  52. private float deltaRotation;
  53. private int lerpSteps;
  54. private double boatPitch;
  55. private double lerpY;
  56. private double lerpZ;
  57. private double boatYaw;
  58. private double lerpXRot;
  59. private boolean leftInputDown;
  60. private boolean rightInputDown;
  61. private boolean forwardInputDown;
  62. private boolean backInputDown;
  63. private double waterLevel;
  64. /**
  65. * How much the boat should glide given the slippery blocks it's currently gliding over.
  66. * Halved every tick.
  67. */
  68. private float boatGlide;
  69. private EntityVehicle.Status status;
  70. private EntityVehicle.Status previousStatus;
  71. private double lastYd;
  72.  
  73. public EntityVehicle(World worldIn)
  74. {
  75. super(worldIn);
  76. this.paddlePositions = new float[2];
  77. this.preventEntitySpawning = true;
  78. this.setSize(1.375F, 0.5625F);
  79. }
  80.  
  81. public EntityVehicle(World worldIn, double x, double y, double z)
  82. {
  83. this(worldIn);
  84. this.setPosition(x, y, z);
  85. this.motionX = 0.0D;
  86. this.motionY = 0.0D;
  87. this.motionZ = 0.0D;
  88. this.prevPosX = x;
  89. this.prevPosY = y;
  90. this.prevPosZ = z;
  91. }
  92.  
  93. /**
  94. * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
  95. * prevent them from trampling crops
  96. */
  97. protected boolean canTriggerWalking()
  98. {
  99. return false;
  100. }
  101.  
  102. protected void entityInit()
  103. {
  104. this.dataManager.register(TIME_SINCE_HIT, Integer.valueOf(0));
  105. this.dataManager.register(FORWARD_DIRECTION, Integer.valueOf(1));
  106. this.dataManager.register(DAMAGE_TAKEN, Float.valueOf(0.0F));
  107. this.dataManager.register(BOAT_TYPE, Integer.valueOf(EntityVehicle.Type.OAK.ordinal()));
  108.  
  109. for (DataParameter<Boolean> dataparameter : DATA_ID_PADDLE)
  110. {
  111. this.dataManager.register(dataparameter, Boolean.valueOf(false));
  112. }
  113. }
  114.  
  115. /**
  116. * Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
  117. * pushable on contact, like boats or minecarts.
  118. */
  119. @Nullable
  120. public AxisAlignedBB getCollisionBox(Entity entityIn)
  121. {
  122. return entityIn.getEntityBoundingBox();
  123. }
  124.  
  125. /**
  126. * Returns the collision bounding box for this entity
  127. */
  128. @Nullable
  129. public AxisAlignedBB getCollisionBoundingBox()
  130. {
  131. return this.getEntityBoundingBox();
  132. }
  133.  
  134. /**
  135. * Returns true if this entity should push and be pushed by other entities when colliding.
  136. */
  137. public boolean canBePushed()
  138. {
  139. return true;
  140. }
  141.  
  142. /**
  143. * Returns the Y offset from the entity's position for any entity riding this one.
  144. */
  145. public double getMountedYOffset()
  146. {
  147. return -0.1D;
  148. }
  149.  
  150. /**
  151. * Called when the entity is attacked.
  152. */
  153. public boolean attackEntityFrom(DamageSource source, float amount)
  154. {
  155. if (this.isEntityInvulnerable(source))
  156. {
  157. return false;
  158. }
  159. else if (!this.worldObj.isRemote && !this.isDead)
  160. {
  161. if (source instanceof EntityDamageSourceIndirect && source.getEntity() != null && this.isPassenger(source.getEntity()))
  162. {
  163. return false;
  164. }
  165. else
  166. {
  167. this.setForwardDirection(-this.getForwardDirection());
  168. this.setTimeSinceHit(10);
  169. this.setDamageTaken(this.getDamageTaken() + amount * 10.0F);
  170. this.setBeenAttacked();
  171. boolean flag = source.getEntity() instanceof EntityPlayer && ((EntityPlayer)source.getEntity()).capabilities.isCreativeMode;
  172.  
  173. if (flag || this.getDamageTaken() > 40.0F)
  174. {
  175. if (!flag && this.worldObj.getGameRules().getBoolean("doEntityDrops"))
  176. {
  177. this.dropItemWithOffset(this.getItemBoat(), 1, 0.0F);
  178. }
  179.  
  180. this.setDead();
  181. }
  182.  
  183. return true;
  184. }
  185. }
  186. else
  187. {
  188. return true;
  189. }
  190. }
  191.  
  192. /**
  193. * Applies a velocity to the entities, to push them away from eachother.
  194. */
  195. public void applyEntityCollision(Entity entityIn)
  196. {
  197. if (entityIn instanceof EntityVehicle)
  198. {
  199. if (entityIn.getEntityBoundingBox().minY < this.getEntityBoundingBox().maxY)
  200. {
  201. super.applyEntityCollision(entityIn);
  202. }
  203. }
  204. else if (entityIn.getEntityBoundingBox().minY <= this.getEntityBoundingBox().minY)
  205. {
  206. super.applyEntityCollision(entityIn);
  207. }
  208. }
  209.  
  210. public Item getItemBoat()
  211. {
  212. switch (this.getBoatType())
  213. {
  214. case OAK:
  215. default:
  216. return ExampleMod.vehicle;
  217. case SPRUCE:
  218. return ExampleMod.vehicle;
  219. case BIRCH:
  220. return ExampleMod.vehicle;
  221. case JUNGLE:
  222. return ExampleMod.vehicle;
  223. case ACACIA:
  224. return ExampleMod.vehicle;
  225. case DARK_OAK:
  226. return ExampleMod.vehicle;
  227. }
  228. }
  229.  
  230. /**
  231. * Setups the entity to do the hurt animation. Only used by packets in multiplayer.
  232. */
  233. @SideOnly(Side.CLIENT)
  234. public void performHurtAnimation()
  235. {
  236. this.setForwardDirection(-this.getForwardDirection());
  237. this.setTimeSinceHit(10);
  238. this.setDamageTaken(this.getDamageTaken() * 11.0F);
  239. }
  240.  
  241. /**
  242. * Returns true if other Entities should be prevented from moving through this Entity.
  243. */
  244. public boolean canBeCollidedWith()
  245. {
  246. return !this.isDead;
  247. }
  248.  
  249. /**
  250. * Set the position and rotation values directly without any clamping.
  251. */
  252. @SideOnly(Side.CLIENT)
  253. public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport)
  254. {
  255. this.boatPitch = x;
  256. this.lerpY = y;
  257. this.lerpZ = z;
  258. this.boatYaw = (double)yaw;
  259. this.lerpXRot = (double)pitch;
  260. this.lerpSteps = 10;
  261. }
  262.  
  263. /**
  264. * Gets the horizontal facing direction of this Entity, adjusted to take specially-treated entity types into
  265. * account.
  266. */
  267. public EnumFacing getAdjustedHorizontalFacing()
  268. {
  269. return this.getHorizontalFacing().rotateY();
  270. }
  271.  
  272. /**
  273. * Called to update the entity's position/logic.
  274. */
  275. public void onUpdate()
  276. {
  277. this.previousStatus = this.status;
  278. this.status = this.getBoatStatus();
  279.  
  280. if (this.status != EntityVehicle.Status.UNDER_WATER && this.status != EntityVehicle.Status.UNDER_FLOWING_WATER)
  281. {
  282. this.outOfControlTicks = 0.0F;
  283. }
  284. else
  285. {
  286. ++this.outOfControlTicks;
  287. }
  288.  
  289. if (!this.worldObj.isRemote && this.outOfControlTicks >= 60.0F)
  290. {
  291. this.removePassengers();
  292. }
  293.  
  294. if (this.getTimeSinceHit() > 0)
  295. {
  296. this.setTimeSinceHit(this.getTimeSinceHit() - 1);
  297. }
  298.  
  299. if (this.getDamageTaken() > 0.0F)
  300. {
  301. this.setDamageTaken(this.getDamageTaken() - 1.0F);
  302. }
  303.  
  304. this.prevPosX = this.posX;
  305. this.prevPosY = this.posY;
  306. this.prevPosZ = this.posZ;
  307. super.onUpdate();
  308. this.tickLerp();
  309.  
  310. if (this.canPassengerSteer())
  311. {
  312. if (this.getPassengers().size() == 0 || !(this.getPassengers().get(0) instanceof EntityPlayer))
  313. {
  314. this.setPaddleState(false, false);
  315. }
  316.  
  317. this.updateMotion();
  318.  
  319. if (this.worldObj.isRemote)
  320. {
  321. this.controlBoat();
  322. this.worldObj.sendPacketToServer(new CPacketSteerBoat(this.getPaddleState(0), this.getPaddleState(1)));
  323. }
  324.  
  325. this.moveEntity(this.motionX, this.motionY, this.motionZ);
  326. }
  327. else
  328. {
  329. this.motionX = 0.0D;
  330. this.motionY = 0.0D;
  331. this.motionZ = 0.0D;
  332. }
  333.  
  334. for (int i = 0; i <= 1; ++i)
  335. {
  336. if (this.getPaddleState(i))
  337. {
  338. this.paddlePositions[i] = (float)((double)this.paddlePositions[i] + 0.01D);
  339. }
  340. else
  341. {
  342. this.paddlePositions[i] = 0.0F;
  343. }
  344. }
  345.  
  346. this.doBlockCollisions();
  347. List<Entity> list = this.worldObj.getEntitiesInAABBexcluding(this, this.getEntityBoundingBox().expand(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), EntitySelectors.<Entity>getTeamCollisionPredicate(this));
  348.  
  349. if (!list.isEmpty())
  350. {
  351. boolean flag = !this.worldObj.isRemote && !(this.getControllingPassenger() instanceof EntityPlayer);
  352.  
  353. for (int j = 0; j < list.size(); ++j)
  354. {
  355. Entity entity = (Entity)list.get(j);
  356.  
  357. if (!entity.isPassenger(this))
  358. {
  359. if (flag && this.getPassengers().size() < 2 && !entity.isRiding() && entity.width < this.width && entity instanceof EntityLivingBase && !(entity instanceof EntityWaterMob) && !(entity instanceof EntityPlayer))
  360. {
  361. entity.startRiding(this);
  362. }
  363. else
  364. {
  365. this.applyEntityCollision(entity);
  366. }
  367. }
  368. }
  369. }
  370. }
  371.  
  372. private void tickLerp()
  373. {
  374. if (this.lerpSteps > 0 && !this.canPassengerSteer())
  375. {
  376. double d0 = this.posX + (this.boatPitch - this.posX) / (double)this.lerpSteps;
  377. double d1 = this.posY + (this.lerpY - this.posY) / (double)this.lerpSteps;
  378. double d2 = this.posZ + (this.lerpZ - this.posZ) / (double)this.lerpSteps;
  379. double d3 = MathHelper.wrapDegrees(this.boatYaw - (double)this.rotationYaw);
  380. this.rotationYaw = (float)((double)this.rotationYaw + d3 / (double)this.lerpSteps);
  381. this.rotationPitch = (float)((double)this.rotationPitch + (this.lerpXRot - (double)this.rotationPitch) / (double)this.lerpSteps);
  382. --this.lerpSteps;
  383. this.setPosition(d0, d1, d2);
  384. this.setRotation(this.rotationYaw, this.rotationPitch);
  385. }
  386. }
  387.  
  388. public void setPaddleState(boolean p_184445_1_, boolean p_184445_2_)
  389. {
  390. this.dataManager.set(DATA_ID_PADDLE[0], Boolean.valueOf(p_184445_1_));
  391. this.dataManager.set(DATA_ID_PADDLE[1], Boolean.valueOf(p_184445_2_));
  392. }
  393.  
  394. @SideOnly(Side.CLIENT)
  395. public float getRowingTime(int p_184448_1_, float limbSwing)
  396. {
  397. return this.getPaddleState(p_184448_1_) ? (float)MathHelper.denormalizeClamp((double)this.paddlePositions[p_184448_1_] - 0.01D, (double)this.paddlePositions[p_184448_1_], (double)limbSwing) : 0.0F;
  398. }
  399.  
  400. /**
  401. * Determines whether the boat is in water, gliding on land, or in air
  402. */
  403. private EntityVehicle.Status getBoatStatus()
  404. {
  405. EntityVehicle.Status entityboat$status = this.getUnderwaterStatus();
  406.  
  407. if (entityboat$status != null)
  408. {
  409. this.waterLevel = this.getEntityBoundingBox().maxY;
  410. return entityboat$status;
  411. }
  412. else if (this.checkInWater())
  413. {
  414. return EntityVehicle.Status.IN_WATER;
  415. }
  416. else
  417. {
  418. float f = this.getBoatGlide();
  419.  
  420. if (f > 0.0F)
  421. {
  422. this.boatGlide = f;
  423. return EntityVehicle.Status.ON_LAND;
  424. }
  425. else
  426. {
  427. return EntityVehicle.Status.IN_AIR;
  428. }
  429. }
  430. }
  431.  
  432. public float getWaterLevelAbove()
  433. {
  434. AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
  435. int i = MathHelper.floor_double(axisalignedbb.minX);
  436. int j = MathHelper.ceiling_double_int(axisalignedbb.maxX);
  437. int k = MathHelper.floor_double(axisalignedbb.maxY);
  438. int l = MathHelper.ceiling_double_int(axisalignedbb.maxY - this.lastYd);
  439. int i1 = MathHelper.floor_double(axisalignedbb.minZ);
  440. int j1 = MathHelper.ceiling_double_int(axisalignedbb.maxZ);
  441. BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain();
  442.  
  443. try
  444. {
  445. label78:
  446.  
  447. for (int k1 = k; k1 < l; ++k1)
  448. {
  449. float f = 0.0F;
  450. int l1 = i;
  451.  
  452. while (true)
  453. {
  454. if (l1 >= j)
  455. {
  456. if (f < 1.0F)
  457. {
  458. float f2 = (float)blockpos$pooledmutableblockpos.getY() + f;
  459. return f2;
  460. }
  461.  
  462. break;
  463. }
  464.  
  465. for (int i2 = i1; i2 < j1; ++i2)
  466. {
  467. blockpos$pooledmutableblockpos.setPos(l1, k1, i2);
  468. IBlockState iblockstate = this.worldObj.getBlockState(blockpos$pooledmutableblockpos);
  469.  
  470. if (iblockstate.getMaterial() == Material.WATER)
  471. {
  472. f = Math.max(f, getBlockLiquidHeight(iblockstate, this.worldObj, blockpos$pooledmutableblockpos));
  473. }
  474.  
  475. if (f >= 1.0F)
  476. {
  477. continue label78;
  478. }
  479. }
  480.  
  481. ++l1;
  482. }
  483. }
  484.  
  485. float f1 = (float)(l + 1);
  486. return f1;
  487. }
  488. finally
  489. {
  490. blockpos$pooledmutableblockpos.release();
  491. }
  492. }
  493.  
  494. /**
  495. * Decides how much the boat should be gliding on the land (based on any slippery blocks)
  496. */
  497. public float getBoatGlide()
  498. {
  499. AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
  500. AxisAlignedBB axisalignedbb1 = new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY - 0.001D, axisalignedbb.minZ, axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ);
  501. int i = MathHelper.floor_double(axisalignedbb1.minX) - 1;
  502. int j = MathHelper.ceiling_double_int(axisalignedbb1.maxX) + 1;
  503. int k = MathHelper.floor_double(axisalignedbb1.minY) - 1;
  504. int l = MathHelper.ceiling_double_int(axisalignedbb1.maxY) + 1;
  505. int i1 = MathHelper.floor_double(axisalignedbb1.minZ) - 1;
  506. int j1 = MathHelper.ceiling_double_int(axisalignedbb1.maxZ) + 1;
  507. List<AxisAlignedBB> list = Lists.<AxisAlignedBB>newArrayList();
  508. float f = 0.0F;
  509. int k1 = 0;
  510. BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain();
  511.  
  512. try
  513. {
  514. for (int l1 = i; l1 < j; ++l1)
  515. {
  516. for (int i2 = i1; i2 < j1; ++i2)
  517. {
  518. int j2 = (l1 != i && l1 != j - 1 ? 0 : 1) + (i2 != i1 && i2 != j1 - 1 ? 0 : 1);
  519.  
  520. if (j2 != 2)
  521. {
  522. for (int k2 = k; k2 < l; ++k2)
  523. {
  524. if (j2 <= 0 || k2 != k && k2 != l - 1)
  525. {
  526. blockpos$pooledmutableblockpos.setPos(l1, k2, i2);
  527. IBlockState iblockstate = this.worldObj.getBlockState(blockpos$pooledmutableblockpos);
  528. iblockstate.addCollisionBoxToList(this.worldObj, blockpos$pooledmutableblockpos, axisalignedbb1, list, this);
  529.  
  530. if (!list.isEmpty())
  531. {
  532. f += iblockstate.getBlock().slipperiness;
  533. ++k1;
  534. }
  535.  
  536. list.clear();
  537. }
  538. }
  539. }
  540. }
  541. }
  542. }
  543. finally
  544. {
  545. blockpos$pooledmutableblockpos.release();
  546. }
  547.  
  548. return f / (float)k1;
  549. }
  550.  
  551. private boolean checkInWater()
  552. {
  553. AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
  554. int i = MathHelper.floor_double(axisalignedbb.minX);
  555. int j = MathHelper.ceiling_double_int(axisalignedbb.maxX);
  556. int k = MathHelper.floor_double(axisalignedbb.minY);
  557. int l = MathHelper.ceiling_double_int(axisalignedbb.minY + 0.001D);
  558. int i1 = MathHelper.floor_double(axisalignedbb.minZ);
  559. int j1 = MathHelper.ceiling_double_int(axisalignedbb.maxZ);
  560. boolean flag = false;
  561. this.waterLevel = Double.MIN_VALUE;
  562. BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain();
  563.  
  564. try
  565. {
  566. for (int k1 = i; k1 < j; ++k1)
  567. {
  568. for (int l1 = k; l1 < l; ++l1)
  569. {
  570. for (int i2 = i1; i2 < j1; ++i2)
  571. {
  572. blockpos$pooledmutableblockpos.setPos(k1, l1, i2);
  573. IBlockState iblockstate = this.worldObj.getBlockState(blockpos$pooledmutableblockpos);
  574.  
  575. if (iblockstate.getMaterial() == Material.WATER)
  576. {
  577. float f = getLiquidHeight(iblockstate, this.worldObj, blockpos$pooledmutableblockpos);
  578. this.waterLevel = Math.max((double)f, this.waterLevel);
  579. flag |= axisalignedbb.minY < (double)f;
  580. }
  581. }
  582. }
  583. }
  584. }
  585. finally
  586. {
  587. blockpos$pooledmutableblockpos.release();
  588. }
  589.  
  590. return flag;
  591. }
  592.  
  593. /**
  594. * Decides whether the boat is currently underwater.
  595. */
  596. @Nullable
  597. private EntityVehicle.Status getUnderwaterStatus()
  598. {
  599. AxisAlignedBB axisalignedbb = this.getEntityBoundingBox();
  600. double d0 = axisalignedbb.maxY + 0.001D;
  601. int i = MathHelper.floor_double(axisalignedbb.minX);
  602. int j = MathHelper.ceiling_double_int(axisalignedbb.maxX);
  603. int k = MathHelper.floor_double(axisalignedbb.maxY);
  604. int l = MathHelper.ceiling_double_int(d0);
  605. int i1 = MathHelper.floor_double(axisalignedbb.minZ);
  606. int j1 = MathHelper.ceiling_double_int(axisalignedbb.maxZ);
  607. boolean flag = false;
  608. BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain();
  609.  
  610. try
  611. {
  612. for (int k1 = i; k1 < j; ++k1)
  613. {
  614. for (int l1 = k; l1 < l; ++l1)
  615. {
  616. for (int i2 = i1; i2 < j1; ++i2)
  617. {
  618. blockpos$pooledmutableblockpos.setPos(k1, l1, i2);
  619. IBlockState iblockstate = this.worldObj.getBlockState(blockpos$pooledmutableblockpos);
  620.  
  621. if (iblockstate.getMaterial() == Material.WATER && d0 < (double)getLiquidHeight(iblockstate, this.worldObj, blockpos$pooledmutableblockpos))
  622. {
  623. if (((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() != 0)
  624. {
  625. EntityVehicle.Status entityboat$status = EntityVehicle.Status.UNDER_FLOWING_WATER;
  626. return entityboat$status;
  627. }
  628.  
  629. flag = true;
  630. }
  631. }
  632. }
  633. }
  634. }
  635. finally
  636. {
  637. blockpos$pooledmutableblockpos.release();
  638. }
  639.  
  640. return flag ? EntityVehicle.Status.UNDER_WATER : null;
  641. }
  642.  
  643. public static float getBlockLiquidHeight(IBlockState p_184456_0_, IBlockAccess p_184456_1_, BlockPos p_184456_2_)
  644. {
  645. int i = ((Integer)p_184456_0_.getValue(BlockLiquid.LEVEL)).intValue();
  646. return (i & 7) == 0 && p_184456_1_.getBlockState(p_184456_2_.up()).getMaterial() == Material.WATER ? 1.0F : 1.0F - BlockLiquid.getLiquidHeightPercent(i);
  647. }
  648.  
  649. public static float getLiquidHeight(IBlockState p_184452_0_, IBlockAccess p_184452_1_, BlockPos p_184452_2_)
  650. {
  651. return (float)p_184452_2_.getY() + getBlockLiquidHeight(p_184452_0_, p_184452_1_, p_184452_2_);
  652. }
  653.  
  654. /**
  655. * Update the boat's speed, based on momentum.
  656. */
  657. private void updateMotion()
  658. {
  659. double d0 = -0.03999999910593033D;
  660. double d1 = this.func_189652_ae() ? 0.0D : -0.03999999910593033D;
  661. double d2 = 0.0D;
  662. this.momentum = 0.05F;
  663.  
  664. if (this.previousStatus == EntityVehicle.Status.IN_AIR && this.status != EntityVehicle.Status.IN_AIR && this.status != EntityVehicle.Status.ON_LAND)
  665. {
  666. this.waterLevel = this.getEntityBoundingBox().minY + (double)this.height;
  667. this.setPosition(this.posX, (double)(this.getWaterLevelAbove() - this.height) + 0.101D, this.posZ);
  668. this.motionY = 0.0D;
  669. this.lastYd = 0.0D;
  670. this.status = EntityVehicle.Status.IN_WATER;
  671. }
  672. else
  673. {
  674. if (this.status == EntityVehicle.Status.IN_WATER)
  675. {
  676. d2 = (this.waterLevel - this.getEntityBoundingBox().minY) / (double)this.height;
  677. this.momentum = 0.9F;
  678. }
  679. else if (this.status == EntityVehicle.Status.UNDER_FLOWING_WATER)
  680. {
  681. d1 = -7.0E-4D;
  682. this.momentum = 0.9F;
  683. }
  684. else if (this.status == EntityVehicle.Status.UNDER_WATER)
  685. {
  686. d2 = 0.009999999776482582D;
  687. this.momentum = 0.45F;
  688. }
  689. else if (this.status == EntityVehicle.Status.IN_AIR)
  690. {
  691. this.momentum = 0.9F;
  692. }
  693. else if (this.status == EntityVehicle.Status.ON_LAND)
  694. {
  695. this.momentum = this.boatGlide;
  696.  
  697. if (this.getControllingPassenger() instanceof EntityPlayer)
  698. {
  699. this.boatGlide /= 2.0F;
  700. }
  701. }
  702.  
  703. this.motionX *= (double)this.momentum;
  704. this.motionZ *= (double)this.momentum;
  705. this.deltaRotation *= this.momentum;
  706. this.motionY += d1;
  707.  
  708. if (d2 > 0.0D)
  709. {
  710. double d3 = 0.65D;
  711. this.motionY += d2 * 0.06153846016296973D;
  712. double d4 = 0.75D;
  713. this.motionY *= 0.75D;
  714. }
  715. }
  716. }
  717.  
  718. private void controlBoat()
  719. {
  720. if (this.isBeingRidden())
  721. {
  722. float f = 0.0F;
  723.  
  724. if (this.leftInputDown)
  725. {
  726. this.deltaRotation += -1.0F;
  727. }
  728.  
  729. if (this.rightInputDown)
  730. {
  731. ++this.deltaRotation;
  732. }
  733.  
  734. if (this.rightInputDown != this.leftInputDown && !this.forwardInputDown && !this.backInputDown)
  735. {
  736. f += 0.005F;
  737. }
  738.  
  739. this.rotationYaw += this.deltaRotation;
  740.  
  741. if (this.forwardInputDown)
  742. {
  743. f += 0.04F;
  744. }
  745.  
  746. if (this.backInputDown)
  747. {
  748. f -= 0.005F;
  749. }
  750.  
  751. this.motionX += (double)(MathHelper.sin(-this.rotationYaw * 0.017453292F) * f);
  752. this.motionZ += (double)(MathHelper.cos(this.rotationYaw * 0.017453292F) * f);
  753. this.setPaddleState(this.rightInputDown || this.forwardInputDown, this.leftInputDown || this.forwardInputDown);
  754. }
  755. }
  756.  
  757. public void updatePassenger(Entity passenger)
  758. {
  759. if (this.isPassenger(passenger))
  760. {
  761. float f = 0.0F;
  762. float f1 = (float)((this.isDead ? 0.009999999776482582D : this.getMountedYOffset()) + passenger.getYOffset());
  763.  
  764. if (this.getPassengers().size() > 1)
  765. {
  766. int i = this.getPassengers().indexOf(passenger);
  767.  
  768. if (i == 0)
  769. {
  770. f = 0.2F;
  771. }
  772. else
  773. {
  774. f = -0.6F;
  775. }
  776.  
  777. if (passenger instanceof EntityAnimal)
  778. {
  779. f = (float)((double)f + 0.2D);
  780. }
  781. }
  782.  
  783. Vec3d vec3d = (new Vec3d((double)f, 0.0D, 0.0D)).rotateYaw(-this.rotationYaw * 0.017453292F - ((float)Math.PI / 2F));
  784. passenger.setPosition(this.posX + vec3d.xCoord, this.posY + (double)f1, this.posZ + vec3d.zCoord);
  785. passenger.rotationYaw += this.deltaRotation;
  786. passenger.setRotationYawHead(passenger.getRotationYawHead() + this.deltaRotation);
  787. this.applyYawToEntity(passenger);
  788.  
  789. if (passenger instanceof EntityAnimal && this.getPassengers().size() > 1)
  790. {
  791. int j = passenger.getEntityId() % 2 == 0 ? 90 : 270;
  792. passenger.setRenderYawOffset(((EntityAnimal)passenger).renderYawOffset + (float)j);
  793. passenger.setRotationYawHead(passenger.getRotationYawHead() + (float)j);
  794. }
  795. }
  796. }
  797.  
  798. /**
  799. * Applies this boat's yaw to the given entity. Used to update the orientation of its passenger.
  800. */
  801. protected void applyYawToEntity(Entity entityToUpdate)
  802. {
  803. entityToUpdate.setRenderYawOffset(this.rotationYaw);
  804. float f = MathHelper.wrapDegrees(entityToUpdate.rotationYaw - this.rotationYaw);
  805. float f1 = MathHelper.clamp_float(f, -105.0F, 105.0F);
  806. entityToUpdate.prevRotationYaw += f1 - f;
  807. entityToUpdate.rotationYaw += f1 - f;
  808. entityToUpdate.setRotationYawHead(entityToUpdate.rotationYaw);
  809. }
  810.  
  811. /**
  812. * Applies this entity's orientation (pitch/yaw) to another entity. Used to update passenger orientation.
  813. */
  814. @SideOnly(Side.CLIENT)
  815. public void applyOrientationToEntity(Entity entityToUpdate)
  816. {
  817. this.applyYawToEntity(entityToUpdate);
  818. }
  819.  
  820. /**
  821. * (abstract) Protected helper method to write subclass entity data to NBT.
  822. */
  823. protected void writeEntityToNBT(NBTTagCompound compound)
  824. {
  825. compound.setString("Type", this.getBoatType().getName());
  826. }
  827.  
  828. /**
  829. * (abstract) Protected helper method to read subclass entity data from NBT.
  830. */
  831. protected void readEntityFromNBT(NBTTagCompound compound)
  832. {
  833. if (compound.hasKey("Type", 8))
  834. {
  835. this.setBoatType(EntityVehicle.Type.getTypeFromString(compound.getString("Type")));
  836. }
  837. }
  838.  
  839. public boolean processInitialInteract(EntityPlayer player, @Nullable ItemStack stack, EnumHand hand)
  840. {
  841. if (!this.worldObj.isRemote && !player.isSneaking() && this.outOfControlTicks < 60.0F)
  842. {
  843. player.startRiding(this);
  844. }
  845.  
  846. return true;
  847. }
  848.  
  849. protected void updateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos)
  850. {
  851. this.lastYd = this.motionY;
  852.  
  853. if (!this.isRiding())
  854. {
  855. if (onGroundIn)
  856. {
  857. if (this.fallDistance > 3.0F)
  858. {
  859. if (this.status != EntityVehicle.Status.ON_LAND)
  860. {
  861. this.fallDistance = 0.0F;
  862. return;
  863. }
  864.  
  865. this.fall(this.fallDistance, 1.0F);
  866.  
  867. if (!this.worldObj.isRemote && !this.isDead)
  868. {
  869. this.setDead();
  870.  
  871. if (this.worldObj.getGameRules().getBoolean("doEntityDrops"))
  872. {
  873. for (int i = 0; i < 3; ++i)
  874. {
  875. this.entityDropItem(new ItemStack(Item.getItemFromBlock(Blocks.PLANKS), 1, this.getBoatType().getMetadata()), 0.0F);
  876. }
  877.  
  878. for (int j = 0; j < 2; ++j)
  879. {
  880. this.dropItemWithOffset(Items.STICK, 1, 0.0F);
  881. }
  882. }
  883. }
  884. }
  885.  
  886. this.fallDistance = 0.0F;
  887. }
  888. else if (this.worldObj.getBlockState((new BlockPos(this)).down()).getMaterial() != Material.WATER && y < 0.0D)
  889. {
  890. this.fallDistance = (float)((double)this.fallDistance - y);
  891. }
  892. }
  893. }
  894.  
  895. public boolean getPaddleState(int p_184457_1_)
  896. {
  897. return ((Boolean)this.dataManager.get(DATA_ID_PADDLE[p_184457_1_])).booleanValue() && this.getControllingPassenger() != null;
  898. }
  899.  
  900. /**
  901. * Sets the damage taken from the last hit.
  902. */
  903. public void setDamageTaken(float damageTaken)
  904. {
  905. this.dataManager.set(DAMAGE_TAKEN, Float.valueOf(damageTaken));
  906. }
  907.  
  908. /**
  909. * Gets the damage taken from the last hit.
  910. */
  911. public float getDamageTaken()
  912. {
  913. return ((Float)this.dataManager.get(DAMAGE_TAKEN)).floatValue();
  914. }
  915.  
  916. /**
  917. * Sets the time to count down from since the last time entity was hit.
  918. */
  919. public void setTimeSinceHit(int timeSinceHit)
  920. {
  921. this.dataManager.set(TIME_SINCE_HIT, Integer.valueOf(timeSinceHit));
  922. }
  923.  
  924. /**
  925. * Gets the time since the last hit.
  926. */
  927. public int getTimeSinceHit()
  928. {
  929. return ((Integer)this.dataManager.get(TIME_SINCE_HIT)).intValue();
  930. }
  931.  
  932. /**
  933. * Sets the forward direction of the entity.
  934. */
  935. public void setForwardDirection(int forwardDirection)
  936. {
  937. this.dataManager.set(FORWARD_DIRECTION, Integer.valueOf(forwardDirection));
  938. }
  939.  
  940. /**
  941. * Gets the forward direction of the entity.
  942. */
  943. public int getForwardDirection()
  944. {
  945. return ((Integer)this.dataManager.get(FORWARD_DIRECTION)).intValue();
  946. }
  947.  
  948. public void setBoatType(EntityVehicle.Type boatType)
  949. {
  950. this.dataManager.set(BOAT_TYPE, Integer.valueOf(boatType.ordinal()));
  951. }
  952.  
  953. public EntityVehicle.Type getBoatType()
  954. {
  955. return EntityVehicle.Type.byId(((Integer)this.dataManager.get(BOAT_TYPE)).intValue());
  956. }
  957.  
  958. protected boolean canFitPassenger(Entity passenger)
  959. {
  960. return this.getPassengers().size() < 2;
  961. }
  962.  
  963. /**
  964. * For vehicles, the first passenger is generally considered the controller and "drives" the vehicle. For example,
  965. * Pigs, Horses, and Boats are generally "steered" by the controlling passenger.
  966. */
  967. @Nullable
  968. public Entity getControllingPassenger()
  969. {
  970. List<Entity> list = this.getPassengers();
  971. return list.isEmpty() ? null : (Entity)list.get(0);
  972. }
  973.  
  974. @SideOnly(Side.CLIENT)
  975. public void updateInputs(boolean p_184442_1_, boolean p_184442_2_, boolean p_184442_3_, boolean p_184442_4_)
  976. {
  977. this.leftInputDown = p_184442_1_;
  978. this.rightInputDown = p_184442_2_;
  979. this.forwardInputDown = p_184442_3_;
  980. this.backInputDown = p_184442_4_;
  981. }
  982.  
  983. public static enum Status
  984. {
  985. IN_WATER,
  986. UNDER_WATER,
  987. UNDER_FLOWING_WATER,
  988. ON_LAND,
  989. IN_AIR;
  990. }
  991.  
  992. public static enum Type
  993. {
  994. OAK(BlockPlanks.EnumType.OAK.getMetadata(), "oak"),
  995. SPRUCE(BlockPlanks.EnumType.SPRUCE.getMetadata(), "spruce"),
  996. BIRCH(BlockPlanks.EnumType.BIRCH.getMetadata(), "birch"),
  997. JUNGLE(BlockPlanks.EnumType.JUNGLE.getMetadata(), "jungle"),
  998. ACACIA(BlockPlanks.EnumType.ACACIA.getMetadata(), "acacia"),
  999. DARK_OAK(BlockPlanks.EnumType.DARK_OAK.getMetadata(), "dark_oak");
  1000.  
  1001. private final String name;
  1002. private final int metadata;
  1003.  
  1004. private Type(int metadataIn, String nameIn)
  1005. {
  1006. this.name = nameIn;
  1007. this.metadata = metadataIn;
  1008. }
  1009.  
  1010. public String getName()
  1011. {
  1012. return this.name;
  1013. }
  1014.  
  1015. public int getMetadata()
  1016. {
  1017. return this.metadata;
  1018. }
  1019.  
  1020. public String toString()
  1021. {
  1022. return this.name;
  1023. }
  1024.  
  1025. /**
  1026. * Get a boat type by it's enum ordinal
  1027. */
  1028. public static EntityVehicle.Type byId(int id)
  1029. {
  1030. if (id < 0 || id >= values().length)
  1031. {
  1032. id = 0;
  1033. }
  1034.  
  1035. return values()[id];
  1036. }
  1037.  
  1038. public static EntityVehicle.Type getTypeFromString(String nameIn)
  1039. {
  1040. for (int i = 0; i < values().length; ++i)
  1041. {
  1042. if (values()[i].getName().equals(nameIn))
  1043. {
  1044. return values()[i];
  1045. }
  1046. }
  1047.  
  1048. return values()[0];
  1049. }
  1050. }
  1051. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement