Why is this happening with onEntityDamage()?

Discussion in 'Plugin Development' started by LRFLEW, Dec 27, 2011.

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

    LRFLEW

    Quite simply, here's my code:

    Code:
            @Override
            public void onEntityDamage(EntityDamageEvent e) {
                if (!(e instanceof EntityDamageByEntityEvent)) return;
                EntityDamageByEntityEvent event = (EntityDamageByEntityEvent)e;
                if (!(event.getDamager() instanceof Player)) return;
                Player player = (Player)event.getDamager();
                if (!player.hasPermission("creativekill")) return;
                if (!player.getGameMode().equals(GameMode.CREATIVE)) return;
                if (!(event.getEntity() instanceof LivingEntity)) return;
                if (event.getEntity() instanceof Player) return;
                LivingEntity le = (LivingEntity)event.getEntity();
                le.setHealth(1);
                event.setDamage(1);
            }
    The goal here, (obviously), is to set the attacked mob's health to 1 and then damage it's 1 health. I had tried once just setting the health to 0, btw, but it just kept the animal alive until a couple of seconds where it just disappeared (not very interesting). This was working perfectly until I actually tested it thoroughly. This kills mobs on first hit except for two (so far): Zombie Pigs and Magma Cubes. These two types of mobs will end up with a health of 1 after the first hit and will die after a second hit.

    Why are these two mob types harder to kill and how can I fix this? Is this an issue that I should submit a ticket for?

    EDIT: regular Zombies fall victim to this flaw as well.

    Does anybody know anything about this, or should I just make a ticket?

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

    user_43347

    Give people some time, be patient.
     
  3. Maybe they have armor ? Try with the damage set to something bigger.
     
  4. What about:
    Code:java
    1.  
    2. public void onEntityDamage(EntityDamageEvent e) {
    3. if (!(e instanceof EntityDamageByEntityEvent)) return;
    4. EntityDamageByEntityEvent event = (EntityDamageByEntityEvent)e;
    5. if (!(event.getDamager() instanceof Player)) return;
    6. Player player = (Player)event.getDamager();
    7. if (!player.hasPermission("creativekill")) return;
    8. if (!player.getGameMode().equals(GameMode.CREATIVE)) return;
    9. if (!(event.getEntity() instanceof LivingEntity)) return;
    10. if (event.getEntity() instanceof Player) return;
    11. LivingEntity le = (LivingEntity)event.getEntity();
    12. event.setDamage(le.getHealth());
    13. }

    ?
     
  5. Offline

    LRFLEW

    I probably should have thought of this, but when i tried it made the problem worse. In addition, magmacubes took something like four hits (each time dividing the health by two).

    When I first read this, I thought it was stupid; then I did some research. It does appear that some mobs do have some sort of armor-like system. I then realized that the mobs with damage resistance labeled on the wiki are the same ones that I'm having issues with here. The problem is, the api doesn't support any way of telling my plugin which mobs have what de-vulnerability. I could add the mobs that do have the vulnerability into my code, but then it would require updates as more mobs come out. I could just hurt them with an insanely high about of damage, but it seems like the higher the number, the more lag the server gets when I use the command. There also seems to be a freezing bug if the number gets high enough :p. I could just say 10000 or something, but I hate having arbitrary numbers, and wish there was some way to just damage them as much as they needed.
     
  6. @LRFLEW Just use 2, 10 or at most 100 dmg, more isn't really enough considering you're attacking 1hp :p
    Still, higher damage number means more lag ? That shouldn't be possible, they're just numbers, it's not like the game calls a event or function for each point of damage =)
     
  7. Offline

    nisovin

    I don't see anything wrong with using a large damage number. Anything above 50 should be sufficient for pretty much every mob.
     
  8. Offline

    LRFLEW

    True, the lag may have just been my computer being weird, but I removed the line that set the health. If I'm going to just damage the heck out of them, I might as well not worry about how much health they had before.

    The enderdragon has 200 :p Anyways, I get your point.

    I'm running a test that spawn and kills sheep repeatedly at increasing damage values (to see if I can find the freezing point), and there is a considerable lag the higher the number. My theory is that the fault lies in the processor, in that it can't perform that big of a calculation as fast as it can with a small one.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 22, 2016
  9. How about the amount of corpses and other variables involved ? :) that's not a reliable test, you should do this, first kill a fixed amount of sheeps with the exact health and then kill the server, recompile the plugin with the 9999999999 damage and re-test :p

    And to be *sure* that it's the math only involved, do a series of loops with only the math and use milisecond getting functions to see how much time it takes to process each.
     
  10. Offline

    LRFLEW

    Touche

    Except for two problems: 1) that number you gave me if far outside the range of an integer :p, and 2) I really don't care for the why. I do know that damaging an entity with a damage of (2^31-1) or the maximum you can have an int hold causes the server to lock up. Wither it's a longer delay or a lockup is uncertain, but I don't care for the why, just the how to avoid it.
     
  11. Well if you really belive that big numbers affect it, just do the previous thing, set hp to 1 and damage 2 or 10 or 100.
     
  12. Offline

    LRFLEW

    In case any of you (maybe @Digi ?) are interested in what I did, I figured out something... weird.

    When poking around in the minecraft files (net.minecraft.server.*) at the entity classes, I found net.minecraft.server.EntityLiving.die(DamageSource). After some testing, I figured out it did the red-mob lie-on-it's-side thing and dropped any drops the mob would have. The problem is the entity didn't go away, and I could even be attacked by the dead mobs. I was stumped, until I realized I had one thing that made the mob appear to die, and one that made it disappear, so I just used both. Creativity FTW.

    here is my final code:
    Code:
            public void onEntityDamage(EntityDamageEvent e) {
                if (e.isCancelled()) return;
                if (!(e instanceof EntityDamageByEntityEvent)) return;
                EntityDamageByEntityEvent event = (EntityDamageByEntityEvent)e;
                if (!(event.getDamager() instanceof Player)) return;
                Player player = (Player)event.getDamager();
                if (!player.getGameMode().equals(GameMode.CREATIVE)) return;
                if (!player.hasPermission("creativekill")) return;
                if (!(event.getEntity() instanceof LivingEntity)) return;
                if (event.getEntity() instanceof Player) return;
                ((LivingEntity)event.getEntity()).setHealth(0);
                ((CraftLivingEntity) ((LivingEntity)event.getEntity())).getHandle().die(DamageSource.OUT_OF_WORLD);
                event.setCancelled(true);
            }
    The only disadvantages I could find so far from this code specifically is the following:
    1. The animal death sounds may only be client side (aka, only for the killer). Not sure about this, but the code suggests this (may just be a delay until next tick or something, I don't really know).
    2. Unlike if I killed them naturally, there is no knock back. They just fall down with this code, but is that really an issue?
    3. The player's stats/achievements aren't updated. Now I can fix this by changing the DamageSource and the variable net.minecraft.server.EntityLiving.ah, but the variable name is going to change with version numbers and, frankly, I don't want to give the players credit :p. Let them actually have to survive to get the achievements :p
     
  13. Talk about complicating yourself :}
     
Thread Status:
Not open for further replies.

Share This Page