Most of the time the scripting for an NPC probably comes from “inside” the NPC themself, via something like AgendaItem.invokeItem()
. And done this way, sense context nonsense takes care of itself automatically. For example:
+ alice: Person 'alice' 'Alice'
"She looks like the first person you'd turn to in a problem."
isHer = true
isProperName = true
;
++ aliceAgenda: AgendaItem
initiallyActive = true
isReady = true
invokeItem() {
"Alice clears her throat. ";
}
;
…means that every turn the player will see “Alice clears her throat.” if they’re in the same room as Alice, and they won’t see it (or anything else related to the agenda) if they’re not in the same location/sense context as Alice.
This is slightly more complicated if you want to implement fidgets like this that can be triggered from elsewhere (that is, not from within the NPC’s own turn/actions). But it’s still relatively straightforward; you can do something like:
modify Actor
fidget(msg, sense?) {
callWithSenseContext(self, (sense ? sense : sight),
{: "<<msg>> " });
}
So now alice.fidget('Alice clears her throat', sound);
will behave the same way the example invokeItem()
output did: Show the fidget message to the player if they’re in the same sense context as Alice, show them nothing otherwise.
Okay. With that all being said, is there a simpler way of doing this:
fidgetNearAndFar(v0, v1, sense?) {
if(!sense)
sense = sight;
if(gPlayerChar.senseObj(sense, self).trans != opaque)
callWithSenseContext(self, sense, {: "<<v0>> " });
else
callWithSenseContext(nil, nil, {: "<<v1>> "});
}
That is, allow something like alice.fidgetNearAndFar('Alice sets off a firecracker.', 'In the distance you hear someone set off a firecracker.', sound);
, which will output one message if the player is in the given sense context and a different one if they’re not in the sense context.
Technically this could be reduced to:
fidgetNearAndFar(v0, v1, sense?) {
if(gPlayerChar.senseObj((sense ? sense : sight), self).trans
!= opaque)
"<<v0>> ";
else
"<<v1>> ";
}
…assuming that gPlayerChar.senseObj()
will evaluate the context in exactly the same way as callWithSenseContext()
, so doing the latter is probably redundant.
But more broadly I’m wondering if I’m missing some method(s) for causing objects to emit sense information in an ad-hoc manner (that is, as opposed to using something like a declared Noise
instance or whatever).