Skip to content

Commit

Permalink
Fix github issue #168, NPE when changing worlds in proximity of a NPC.
Browse files Browse the repository at this point in the history
  • Loading branch information
aufdemrand committed Apr 10, 2013
1 parent eb2428a commit d94ca6d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
34 changes: 22 additions & 12 deletions src/main/java/net/aufdemrand/denizen/npc/traits/HealthTrait.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package net.aufdemrand.denizen.npc.traits;

import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizen.tags.TagManager;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.arguments.Duration;
import net.aufdemrand.denizen.utilities.arguments.aH;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.citizensnpcs.api.event.DespawnReason;
import net.citizensnpcs.api.event.NPCDeathEvent;
import net.citizensnpcs.api.persistence.Persist;
Expand Down Expand Up @@ -194,11 +196,15 @@ public void setHealth(int health) {

public void die()
{
try {
// Set the player as the killer of the NPC, for listeners
if (player != null)
((CraftLivingEntity) npc.getBukkitEntity())
.getHandle().killer = (EntityHuman) ((CraftLivingEntity) player).getHandle();

} catch (Exception e) {
dB.echoError("Report this error to aufdemrand! Err: HealthTraitDie");
}

setHealth();

EntityDeathEvent entityDeath = new EntityDeathEvent(npc.getBukkitEntity(), null);
Expand Down Expand Up @@ -276,33 +282,37 @@ else if (event instanceof EntityDamageByBlockEvent)
if (npc.getBukkitEntity() == null)
return;

loc = aH.getLocationFrom(DenizenAPI.getCurrentInstance().tagManager()
.tag(null, DenizenAPI.getDenizenNPC(npc), respawnLocation, false));
loc = aH.getLocationFrom(
TagManager.tag(null, DenizenAPI.getDenizenNPC(npc), respawnLocation, false));
if (loc == null) loc = npc.getBukkitEntity().getLocation();

if (animatedeath) {
// Cancel navigation to keep the NPC from damaging players
// while the death animation is being carried out.
npc.getNavigator().cancelNavigation();
// Reset health now to avoid the death from happening instantly
setHealth();
// Play animation
npc.getBukkitEntity().playEffect(EntityEffect.DEATH);

// Schedule the delayed task to carry out the death after the animation
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(DenizenAPI.getCurrentInstance(),
new Runnable() {
public void run() {
die();
}
} , (long) ((Duration.valueOf(animationDelay).getSeconds() * 20)) );

} else {
die();
public void run() { die(); }
}, 60);
}

// No animated death? Then just die now.
else die();

if (respawn) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(DenizenAPI.getCurrentInstance(),
new Runnable() {
public void run() {
if (npc.isSpawned()) return;
npc.spawn(loc);
else npc.spawn(loc);
}
} , (long) ((Duration.valueOf(respawnDelay).getSeconds() * 20)) );
} , (Duration.valueOf(respawnDelay).getTicks()));
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ public void proximityTrigger(PlayerMoveEvent event) {
// the "Move" script.
//
boolean exitedProximity = hasExitedProximityOf(event.getPlayer(), npc);
double distance = npcLocation.distance(toBlockLocation);
double distance = 0;
if (!playerChangedWorlds) distance = npcLocation.distance(toBlockLocation);

if (!exitedProximity
&& (playerChangedWorlds || distance >= exitRadius)) {
if (!npc.getTriggerTrait().triggerCooldownOnly(this, event.getPlayer()))
Expand Down

0 comments on commit d94ca6d

Please sign in to comment.