简体   繁体   中英

Bukkit / Spigot - EntityDamageByEntityEvent : cast the shooter

I am creating a PvP plugin, but I cannot continue because I have a annoying cast problem that I cannot solve. I am trying to get the last damage cause , the damager , check if the damager used a Arrow , convert the 'arrow' into the shooter . But it constantly gives me errors in my console.

So here is my code

Player player = (Player)event.getPlayer(); // this variable is in my public void onPlayerMovement event
if(((EntityDamageByEntityEvent) player.getLastDamageCause()).getDamager() instanceof Arrow) 
{
   Arrow arrow = (Arrow) ((EntityDamageByEntityEvent) player.getLastDamageCause()).getDamager();
   ProjectileSource shooter = ((ProjectileSource) ((EntityDamageByEntityEvent) player.getLastDamageCause()).getDamager());

   if(shooter instanceof Player) // checking if the shooter is a player.
   {
      shooter.sendMessage("You hitted someone with a bow right?");
      player.sendMessage("You got hit by a bow..");
   }
}

The reason why I want to convert the arrow into the shooter is because I want to display a message to the shooter, and couple of other things.

This is the error

[22:39:10 ERROR]: Could not pass event PlayerMoveEvent to FendykPVP v1.8
    org.bukkit.event.EventException
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:270) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.PacketPlayInFlying.a(SourceFile:126) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.PacketPlayInFlying$PacketPlayInPosition.a(SourceFile:57) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_121]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_121]
    at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]
Caused by: java.lang.ClassCastException: org.bukkit.craftbukkit.v1_8_R3.entity.CraftArrow cannot be cast to org.bukkit.entity.Player
    at GameCore.playerKill.onPlayerMovement(playerKill.java:102) ~[?:?]
    at sun.reflect.GeneratedMethodAccessor1391.invoke(Unknown Source) ~[?:?]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.8.8.jar:git-Spigot-21fe707-e1ebe52]
    ... 15 more

I hope someone can help me with this

This may or may not work, haven't tested it myself. But you need to check if it's an arrow before casting it. Also to get the shooter there is the method arrow.getShooter() in the projectile class which can be used by the arrow.

if(((EntityDamageByEntityEvent) player.getLastDamageCause()).getDamager() instanceof Arrow) {
    Arrow arrow = (Arrow) ((EntityDamageByEntityEvent) player.getLastDamageCause()).getDamager();
    ProjectileSource shooter = arrow.getShooter();

       if(shooter instanceof Player) // checking if the shooter is a player.
       {
          Player shooterPlayer = (Player) shooter;
          shooterPlayer.sendMessage("You hitted someone with a bow right?");
          player.sendMessage("You got hit by a bow..");
       }
}

If it does not help, please let me know what line 102 is.

The following is an excerpt of a tested solution to notify players when they shoot each other. This should help you along.

@EventHandler
public void onEntityDamageByEntity( EntityDamageByEntityEvent evt ) {
    // Is target a player, if not stop
    if ( !(evt.getEntity() instanceof Player) )
        return;

    Player damagee = (Player) evt.getEntity();

    // Is damager an arrow, if not stop
    if ( !(evt.getDamager() instanceof Arrow) )
        return;

    // Is shooter a player, if not stop
    ProjectileSource src = ((Arrow) evt.getDamager()).getShooter();
    if ( !(src instanceof Player) )
        return;

    Player damager = (Player) src;
    damager.sendMessage( "You just shot " + damagee.getName() );
    damagee.sendMessage( "You were shot by " + damager.getName() );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM