Follow
Follow
is an extension by Kent Tessman that allows for multiple
following NPCs (defaults to 8). This slightly-modified version (some
Future Boy! -specific code has been commented out) follows the
instructions dictated by
its license.
A version of this is included with Roodylib.
Usage
Use the AddFollower
and RemoveFollower
routines to add characters to
the characters-following array, and StartFollowing
to turn it on (and
StopFollowing
to turn it off).
The code
!-————————————————————————–
follow.h version 2.0
Mechanisms for enabling NPCs to follow the player
by Kent Tessman
Updated for general usage by Jon Blask
(See original at http://roody.gerynarsabode.org/follow.hug)
[Original code also has a routine for counting followers,
support for a follower-of-a-follower, and multimedia stuff- as
they pertain to Future Boy!]
—————————————————————————! #ifclear _FOLLOW_H #set _FOLLOW_H
#ifset VERSIONS #message “Follow.h Version 2.0” #endif
constant MAX_FOLLOWERS 8
array follower_list[MAX_FOLLOWERS] array moved_follower[MAX_FOLLOWERS] attribute following global followers global following_paused
property follow_message ! for locations, a suffix such as ! “ you down the stairs.”
property disallow_follow ! return true if circumstances disallow ! following (for characters or locations)
property pause_following ! for NPCs
routine AddFollower(char) { if followers = MAX_FOLLOWERS or char is following return false follower_list[followers++] = char char is following return true }
routine RemoveFollower(char) { local i for (i=0; i<MAX_FOLLOWERS; i++) { if follower_list[i] = char { while (i < MAX_FOLLOWERS-2) { follower_list[i] = follower_list[i+1] i++ } follower_list[MAX_FOLLOWERS-1] = 0 followers– char is not following return } } }
!
StartFollowing and StopFollowing are just two “helper” routines so authors
don’t need to remember that the following mechanism is handled by a
daemon (and therefore needs to be activated or deactivated)
If your game starts with a character following the PC,
call StartFollowing *after* the player global is set. \!
routine StartFollowing { return Activate(follow_daemon) }
routine StopFollowing { return Deactivate(follow_daemon) }
daemon follow_daemon { }
event in follow_daemon { ! if (verbroutine = &DoGo, &DoExit, &DoCrawl) and location ~= old_location ! ^ Future Boy! has a DoCrawl verb if (verbroutine = &DoGo, &DoExit, &DoEnter) and location ~= old_location MoveFollowers }
routine MoveFollowers { local i, mf
if followers = 0
return
if location.disallow_follow
return
! Don't allow following through or during a teleport sequence
! Roody's note: I don't really understand what the next two lines do, but
! I tried to change them to be less Hugo-shell-centric (since not everybody
! names their player object "you" ! if player ~= you ! return
#ifclear _ROODYLIB_H if player.type ~= character return #else if player.type ~= player_character return #endif
for (i=0; i<followers; i++)
{
if follower_list[i] in old_location and
follower_list[i] not in location and
not follower_list[i].pause_following and
not follower_list[i].disallow_follow
{
move follower_list[i] to location
moved_follower[mf] = follower_list[i]
mf++
}
}
if (mf)
{
print ""
FollowMessage(&MoveFollowers,1,mf) ! "So-and-so follows you."
} }
#if undefined PrintArrayList ! taken from misc.h … called from MoveFollowers:
! PrintArrayList(list, count) ! Prints count elements of the array list.
routine PrintArrayList(list, count) { local i for (i=1; i<=count; i++) { if i > 1: “ “; The(array list[i-1]) if i < count and count > 2: “,”; if i = count-1: print “ “; AND_WORD; } return false } #endif ! if undefined PrintArrayList
routine FollowMessage(r, num, a, b) { if NewFollowMessages(r, num, a, b): return
select r
case &MoveFollowers
{
select num
case 1:
{
print capital PrintArrayList(moved_follower, a);
" follow";
if a = 1 and moved_follower[0] is not plural: "s";
if not location.follow_message
{
print " ";
if player_person = 1,2
{
print player.pronoun #2;
}
else
print player.name;
"."
}
event_flag = true
}
} }
routine NewFollowMessages(r, num, a, b) { return false } #endif ! #ifset _FOLLOW_H
Examples
! this code assumes you have already run "StartFollowing"
! (must be done AFTER the player global is set in init routine)
character friendlygiant "friendly giant"
{
article "the"
adjective "friendly"
noun "giant"
order_response
{
! a response to GIANT, FOLLOW ME
if verbroutine = &DoFollow and object = player ! DoFollow can be found in verbstub
{
if self is following
"The giant says, \"I'm already following you!\""
else
{
"The giant says, \"OK!\""
AddFollower(self)
}
return true
}
elseif verbroutine = &DoStop ! DoStop is made up for this example
{
if self is not following
"The giant says, \"I wasn't following you!\""
else
{
"The giant says, \"OK!\""
RemoveFollower(self)
}
return true
}
return false ! for other commands, do the normal behavior
}
}
room tinyroom "Cramped Space"
{
long_desc
"Man, this place is tiny."
out_to giant_hall
disallow_follow 1 ! (true so our giant can't follow us in here)
}
! here is an example of a character that will only follow under
! certain circumstances
character rats "rats"
{
article "the"
noun "rats"
disallow_follow
{
if not Contains(player,musicpipe) ! is the player not holding the pipe instrument?
return true
else
return false
}
is plural
}