Search code examples
javabukkit

How to make, that eggs wouldn't deal knockback to teammates?


How to make eggs not deal knockback to teammates?

It wouldn't damage teammates with swords and other things when i used this code, but I don't know how to make eggs not give knockback to teammates.

Actually, when I was in-game I threw some eggs to a teammate, it looked as though it damaged him from my perspective, but he took no damage.

@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent event) {
    if(faze.equals("game")){
        if (Team.getTeamType(event.getEntity()) == Team.getTeamType(event.getDamager())) {
            event.setCancelled(true);
            event.getEntity().setVelocity(event.getEntity().getLocation().getDirection().multiply(0));
        }
    }
}

I will appreciate it if someone can help me solve this problem


Solution

  • The old way to cancel knockback was to set the velocity of the damaged entity to zero (in all three directions) one tick (using scheduled tasks) after the damage event was dealt, although I believe you can now simply cancel the damage event and then use the damage(double) method yourself to reapply the final damage dealt by the initial event except this time without any knockback.

    This second method used to be a lot more difficult to execute since using event.getDamage() to reapply the damage only returned the base amount dealt to the entity, without taking into consideration damage reduction by factors such as armor, etc., resulting in more damage being dealt than often intended. The method of setting the velocity to zero works fairly well, except when the damaged entity is already in motion, in which case the velocity will still be canceled which can cause unwanted behavior.

    Now there is a getFinalDamage() method in the EntityDamageEvent that you can use to make sure the correct damage is still dealt (haven't thoroughly tested this though to see whether it works well in every case).

    Here is an example of how this would look:

    @EventHandler
    public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
        if (event.getDamager() instanceof Egg && event.getEntity() instanceof LivingEntity) { // If damager is an egg and hurt entity is a living entity
            LivingEntity hurt = (LivingEntity) event.getEntity(); // Cast living entity so we can use damage() method
            event.setCancelled(true); // Cancel the event, removing any knockback/velocity changes
            hurt.damage(event.getFinalDamage()); // Re-apply final/original damage
        }
    }
    

    And here is the old method of resetting the velocity:

    @EventHandler
    public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
        if (event.getDamager() instanceof Egg) { // If damager is an egg
            final Entity hurt = event.getEntity(); // Declare entity final so that we can use it in future scheduling
            Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { // Schedule a delayed task to run in one tick, plugin is main class
                public void run() { 
                    hurt.setVelocity(new Vector(0, 0, 0)); // Set velocity to zero vector, cancelling all motion
                }
            });
        }
    }