Advertisement
Guest User

EntityTameableDragon J

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