Here's one way I've handled scope and visibility for offstage indirect objects. In my case these were rooms but it should be obvious how to adapt that; just generate a list of the appropriate objects and plug it into the getScopeList() functions.
Code:
// put all rooms in scope for USE WITH
modify UseWithAction
objInScope(obj) { local scope = getScopeList(); return scope.indexOf(obj); }
getScopeList() { return scope_ + allRooms.lst(); }
createIobjResolver(issuingActor, targetActor)
{
return new CustomIobjResolver(self, issuingActor, targetActor);
}
resolveFirst = DirectObject
execFirst = DirectObject
;
// make rooms available as indirect objects for USE WITH
CustomIobjResolver: IobjResolver
objInScope(obj) { return true; }
getScopeList() { return scope_ + allRooms.lst(); }
;
Here, the
objInScope(obj) and
getScopeList() functions in the UseWithAction object handle scope resolution for the direct object, and the corresponding functions in the CustomIobjResolver handle it for the indirect object. The code is similar but not quite identical; I had to lobotomize
objInScope(obj) on the indirect resolver in order to make things work.
(The execFirst / resolveFirst modifications aren't strictly necessary, but I found that the default responses tended to be more logical that way.)
I also needed a custom precondition for my UseWith action that would let objects through verification even if they were not visible to the player.
Code:
// can only USE WITH rooms and visible objects
objUsable: PreCondition
verifyPreCondition(obj)
{
if (obj != nil && !(gActor.canSee(obj) || obj.ofKind(Room)))
{
inaccessible(&mustBeVisibleMsg, obj);
}
}
;
modify Thing
dobjFor(UseWith) { preCond = [objUsable] } // is direct object usable?
iobjFor(UseWith) { preCond = [objUsable] } // is indirect object usable?
;