Guest User

Untitled

a guest
Sep 22nd, 2017
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.21 KB | None | 0 0
  1. /*
  2. ** 2012 August 13
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. ** May you do good and not evil.
  7. ** May you find forgiveness for yourself and forgive others.
  8. ** May you share freely, never taking more than you give.
  9. */
  10. package com.TheRPGAdventurer.ROTD.server.entity;
  11.  
  12. import static net.minecraft.entity.SharedMonsterAttributes.ARMOR_TOUGHNESS;
  13. import static net.minecraft.entity.SharedMonsterAttributes.ATTACK_DAMAGE;
  14. import static net.minecraft.entity.SharedMonsterAttributes.FOLLOW_RANGE;
  15. import static net.minecraft.entity.SharedMonsterAttributes.KNOCKBACK_RESISTANCE;
  16. import static net.minecraft.entity.SharedMonsterAttributes.MAX_HEALTH;
  17. import static net.minecraft.entity.SharedMonsterAttributes.MOVEMENT_SPEED;
  18.  
  19. import java.util.BitSet;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.UUID;
  24.  
  25. import org.apache.logging.log4j.LogManager;
  26. import org.apache.logging.log4j.Logger;
  27.  
  28. import com.TheRPGAdventurer.ROTD.RealmOfTheDragonsLootTables;
  29. import com.TheRPGAdventurer.ROTD.client.init.ModItems;
  30. import com.TheRPGAdventurer.ROTD.client.init.ModTools;
  31. import com.TheRPGAdventurer.ROTD.client.model.anim.DragonAnimator;
  32. import com.TheRPGAdventurer.ROTD.server.entity.ai.path.PathNavigateFlying;
  33. import com.TheRPGAdventurer.ROTD.server.entity.breeds.DragonBreed;
  34. import com.TheRPGAdventurer.ROTD.server.entity.breeds.EnumDragonBreed;
  35. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonBodyHelper;
  36. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonBrain;
  37. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonBreedHelper;
  38. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonHelper;
  39. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonInteractHelper;
  40. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonLifeStageHelper;
  41. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonMoveHelper;
  42. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonParticleHelper;
  43. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonReproductionHelper;
  44. import com.TheRPGAdventurer.ROTD.server.entity.helper.DragonSoundManager;
  45. import com.google.common.base.Optional;
  46.  
  47. import net.minecraft.block.Block;
  48. import net.minecraft.entity.Entity;
  49. import net.minecraft.entity.EntityAgeable;
  50. import net.minecraft.entity.EntityList;
  51. import net.minecraft.entity.EntityLivingBase;
  52. import net.minecraft.entity.EnumCreatureAttribute;
  53. import net.minecraft.entity.ai.EntityAISit;
  54. import net.minecraft.entity.ai.attributes.IAttribute;
  55. import net.minecraft.entity.ai.attributes.RangedAttribute;
  56. import net.minecraft.entity.monster.EntityMob;
  57. import net.minecraft.entity.passive.EntityAnimal;
  58. import net.minecraft.entity.passive.EntityTameable;
  59. import net.minecraft.entity.passive.EntityWaterMob;
  60. import net.minecraft.entity.player.EntityPlayer;
  61. import net.minecraft.init.Items;
  62. import net.minecraft.init.SoundEvents;
  63. import net.minecraft.item.Item;
  64. import net.minecraft.item.ItemStack;
  65. import net.minecraft.nbt.NBTTagCompound;
  66. import net.minecraft.network.datasync.DataParameter;
  67. import net.minecraft.network.datasync.DataSerializers;
  68. import net.minecraft.network.datasync.EntityDataManager;
  69. import net.minecraft.pathfinding.PathNavigateGround;
  70. import net.minecraft.util.DamageSource;
  71. import net.minecraft.util.EntitySelectors;
  72. import net.minecraft.util.EnumHand;
  73. import net.minecraft.util.ResourceLocation;
  74. import net.minecraft.util.SoundEvent;
  75. import net.minecraft.util.math.BlockPos;
  76. import net.minecraft.util.math.Vec3d;
  77. import net.minecraft.util.text.translation.I18n;
  78. import net.minecraft.world.World;
  79. import net.minecraft.world.WorldProvider;
  80. import net.minecraft.world.chunk.Chunk;
  81. import net.minecraftforge.common.IShearable;
  82.  
  83. /**
  84. * Here be dragons.
  85. *
  86. * @author Nico Bergemann <barracuda415 at yahoo.de>
  87. * @Modifier James Miller <TheRPGAdventurer.>
  88. */
  89. public class EntityTameableDragon extends EntityTameable implements IShearable {
  90.  
  91. private static final Logger L = LogManager.getLogger();
  92.  
  93. public static final IAttribute MOVEMENT_SPEED_AIR = new RangedAttribute(null,
  94. "generic.movementSpeedAir", 1.5, 0.0, Double.MAX_VALUE)
  95. .setDescription("Movement Speed Air")
  96. .setShouldWatch(true);
  97.  
  98. // base attributes
  99. public static final double BASE_SPEED_GROUND = 0.3;
  100. public static final double BASE_SPEED_AIR = 0.4;
  101. public static final double BASE_DAMAGE = 10;
  102. public static final double BASE_HEALTH = 60;
  103. public static final double BASE_ARMOR = 10.0D;
  104. public static final double BASE_ARMOR_TOUGHNESS = 5.0D;
  105. public static final float BASE_WIDTH = 2.5F;
  106. public static final float BASE_HEIGHT = 2.3F;
  107. public static final float RESISTANCE = 7.0F;
  108. public static final double BASE_FOLLOW_RANGE = 16;
  109. public static final double BASE_FOLLOW_RANGE_FLYING = BASE_FOLLOW_RANGE * 2;
  110. public static final int HOME_RADIUS = 64;
  111. public static final double ALTITUDE_FLYING_THRESHOLD = 2;
  112.  
  113. // data value IDs
  114. private static final DataParameter<Boolean> DATA_FLYING =
  115. EntityDataManager.<Boolean>createKey(EntityTameableDragon.class, DataSerializers.BOOLEAN);
  116. private static final DataParameter<Boolean> DATA_SADDLED =
  117. EntityDataManager.<Boolean>createKey(EntityTameableDragon.class, DataSerializers.BOOLEAN);
  118. private static final DataParameter<Optional<UUID>> DATA_BREEDER =
  119. EntityDataManager.<Optional<UUID>>createKey(EntityTameableDragon.class, DataSerializers.OPTIONAL_UNIQUE_ID);
  120. private static final DataParameter<String> DATA_BREED =
  121. EntityDataManager.<String>createKey(EntityTameableDragon.class, DataSerializers.STRING);
  122. private static final DataParameter<Integer> DATA_REPRO_COUNT =
  123. EntityDataManager.<Integer>createKey(EntityTameableDragon.class, DataSerializers.VARINT);
  124. private static final DataParameter<Integer> DATA_TICKS_SINCE_CREATION =
  125. EntityDataManager.<Integer>createKey(EntityTameableDragon.class, DataSerializers.VARINT);
  126. private static final DataParameter<Byte> DRAGON_SCALES =
  127. EntityDataManager.<Byte>createKey(EntityTameableDragon.class, DataSerializers.BYTE);
  128.  
  129. // data NBT IDs
  130. private static final String NBT_SADDLED = "Saddle";
  131.  
  132. // server/client delegates
  133. private final Map<Class, DragonHelper> helpers = new HashMap<>();
  134.  
  135. // client-only delegates
  136. private final DragonBodyHelper bodyHelper = new DragonBodyHelper(this);
  137.  
  138. // server-only flags
  139. private BitSet controlFlags;
  140.  
  141. public WorldProvider worldprovider;
  142.  
  143. private PathNavigateFlying waypoint;
  144. private double airSpeedHorizonal = 1.5;
  145. private double airSpeedVertical = 0;
  146.  
  147. private float deltaRotation;
  148.  
  149. public EntityTameableDragon(World world) {
  150. super(world);
  151.  
  152. // set base size
  153. setSize(BASE_WIDTH, BASE_HEIGHT);
  154.  
  155. // enables walking over blocks
  156. stepHeight = 1;
  157.  
  158. // create entity delegates
  159. addHelper(new DragonBreedHelper(this, DATA_BREED));
  160. addHelper(new DragonLifeStageHelper(this, DATA_TICKS_SINCE_CREATION));
  161. addHelper(new DragonReproductionHelper(this, DATA_BREEDER, DATA_REPRO_COUNT));
  162. addHelper(new DragonSoundManager(this));
  163. addHelper(new DragonInteractHelper(this));
  164.  
  165. if (isClient()) {
  166. addHelper(new DragonParticleHelper(this));
  167. addHelper(new DragonAnimator(this));
  168. } else {
  169. addHelper(new DragonBrain(this));
  170. }
  171.  
  172. moveHelper = new DragonMoveHelper(this);
  173. aiSit = new EntityAISit(this);
  174.  
  175. // init helpers
  176. helpers.values().forEach(DragonHelper::applyEntityAttributes);
  177. }
  178.  
  179. @Override
  180. protected float updateDistance(float p_110146_1_, float p_110146_2_) {
  181. // required to fixate body while sitting. also slows down rotation while
  182. // standing.
  183. bodyHelper.updateRenderAngles();
  184. return p_110146_2_;
  185. }
  186.  
  187. @Override
  188. protected void entityInit() {
  189. super.entityInit();
  190.  
  191. dataManager.register(DATA_FLYING, false);
  192. dataManager.register(DATA_SADDLED, false);
  193. dataManager.register(DRAGON_SCALES, Byte.valueOf((byte)0));
  194. }
  195.  
  196. @Override
  197. protected void applyEntityAttributes() {
  198. super.applyEntityAttributes();
  199.  
  200. getAttributeMap().registerAttribute(ATTACK_DAMAGE);
  201. getAttributeMap().registerAttribute(MOVEMENT_SPEED_AIR);
  202. getEntityAttribute(MOVEMENT_SPEED).setBaseValue(BASE_SPEED_GROUND);
  203. getEntityAttribute(MOVEMENT_SPEED_AIR).setBaseValue(BASE_SPEED_AIR);
  204. getEntityAttribute(MAX_HEALTH).setBaseValue(BASE_HEALTH);
  205. getEntityAttribute(ATTACK_DAMAGE).setBaseValue(BASE_DAMAGE);
  206. getEntityAttribute(FOLLOW_RANGE).setBaseValue(BASE_FOLLOW_RANGE);
  207. getEntityAttribute(KNOCKBACK_RESISTANCE).setBaseValue(RESISTANCE);
  208. getEntityAttribute(ARMOR_TOUGHNESS).setBaseValue(BASE_ARMOR_TOUGHNESS);
  209.  
  210. }
  211.  
  212. /**
  213. * Returns true if the dragon is saddled.
  214. */
  215. public boolean isSaddled() {
  216. return dataManager.get(DATA_SADDLED);
  217. }
  218.  
  219. /**
  220. * Set or remove the saddle of the dragon.
  221. */
  222. public void setSaddled(boolean saddled) {
  223. L.trace("setSaddled({})", saddled);
  224. dataManager.set(DATA_SADDLED, saddled);
  225. }
  226.  
  227. public boolean canFly() {
  228. // eggs and hatchlings can't fly
  229. return !isEgg() && !isHatchling();
  230. }
  231.  
  232. /**
  233. * Returns true if the entity is flying.
  234. */
  235. public boolean isFlying() {
  236. return dataManager.get(DATA_FLYING);
  237. }
  238.  
  239. /**
  240. * Set the flying flag of the entity.
  241. */
  242. public void setFlying(boolean flying) {
  243. L.trace("setFlying({})", flying);
  244. dataManager.set(DATA_FLYING, flying);
  245. }
  246.  
  247. public PathNavigateFlying getWaypoint() {
  248. return waypoint;
  249. }
  250.  
  251. /**
  252. * Returns relative speed multiplier for the horizontal speed.
  253. *
  254. * @return relative horizontal speed multiplier
  255. */
  256. public double getMoveSpeedAirHoriz() {
  257. return this.airSpeedHorizonal;
  258. }
  259.  
  260. /**
  261. * Sets new relative speed multiplier for the horizontal flying speed.
  262. *
  263. * @param airSpeedHorizonal new relative horizontal speed multiplier
  264. */
  265. public void setMoveSpeedAirHoriz(double airSpeedHorizonal) {
  266. L.trace("setMoveSpeedAirHoriz({})", airSpeedHorizonal);
  267. this.airSpeedHorizonal = airSpeedHorizonal;
  268. }
  269.  
  270. /**
  271. * Returns relative speed multiplier for the vertical flying speed.
  272. *
  273. * @return relative vertical speed multiplier
  274. */
  275. public double getMoveSpeedAirVert() {
  276. return this.airSpeedVertical;
  277. }
  278.  
  279. /**
  280. * Sets new relative speed multiplier for the vertical flying speed.
  281. *
  282. * @param airSpeedHorizonal new relative vertical speed multiplier
  283. */
  284. public void setMoveSpeedAirVert(double airSpeedVertical) {
  285. L.trace("setMoveSpeedAirVert({})", airSpeedVertical);
  286. this.airSpeedVertical = airSpeedVertical;
  287. }
  288.  
  289. // public double getAltitude() {
  290. // int blockX = (int) (posX - 0.5);
  291. // int blockZ = (int) (posZ - 0.5);
  292. // return posY - this.getHeightValue(blockX, blockZ);
  293. // }
  294.  
  295. /**
  296. * Returns the distance to the ground while the entity is flying.
  297. */
  298. public double getAltitude() {
  299. int groundpos = worldprovider.getActualHeight(); // new
  300. BlockPos groundPos1 = world.getHeight(getPosition());
  301. return posY - groundPos1.getY() - groundpos; // return posY - groundPos1.getY()
  302. }
  303.  
  304. /**
  305. * Causes this entity to lift off if it can fly.
  306. */
  307. public void liftOff() {
  308. L.trace("liftOff");
  309. if (canFly()) {
  310. jump();
  311. }
  312. }
  313.  
  314. @Override
  315. protected float getJumpUpwardsMotion() {
  316. // stronger jumps for easier lift-offs
  317. return canFly() ? 1 : super.getJumpUpwardsMotion();
  318. }
  319.  
  320. /**
  321. * Called when the mob is falling. Calculates and applies fall damage.
  322. */
  323. @Override
  324. public void fall(float distance, float damageMultiplier) {
  325. // ignore fall damage if the entity can fly
  326. if (!canFly()) {
  327. super.fall(distance, damageMultiplier);
  328. }
  329. }
  330.  
  331. /**
  332. * (abstract) Protected helper method to write subclass entity data to NBT.
  333. */
  334. @Override
  335. public void writeEntityToNBT(NBTTagCompound nbt) {
  336. super.writeEntityToNBT(nbt);
  337. nbt.setBoolean(NBT_SADDLED, isSaddled());
  338. nbt.setBoolean("Sheared", this.getSheared());
  339.  
  340. helpers.values().forEach(helper -> helper.writeToNBT(nbt));
  341. }
  342.  
  343. /**
  344. * (abstract) Protected helper method to read subclass entity data from NBT.
  345. */
  346. @Override
  347. public void readEntityFromNBT(NBTTagCompound nbt) {
  348. super.readEntityFromNBT(nbt);
  349. setSaddled(nbt.getBoolean(NBT_SADDLED));
  350. this.setSheared(nbt.getBoolean("Sheared"));
  351.  
  352. helpers.values().forEach(helper -> helper.readFromNBT(nbt));
  353. }
  354.  
  355. @Override
  356. public void onLivingUpdate() {
  357. helpers.values().forEach(DragonHelper::onLivingUpdate);
  358.  
  359. if (isServer()) {
  360. // set home position near owner when tamed
  361. if (isTamed()) {
  362. Entity owner = getOwner();
  363. if (owner != null) {
  364. setHomePosAndDistance(owner.getPosition(), HOME_RADIUS);
  365. }
  366. }
  367.  
  368. if (this.getHealth() < this.getMaxHealth() && this.ticksExisted % 55 == 0) {
  369. this.heal(1.0F);
  370. }
  371.  
  372. // update flying state based on the distance to the ground
  373. boolean flying = canFly() && getAltitude() >= ALTITUDE_FLYING_THRESHOLD; //> ALTITUDE_FLYING_THRESHOLD
  374. if (flying != isFlying()) {
  375. // notify client
  376. setFlying(flying);
  377.  
  378. // clear tasks (needs to be done before switching the navigator!)
  379. getBrain().clearTasks();
  380.  
  381. // update AI follow range (needs to be updated before creating
  382. // new PathNavigate!)
  383. getEntityAttribute(FOLLOW_RANGE).setBaseValue(
  384. flying ? BASE_FOLLOW_RANGE_FLYING : BASE_FOLLOW_RANGE);
  385.  
  386. // update pathfinding method
  387. if (flying) {
  388. navigator = new PathNavigateFlying(this, world);
  389. } else {
  390. navigator = new PathNavigateGround(this, world);
  391. }
  392.  
  393. // tasks need to be updated after switching modes
  394. getBrain().updateAITasks();
  395. }
  396.  
  397. this.doBlockCollisions();
  398. List<Entity> list = this.world.getEntitiesInAABBexcluding(this, this.getEntityBoundingBox().grow(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), EntitySelectors.getTeamCollisionPredicate(this));
  399.  
  400. if (!list.isEmpty()) {
  401. boolean flag = !this.world.isRemote && !(this.getControllingPassenger() instanceof EntityPlayer);
  402.  
  403. for (int j = 0; j < list.size(); ++j) {
  404. Entity entity = list.get(j);
  405.  
  406. if (!entity.isPassenger(this)) {
  407. if (flag && this.getPassengers().size() < 2 && !entity.isRiding() && entity.width < this.width && entity instanceof EntityLivingBase && !(entity instanceof EntityWaterMob) && !(entity instanceof EntityPlayer)
  408. && !(entity instanceof EntityMob) && (entity instanceof EntityAnimal) && !(entity instanceof EntityTameableDragon)) {
  409. entity.startRiding(this);
  410. } else {
  411. this.applyEntityCollision(entity);
  412. }
  413. }
  414. }
  415. }
  416. } super.onLivingUpdate();
  417. }
  418.  
  419. protected boolean canFitPassenger(Entity passenger) {
  420. return this.getPassengers().size() < 2;
  421. }
  422.  
  423. @Override
  424. public void travel(float strafe, float forward, float vertical) {
  425. // disable method while flying, the movement is done entirely by
  426. // moveEntity() and this one just makes the dragon to fall slowly when
  427. // hovering
  428. if (!isFlying()) {
  429. super.travel(strafe, forward, vertical);
  430. }
  431. }
  432.  
  433. /**
  434. * Handles entity death timer, experience orb and particle creation
  435. */
  436. @Override
  437. protected void onDeathUpdate() {
  438. helpers.values().forEach(DragonHelper::onDeathUpdate);
  439.  
  440. // unmount any riding entities
  441. removePassengers();
  442.  
  443. // freeze at place
  444. motionX = motionY = motionZ = 0;
  445. rotationYaw = prevRotationYaw;
  446. rotationYawHead = prevRotationYawHead;
  447.  
  448. if (isEgg()) {
  449. setDead();
  450. } else {
  451. // actually delete entity after the time is up
  452. if (deathTime >= getMaxDeathTime()) {
  453. setDead();
  454. }
  455. }
  456.  
  457. deathTime++;
  458. }
  459.  
  460. @Override
  461. public void setDead() {
  462. helpers.values().forEach(DragonHelper::onDeath);
  463. super.setDead();
  464. }
  465.  
  466. @Override
  467. public String getName() {
  468. // return custom name if set
  469. if (hasCustomName()) {
  470. return getCustomNameTag();
  471. }
  472.  
  473. // return default breed name otherwise
  474. String entName = EntityList.getEntityString(this);
  475. String breedName = getBreedType().getName().toLowerCase();
  476. return I18n.translateToLocal("entity." + entName + "." + breedName + ".name");
  477. }
  478.  
  479. /**
  480. * Returns the sound this mob makes while it's alive.
  481. */
  482. @Override
  483. protected SoundEvent getAmbientSound() {
  484. return getSoundManager().getLivingSound();
  485. }
  486.  
  487. /**
  488. * Returns the sound this mob makes when it is hurt.
  489. */
  490. @Override
  491. protected SoundEvent getHurtSound(DamageSource p_184601_1_) {
  492. return getSoundManager().getHurtSound();
  493. }
  494.  
  495. /**
  496. * Returns the sound this mob makes on death.
  497. */
  498. @Override
  499. protected SoundEvent getDeathSound() {
  500. return getSoundManager().getDeathSound();
  501. }
  502.  
  503. /**
  504. * Plays living's sound at its position
  505. */
  506. @Override
  507. public void playLivingSound() {
  508. getSoundManager().playLivingSound();
  509. }
  510.  
  511. @Override
  512. public void playSound(SoundEvent soundIn, float volume, float pitch) {
  513. getSoundManager().playSound(soundIn, volume, pitch);
  514. }
  515.  
  516. /**
  517. * Plays step sound at given x, y, z for the entity
  518. */
  519. @Override
  520. protected void playStepSound(BlockPos entityPos, Block block) {
  521. getSoundManager().playStepSound(entityPos, block);
  522. }
  523.  
  524. /**
  525. * Returns the volume for the sounds this mob makes.
  526. */
  527. @Override
  528. protected float getSoundVolume() {
  529. // note: unused, managed in playSound()
  530. return 1;
  531. }
  532.  
  533. /**
  534. * Gets the pitch of living sounds in living entities.
  535. */
  536. @Override
  537. protected float getSoundPitch() {
  538. // note: unused, managed in playSound()
  539. return 1;
  540. }
  541.  
  542. /**
  543. * Get number of ticks, at least during which the living entity will be silent.
  544. */
  545. @Override
  546. public int getTalkInterval() {
  547. return getSoundManager().getTalkInterval();
  548. }
  549.  
  550. /**
  551. * Get this Entity's EnumCreatureAttribute
  552. */
  553. @Override
  554. public EnumCreatureAttribute getCreatureAttribute() {
  555. return getBreed().getCreatureAttribute();
  556. }
  557.  
  558. /**
  559. * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
  560. */
  561. @Override
  562. public boolean processInteract(EntityPlayer player, EnumHand hand) {
  563. // don't interact with eggs!
  564. if (isEgg()) {
  565. return !this.canBeLeashedTo(player);
  566. }
  567.  
  568. // inherited interaction
  569. if (super.processInteract(player, hand)) {
  570. return true;
  571. }
  572.  
  573. return getInteractHelper().interact(player, activeItemStack);
  574. }
  575.  
  576. public void tamedFor(EntityPlayer player, boolean successful) {
  577. if (successful) {
  578. setTamed(true);
  579. navigator.clearPathEntity(); // replacement for setPathToEntity(null);
  580. setAttackTarget(null);
  581. setOwnerId(player.getUniqueID());
  582. playTameEffect(true);
  583. world.setEntityState(this, (byte) 7);
  584. } else {
  585. playTameEffect(false);
  586. world.setEntityState(this, (byte) 6);
  587. }
  588. }
  589.  
  590. /**
  591. * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
  592. * the animal type)
  593. */
  594. @Override
  595. public boolean isBreedingItem(ItemStack item) {
  596. return getBreed().getBreedingItem() == item.getItem();
  597. }
  598.  
  599. /**
  600. * Returns the height of the eyes. Used for looking at other entities.
  601. */
  602. @Override
  603. public float getEyeHeight() {
  604. float eyeHeight = 2.85F;
  605.  
  606. if (isSitting()) {
  607. eyeHeight *= 0.8f;
  608. }
  609.  
  610. return eyeHeight;
  611. }
  612.  
  613. /**
  614. * Returns the Y offset from the entity's position for any entity riding this one.
  615. */
  616. @Override
  617. public double getMountedYOffset() {
  618. return (isSitting() ? 1.7f : 2.1f) * getScale();
  619. }
  620.  
  621. /**
  622. * Returns render size modifier
  623. */
  624. @Override
  625. public float getRenderSizeModifier() {
  626. return getScale();
  627. }
  628.  
  629. /**
  630. * Returns true if this entity should push and be pushed by other entities when colliding.
  631. */
  632. @Override
  633. public boolean canBePushed() {
  634. return super.canBePushed() && isEgg();
  635. }
  636.  
  637. /**
  638. * Determines if an entity can be despawned, used on idle far away entities
  639. */
  640. @Override
  641. protected boolean canDespawn() {
  642. return false;
  643. }
  644.  
  645. /**
  646. * returns true if this entity is by a ladder, false otherwise
  647. */
  648. @Override
  649. public boolean isOnLadder() {
  650. // this better doesn't happen...
  651. return false;
  652. }
  653.  
  654. /**
  655. * Drop 0-2 items of this living's type.
  656. * @param par1 - Whether this entity has recently been hit by a player.
  657. * @param par2 - Level of Looting used to kill this mob.
  658. */
  659. @Override
  660. protected void dropFewItems(boolean par1, int par2) {
  661. super.dropFewItems(par1, par2);
  662.  
  663. // drop saddle if equipped
  664. if (isSaddled()) {
  665. dropItem(Items.SADDLE, 1);
  666. }
  667. }
  668.  
  669. public boolean attackEntityAsMob(Entity entityIn) {
  670. boolean attacked = entityIn.attackEntityFrom(
  671. DamageSource.causeMobDamage(this),
  672. (float) getEntityAttribute(ATTACK_DAMAGE).getAttributeValue()
  673. );
  674.  
  675. if (attacked) {
  676. applyEnchantments(this, entityIn);
  677. }
  678.  
  679. return attacked;
  680. }
  681.  
  682. @Override
  683. public void swingArm(EnumHand hand) {
  684. // play eating sound
  685. playSound(getSoundManager().getAttackSound(), 1, 0.7f);
  686.  
  687. }
  688.  
  689. /**
  690. * Called when the entity is attacked.
  691. */
  692. @Override
  693. public boolean attackEntityFrom(DamageSource src, float par2) {
  694. if (isInvulnerableTo(src)) {
  695. return false;
  696. }
  697.  
  698. // don't just sit there!
  699. aiSit.setSitting(false);
  700.  
  701. return super.attackEntityFrom(src, par2);
  702. }
  703.  
  704. /**
  705. * Return whether this entity should be rendered as on fire.
  706. */
  707. @Override
  708. public boolean canRenderOnFire() {
  709. return super.canRenderOnFire() && !getBreed().isImmuneToDamage(DamageSource.IN_FIRE);
  710. }
  711.  
  712. /**
  713. * Returns true if the mob is currently able to mate with the specified mob.
  714. */
  715. @Override
  716. public boolean canMateWith(EntityAnimal mate) {
  717. return getReproductionHelper().canMateWith(mate);
  718. }
  719.  
  720. /**
  721. * This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
  722. */
  723. @Override
  724. public EntityAgeable createChild(EntityAgeable mate) {
  725. return getReproductionHelper().createChild(mate);
  726. }
  727.  
  728. private void addHelper(DragonHelper helper) {
  729. L.trace("addHelper({})", helper.getClass().getName());
  730. helpers.put(helper.getClass(), helper);
  731. }
  732.  
  733. private <T extends DragonHelper> T getHelper(Class<T> clazz) {
  734. return (T) helpers.get(clazz);
  735. }
  736.  
  737. public DragonBreedHelper getBreedHelper() {
  738. return getHelper(DragonBreedHelper.class);
  739. }
  740.  
  741. public DragonLifeStageHelper getLifeStageHelper() {
  742. return getHelper(DragonLifeStageHelper.class);
  743. }
  744.  
  745. public DragonReproductionHelper getReproductionHelper() {
  746. return getHelper(DragonReproductionHelper.class);
  747. }
  748.  
  749. public DragonParticleHelper getParticleHelper() {
  750. return getHelper(DragonParticleHelper.class);
  751. }
  752.  
  753. public DragonAnimator getAnimator() {
  754. return getHelper(DragonAnimator.class);
  755. }
  756.  
  757. public DragonSoundManager getSoundManager() {
  758. return getHelper(DragonSoundManager.class);
  759. }
  760.  
  761. public DragonBrain getBrain() {
  762. return getHelper(DragonBrain.class);
  763. }
  764.  
  765. public DragonInteractHelper getInteractHelper() {
  766. return getHelper(DragonInteractHelper.class);
  767. }
  768.  
  769. /**
  770. * Returns the breed for this dragon.
  771. *
  772. * @return breed
  773. */
  774. public EnumDragonBreed getBreedType() {
  775. return getBreedHelper().getBreedType();
  776. }
  777.  
  778. /**
  779. * Sets the new breed for this dragon.
  780. *
  781. * @param type new breed
  782. */
  783. public void setBreedType(EnumDragonBreed type) {
  784. getBreedHelper().setBreedType(type);
  785. }
  786.  
  787. public DragonBreed getBreed() {
  788. return getBreedType().getBreed();
  789. }
  790.  
  791. /**
  792. * For vehicles, the first passenger is generally considered the controller and "drives" the vehicle. For example,
  793. * Pigs, Horses, and Boats are generally "steered" by the controlling passenger.
  794. */
  795. @Override
  796. public Entity getControllingPassenger() {
  797. List<Entity> list = getPassengers();
  798. return list.isEmpty() ? null : list.get(0);
  799. }
  800.  
  801. @Override
  802. public boolean canPassengerSteer() {
  803. // must always return false or the vanilla movement code interferes
  804. // with DragonMoveHelper
  805. return false;
  806. }
  807.  
  808. public EntityPlayer getRidingPlayer() {
  809. Entity entity = getControllingPassenger();
  810. if (entity instanceof EntityPlayer) {
  811. return (EntityPlayer) entity;
  812. } else {
  813. return null;
  814. }
  815. }
  816.  
  817. public void setRidingPlayer(EntityPlayer player) {
  818. L.trace("setRidingPlayer({})", player.getName());
  819. player.rotationYaw = rotationYaw;
  820. player.rotationPitch = rotationPitch;
  821. player.startRiding(this);
  822. }
  823.  
  824. // @Override
  825. // public void updatePassenger(Entity passenger) {
  826. // if (this.isPassenger(passenger)) {// this.isPassenger(passenger) this.getPassengers().size() > 1)
  827. // double px = posX;
  828. // double py = posY + getMountedYOffset() + passenger.getYOffset();
  829. // double pz = posZ;
  830.  
  831. // player position is in the middle of the model and the saddle is on
  832. // the shoulders, so move player forwards on Z axis relative to the
  833. // dragon's rotation to fix that
  834. // Vec3d pos = new Vec3d(0, 0, 0.8 * getScale());
  835. // pos = pos.rotateYaw((float) Math.toRadians(-renderYawOffset)); // oops
  836. // px += pos.x;
  837. // py += pos.y;
  838. // pz += pos.z;
  839.  
  840. // passenger.setPosition(px, py, pz);
  841.  
  842. // fix rider rotation
  843. // if (passenger instanceof EntityLiving) {
  844. // EntityLiving rider = ((EntityLiving) passenger);
  845. // rider.prevRotationPitch = rider.rotationPitch;
  846. // rider.prevRotationYaw = rider.rotationYaw;
  847. // rider.renderYawOffset = renderYawOffset;
  848.  
  849. // }
  850. // }
  851. // }
  852.  
  853. public void updatePassenger(Entity passenger)
  854. {
  855. if (this.isPassenger(passenger))
  856. {
  857. float f = 0.0F;
  858. float f1 = (float)((this.isDead ? 0.009999999776482582D : this.getMountedYOffset()) + passenger.getYOffset());
  859.  
  860. if (this.getPassengers().size() > 1)
  861. {
  862. int i = this.getPassengers().indexOf(passenger);
  863.  
  864. if (i == 0)
  865. {
  866. f = 0.8F;
  867. }
  868. else
  869. {
  870. f = -0.2F;
  871. }
  872.  
  873. if (passenger instanceof EntityAnimal)
  874. {
  875. f = (float)((double)f + 0.2D);
  876. }
  877. }
  878.  
  879. Vec3d vec3d = (new Vec3d((double)f, 0.0D, 0.0D)).rotateYaw(-this.rotationYaw * 0.017453292F - ((float)Math.PI / 2F));
  880. passenger.setPosition(this.posX + vec3d.x, this.posY + (double)f1, this.posZ + vec3d.z);
  881. passenger.rotationYaw += this.deltaRotation;
  882. passenger.setRotationYawHead(passenger.getRotationYawHead() + this.deltaRotation);
  883. this.applyOrientationToEntity(passenger);
  884.  
  885. if (passenger instanceof EntityAnimal && this.getPassengers().size() > 1)
  886. {
  887. int j = passenger.getEntityId() % 2 == 0 ? 90 : 270;
  888. passenger.setRenderYawOffset(((EntityAnimal)passenger).renderYawOffset + (float)j);
  889. passenger.setRotationYawHead(passenger.getRotationYawHead() + (float)j);
  890. }
  891. }
  892. }
  893.  
  894. public boolean isInvulnerableTo(DamageSource src) {
  895. Entity srcEnt = src.getTrueSource();
  896. if (srcEnt != null) {
  897. // ignore own damage
  898. if (srcEnt == this) {
  899. return true;
  900. }
  901.  
  902. // ignore damage from riders
  903. if (isPassenger(srcEnt)) {
  904. return true;
  905. }
  906. }
  907.  
  908. // don't drown as egg
  909. if (src.damageType.equals("drown") && isEgg()) {
  910. return true;
  911. }
  912.  
  913. return getBreed().isImmuneToDamage(src);
  914. }
  915.  
  916. /**
  917. * Returns the entity's health relative to the maximum health.
  918. *
  919. * @return health normalized between 0 and 1
  920. */
  921. public double getHealthRelative() {
  922. return getHealth() / (double) getMaxHealth();
  923. }
  924.  
  925. public int getDeathTime() {
  926. return deathTime;
  927. }
  928.  
  929. public int getMaxDeathTime() {
  930. return 120;
  931. }
  932.  
  933. public boolean canBeLeashedTo(EntityPlayer player) {
  934. return this.isEgg() || this.isAdult() || this.isChild();
  935. }
  936.  
  937. public void setImmuneToFire(boolean isImmuneToFire) {
  938. L.trace("setImmuneToFire({})", isImmuneToFire);
  939. this.isImmuneToFire = isImmuneToFire;
  940. }
  941.  
  942. public void setAttackDamage(double damage) {
  943. L.trace("setAttackDamage({})", damage);
  944. getEntityAttribute(ATTACK_DAMAGE).setBaseValue(damage);
  945. }
  946.  
  947. /**
  948. * Public wrapper for protected final setScale(), used by DragonLifeStageHelper.
  949. *
  950. * @param scale
  951. */
  952. public void setScalePublic(float scale) {
  953. double posXTmp = posX;
  954. double posYTmp = posY;
  955. double posZTmp = posZ;
  956. boolean onGroundTmp = onGround;
  957.  
  958. setScale(scale);
  959.  
  960. // workaround for a vanilla bug; the position is apparently not set correcty
  961. // after changing the entity size, causing asynchronous server/client positioning
  962. setPosition(posXTmp, posYTmp, posZTmp);
  963.  
  964. // otherwise, setScale stops the dragon from landing while it is growing
  965. onGround = onGroundTmp;
  966. }
  967.  
  968. /**
  969. * The age value may be negative or positive or zero. If it's negative, it get's incremented on each tick, if it's
  970. * positive, it get's decremented each tick. Don't confuse this with EntityLiving.getAge. With a negative value the
  971. * Entity is considered a child.
  972. */
  973. @Override
  974. public int getGrowingAge() {
  975. // adapter for vanilla code to enable breeding interaction
  976. return isAdult() ? 0 : -1;
  977. }
  978.  
  979. /**
  980. * The age value may be negative or positive or zero. If it's negative, it get's incremented on each tick, if it's
  981. * positive, it get's decremented each tick. With a negative value the Entity is considered a child.
  982. */
  983. @Override
  984. public void setGrowingAge(int age) {
  985. // managed by DragonLifeStageHelper, so this is a no-op
  986. }
  987.  
  988. /**
  989. * Sets the scale for an ageable entity according to the boolean parameter, which says if it's a child.
  990. */
  991. @Override
  992. public void setScaleForAge(boolean p_98054_1_) {
  993. // managed by DragonLifeStageHelper, so this is a no-op
  994. }
  995.  
  996. /**
  997. * Returns the size multiplier for the current age.
  998. *
  999. * @return scale
  1000. */
  1001. public float getScale() {
  1002. return getLifeStageHelper().getScale();
  1003. }
  1004.  
  1005. public boolean isEgg() {
  1006. return getLifeStageHelper().isEgg();
  1007. }
  1008.  
  1009. public boolean isHatchling() {
  1010. return getLifeStageHelper().isHatchling();
  1011. }
  1012.  
  1013. public boolean isJuvenile() {
  1014. return getLifeStageHelper().isJuvenile();
  1015. }
  1016.  
  1017. public boolean isAdult() {
  1018. return getLifeStageHelper().isAdult();
  1019. }
  1020.  
  1021. @Override
  1022. public boolean isChild() {
  1023. return !isAdult();
  1024. }
  1025.  
  1026. /**
  1027. * Checks if this entity is running on a client.
  1028. *
  1029. * Required since MCP's isClientWorld returns the exact opposite...
  1030. *
  1031. * @return true if the entity runs on a client or false if it runs on a server
  1032. */
  1033. public final boolean isClient() {
  1034. return world.isRemote;
  1035. }
  1036.  
  1037. /**
  1038. * Checks if this entity is running on a server.
  1039. *
  1040. * @return true if the entity runs on a server or false if it runs on a client
  1041. */
  1042. public final boolean isServer() {
  1043. return !world.isRemote;
  1044. }
  1045.  
  1046. protected ResourceLocation getLootTable() {
  1047.  
  1048. switch (this.getBreedType()) {
  1049. case JADE:
  1050. return RealmOfTheDragonsLootTables.ENTITIES_DRAGON_JADE;
  1051. case GARNET:
  1052. return RealmOfTheDragonsLootTables.ENTITIES_DRAGON_GARNET;
  1053. case RUBY:
  1054. return RealmOfTheDragonsLootTables.ENTITIES_DRAGON_RUBY;
  1055. case SAPPHIRE:
  1056. return RealmOfTheDragonsLootTables.ENTITIES_DRAGON_SAPPHIRE;
  1057. case AMETHYST:
  1058. return RealmOfTheDragonsLootTables.ENTITIES_DRAGON_AMETHYST;
  1059. default:
  1060. return null; // nein defaults!
  1061.  
  1062. }
  1063.  
  1064. }
  1065.  
  1066. protected Item getShearDropItem() {
  1067.  
  1068. switch (this.getBreedType()) {
  1069. case JADE:
  1070. return ModItems.JadeDragonScales;
  1071. case GARNET:
  1072. return ModItems.GarnetDragonScales;
  1073. case RUBY:
  1074. return ModItems.RubyDragonScales;
  1075. case SAPPHIRE:
  1076. return ModItems.SapphireDragonScales;
  1077. case AMETHYST:
  1078. return ModItems.AmethystDragonScales;
  1079. default: // no defaults!
  1080. return null;
  1081.  
  1082. }
  1083. }
  1084.  
  1085. public boolean getSheared()
  1086. {
  1087. return (((Byte)this.dataManager.get(DRAGON_SCALES)).byteValue() & 16) != 0;
  1088. }
  1089.  
  1090. /**
  1091. * make a sheep sheared if set to true
  1092. */
  1093. public void setSheared(boolean sheared)
  1094. {
  1095. byte b0 = ((Byte)this.dataManager.get(DRAGON_SCALES)).byteValue();
  1096.  
  1097. if (sheared)
  1098. {
  1099. this.dataManager.set(DRAGON_SCALES, Byte.valueOf((byte)(b0 | 16)));
  1100. }
  1101. else
  1102. {
  1103. this.dataManager.set(DRAGON_SCALES, Byte.valueOf((byte)(b0 & -17)));
  1104. }
  1105. }
  1106.  
  1107. @Override
  1108. public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) {
  1109. return item != null && item.getItem() == ModTools.diamond_shears && !this.isChild() && !this.getSheared();
  1110.  
  1111. }
  1112.  
  1113. @Override
  1114. public List<ItemStack> onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) {
  1115. this.setSheared(true);
  1116. int i = 1 + this.rand.nextInt(3);
  1117.  
  1118. java.util.List<ItemStack> ret = new java.util.ArrayList<ItemStack>();
  1119. for (int j = 0; j < i; ++j)
  1120. ret.add(new ItemStack(this.getShearDropItem()));
  1121.  
  1122. this.playSound(SoundEvents.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F);
  1123. return ret;
  1124. }
  1125.  
  1126. }
Advertisement
Add Comment
Please, Sign In to add comment