2
2
3
3
import java .io .File ;
4
4
import java .lang .reflect .Field ;
5
+ import java .lang .reflect .Method ;
5
6
import java .util .ArrayList ;
6
7
import java .util .HashMap ;
7
8
import java .util .List ;
18
19
import org .bukkit .command .CommandSender ;
19
20
import org .bukkit .entity .Entity ;
20
21
import org .bukkit .entity .HumanEntity ;
22
+ import org .bukkit .entity .LivingEntity ;
21
23
import org .bukkit .entity .Player ;
22
24
import org .bukkit .inventory .ItemStack ;
23
25
import org .bukkit .inventory .PlayerInventory ;
37
39
import com .trc202 .settings .SettingsHelper ;
38
40
import com .trc202 .settings .SettingsLoader ;
39
41
42
+ import static com .trc202 .CombatTag .Reflection .*;
43
+
40
44
public class CombatTag extends JavaPlugin {
41
45
42
46
private final SettingsHelper settingsHelper ;
@@ -87,11 +91,13 @@ public CombatTag() {
87
91
*/
88
92
@ Override
89
93
public void onDisable () {
90
- for (NPC npc : npcm .getNPCs ()) {
91
- UUID uuid = npcm .getNPCIdFromEntity (npc .getEntity ());
92
- despawnNPC (uuid , NpcDespawnReason .PLUGIN_DISABLED );
93
- if (isDebugEnabled ()) {
94
- log .info ("[CombatTag] Disabling npc with ID of: " + uuid );
94
+ if (npcm != null ) {
95
+ for (NPC npc : npcm .getNPCs ()) {
96
+ UUID uuid = npcm .getNPCIdFromEntity (npc .getEntity ());
97
+ despawnNPC (uuid , NpcDespawnReason .PLUGIN_DISABLED );
98
+ if (isDebugEnabled ()) {
99
+ log .info ("[CombatTag] Disabling npc with ID of: " + uuid );
100
+ }
95
101
}
96
102
}
97
103
//Just in case...
@@ -367,7 +373,7 @@ public boolean onCommand(CommandSender sender, Command command, String commandLa
367
373
sender .sendMessage ("Please specify a player to force into combat" );
368
374
return true ;
369
375
}
370
- if (isInCombat (toForce .getUniqueId ())) {
376
+ if (! isInCombat (toForce .getUniqueId ())) {
371
377
tagged .put (toForce .getUniqueId (), PvPTimeout (60 ));
372
378
if (!toForce .equals (sender )) sender .sendMessage ("You have been forced into combat for one minute" );
373
379
sender .sendMessage ("Sucessfuly forced " + toForce .getName () + " into combat." );
@@ -457,7 +463,7 @@ public void updatePlayerData(NPC npc, UUID playerUUID) {
457
463
emptyArmorStack [x ] = airItem ;
458
464
}
459
465
target .getInventory ().setArmorContents (emptyArmorStack );
460
- target . setHealth ( 0 );
466
+ setHealth ( target , healthCheck ( source . getHealth ()) );
461
467
} else {
462
468
copyTo (target , source );
463
469
}
@@ -480,13 +486,7 @@ public void copyTo(Player target, Player source) {
480
486
target .setExhaustion (source .getExhaustion ());
481
487
target .setSaturation (source .getSaturation ());
482
488
target .setFireTicks (source .getFireTicks ());
483
- if (target instanceof HumanEntity ) {
484
- HumanEntity humanTarget = (HumanEntity ) target ;
485
- double healthSet = healthCheck (source .getHealth ());
486
- humanTarget .setHealth ((float ) healthSet );
487
- } else {
488
- log .info ("[CombatTag] An error has occurred! Target is not a HumanEntity!" );
489
- }
489
+ setHealth (target , healthCheck (source .getHealth ()));
490
490
}
491
491
492
492
public double healthCheck (double health ) {
@@ -506,13 +506,22 @@ public SettingsHelper getSettingsHelper() {
506
506
public static boolean isVersionSupported () {
507
507
return NPCLib .isSupported ();
508
508
}
509
-
510
- public static final Field ENTITY_PLAYER_INVULNERABLE_TICKS_FIELD = Reflection .makeField (Reflection .getNmsClass ("EntityPlayer" ), "invulnerableTicks" );
511
-
509
+
510
+ public static final Field ENTITY_PLAYER_INVULNERABLE_TICKS_FIELD = Reflection .makeField (getNmsClass ("EntityPlayer" ), "invulnerableTicks" );
511
+ public static final Method ENTITY_LIVING_SET_HEALTH_METHOD = Reflection .makeMethod (getNmsClass ("EntityLiving" ), "setHealth" , float .class );
512
+
512
513
public static void setInvulnerableTicks (Entity bukkitEntity , int invulnerableTicks ) { //Entity.setNoDamageTicks() doesn't set EntityPlayer.invulnerableTicks
513
514
Object entity = Reflection .getHandle (bukkitEntity );
514
- if (Reflection . getNmsClass ("EntityPlayer" ).isInstance (entity )) {
515
+ if (getNmsClass ("EntityPlayer" ).isInstance (entity )) {
515
516
Reflection .setField (ENTITY_PLAYER_INVULNERABLE_TICKS_FIELD , entity , invulnerableTicks );
516
517
}
517
518
}
519
+ /*
520
+ * EntityLiving.setHealth() calls die() if the entity is a player.
521
+ * EntityPlayer.die() tries to close any open inventories, causing the offline player to throw an exception.
522
+ */
523
+ public static void setHealth (LivingEntity bukkitEntity , double health ) {
524
+ Object entity = Reflection .getHandle (bukkitEntity );
525
+ Reflection .callMethod (ENTITY_LIVING_SET_HEALTH_METHOD , entity , (float )health );
526
+ }
518
527
}
0 commit comments