Solved Attempting to extend CraftPlayer; keeps saying incompatible return types.

Discussion in 'Plugin Development' started by Cirno, Sep 3, 2013.

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

    Cirno

    "The return types are incompatible for the inherited methods Damageable.getHealth(), CraftLivingEntity.getHealth()"

    Code:java
    1. package com.tenko.npc;
    2.  
    3. import java.util.List;
    4. import java.util.ArrayList;
    5. import java.util.Random;
    6.  
    7. import net.minecraft.server.v1_6_R2.Entity;
    8. import net.minecraft.server.v1_6_R2.EntityInsentient;
    9. import net.minecraft.server.v1_6_R2.EntityLiving;
    10. import net.minecraft.server.v1_6_R2.EntityPlayer;
    11.  
    12. import org.bukkit.ChatColor;
    13. import org.bukkit.Location;
    14. import org.bukkit.craftbukkit.v1_6_R2.CraftServer;
    15. import org.bukkit.craftbukkit.v1_6_R2.entity.CraftEntity;
    16. import org.bukkit.craftbukkit.v1_6_R2.entity.CraftLivingEntity;
    17. import org.bukkit.craftbukkit.v1_6_R2.entity.CraftPlayer;
    18. import org.bukkit.entity.Player;
    19. import org.bukkit.util.Vector;
    20.  
    21. import com.google.common.collect.Lists;
    22. import com.tenko.NovEngine.Option;
    23. import com.tenko.npc.controllers.NPCControllerJump;
    24.  
    25. public abstract class BaseNPC extends CraftPlayer {
    26.  
    27. public static EntityInsentient SCAPEGOAT = new EntityInsentient(null){};
    28.  
    29. public BaseNPC(CraftServer server, EntityPlayer entity){
    30. super(server, entity);
    31. //this.goals = new PathfinderGoalSelector(entity.world.methodProfiler);
    32. //goals.a(new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 0.04F));
    33. }
    34.  
    35. private ArrayList<String> quotes = Lists.newArrayList();
    36. private ArrayList<Option> options = Lists.newArrayList();
    37.  
    38. private int chatIndex = 0;
    39. //private PathfinderGoalSelector goals;
    40. private Random random = new Random();
    41.  
    42. public abstract void lookAt(Location loc);
    43. public abstract void die();
    44. public abstract void teleportTo(Location loc);
    45.  
    46. public abstract String getName();
    47.  
    48. public ArrayList<String> getQuotes(){
    49. return quotes;
    50. }
    51.  
    52. public ArrayList<Option> getOptions(){
    53. return options;
    54. }
    55.  
    56. public void setQuotes(List<String> list){
    57. quotes = new ArrayList<String>(list);
    58. }
    59.  
    60. public void setOptions(List<Option> list){
    61. options = new ArrayList<Option>(list);
    62. }
    63.  
    64. public void chat(Player plyr){
    65. if(quotes.size() > 0){
    66. plyr.sendMessage("<" + ChatColor.RED + getName() + ChatColor.RESET + "> " + quotes.get(chatIndex).replace("%plyr%", plyr.getName()).replace("%ai%", getName()));
    67. chatIndex++;
    68. if(chatIndex >= quotes.size()){
    69. chatIndex = 0;
    70. }
    71. }
    72. }
    73.  
    74. public void chat(Player plyr, String message){
    75. plyr.sendMessage("<" + ChatColor.RED + getName() + ChatColor.WHITE + "> " + message.replace("%plyr%", plyr.getName()).replace("%ai%", getName()));
    76. }
    77.  
    78. public double calculateYaw(Vector motion){
    79. double dX = motion.getX();
    80. double dZ = motion.getZ();
    81. double yawZ = 0;
    82.  
    83. if(dX != 0){
    84. if(dX < 0){
    85. yawZ = 1.5 * 3.141592;
    86. } else {
    87. yawZ = 0.5 * 3.141592;
    88. }
    89.  
    90. //I really don't want to Math.atan.
    91. yawZ -= Math.atan(dZ / dX);
    92. } else if(dZ < 0){
    93. yawZ = 3.141692;
    94. }
    95.  
    96. return -yawZ * 180 / 3.141592;
    97. }
    98.  
    99. //This is probably going to be amazingly inaccurate.
    100. public double fastAtan(double var){
    101. //pi/4 * x - x * (|x| - 1) * (0.2447 + 0.0663*|x|)
    102. return 0.78539 * var - var * (Math.abs(var) - 1) * (0.2447 + 0.0663*Math.abs(var));
    103. }
    104.  
    105. public NPCControllerJump getJumpController(){
    106. return null;
    107. }
    108.  
    109. public Random getRandom(){
    110. return random;
    111. }
    112.  
    113. public EntityLiving getLivingHandle(){
    114. return (EntityLiving)getHandle();
    115. }
    116.  
    117. }


    I'm referencing CraftBukkit and only CraftBukkit.

    This error doesn't make any sense; does CraftBukkit have an error with changing float and double numbers?

    Edit: It looks like they both return double. Weird.
     
  2. Offline

    Saposhiente

    This is caused by the new getHealth system where the devs have created some trickery to allow the getHealth() functions to return either a double or an int in order to provide backwards compatibility.
     
  3. Extending CraftPlayer wat why. And yeah, it's because of the new getHealth system. Paste the error?
     
  4. Offline

    Cirno

    I did; it's the one at the top. I need to do this so I can create custom entities, and I want to make it so I can use Player methods within the entity.

    Do you know if there's a way around this? I checked all of the sources; everything that is normalized (aka, not INVALID_getHealth()) returns a double as it should.
     
  5. Offline

    Polaris29

    Cirno
    I had this problem too, unfortunately, I could not find an quick fix for it. This error is caused by conflicting intefaces, (CraftPlayer implements a interface with a getHealth() method that returns int and another interface with a getHealth() method returning double). Here's what I noticed and tried doing:

    I tried creating a class implementing Player, it gave errors for getMaxHealth(), getHealth(), and getLastDamage() because of return types.

    There are no errors with this code:
    Code:java
    1. public class CraftHumanNPC extends CraftPlayer {
    2.  
    3. public CraftHumanNPC(CraftServer server, EntityHumanNPC entity) {
    4. super(server, entity);
    5. }
    6.  
    7. @Override
    8. public EntityHumanNPC getHandle() {
    9. return (EntityHumanNPC) super.getHandle();
    10. }
    11. }
    12.  

    But there is an incompatible return type error with this code:
    Code:java
    1.  
    2. public class CraftHumanNPC extends CraftPlayer implements HumanNPC {
    3.  
    4. public CraftHumanNPC(CraftServer server, EntityHumanNPC entity) {
    5. super(server, entity);
    6. }
    7.  
    8. @Override
    9. public EntityHumanNPC getHandle() {
    10. return (EntityHumanNPC) super.getHandle();
    11. }
    12.  
    13. }
    14.  

    The first code block I posted (will be refered to as example A) does not implement another interface, the second code block I posted (will be refered to as example B) does implement another interface (the HumanNPC interface contains nothing and EntityHumanNPC is my custom EntityPlayer class).

    Overriding the getHealth method in example A gave the incompatible return type error, but you can override other methods (not the getHealth, getMaxHealth or getLastDamage methods) and there is no problem.

    Also, it is possible to cast a class to any interface (it doesn't matter if the class implements the interface) as long as the class has the methods within that interface.
    So this tells me that I can work around this error by using the default health system and I can do custom stuff for everything else, and even though I can't implement anything within my custom CraftPlayer class, I can still cast it to my HumanNPC class. The only downfall about this, is that I can't make custom getHealth methods.

    But, it seems like you're using an abstract class for this. I tried copying your code, removing the abstract modifier and getting rid of all of the abstract methods, and it gave no errors (except for the Option and NPCControllerJump classes not existing).

    To fix this, you could just not use an abstract class and instead make all your abstract methods, normal methods with empty bodies and override those. But this means that classes extending your BaseNPC class does not have to override those methods. You could make your own rule to yourself to make sure every class extending BaseNPC has those methods, but if other people are going to use this, they might not follow that rule. So, to work around this, you could add default stuff to what are supposed to be your abstract methods and just not call super in your classes extending BaseNPC.

    But there's still the problem of "But I want to add my own health stuff...". So here's what I tried to fix that.
    I made my class extending CraftPlayer final and made something like this:
    Code:java
    1.  
    2. public class CraftHumanNPC2 implements HumanNPC {
    3. final CraftHumanNPC npc;
    4.  
    5. public CraftHumanNPC2(CraftHumanNPC npc) {
    6. this.npc = npc;
    7. }
    8.  
    9. public PlayerInventory getInventory() {
    10. return npc.getInventory();
    11. }
    12.  
    13. public CraftHumanNPC2 setHealth(double health) {
    14. npc.setHealth(health);
    15. return this;
    16. }
    17.  
    18. public double getHealth() {
    19. return 42; // Custom stuffz
    20. }
    21. }
    22.  

    The above code doesn't have any errors and acts like a "wrapper" class. In this wrapper class you add all the methods belong to the Player interface and just call the same method in the class extending CraftPlayer.
    You could then extend the wrapper class and use it for everything and never use the class extending CraftPlayer anywhere else
     
    Cirno likes this.
  6. Offline

    Cirno

    Wow... I... Just wow. Thanks. I've never really seen someone post this much (I don't go much on Plugin Dev for this kind of stuff, so maybe I'm just blind). You deserve internets.
    I've said it once, but, thank you.

    edit: Just an off topic; is your avatar of the main char (forgot his name) from Guilty Crown? or is it main char from Kore wa Zombie Desu Ka?
     
  7. Offline

    Polaris29

    Cirno I think it's Kirigaya Kazuto from SAO
     
  8. Offline

    Wolvereness Bukkit Team Member

    Or... You could just add Bukkit to your build path above CraftBukkit...
     
    lol768 likes this.
  9. Offline

    Polaris29

Thread Status:
Not open for further replies.

Share This Page