Solved Custom Entity Despawns Immediately After Spawning

Discussion in 'Plugin Development' started by DSH105, Jun 13, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    DSH105

    So I have this abstract Entity class that extends EntityCreature (in order to achieve in the simplest form, controlled navigation), as below...

    Show Spoiler
    Code:java
    1.  
    2.  
    3. package me.dsh105.echopet.entity.pet;
    4. //relevant imports
    5. import net.minecraft.server.v1_5_R3.EntityCreature;
    6. import net.minecraft.server.v1_5_R3.EntityHuman;
    7. import net.minecraft.server.v1_5_R3.EntityLiving;
    8. import net.minecraft.server.v1_5_R3.IMonster;
    9. import net.minecraft.server.v1_5_R3.Navigation;
    10. import net.minecraft.server.v1_5_R3.Packet63WorldParticles;
    11. import net.minecraft.server.v1_5_R3.World;
    12.  
    13. public abstract class EntityPet extends EntityCreature implements IMonster {
    14.  
    15. public EntityLiving goalTarget = null;
    16. protected Pet pet;
    17.  
    18. public PetGoalSelector petGoalSelector;
    19. public Navigation nav;
    20.  
    21. public EntityPet(World world, Pet pet) {
    22. super(world);
    23. try {
    24. pet.setCraftPet(pet.getPetType().getNewCraftInstance(this));
    25.  
    26. setPet(pet);
    27.  
    28. this.petGoalSelector = new PetGoalSelector();
    29.  
    30. nav = this.getNavigation();
    31.  
    32. if (EchoPet.getPluginInstance().DO.flyTeleport()) {
    33. petGoalSelector.addGoal("Fly", new PetGoalFly(this));
    34. }
    35. petGoalSelector.addGoal("Ride", new PetGoalPassenger(this, 0.25F));
    36. petGoalSelector.addGoal("Float", new PetGoalFloat(this));
    37. petGoalSelector.addGoal("FollowOwner", new PetGoalFollowOwner(this, EchoPet.getPluginInstance().DO.getStartWalkDistance(), EchoPet.getPluginInstance().DO.getStopWalkDistance(), EchoPet.getPluginInstance().DO.getTeleportDistance()));
    38. petGoalSelector.addGoal("LookAtPlayer", new PetGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
    39. petGoalSelector.addGoal("RandomLookAround", new PetGoalRandomLookaround(this));
    40. petGoalSelector.addGoal("RandomStroll", new PetGoalRandomStroll(this));
    41.  
    42. } catch (Exception e) {
    43. EchoPet.getPluginInstance().severe(e, "Error creating new pet entity.");
    44. }
    45. }
    46.  
    47. public void setPet(Pet pet) {
    48. if (pet != null) {
    49. this.pet = pet;
    50. }
    51. }
    52.  
    53. public Pet getPet() {
    54. return this.pet;
    55. }
    56.  
    57. public Player getOwner() {
    58. return pet.getOwner();
    59. }
    60.  
    61. public Location getLocation() {
    62. return new Location(this.pet.getOwner().getWorld(), this.locX, this.locY, this.locZ);
    63. }
    64.  
    65. @Override
    66. public int getMaxHealth() {
    67. return this.maxHealth;
    68. }
    69.  
    70. @Override
    71. public CraftEntity getBukkitEntity() {
    72. if (this.bukkitEntity == null) {
    73. this.bukkitEntity = new CraftPet(this.world.getServer(), this);
    74. }
    75. return this.bukkitEntity;
    76. }
    77.  
    78. public boolean bh() {return true;}
    79.  
    80. protected abstract String bb();
    81.  
    82. // Overriden from EntityLiving - Most importantly overrides pathfinding selectors
    83. @Override
    84. protected void bo() {
    85. ++this.bC;
    86. //this.world.methodProfiler.a("checkDespawn");
    87. //this.bn();
    88. //this.world.methodProfiler.b();
    89.  
    90. //this.world.methodProfiler.a("sensing");
    91. this.getEntitySenses().a(); // Gets the field 'bP', as in EntityLiving class
    92. //this.world.methodProfiler.b();
    93.  
    94. //this.world.methodProfiler.a("targetSelector");
    95. //this.targetSelector.a();
    96. //this.world.methodProfiler.b();
    97.  
    98. //this.world.methodProfiler.a("goalSelector");
    99. //this.goalSelector.a();
    100. this.petGoalSelector.run(); // This is where I tick my own pathfinder selector
    101. //this.world.methodProfiler.b();
    102.  
    103. //this.world.methodProfiler.a("navigation");
    104. //this.navigation.e();
    105. this.nav.e();
    106. //this.world.methodProfiler.b();
    107.  
    108. //this.world.methodProfiler.a("mob tick");
    109. this.bp();
    110. //this.world.methodProfiler.b();
    111.  
    112. //this.world.methodProfiler.a("controls");
    113.  
    114. //this.world.methodProfiler.a("move");
    115. this.getControllerMove().c();
    116.  
    117. //this.world.methodProfiler.c("look");
    118. this.getControllerLook().a();
    119.  
    120. //this.world.methodProfiler.c("jump");
    121. this.getControllerJump().b();
    122. //this.world.methodProfiler.b();
    123. //this.world.methodProfiler.b();
    124. }
    125.  
    126. public boolean a_(EntityHuman human) {
    127. if (super.a_(human)) {
    128. return false;
    129. }
    130.  
    131. if (human.getBukkitEntity() == this.getOwner().getPlayer()) {
    132. ArrayList<MenuOption> options = MenuUtil.createOptionList(getPet().getPetType());
    133. PetMenu menu = new PetMenu(getPet(), options);
    134. menu.open();
    135. return true;
    136. }
    137. return false;
    138. }
    139.  
    140. public void setLocation(Location l) {
    141. this.setLocation(l.getX(), l.getY(), l.getZ(), l.getPitch(), l.getYaw());
    142. }
    143.  
    144. public void teleport(Location l) {
    145. this.getPet().getCraftPet().teleport(l);
    146. }
    147.  
    148. public void remove() {
    149. this.getPet().getCraftPet().remove();
    150. }
    151. }
    152.  

    If needed, this is an example of the EntityBat class.
    Code:java
    1.  
    2. package me.dsh105.echopet.entity.pet.bat;
    3. import org.bukkit.ChatColor;
    4. import net.minecraft.server.v1_5_R3.MathHelper;
    5. import net.minecraft.server.v1_5_R3.World;
    6. import me.dsh105.echopet.EchoPet;
    7. import me.dsh105.echopet.entity.pet.EntityPet;
    8. import me.dsh105.echopet.entity.pet.Pet;
    9. public class EntityBatPet extends EntityPet {
    10.  
    11. public EntityBatPet(World world, Pet pet) {
    12. super(world, pet);
    13. this.texture = "/mob/bat.png";
    14. this.a(0.5F, 0.9F);
    15. this.fireProof = true;
    16. }
    17.  
    18. public void setPet(Pet pet) {
    19. if (pet != null) {
    20. super.setPet(pet);
    21. setHanging(((BatPet) pet.getCraftPet()).hanging);
    22. }
    23. }
    24.  
    25. public void setHanging(boolean flag) {
    26. byte b0 = this.datawatcher.getByte(16);
    27. if (flag) {
    28. this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1)));
    29. }
    30. else {
    31. this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2)));
    32. }
    33. ((BatPet) pet.getCraftPet()).hanging = flag;
    34. }
    35.  
    36. protected void a() {
    37. super.a();
    38. this.datawatcher.a(16, new Byte((byte) 0));
    39. }
    40.  
    41. protected float aY() {
    42. return super.aY() * 0.95F;
    43. }
    44.  
    45. @Override
    46. protected String bb() {
    47. return this.h() && this.random.nextInt(4) != 0 ? null : "mob.bat.idle";
    48. }
    49.  
    50. public void l_() {
    51. super.l_();
    52. if (this.h()) {
    53. this.motX = this.motY = this.motZ = 0.0D;
    54. this.locY = (double) MathHelper.floor(this.locY) + 1.0D - (double) this.length;
    55. } else {
    56. this.motY *= 0.6000000238418579D;
    57. }
    58. }
    59. }
    60.  


    All code has been researched thoroughly from the Entity classes in the GitHub NMS Source.

    The Goal Selector, setCraftPet and other plugin-related references are not the cause of the problem. Referenced CraftPets are similar to the CraftBukkit entities and are used for setting specific values of the pets without using the entity form.

    I also have a whole series of entity classes that extend the class above (for most of the Vanilla Minecraft creatures). That's not the problem though. The problem is that whenever I attempt at spawning in an instance of this entity, it appears for about a second, then disappears. There's no errors and the entity was created completely. It's location is still stored in the EntityPet instance as well, as I am able to reference that without issues.

    I have each entity instance registered, as below.
    Show Spoiler

    Code:java
    1.  
    2. try {
    3. Method a = EntityTypes.class.getDeclaredMethod("a", Class.class, String.class, Integer.TYPE);
    4. a.setAccessible(true);
    5.  
    6. a.invoke(a, EntityBatPet.class, "Bat", 65);
    7. //...
    8. // etc, etc etc.
    9.  
    Show Spoiler


    Spawning the entity is as follows:
    Show Spoiler
    Code:java
    1.  
    2. net.minecraft.server.v1_5_R3.World mcWorld = ((CraftWorld) petLocation.getWorld()).getHandle();
    3. EntityPet entityPet = pt.getNewEntityInstance(mcWorld, this);
    4.  
    5. entityPet.setLocation(petLocation.getX(), petLocation.getY(), petLocation.getZ(), petLocation.getPitch(), petLocation.getYaw());
    6. if (!petLocation.getChunk().isLoaded()) {
    7. petLocation.getChunk().load();
    8. }
    9. if (!mcWorld.addEntity(entityPet)) {
    10. owner.sendMessage(ec.prefix + ChatColor.YELLOW + "Failed to spawn pet entity.");
    11. ec.PH.removePet(this);
    12. }
    13.  
    14. Event spawnEvent = new EchoPetSpawnEvent(this, petLocation);
    15. EchoPet.getPluginInstance().getServer().getPluginManager().callEvent(spawnEvent);
    16.  


    I can show more code if needed.
    Thanks for your time,
    DSH105

    Bump.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  2. Offline

    DSH105

    Bump. Any help would do.
     
  3. Offline

    Deckerz

    this.bn();

    i would have thought you would need that code (its commented out)

    Also you didn't set a texture like in the other one

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  4. Offline

    DSH105

    declanmc96
    Adding this.bn() doesn't change the outcome (but I admit I should have had it in there, so thanks :)). And what part are you referring to for the texture? This?
    this.texture = "/mob/bat.png";
     
  5. Offline

    Deckerz

    yes
     
  6. Offline

    DSH105

    So I should be setting a texture in the EntityPet class constructor?

    Bump :\

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  7. Offline

    Deckerz

  8. Offline

    DSH105

    But EntityPet doesn't have a texture...it's super class for all of my entities.
    I'm sorry, but I'm not sure what your suggestion is achieving.
     
  9. Offline

    DSH105

    No-one else has a solution?
     
  10. Offline

    Europia79


    Do you remember how you fixed this issue for v1_5_R3 ?

    I'm working on backwards compatibility for one of my plugins and it's working for 1.6.1 to 1.7.9

    But I'm getting the exact same issue as you for v1_5_R3,R2 : mobs visually spawn for a few milliseconds then immediately disappear. If you're curious about my code, here is my 1.7.2 code https://github.com/Europia79/Extraction - (haven't uploaded the others yet).
     
  11. Offline

    DSH105

    Make sure you set the health of the entity when it is spawned :).
     
  12. Offline

    Europia79


    My plugin doesn't spawn anything. I merely register and replace EntityVillager with my CustomEntityVillager, and for 1.6.1 to 1.7.9, anytime a Villager would have spawned, my custom one spawns instead.

    For testing, I just use spawn eggs and a spawner.

    Despite this, inside CreatureSpawnEvent, i did villager.setHealth(20); but it didn't work. I even checked if the event was cancelled so that I could un-cancel it.

    I guess I should just be happy that I have SOME backwards compatibility... But eventually, I would like to figure out the problem... It sounds exactly like yours... same version, same observations.
     
  13. Offline

    DSH105

    Spawn eggs and a spawner is still spawning the entity though. I'm pretty sure that was the solution to my problem at the time, in particular these two lines.
     
  14. Offline

    Europia79


    https://github.com/Europia79/Extrac...o/extraction/nms/v1_5_R3/Hostage.java#L28-L29

    I added those lines, but it didn't work, so I added debugging lines BEFORE i set the Health and MaxHealth, and they were both already at 20. So, since their health is already at 20, I don't think this is the problem.

    Are you sure those lines fixed disappearing mobs in 1.5.x ? It just looks like you're setting them to custom amounts.
     
  15. Offline

    DSH105

    That's the only thing I remember fixing it for me in that situation. It was a long time ago :p
     
Thread Status:
Not open for further replies.

Share This Page