Advertisement
Guest User

Untitled

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