DoorTo() for NPC

is there a way, using simple doors, that a wandering or pathfinding NPC can find out what is on the other side of a door?

the DoorTo() function won’t work as-is because it uses real_location not the NPC’s location. i’ve tried rewriting the function plugging in the NPC’s location instead but this doesn’t work. i’m assuming this has something to do with that fact that whichever room the door is found_in at any given instant is based on the player location and not the NPCs?

1 Like

Unfortunately, it’s not straightforward. Generally (though this isn’t actually a requirement of the library, just a common design pattern), the door_to and door_dir routines are written to either check real_location, or to check the door’s location (which is set by MoveFloatingObjects which checks real_location).

So the way I would do this is:

  • Take the NPC’s current location
  • Repeat through every door in the game:
    • Check if that room is listed in the door’s found_in array
    • If it is, move the door to that location, and call its door_to routine
  • Call MoveFloatingObjects to put the doors back where they’re supposed to be

Not ideal by any means. But that’s how doors are!

It’s pretty straight forward using normal doors, but I’ve never used simple doors, so can’t help out there. Can you convert your simple doors to normal doors?

Wait, I missed the punyinform tag. Never mind, I was thinking I6 standard library.

1 Like

I don’t think you need to care about where the door is currently located. You find the door through an exit link from a room, when pathfinding.

If you use Simple Doors instead of a door_to routine, you can find out where the door leads, regardless if it’s for the player or an NPC.

If you have doors with door_to routines, make sure they test location or real_location to figure out in which location we are, rather than in, e.g. if(self in Kitchen) ... since this won’t work with pathfinding routines.

To check what’s on the other side:

  • If the door provides door_to:
    • If it’s an object number, this is where the door leads.
    • If it’s a function, store the values of location and real_location, then change them to the current room, then call the door_to routine, and restore the values of location and real_location.
  • If the door doesn’t provide door_to, this is a Simple Door and the found_in property is an array with two values representing locations. If the NPC is in the first location, the door leads to the second location. If not, the door leads to the first location.

Something like this:

if(obj provides door_to) {
  v = obj.door_to;
  if(metaclass(v) == Routine) {
    @push location; @push real_location;
    location = current_npc_location; real_location = location;
    v = obj.door_to();
    @pull real_location; @pull location;
  }
} else {
  v = obj.&found_in-->0;
  if(v == current_npc_location)
    v = obj.&found_in-->1;
} 

(current_npc_location is a local variable holding the room that you’re currently searching for exits)

Or use DoorTo (which I wrote, but had forgotten all about):

@push location; @push real_location;
location = current_npc_location; real_location = location;
v = DoorTo(obj);
@pull real_location; @pull location;
2 Likes

that works perfectly, thx!

1 Like