Re: Inform: moving NPCs through doors


03 Apr 1995 10:01:34 GMT

Bruce Barnett <bbarnett@crash.cts.com> wrote:
> The "thief" example in Inform's designer manual (page 94) demonstrates
> how to move a non-player character from one room to another, but the
> example explicitly rules out movements through doors. That turned out to
> be a crucial omission for me; my game doesn't move: room -> room -> room
> . . ., but rather room -> door -> room -> door -> room -> . . .
>
> I finally cobbled up a method to get the thief through a door, but it's
> really a Rube Goldberg method involving the ChangePlayer function and a
> slightly tweaked version of the GoSub routine in the library. It works
> most of the time, but it's buggy. There's a lot going on in GoSub that I
> don't understand and which seems to be mostly undocumented (e. g.,
> RunRoutines, L__M). Besides, this really seems to be the hard way. Is
> there a more straightforward way to get the thief through a door?

RunRoutines (object, property)
just runs the routine associated with the property of the object.
Thus, to run the `before' routine of the player, you call
RunRoutines(player,before). The debugging command `routines' causes
RunRoutines to produce diagnostic output whenever it runs.

The library messages system is a recent addition to the libraries (i.e.,
since the Designer's Manual was written). It's described in item #58 of
the `Life and time of the Inform library'; see the URL

http://www.cl.cam.ac.uk/users/gdr11/inform/library-history.html

I think there's no easy way to persuade a thief to go through doors.
You have to duplicate the door code yourself. For example, if dir is a
direction property (n_to, s_to, etc), then the following will move the
thief in that direction, if there is a door in that direction that isn't
locked.

The code below is untested, but it might give you some idea of what's
required.

---------------------------------------------------------------------------
! This is set when we're trying to move the thief, so that other
! routines can do the right thing.
global moving_thief = 0;

! Returns 1 if it moved the thief successfully
! Returns 0 if it couldn't move the thief in the requested direction
[ MoveThief dir i j p zr;

! Find out what's in the requested direction
p = parent(thief); ! this won't work if the thief enter vehicles
i = p.dir;
zr = ZRegion(i);

! It might be a string which would be printed to the player.
! Assume that this means that the thief can't go in that direction.
if (zr == 3) rfalse;

! It might be a routine which is activated when the player tries to
! move in that direction. We'll set moving_thief to 1 and hope that
! the routine does the right thing (it should return the
! destination if possible, or else 1 if there is no exit).
if (zr == 3) {
moving_thief = 1;
i = RunRoutines(p, i);
moveing_thief = 0;
if (i == 1) rfalse;
}

! If there's no exit in the given direction
if (zr == 0 || i == 0) rfalse;

! If the destination has the `door' attribute, then it's a door
if (i has door) {
if (i has locked) rfalse; ! change this if the thief has keys!
if (i hasnt open) {
give i open;
if (p == location) {
new_line; CDefArt(thief); print " opens ";
DefArt(i); print ".^"
}
}

! Find out where the door goes
if (ZRegion(i.door_to) == 2) i = RunRoutines(i,door_to);
else i = i.door_to;
if (i == 0) rfalse; ! It might not lead anywhere.
}

! Now i contains the destination room, so move the thief
move thief to i;
if (p == location) "^The thief stalks away!";
if (i == location) "^The thief stalks in!";
rtrue;
];
---------------------------------------------------------------------------

--
Gareth Rees
In search of: revision-tracking software for MS Word documents.