home *** CD-ROM | disk | FTP | other *** search
-
- {DESCRIBE.PA2}
-
-
- { Proc List_Contents }
- { *recursive* }
- {Given a location (integer) and the recursion }
- {level, prints out the items which are inside }
- {the location specified. If any of the items are}
- {themselves open, calls itself again to list }
- {the contents of that item, passing level+1 to }
- {insure proper indentation. }
- {Routine only executes if something}
- {is at location that should be listed}
-
- PROCEDURE List_Contents(loc : Integer;
- level : Integer);
- LABEL Done;
- VAR i : Integer;
- FWord : words;
-
- FUNCTION ds : names; {handles spacing}
- VAR k : Integer; {level is global to this}
- st : names;
- BEGIN
- k := 0;
- st := ' ';
- REPEAT
- st := st+' ';
- k := k+1;
- UNTIL k >= ((2*level)-1);
- ds := st;
- END; {ds}
-
- BEGIN {List_Contents}
- IF Things_Here(loc) < 1 THEN GOTO Done;
- FOR i := First_noun TO MaxNoun DO
- IF N[i]^.location = loc THEN
- BEGIN
- IF (morecount >= MoreLimit)
- THEN BEGIN
- morecount := 0;
- Pause;
- END;
- FWord := first_word(N[i]^.short); {get first world of short description}
- {$V-} Capitalize(FWord); {$V+} {Capitalize it}
- IF FWord <> 'INVISIBLE' THEN
- BEGIN
- Write(IO, ds, N[i]^.short);
- IF ((level = 1) AND (N[i]^.position <> 'none'))
- THEN Write(IO, ' (', N[i]^.position, ')');
- IF (level > 1) THEN Write(IO, ' (in the ', name(loc), ')');
- WriteLn(IO, ' ');
- morecount := morecount+1;
- IF N[i]^.open THEN List_Contents(i, level+1);
- END;
- END;
- Done:
- END; {list_contents}
-
- { Procedure List_Creatures }
- {Similar in function to List_Contents. Lists }
- {all creatures whose location is specified. This}
- {is not a recursive procedure, since creatures }
- {can only be in rooms, not other creatures or }
- {nouns. }
-
- PROCEDURE List_Creatures(loc : Integer);
-
- VAR i : Integer;
- FWord : words;
- BEGIN
- FOR i := First_creature TO MaxCreature DO
- IF M[i]^.location = loc THEN
- BEGIN
- IF (morecount >= MoreLimit)
- THEN BEGIN
- morecount := 0;
- Pause;
- END;
- FWord := M[i]^.short; {get first world of short description}
- {$V-} Capitalize(FWord); {$V+} {Capitalize it}
- IF FWord <> 'INVISIBLE' THEN
- BEGIN
- WriteLn(IO, ' ', M[i]^.short);
- morecount := morecount+1;
- END;
- END;
- END; {list_Creatures}
-
-
- { SwapWords }
- {Swaps two words in a sentence}
-
- PROCEDURE SwapWords(FromWord, ToWord : words; VAR sentence : s; LowerCase : Boolean);
-
- VAR
- Spot, FromLength : Integer;
- BEGIN
- IF LowerCase THEN Normalize(ToWord); {make lower case}
- IF (FromWord[1] = '$') THEN
- BEGIN
- Normalize(ToWord); { make lower case }
- IF (FromWord[2] <= 'Z') THEN { if first letter capital... }
- ToWord[1] := Upcase(ToWord[1]);
- IF (FromWord[3] <= 'Z') THEN { if second letter capital... }
- FOR Spot := 2 TO Length(ToWord) DO ToWord[Spot] := Upcase(ToWord[Spot]);
- END;
- FromLength := Length(FromWord);
- WHILE POS(FromWord, sentence) <> 0 DO
- BEGIN
- Spot := POS(FromWord, sentence);
- Delete(sentence, Spot, FromLength); {delete FromWord}
- Insert(ToWord, sentence, Spot); {insert ToWord}
- END;
- IF (FromWord[1] = '$') AND (FromWord[3] <= 'Z') THEN
- BEGIN
- Normalize(FromWord);
- SwapWords(FromWord, ToWord, sentence, LowerCase);
- FromWord[2] := Upcase(FromWord[2]);
- SwapWords(FromWord, ToWord, sentence, LowerCase);
- END;
- END; {SwapWords}
-
-
-
- { Handle Word Combinations }
- {Remove the specific word combination from the}
- {sentence and replace them with other words.}
- PROCEDURE Handle_Word_Combinations(VAR sentence : s);
- BEGIN
- SwapWords(',', ' AND ', sentence, False); {convert ,s to 'and'}
- SwapWords(';', ' AND ', sentence, False); {convert ;s to 'and'}
- SwapWords(' ', ' ', sentence, False); {remove any double spaces}
- SwapWords(' AND AND ', ' AND ', sentence, False);
- SwapWords(' AND THEN ', ' AND ', sentence, False);
- SwapWords(' IN TO ', ' INTO ', sentence, False);
- SwapWords(' NEAR BY ', ' BY ', sentence, False);
- SwapWords(' NEXT TO ', ' NEAR ', sentence, False);
- END;
-
-
- { Check For Name }
- {Checks to see if the command is being addressed to a creature}
- {If it is then routine sets Global NameStr to name of creature and}
- { the Global NameNum to the creature's number.}
- {If it is NOT then routine sets Global NameStr to '' and}
- { the Global NameNum to 0.}
- {After returning from this routine, sentence has the name (if any) stripped off}
- PROCEDURE CheckForName(VAR sentence : s);
- VAR FWord : words;
- num : Integer;
- BEGIN
- FWord := first_word(sentence);
- num := Creature_Number(FWord);
- IF ((FWord = 'ANYONE') OR (FWord = 'ANYBODY'))
- THEN num := Num_Verbs+1;
- IF ((FWord = 'EVERYONE') OR (FWord = 'EVERYBODY'))
- THEN num := Num_Verbs+2;
- IF num = 0 THEN {Command is NOT being addressed to a creature}
- BEGIN
- NameStr := '';
- NameNum := 0;
- END
- ELSE BEGIN {Command is NOT being addressed to a creature}
- NameNum := num;
- Normalize(FWord); {make lower case except for first letter}
- IF (FWord[1] IN ['a'..'z'])
- THEN FWord[1] := Char(Integer(FWord[1])-32);
- NameStr := FWord;
- sentence := But_First(sentence); {strip off name}
- FWord := first_word(sentence); {second word of command}
- IF FWord = 'AND' THEN sentence := But_First(sentence); {strip off AND}
- END;
- END;
-
- {Move any group member in FromLoc to ToLoc}
- PROCEDURE MoveGroup(FromLoc, ToLoc : Integer);
- VAR i : Integer;
- BEGIN
- IF MaxCreature > 0 THEN
- FOR i := First_creature TO MaxCreature DO
- IF ((M[i]^.location = FromLoc) AND (M[i]^.groupmember))
- THEN M[i]^.location := ToLoc;
- END;
-
-
- { Procedure Describe_It }
- {Given a number, it searches the data file and }
- {provides a description. }
- { 1. Allow Verb, Noun or Object to be "played back" in output.}
- { 2. Give short description (if available), if long description is missing.}
- { 3. Show short description of any nouns inside noun being described.}
-
- PROCEDURE Describe_It(keyword : words; num : Integer);
-
- VAR st : s;
- i, k, adjnum, Tries : Integer;
- VarStr, adj, SubWord, CapSubWord : words;
- start, len, Spot, VarLn, VarNum, ErrorNum, FirstDollar, NextDollar : Integer;
-
- BEGIN
- start := 0;
- IF keyword = 'NOUN_DESCR' THEN start := Noun_Ptr[num].start
- ELSE IF keyword = 'PLAY_DESCR' THEN start := Play_Ptr[num].start
- ELSE IF keyword = 'PUSH_DESCR' THEN start := Push_Ptr[num].start
- ELSE IF keyword = 'PULL_DESCR' THEN start := Pull_Ptr[num].start
- ELSE IF keyword = 'TURN_DESCR' THEN start := Turn_Ptr[num].start
- ELSE IF keyword = 'TEXT' THEN start := Text_Ptr[num].start
- ELSE IF keyword = 'ROOM_DESCR' THEN start := Room_Ptr[num].start
- ELSE IF keyword = 'SPECIAL' THEN start := Special_Ptr[num].start
- ELSE IF keyword = 'MESSAGE' THEN start := Message_Ptr[num].start
- ELSE IF keyword = 'HELP' THEN start := Help_Ptr[num].start
- ELSE IF keyword = 'INTRO' THEN start := Intro_Ptr.start
- ELSE IF keyword = 'CREATURE_DESCR' THEN start := Creature_Ptr[num].start;
- IF start > 0 THEN
- IF keyword = 'NOUN_DESCR' THEN len := Noun_Ptr[num].len
- ELSE IF keyword = 'PLAY_DESCR' THEN len := Play_Ptr[num].len
- ELSE IF keyword = 'PUSH_DESCR' THEN len := Push_Ptr[num].len
- ELSE IF keyword = 'PULL_DESCR' THEN len := Pull_Ptr[num].len
- ELSE IF keyword = 'TURN_DESCR' THEN len := Turn_Ptr[num].len
- ELSE IF keyword = 'TEXT' THEN len := Text_Ptr[num].len
- ELSE IF keyword = 'ROOM_DESCR' THEN len := Room_Ptr[num].len
- ELSE IF keyword = 'SPECIAL' THEN len := Special_Ptr[num].len
- ELSE IF keyword = 'MESSAGE' THEN len := Message_Ptr[num].len
- ELSE IF keyword = 'HELP' THEN len := Help_Ptr[num].len
- ELSE IF keyword = 'INTRO' THEN len := Intro_Ptr.len
- ELSE IF keyword = 'CREATURE_DESCR' THEN len := Creature_Ptr[num].len;
- IF start <= 0 THEN
- IF keyword = 'MESSAGE'
- THEN WriteLn(IO, 'MESSAGE ',num, ' is missing from .MSG file!')
- ELSE IF (num >= First_noun) AND (num <= MaxNoun)
- THEN WriteLn(IO, N[num]^.short) {give short description of no long one}
- ELSE IF (num >= First_creature) AND (num <= MaxCreature)
- THEN WriteLn(IO, M[num]^.short) {give short description of no long one}
- ELSE WriteLn(IO, 'Sorry, I can''t describe that.')
- ELSE {seek(datafile,start)}
- BEGIN
- Seek(descr_file, start);
- FOR i := 1 TO len DO
- BEGIN
- IF (morecount >= MoreLimit)
- THEN BEGIN
- morecount := 0;
- Pause;
- END;
- Read(descr_file, st);
- st := Decode(st);
- WHILE POS('#VAR', st) <> 0 DO
- BEGIN {Sub Variable N (0 .. 9) for #VARN#}
- Spot := POS('#VAR', st);
- VarStr := Copy(st, Spot+4, 2);
- IF VarStr[2] = '#'
- THEN BEGIN
- VarLn := 1;
- VarStr := VarStr[1];
- END ELSE VarLn := 2;
- Delete(st, Spot+4, VarLn); {get ride of Var digit}
- Val(VarStr, VarNum, ErrorNum);
- IF ErrorNum = 0 THEN
- BEGIN
- VarNum := Variable[VarNum];
- Str(VarNum, VarStr);
- SwapWords('#VAR#', VarStr, st, True); {substitute Variable value}
- END;
- END; {WHILE}
- WHILE POS('#CTR', st) <> 0 DO
- BEGIN {Sub Counter N (0 .. 9) for #CTRN#}
- Spot := POS('#CTR', st);
- VarStr := Copy(st, Spot+4, 2);
- IF VarStr[2] = '#'
- THEN BEGIN
- VarLn := 1;
- VarStr := VarStr[1];
- END ELSE VarLn := 2;
- Delete(st, Spot+4, VarLn); {get ride of Ctr digit(s)}
- Val(VarStr, VarNum, ErrorNum);
- IF ErrorNum = 0 THEN
- BEGIN
- VarNum := counter[VarNum];
- Str(VarNum, VarStr);
- SwapWords('#CTR#', VarStr, st, True); {substitute Counter value}
- END;
- END; {WHILE}
- adjnum := Noun_Number(noun);
- adj := Things_Adjective(adjnum);
- Tries := 0;
- WHILE ((POS('$', st) <> 0) AND (Tries < 10)) DO
- BEGIN
- Tries := Tries + 1;
- FirstDollar := POS('$', st);
- st[FirstDollar] := 'X';
- NextDollar := POS('$', st);
- st[FirstDollar] := '$'; {restore first '$' sign}
- IF NextDollar > FirstDollar THEN
- BEGIN
- {FromWord to substitute -- no necessarily capitalized}
- SubWord := Copy(st, FirstDollar, NextDollar-FirstDollar+1);
- CapSubWord := SubWord;
- FOR k := 1 TO Length(CapSubWord) DO
- CapSubWord[k] := Upcase(CapSubWord[k]); {capitalized word}
- IF CapSubWord = '$ADJECTIVE$'
- THEN SwapWords(SubWord, adj, st, True);
- {substitute Adj wherever $ADJECTIVE$ appears}
- IF CapSubWord = '$PREPOSITION$'
- THEN SwapWords(SubWord, prep, st, True);
- {substitute Prep wherever it appears}
- IF CapSubWord = '$NOUN$'
- THEN SwapWords(SubWord, noun, st, True);
- {substitute Noun wherever $NOUN$ appears}
- IF CapSubWord = '$VERB$'
- THEN SwapWords(SubWord, Original_Verb, st, True);
- {substitute verb for $VERB$}
- IF CapSubWord = '$OBJECT$'
- THEN SwapWords(SubWord, object_word, st, True);
- {substitute Object for $OBJECT$}
- IF CapSubWord = '$NAME$'
- THEN SwapWords(SubWord, NameStr, st, False);
- {substitute NameStr for $NAME$}
- END; {NextDollar > FirstDollar}
- END; {WHILE}
-
- WriteLn(IO, st);
- morecount := morecount+1;
- END;
- END;
- IF (keyword = 'NOUN_DESCR') AND (num >= First_noun) AND (num <= MaxNoun)
- THEN IF N[num]^.open THEN List_Contents(num, 2); {show items inside - if any}
- END;
-
- { Function LightIsHere }
- {Returns true if possible to see in Current_Room}
-
- FUNCTION LightIsHere : Boolean;
-
- VAR i, l : Integer;
- can_see : Boolean;
- BEGIN
- can_see := False;
- {determine if need and have specific light}
- IF (Room[Current_room]^.light <= 0)
- THEN can_see := True {do not need light}
- ELSE
- IF Room[Current_room]^.light > 1 {room needs specific light if > 1}
- THEN
- BEGIN
- l := location(Room[Current_room]^.light);
- can_see := ((l = Player) OR (l = Current_room));
- END
- ELSE
- FOR i := First_noun TO MaxNoun DO
- BEGIN
- l := location(i);
- IF (N[i]^.on) AND (N[i]^.is_light)
- AND ((l = Player) OR (l = Current_room))
- THEN can_see := True;
- END;
- LightIsHere := can_see;
- END; {LightIsHere}
-
- { Proc Describe_Scene }
- { (Describe Room, Situation) }
- {Assumes that everything is global but doesn't }
- {modify any variables. It checks the boolean }
- {variable 'verbose' to see if full descriptions }
- {are normally desired. Calls all three of the }
- {above procedures. }
-
- PROCEDURE Describe_scene;
-
- VAR
- can_see : Boolean;
- BEGIN
- IF (Current_room <> Previous_room) {just moved into room}
- THEN IF (NOT Room[Current_room]^.has_seen)
- THEN FirstVisitFlag := True {Player has been here before}
- ELSE FirstVisitFlag := False; {Player has not been here before}
- can_see := LightIsHere;
- {determine if need and have specific light}
- IF NOT can_see
- THEN
- IF (Room[Current_room]^.light = 1)
- THEN {player isn't carrying any light at all}
- WriteLn(IO, 'It is pitch black. You can see nothing, not even your hands.')
- ELSE {player may be carrying a light but still can't see}
- WriteLn(IO, 'For some reason, you can''t see anything here.')
- ELSE
- BEGIN {Show room description only if first turn in room}
- IF ((verb <> 'LOOK') AND (verb <> 'L')
- AND (Current_room = Previous_room) AND (NOT Is_Direction(verb)))
- THEN BEGIN {No Description}
- END {No description}
- ELSE IF ((verb = 'LOOK') OR (verb = 'L') OR (FirstVisitFlag)
- OR ((verbose) AND (Current_room <> Previous_room)))
- THEN BEGIN {Verbose Description}
- IF Scripting THEN WriteLn(IO, '<< ', Room[Current_room]^.name, ' >>');
- morecount := morecount+2;
- Describe_It('ROOM_DESCR', Current_room);
- List_Contents(Current_room, 1);
- List_Creatures(Current_room);
- END {full verbose description}
- ELSE IF (NOT verbose) AND ((Current_room <> Previous_room)
- OR (Room[Current_room]^.has_seen))
- THEN BEGIN {Brief Description}
- WriteLn(IO, '<< ', Room[Current_room]^.name, ' >>');
- morecount := morecount+2;
- List_Contents(Current_room, 1);
- List_Creatures(Current_room);
- END; {Brief description}
- END; {normal room description if light on or not needed}
- Previous_room := Current_room;
- Room[Current_room]^.has_seen := True;
- END; {describe_scene}
-
- {Describe(something)}
-
- PROCEDURE Describe(w : words);
-
- VAR l, num : Integer;
- BEGIN
- {$V-} Capitalize(w); {$V+}
- IF noun = 'ALL'
- THEN WriteLn(IO, 'Not everything at once! Pick one thing at a time!')
- ELSE
- IF (noun = 'DOOR') AND (location(NounNumber) <> Current_room)
- THEN IF Room[Current_room]^.locked_door
- THEN WriteLn(IO, 'It looks like a solid, locked door.')
- ELSE WriteLn(IO, 'The doors here all look pretty much like doors.')
- ELSE
- IF ((NounNumber >= First_noun) AND (NounNumber <= MaxNoun)) OR
- (NounNumber = 0)
- THEN
- BEGIN
- Normalize(w);
- IF (NOT Is_Visible(NounNumber)) AND (NOT(location(NounNumber) = Player))
- THEN WriteLn(IO, 'I see no ', w, ' here.')
- ELSE Describe_It('NOUN_DESCR', NounNumber);
- END
- ELSE {it must be a creature}
- BEGIN
- num := Creature_Number(w);
- Normalize(w);
- l := M[num]^.location;
- IF NOT(l = Current_room)
- THEN WriteLn(IO, 'The ', w, ' isn''t here.')
- ELSE Describe_It('CREATURE_DESCR', num);
- END;
- END; {describe}
-
- { Drop (noun ) }
- {Also take off or remove worn nouns}
- {e.g., drop axe or take off hat }
- { 1. Allows player to drop a worn item.}
- { 2. Keeps track of number of items being carried and in room.}
-
- PROCEDURE Drop(noun : words);
-
- VAR num : Integer;
- adj : words;
- BEGIN
- num := Noun_Number(noun);
- Normalize(noun);
- adj := Things_Adjective(num);
- IF (N[num]^.location <> Player) AND (N[num]^.location <> Wearing)
- THEN WriteLn(IO, 'You don''t seem to have the ', adj, ' ', noun, '.')
- ELSE
- BEGIN
- Adjust_Count(N[num]^.location, -1);
- Adjust_Count(Current_room, 1);
- N[num]^.location := Current_room;
- WriteLn(IO, 'You ', Original_Verb, ' the ', adj, ' ', noun, '.');
- END;
- END; {drop}
-
-