Catching player before death

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

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

    rsod

    [SOLVED]
    Hello, I need to catch player before he died to cancel event and execute my own death code.
    Code:text
    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

    etaxi341

    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

    HackintoshMan

    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

    iFamasssxD

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

    HackintoshMan

    No because of armor.
     
  6. Offline

    rsod

    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.
    http://wiki.vg/Protocol#Update_Health_.280x08.29
    Edit: Just saw post above, this should be fairly easy to make with protocallib.
     
  8. Offline

    rsod

    BorisTheTerrible
    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.
    Code:
        private ProtocolManager manager;
     
        public void onLoad() {
            manager = ProtocolLibrary.getProtocolManager();
        }
     
        @Override
        public void onEnable() {
            manager.addPacketListener(new PacketAdapter(this, ConnectionSide.SERVER_SIDE,
                    Packets.Server.UPDATE_HEALTH) {
     
                @Override
                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

    Chiller

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

    fanaticmw2

    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

    Comphenix

    Sure you can - just use getEntityModifier:
    Code:java
    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();
    8.  
    9. // Health and entity
    10. float health = packet.getFloat().read(0);
    11. Entity entity = packet.getEntityModifier(event.getPlayer().getWorld()).read(0);
    12.  
    13. if (Math.abs(0.1 - health) < 0.1) {
    14. System.out.println("Entity or player: " + entity);
    15.  
    16. // give player 20 health
    17. packet.getFloat().write(0, 20F);
    18. }
    19. }
    20. });
    21. }
     
  13. Offline

    chasechocolate

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

    rsod

    chasechocolate
    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