//
// Iterate over all of the NPCs
//
Iterator<dNPC> it = dNPCRegistry.getSpawnedNPCs().iterator();
while (it.hasNext ()) {
dNPC npc = it.next ();
if (npc == null)
continue;
if (npc.getCitizen() == null)
continue;
//
// If the NPC doesn't have triggers, or the Proximity Trigger is not enabled,
// then just return.
//
if (!npc.getCitizen().hasTrait(TriggerTrait.class)) continue;
if (!npc.getCitizen().getTrait(TriggerTrait.class).isEnabled(name)) continue;
if (!npc.isSpawned()) continue;
// Loop through all players
for (Player BukkitPlayer: Bukkit.getOnlinePlayers()) {
//
// If this NPC is not spawned or in a different world, no need to check,
// unless the Player hasn't yet triggered an Exit Proximity after Entering
//
if (!npc.getWorld().equals(BukkitPlayer.getWorld())
&& hasExitedProximityOf(BukkitPlayer, npc)) continue;
//
// If this NPC is more than the maxProximityDistance, skip it, unless
// the Player hasn't yet triggered an 'Exit Proximity' after entering.
//
if (!isCloseEnough(BukkitPlayer, npc)
&& hasExitedProximityOf(BukkitPlayer, npc)) continue;
// Get the player
dPlayer player = dPlayer.mirrorBukkitPlayer(BukkitPlayer);
//
// Check to make sure the NPC has an assignment. If no assignment, a script doesn't need to be parsed,
// but it does still need to trigger for cooldown and action purposes.
//
InteractScriptContainer script = npc.getInteractScriptQuietly(player, ProximityTrigger.class);
//
// Set default ranges with information from the TriggerTrait. This allows per-npc overrides and will
// automatically check the config for defaults.
//
double entryRadius = npc.getTriggerTrait().getRadius(name);
double exitRadius = npc.getTriggerTrait().getRadius(name);
double moveRadius = npc.getTriggerTrait().getRadius(name);
//
// If a script was found, it might have custom ranges.
//
if (script != null) {
try {
if (script.hasTriggerOptionFor(ProximityTrigger.class, player, null, "ENTRY RADIUS"))
entryRadius = Integer.valueOf(script.getTriggerOptionFor(ProximityTrigger.class, player, null, "ENTRY RADIUS"));
} catch (NumberFormatException nfe) {
dB.echoDebug(script, "Entry Radius was not an integer. Assuming " + entryRadius + " as the radius.");
}
try {
if (script.hasTriggerOptionFor(ProximityTrigger.class, player, null, "EXIT RADIUS"))
exitRadius = Integer.valueOf(script.getTriggerOptionFor(ProximityTrigger.class, player, null, "EXIT RADIUS"));
} catch (NumberFormatException nfe) {
dB.echoDebug(script, "Exit Radius was not an integer. Assuming " + exitRadius + " as the radius.");
}
try {
if (script.hasTriggerOptionFor(ProximityTrigger.class, player, null, "MOVE RADIUS"))
moveRadius = Integer.valueOf(script.getTriggerOptionFor(ProximityTrigger.class, player, null, "MOVE RADIUS"));
} catch (NumberFormatException nfe) {
dB.echoDebug(script, "Move Radius was not an integer. Assuming " + moveRadius + " as the radius.");
}
}
Location npcLocation = npc.getLocation();
//
// If the Player switches worlds while in range of an NPC, trigger still needs to
// fire since technically they have exited proximity. Let's check that before
// trying to calculate a distance between the Player and NPC, which will throw
// an exception if worlds do not match.
//
boolean playerChangedWorlds = false;
if (npcLocation.getWorld() != player.getWorld())
playerChangedWorlds = true;
//
// If the user is outside the range, and was previously within the
// range, then execute the "Exit" script.
//
// If the user entered the range and were not previously within the
// range, then execute the "Entry" script.
//
// If the user was previously within the range and moved, then execute
// the "Move" script.
//
boolean exitedProximity = hasExitedProximityOf(BukkitPlayer, npc);
double distance = 0;
if (!playerChangedWorlds) distance = npcLocation.distance(player.getLocation());
if (!exitedProximity
&& (playerChangedWorlds || distance >= exitRadius)) {
if (!npc.getTriggerTrait().triggerCooldownOnly(trigger, player))
continue;
// Remember that NPC has exited proximity.
exitProximityOf(BukkitPlayer, npc);
dB.echoDebug(script, ChatColor.YELLOW + "FOUND! NPC is in EXITING range: '" + npc.getName() + "'");
// Exit Proximity Action
npc.action("exit proximity", player);
// Parse Interact Script
parse(npc, player, script, "EXIT");
}
else if (exitedProximity && distance <= entryRadius) {
// Cooldown
if (!npc.getTriggerTrait().triggerCooldownOnly(trigger, player))
continue;
// Remember that Player has entered proximity of the NPC
enterProximityOf(BukkitPlayer, npc);
// Enter Proximity Action
npc.action("enter proximity", player);
// Parse Interact Script
parse(npc, player, script, "ENTRY");
}
else if (!exitedProximity && distance <= moveRadius) {
// TODO: Remove this? Constantly cooling down on move may make
// future entry/exit proximities 'lag' behind. Temporarily removing
// cooldown on 'move proximity'.
// if (!npc.getTriggerTrait().triggerCooldownOnly(this, event.getPlayer()))
// continue;
// Move Proximity Action
npc.action("move proximity", player);
// Parse Interact Script
parse(npc, player, script, "MOVE");
}
}
}