Catching player before death

Discussion in 'Plugin Development' started by rsod, Jul 18, 2013.

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


    Hello, I need to catch player before he died to cancel event and execute my own death code.
    1. if(p.getHealth() - e.getDamage() <= 0){

    this will not work, because e.getDamage() returns raw damage, not actual damage which player will receive (it's not reducing by armor, potion effects, blocking and stuff like this).
  2. Offline


    I think you can't fix this with the Raw Damage. Big Plugins like Survival Games does have this Bug too. I am not sure but I think you can't fix this. But I hope someone will comment and know the answer.
  3. Offline


    What do you need to do? You could cancel the death event and trigger something else because at that point they should be dead.
  4. Offline


    if(event.getDamage() > player.getHealth()){
    This might work. not sure.
  5. Offline


    No because of armor.
  6. Offline


    yeah, I'm trying to remove death screen while still passing events to plugins. The only problem is catching player on death. Maybe something possible to do with reflections? Maybe just modifying source of bukkit itself can help here?
    As a variant, I'm thinking about kinda maybe doing that
    1) listen for health change packet
    2) if it's 0 health packet, cancel, so player will not see death screen
    3) simulate pressing respawn button on the server
    The question is how? Especially with 3?
  7. I believer catching the packet for updating health will take into effect armour and other varialbes, but I'm not sure.
    Edit: Just saw post above, this should be fairly easy to make with protocallib.
  8. Offline


    the problem is that either I'm blind or stupid, but I can't find any documentation or examples in protocollib
  9. So I was just writing out the code for you but then I realized you can't get the player id from the update health event. Sooooo to teleport the player you will have to loop through all the players and see which one has zero health then set there health to 20 and then teleport them. Here is the code I made you can should be able to finish from here.
        private ProtocolManager manager;
        public void onLoad() {
            manager = ProtocolLibrary.getProtocolManager();
        public void onEnable() {
            manager.addPacketListener(new PacketAdapter(this, ConnectionSide.SERVER_SIDE,
                    Packets.Server.UPDATE_HEALTH) {
                public void onPacketSending(PacketEvent event) {
                    PacketContainer packet = event.getPacket();
                    byte id = 0x08;
                    //checks if packet is update health
                    if (event.getPacketID() == id) {
                        //gets health
                        float health = packet.getFloat().read(0);
                        if (health == 0){
                           //give player 20 health
                            packet.getFloat().write(0, 20F);
  10. Offline


    Try this to get the amount of damage inflicted: Integer.valueOf(((CraftPlayer)p).getHandle().inventory.a(((CraftEntity)evt.getEntity()).getHandle()));
  11. Offline


    If you want to remove the death screen, and be able to pass the death event, you could just listen onPlayerDeath and send packet 205ClientCommand when the player dies.
  12. Offline


    Sure you can - just use getEntityModifier:
    1. @Override
    2. public void onEnable() {
    3. ProtocolLibrary.getProtocolManager().addPacketListener(
    4. new PacketAdapter(this, ConnectionSide.SERVER_SIDE, Packets.Server.UPDATE_HEALTH) {
    5. @Override
    6. public void onPacketSending(PacketEvent event) {
    7. PacketContainer packet = event.getPacket();
    9. // Health and entity
    10. float health = packet.getFloat().read(0);
    11. Entity entity = packet.getEntityModifier(event.getPlayer().getWorld()).read(0);
    13. if (Math.abs(0.1 - health) < 0.1) {
    14. System.out.println("Entity or player: " + entity);
    16. // give player 20 health
    17. packet.getFloat().write(0, 20F);
    18. }
    19. }
    20. });
    21. }
  13. Offline


    rsod if you want to do this without packets, simply change it from PlayerDeathEvent to EntityDamageEvent.
  14. Offline


    EntityDamageEvent can't be used, reason in OP.
    But I already did that with protocol and it works just perfectly, thanks guys! ProtocolLib is just amazing library.
Thread Status:
Not open for further replies.

Share This Page