During action execution the current actor will be gActor. Their location is gActor.location. If the location may or may not be a Room (like if they might be lying in a bed, for example) you can use gActor.getOutermostRoom().
There are several ways to exclude a specific element from a list. I’ll talk about List.subset() as perhaps the easiest to understand. It takes an function as an argument, and will return go through the list calling the function with each element as its argument, and will return a list containing only the elements it returned true for. So:
local lst = [ 1, 2, 3 ].subset({ x: x > 1 })
…will set lst equal to [ 2, 3 ].
There are several ways to pick a random element; the most portable is probably something like:
lst[rand(lst.length) + 1]
Putting that all together, here’s a little function that takes a list and a function as an argument, and returns a random element of the subset that matches the function:
pickRandomWithExlusion(lst, fn) {
lst = lst.subset({ x: (fn)(x) });
return(lst[rand(lst.length) + 1]);
}
And here’s a little test “game” that illustrates it. It provides a >FOOZLE action that picks a random room that the player isn’t currently in:
#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>
startRoom: Room 'Void'
"This is a featureless void. "
north = northRoom
south = southRoom
;
+me: Person;
northRoom: Room 'North Room'
"This is the north room. "
south = startRoom
;
southRoom: Room 'South Room'
"This is the south room. "
north = startRoom
;
versionInfo: GameID;
gameMain: GameMainDef initialPlayerChar = me;
DefineSystemAction(Foozle)
execSystemAction() {
local rm;
rm = pickRandomWithExlusion([ startRoom, northRoom, southRoom ],
{ x: x != gActor.getOutermostRoom });
defaultReport('Picked <<rm.roomName>>. ');
local lst = [ 1, 2, 3 ].subset({ x: x > 1 });
aioSay('\nlst = <<toString(lst)>>\n ');
}
;
VerbRule(Foozle)
'foozle' : FoozleAction
verbPhrase = 'foozle/foozling'
;
pickRandomWithExlusion(lst, fn) {
lst = lst.subset({ x: (fn)(x) });
return(lst[rand(lst.length) + 1]);
}
I don’t know how you’re selecting the Rooms that are valid. If it’s a static list this will work fine. If you just wanted to pick adjacent rooms you could walk through Direction.allDirections to enumerate all the adjoining rooms and pick from it. I’ve got code that does that kind of thing as well, but I don’t know if that’s what you’re after.