! --------------------------------------------------------------------------
! GONEIGHBOUR
!
! Version 0.20, written by Alan Trewartha
[email protected]
! Last updated 3rd Feb 2001
!
! SUMMARY
! This extension makes extra use of room 'name' properties, which are
! usually only used to produce a "you do not need to refer to that" sort
! of message. It allows the objects in the Compass (n_obj, e_obj, etc)
! to take on the 'name's of the location that the player would get to by
! GOing in that direction. i.e. if the n_to of the current location leads
! to a location with the word 'farm' in its name property, then "GO FARM"
! will be the same as "GO NORTH" and "FARM" is the same as "NORTH".
!
! More precisely the compass object will take on the neighbouring
! locations 'name' property if that location has either the 'visited' or
! 'transparent' attribute but not if it is 'concealed'. The compass object
! also takes on words in a property called "external_name", regardless.
!
! --------------------------------------------------------------------------
! HOW TO USE GONEIGHBOUR
!
! Before include "Parser" add the line "Replace Refers;"
! Include "GoNeighbour" any point after "Parser"
!
! If you have "noisy" *_to properties then add "Constant NOISY_DIR_TOS".
! This means that LeadsTo() won't call routines to see what they return.
!
! When writing location or "Room" objects, keep in mind
! * transparent attribute (to allow 'name' words even if not visited)
! * concealed attribute (to disallow 'name' words even if visited)
! * name property
! * external_name property (YOU MUST USE SINGLE QUOTES!!)
!
! Optionally it's quite nice to add a little extra bit of grammar so that
! it accepts "GO TO FARM" "GO TOWARDS FARM":
!
! Extend 'go' last
! * 'to'/'toward'/'towards' noun -> Go;
!
! --------------------------------------------------------------------------
! EXAMPLE CODE
!
! Room_2 can be got to with "GO GREEN" before you've been there. You can see
! the green-ness from Room_1, so it's in the external_name property. You can
! only use "GO TRIANGLE" once you've been there.
!
! Object Room_1 "Red Circle Room"
! with description
! "The walls here are red. There is a circle on the ceiling.
! To the north is a green room",
! name "red" "circle",
! external_name 'red',
! n_to Room_2,
! has light;
!
! Object Room_2 "Green Triangle Room"
! with description
! "The walls here are green. There is a triangle on the ceiling.
! To the south is a red room.",
! name "green" "triangle",
! external_name 'green',
! s_to Room_1,
! has light;
!
! --------------------------------------------------------------------------
! A new common property
Property external_name;
! The refers patch
[ Refers obj wnum wd i;
if (obj==0) rfalse;
i = wn; wn = wnum; wd = NextWordStopped(); wn = i;
! First the default
if (WordInProperty(wd,obj,name)) rtrue;
! Then if obj has 'external_name' try that too
if (obj provides external_name)
if (WordInProperty(wd,obj,external_name)) rtrue;
! Now the trick.
! If obj is in compass, then try the object it leads to
if (parent(obj)==Compass)
{ i=location; if (i==thedark) i=real_location;
i=LeadsTo(obj,i); if (i==0) rfalse;
! First the external_name
if (WordInProperty(wd,i,external_name)) rtrue;
! If the room is concealed forget it...
if (i has concealed) rfalse;
! If the room is unvisited and "opaque" forget it
if (i hasnt visited && i hasnt transparent) rfalse;
! Otherwise check name
if (WordInProperty(wd,i,name)) rtrue;
}
rfalse;
];
! LeadsTo returns either false (0), or the location that the player would
! come to by GOing in the direction given. This is a cut down version of
! the same routione provided in 'MoveClass' so the "Ifndef" makes sure that
! this is only compiled if it isn't already defined.
Ifndef LeadsTo;
Ifndef NOISY_DIR_TOS;
Message "** LeadsTo assuming quiet *_to (NOISY_DIR_TOS not defined) **";
Endif;
[ LeadsTo direction thisroom k tmp tmp2;
if (~~(direction provides door_dir)) rfalse;
if (~~(thisroom provides direction.door_dir)) rfalse;
k=thisroom.(direction.door_dir);
#ifdef NOISY_DIR_TOS;
if (ZRegion(k)==2) rfalse;
#endif;
#ifndef NOISY_DIR_TOS;
if (ZRegion(k)==2)
k=k();
#endif;
if (ZRegion(k)~=1) rfalse;
if (k has door)
{ tmp=parent(k);
move k to thisroom;
tmp2=k.door_to();
if (tmp==0)
remove k;
else
move k to tmp;
k=tmp2;
}
return k;
];
Endif;