I keep having this issue with overland map triggers firing off at seemingly random times.
A few observations: it was the same few triggers that kept on firing randomly. After doing some retexturing and redrawing triggers, the issue persisted, but it was different triggers that misfired.
Simply running a check to see if the entering PC is actually in the area by comparing location of PC to trigger sometimes works… but sometimes not.
At one point I had the entry trigger comparing OBJECT_SELF to GetNearestSubArea, and it returned an invalid match. However, when comparing names (and the names were unique), they were the same, so somehow it was confused into thinking it was a different object, but GetName() returned identical names (and again - they were unique names). Which is to say, it’s a weird bug.
My fix was to set the entry script to set OBJECT_SELF as a local object on the entering PC, then fire off the actual script with a 0.01s wait, where it runs a check to see if the local object it set is indeed OBJECT_SELF or not, and if not, aborts.
It’s overland map code, but you should be able to figure out what’s important pretty easily. Relevant parts of first script look like this:
object oEnter = GetEnteringObject();
location lLocation = GetLocation(oEnter);
object oArea = GetAreaFromLocation(lLocation);
object oTrigger = GetFirstSubArea(oArea, GetPositionFromLocation(lLocation));
int i=0;
while ( GetTag(oTrigger) != "nx2_tr_terrain" && GetIsObjectValid(oTrigger))
{
oTrigger = GetNextSubArea(oArea);
}
if (oTrigger != OBJECT_SELF)
{
SendMessageToPC(oEnter, "1: Trigger mismatch, attempted script for: " + GetName(OBJECT_SELF));
return;
}
SendMessageToPC(GetFactionLeader(oEnter), "1: Current trigger: " + GetName(OBJECT_SELF));
SetLocalObject(GetFactionLeader(oEnter), "oAttemptedTrigger", OBJECT_SELF);
DelayCommand(0.01, ExecuteScript("nx2_tr_terrain_en_actual", OBJECT_SELF));
And for the actual entry script:
object oEnter = GetEnteringObject();
location lLocation = GetLocation(oEnter);
object oArea = GetAreaFromLocation(lLocation);
object oTrigger = GetFirstSubArea(oArea, GetPositionFromLocation(lLocation));
int i=0;
while ( GetTag(oTrigger) != "nx2_tr_terrain" && GetIsObjectValid(oTrigger))
{
oTrigger = GetNextSubArea(oArea);
}
if (oTrigger != OBJECT_SELF)
{
SendMessageToPC(oEnter, "2: Trigger mismatch, attempted script for: " + GetName(OBJECT_SELF));
return;
}
SendMessageToPC(oEnter, "2: Current trigger: " + GetName(OBJECT_SELF));
if (GetLocalObject(GetFactionLeader(oEnter), "oAttemptedTrigger") != OBJECT_SELF) // Fix to get around a weird bug with misfiring triggers. No, it doesn't make sense, but neither does the bug.
{SendMessageToPC(oEnter, "Trigger issue."); return;}
Since implementing this I haven’t had any actual misfirings of entry scripts (debug code shows it attempts them still occasionally, but the failsafes prevent them from actually running the relevant code), nor have I ever had a trigger not run when it should. I’m not 100% sure the delay is actually needed, there was thought behind it and I had intended to test it, but… it works, and that did an excellent job ruining my interest in figuring it out further. Hopefully it’ll help out.