Not Allowing Wandering NPCs to Enter Certain Rooms/Use Certain Exits [SOLVED]

1234676543224
11 Feb 2022, 22:20

Hello,
I am looking for a way to not allow wandering NPCs to enter certain rooms. For instance, it is somewhat strange when having villagers that are supposed to be in a village wandering through mountains inhabited by monsters.

I have used the tutorial for Independent NPCs and I have edited the NpcSearch function so that it is now:

exit = PickOneUnlockedExit (npc.parent)
if (GetBoolean(exit, "barred")) {
  loop = true
  while (loop) {
    exit = PickOneUnlockedExit(npc.parent)
    if (not GetBoolean(exit, "barred")) {
      loop = false
    }
  }
}
oldroom = npc.parent
NpcMove (npc, exit.to)
return (obj.parent = npc.parent)

The problem that I have is that the game is very slow (I believe this is because of the while loop). Is there a better way to do this?

I have named the exits that I want to be unusable and I also have set a flag on them 'barred'. Also, I use the online editor of quest.

Thank you


mrangel
11 Feb 2022, 23:10

The slowdown is probably because you're going through every exit in the game, checking if they're in the current room and unlocked, and if they are, put them on a list. Then pick one from the list, and discard the rest. If the one you picked is barred, go through the whole process of generating the list again until you get a different one.

You could make it quicker if you generated a list of exits to start with, and then pick from the same list each time. (PickOneUnlockedExit is just ScopeUnlockedExitsForRoom and PickOneObject stuck together – the first one is the time-consuming one, and you only need to do it once.

Even better, make a list of the valid exits, remove any barred ones from the list, and pick one from the remaining exits.

So:

possible_exits = ScopeUnlockedExitsForRoom (npc.parent)
possible_exits = FilterByNotAttribute (possible_exits, "barred", true)
exit = PickOneObject (possible_exits)
NpcMove (npc, exit.to)
return (obj.parent = npc.parent)

1234676543224
11 Feb 2022, 23:37

@mrangel
When I try that code, I get an error saying: "Error running script: Error compiling expression 'exit.to': Variable does not refer to an object: 'exit'"


mrangel
12 Feb 2022, 01:19

The only way I can see that happening is if the NPC is in a room that doesn't have any non-barred exits. I would normally check for that just to be safe, but I assumed that wasn't the case (as the code you posted would have looped forever in that case).

How about something like:

possible_exits = ScopeUnlockedExitsForRoom (npc.parent)
possible_exits = FilterByNotAttribute (possible_exits, "barred", true)
if (ListCount (possible_exits) = 0) {
  msg ("Can't move NPC " + npc.name + ", room " + npc.parent.name + " has no exits.")
  return (false)
}
exit = PickOneObject (possible_exits)
NpcMove (npc, exit.to)
return (obj.parent = npc.parent)

That should help in working out why there is a problem.


1234676543224
12 Feb 2022, 02:32

Thank you, this works perfectly.