home *** CD-ROM | disk | FTP | other *** search
/ CD PowerPlay 6 / TheCompleteAdventureCollection1995 / CDPP6.ISO / utility / agtsrc / command.pa4 < prev    next >
Encoding:
Text File  |  1989-12-20  |  50.4 KB  |  953 lines

  1.  
  2.   {COMMAND.PA2}
  3.  
  4.   {              READ_INSTRUCTIONS}
  5.   {Read INSTRUCTIONS file (if it exists) and display it}
  6.  
  7.   PROCEDURE Read_INSTRUCTIONS;
  8.  
  9.   LABEL Exit;
  10.   VAR
  11.     sentence, Answer : s;
  12.     fname : words;
  13.     LineCount : Integer;
  14.  
  15.   BEGIN                           {read_instructions}
  16.     fname := Instruction_File_Name;
  17.     IF NOT File_Exists(fname) THEN GOTO Exit;
  18.     Write(IO, 'Would you like to read the instructions ? ');
  19.     Answer := GetInputString;
  20.     Answer := Upcase(Answer[1]);
  21.     IF Answer = 'N' THEN GOTO Exit;
  22.     CLRSCR;                       {start with clean slate}
  23.     LineCount := 0;
  24.     Assign(datafile, Instruction_File_Name);
  25.     Reset(datafile);
  26.     REPEAT                        {until (sentence = 'END OF FILE') or (EOF(datafile))}
  27.       LineCount := LineCount+1;
  28.       IF LineCount = 22 THEN
  29.         BEGIN
  30.           Pause;
  31.           LineCount := 0;         {start over}
  32.         END;
  33.       ReadLn(datafile, sentence);
  34.       WriteLn(IO, sentence);
  35.     UNTIL (POS('END OF FILE', sentence) <> 0) OR (EOF(datafile));
  36.     Pause;                        {when done reading instructions}
  37. Exit:
  38.     CLRSCR;                       {clear before showing starting room}
  39.   END;                            {Read_Instructions}
  40.  
  41.  
  42.   {Set_Token_Parameters}
  43.  
  44.   PROCEDURE Set_Token_Parameters;
  45.   VAR i : Token;
  46.  
  47.   BEGIN
  48.     FOR i := AtLocation TO DoneWithTurn
  49.     DO P[i] := 1;                 {set all parameter values to 1}
  50.  
  51.     {Now deal with exceptions, i.e., parameter values of 0 and 2}
  52.  
  53.     {*************************************************************************}
  54.     {*                C O N D I T I O N    T O K E N S                       *}
  55.     {*************************************************************************}
  56.  
  57.     {**********************   PLAYER CONDITIONS   ****************************}
  58.     {                 Type of   Number Of}
  59.     {TOKEN NAME     Parameters Parameters     Explanation}
  60.     {=============== =============  ==== ====================================}
  61.     P[IsCarryingSomething {None} ] := 0; {Player is carrying something}
  62.     P[IsCarryingNothing {None} ] := 0; {Player is carrying nothing}
  63.     {worth at least PTS# points}
  64.     P[IsWearingSomething {None} ] := 0; {Player is wearing something}
  65.     P[IsWearingNothing {None} ] := 0; {Player is wearing nothing}
  66.     P[FirstVisitToRoom {None} ] := 0; {Player is in current room for first time}
  67.     P[NewLife {None} ] := 0;      {Player is starting game or has just been resurrected}
  68.  
  69.     {**********************   ITEM CONDITIONS   **********************************}
  70.     {                 Type of   Number Of}
  71.     {TOKEN NAME     Parameters Parameters     Explanation}
  72.     {=============== =============  ==== ========================================}
  73.     P[IsLocated {ITEM#  loc#} ] := 2; {ITEM# is located in room loc#}
  74.     P[Together {ITEM# ITEM#} ] := 2; {ITEM# and ITEM# are in same place}
  75.  
  76.     {*********************   NOUN CONDITIONS   *******************************}
  77.     {                 Type of   Number Of}
  78.     {TOKEN NAME     Parameters Parameters     Explanation}
  79.     {=============== =============  ==== ====================================}
  80.     P[NOUNPresent {none} ] := 0;  {NOUN ITEM is in room, carried or worn}
  81.     P[NOUNIsWearing {none} ] := 0; {NOUN ITEM is being worn}
  82.     P[NOUNIsCarrying {none} ] := 0; {NOUN ITEM is being carried}
  83.     P[NOUNIsNowhere {none} ] := 0; {NOUN ITEM is located NOWHERE (room 0)}
  84.     P[NOUNIsSomewhere {none} ] := 0; {NOUN ITEM is located somewhere}
  85.     P[NOUNInRoom {none} ] := 0;   {NOUN ITEM is located in current room}
  86.     P[NOUNIsON {none} ] := 0;     {NOUN ITEM is ON}
  87.     P[NOUNIsOFF {none} ] := 0;    {NOUN ITEM is OFF}
  88.     P[NOUNIsOpen {none} ] := 0;   {NOUN ITEM is Open}
  89.     P[NOUNIsClosed {none} ] := 0; {NOUN ITEM is Closed}
  90.     P[NOUNIsLocked {none} ] := 0; {NOUN ITEM is Locked}
  91.     P[NOUNIsUnLocked {none} ] := 0; {NOUN ITEM is UnLocked}
  92.     P[NOUNIsEdible {none} ] := 0; {NOUN ITEM is Edible}
  93.     P[NOUNIsDrinkable {none} ] := 0; {NOUN ITEM is Drinkable}
  94.     P[NOUNIsPoisonous {none} ] := 0; {NOUN ITEM is Poisonous}
  95.     P[NOUNIsMovable {none} ] := 0; {NOUN ITEM is Movable}
  96.  
  97.     {*****************   MISCELLANEOUS CONDITIONS   **************************}
  98.     {                 Type of   Number Of}
  99.     {TOKEN NAME     Parameters Parameters     Explanation}
  100.     {=============== =============  ==== ====================================}
  101.     P[LightPresent {none} ] := 0; {Room has necessary light}
  102.     P[RoomNeedsLight {none} ] := 0; {Room needs a light}
  103.     P[AnswerIsCorrect {none} ] := 0; {last answer was correct}
  104.     P[AnswerIsWrong {none} ] := 0; {last answer was wrong}
  105.     P[CounterEquals {ctr# num} ] := 2; {Counter # is equal to num}
  106.     P[CounterGT {ctr# num} ] := 2; {Counter # is greater than num}
  107.     P[CounterLT {ctr# num} ] := 2; {Counter # is less than num}
  108.     P[VariableEquals {var# num} ] := 2; {Variable # is equal to num}
  109.     P[VariableGT {var# num} ] := 2; {Variable # is greater than num}
  110.     P[VariableLT {var# num} ] := 2; {Variable # is less than num}
  111.     P[CompareVariables {V1 V2} ] := 2; {TRUE if V1 < V2 }
  112.     P[VariableChance {V N} ] := 2; {TRUE if V < Random(1..N)}
  113.     P[NamePresent {none} ] := 0;  {TRUE if Name being addressed is at location or No Name addressed}
  114.     P[PromptForYES {none} ] := 0; {Prompts for Y or N -- Ok if Yes}
  115.     P[PromptForNO {none} ] := 0;  {Prompts for Y or N -- Ok if No}
  116.     P[VerbIsDirection {none} ] := 0; {Verb is movement or direction}
  117.     P[NounIsCreature] := 0;       {TRUE if noun is a creature}
  118.     P[ObjectIsCreature] := 0;     {TRUE if object is a creature}
  119.     P[ObjectPresent] := 0;        {TRUE if object is present in room}
  120.     P[LogicalNOT {none} ] := 0;   {Logical NOT of current condition}
  121.     P[LogicalOR {none} ] := 0;    {Logical OR of conditions}
  122.  
  123.     {*************************************************************************}
  124.     {*                    A C T I O N     T O K E N S                        *}
  125.     {*************************************************************************}
  126.  
  127.     {******************* PLAYER ACTION TOKENS ********************************}
  128.     {                 Type of   Number Of}
  129.     {TOKEN NAME     Parameters Parameters     Explanation}
  130.     {=============== =============  ==== ====================================}
  131.     P[GoToRandomRoom {R1 R2} ] := 2; {Send player to Room >= R1 and <= R2}
  132.     P[SendToVariableRoom] := 2;   {Item# Var# -- will send Item# to room number Var#}
  133.     P[GetNOUN {none} ] := 0;      {NOUN is now being carried}
  134.     P[WearNOUN {none} ] := 0;     {NOUN is now being worn}
  135.     P[DropNOUN {none} ] := 0;     {Drops NOUN into current room}
  136.     P[RemoveNOUN {none} ] := 0;   {Removes NOUN and drops into room}
  137.     P[DropEverything {none} ] := 0; {Drop all items being carried}
  138.     P[RemoveEverything {none} ] := 0; {Remove all items being worn}
  139.     P[KillPlayer {none} ] := 0;   {Makes player dead}
  140.  
  141.     {************** ITEM/NOUN/LOCATION ACTION TOKENS *************************}
  142.     {                 Type of   Number Of}
  143.     {TOKEN NAME     Parameters Parameters     Explanation}
  144.     {=============== =============  ==== ====================================}
  145.     P[PutNOUNInCurrentRoom {none} ] := 0; {Put NOUN in current room}
  146.     P[SendToRoom {ITEM# loc#} ] := 2; {Put ITEM# in room loc#}
  147.     P[SendTreasuresToRoom {loc# pts#} ] := 2; {Send all carried ITEMs whose}
  148.     {points > pts# to loc#}
  149.     P[RelocateAll {loc1 loc2} ] := 2; {Move all items at loc1 to loc2}
  150.     P[DestroyNOUN {none} ] := 0;  {NOUN is now NOWHERE (room 0)}
  151.     P[SwapLocations {ITEM1 ITEM2} ] := 2; {swap locations of ITEM1 & ITEM2}
  152.     P[SendToItem {ITEM1 ITEM2} ] := 2; {Put ITEM1 in location of ITEM2}
  153.     P[ReDirectTo] := 0;           {Re-Direct command to different VERB-NOUN-OBJECT}
  154.     P[RandomMessage] := 2;        {Select message between Num1 and Num2 and print it}
  155.     P[OpenNOUN {none} ] := 0;     {NOUN is now open}
  156.     P[CloseNOUN {none} ] := 0;    {NOUN is now closed}
  157.     P[LockNOUN {none} ] := 0;     {NOUN is now locked}
  158.     P[UnlockNOUN {none} ] := 0;   {NOUN is now unlocked}
  159.  
  160.     {**************** MISCELLANEOUS ACTION TOKENS ****************************}
  161.     {                 Type of   Number Of}
  162.     {TOKEN NAME     Parameters Parameters     Explanation}
  163.     {=============== =============  ==== ====================================}
  164.     P[ShowScore {none} ] := 0;    {Show current SCORE}
  165.     P[ShowInventory {none} ] := 0; {Show current INVENTORY}
  166.     P[WaitForReturn {none} ] := 0; {Prints 'Hit RETURN' message}
  167.     P[TimePasses {none} ] := 0;   {Show 'Time passes...' message}
  168.     P[CLEARSCREEN {none} ] := 0;  {Clears screen}
  169.     P[LookAtRoom {none} ] := 0;   {Cause a VERBOSE look at room}
  170.     P[BlankLine {none} ] := 0;    {Prints a blank line}
  171.     P[Tone {H M} ] := 2;          {makes a sound at H hertz for M milliseconds}
  172.     P[GetNumberInput {num1 num2} ] := 2; {Prompt for player to input a number}
  173.     {where num1 <= number <= num2}
  174.     {if num1=num2, then no range will be given in prompt}
  175.     P[ChangePassageway {dir# loc#} ] := 2; {Creates or closes a passageway}
  176.     {from current_room to loc# via dir#}
  177.     {dir# = 1 = north ... 12 = exit}
  178.     P[SetVariableTo {var# num#} ] := 2; {Set Variable var# to num#}
  179.     P[AddToVariable {var# num#} ] := 2; {Add num# to Variable var#}
  180.     P[SubtractFromVariable {var# num#} ] := 2; {Subtract num# from Variable #}
  181.     P[AddVariables {V1 V2} ] := 2; {Add V2 to V1 and put answer in V1}
  182.     P[SubtractVariables {V1 V2} ] := 2; {Subtract V2 from V1 and put answer in V1}
  183.     P[RandomVariable {V N} ] := 2; {Set variable V to random number [1 .. N]}
  184.     P[QuitThisCMD {none} ] := 0;  {Quit evaluating this CMD}
  185.     P[QuitAllCMDs {none} ] := 0;  {Finished with all special CMDs}
  186.     P[DoneWithTurn {none} ] := 0; {All Done this turn -- get input next}
  187.     P[WinGame {none} ] := 0;      {Player wins game at end of turn}
  188.     P[EndGame {none} ] := 0;      {game ends at end of turn}
  189.   END;                            {Set_Token_Parameters}
  190.  
  191.   PROCEDURE MoveIt(ITEMNum, PLACE : Integer);
  192.     {Move ITEMNum to location Place}
  193.     {WARNING -- No condition checking -- Just Move It}
  194.   BEGIN
  195.     IF ITEMNum < First_creature
  196.     THEN BEGIN                    {Adjust count ONLY for Nouns -- NOT for Creatures}
  197.       Adjust_Count(N[ITEMNum]^.location, -1); {reduce count at old location}
  198.       N[ITEMNum]^.location := PLACE; {move it to new Place}
  199.       Detach(ITEMNum);            {make 'position' = none}
  200.       IF PLACE <> Nowhere THEN Adjust_Count(PLACE, 1); {add one to count at new location}
  201.     END
  202.     ELSE M[ITEMNum]^.location := PLACE; {move creature -- don't adjust count}
  203.   END;                            {MoveIt}
  204.  
  205.  
  206.   {PERFORM_Special_CMDS(TempVerb,TempNoun,TempObject)}
  207.   {  Perform any Special_CMDs associated with a}
  208.   {  given verb noun object trio, plus 'ANY'}
  209.  
  210.   PROCEDURE PERFORM_Special_CMDS(VAR TempVerb, TempNoun, TempObject : words);
  211.  
  212.   LABEL Leave;
  213.   VAR i, J, k, l, CMDnum, Last, num1, num2, loc1, loc2, TestNum, code : Integer;
  214.     Condition, Diag_Mode, OR_Condition, Doing_OR, Prior_Condition : Boolean;
  215.     ReverseCondition, NumOK : Boolean;
  216.     CMDverb, CMDnoun, CMDobject, TempVWord, TempNWord, TempOWord : words;
  217.     TempNameNumber, TempNounNumber, TempObjectNumber : Integer;
  218.     st, st1 : s;
  219.     CurrentToken, NextToken : Token;
  220.     Dir, OpDir : Direction;
  221.  
  222.     FUNCTION PromptYorN : Char;
  223.     VAR Answer : s;
  224.     BEGIN
  225.       Write(IO, 'Please answer Yes or No: ');
  226.       Answer := GetInputString;
  227.       PromptYorN := Upcase(Answer[1]);
  228.     END;                          {PromptYorN}
  229.  
  230.     FUNCTION ImmediateLocation(num : Integer) : Integer;
  231.       {Returns immediate location of item}
  232.       {Unlike Global LOCATION which returns location where item is visible}
  233.       {For example, if item is in knapsack which is open and being worn}
  234.       {   ImmediateLocation will return knapsack location number}
  235.       {   Global Location will return wearing number}
  236.     BEGIN
  237.       IF (num >= First_noun) AND (num <= MaxNoun)
  238.       THEN ImmediateLocation := N[num]^.location ELSE
  239.         IF (num >= First_creature) AND (num <= MaxCreature)
  240.         THEN ImmediateLocation := M[num]^.location ELSE
  241.           ImmediateLocation := 0;
  242.     END;                          {ImmediateLocation}
  243.  
  244.     FUNCTION OppositeDirection(Dir : Direction) : Direction;
  245.     VAR Ans : Direction;
  246.     BEGIN
  247.       Ans := NORTH;
  248.       IF Dir = NORTH THEN Ans := SOUTH ELSE
  249.         IF Dir = SOUTH THEN Ans := NORTH ELSE
  250.           IF Dir = EAST THEN Ans := WEST ELSE
  251.             IF Dir = WEST THEN Ans := EAST ELSE
  252.               IF Dir = northeast THEN Ans := southwest ELSE
  253.                 IF Dir = northwest THEN Ans := southeast ELSE
  254.                   IF Dir = southwest THEN Ans := northeast ELSE
  255.                     IF Dir = southeast THEN Ans := northwest ELSE
  256.                       IF Dir = up THEN Ans := down ELSE
  257.                         IF Dir = down THEN Ans := up ELSE
  258.                           IF Dir = enter THEN Ans := Exit ELSE
  259.                             IF Dir = Exit THEN Ans := enter;
  260.       OppositeDirection := Ans;
  261.     END;                          {OppositeDirection}
  262.  
  263.   BEGIN                           {PERFORM_Special_CMDS}
  264.     i := Verb_Number(TempVerb);
  265.     IF NameNum <> 0
  266.     THEN BEGIN
  267.       i := NameNum;               {use Name as sort key}
  268.       NameNum := TempNameNum;     {Restore NameNum to correct creature number}
  269.     END;
  270.     Diag_Mode := Flag[0];         {can be turned on and off by entering commands}
  271.     IF Diag_Mode THEN BEGIN
  272.       WriteLn(IO, 'For  Verb"', TempVerb, '"  Noun "', TempNoun, '"  Object "',
  273.               TempObject, '"');
  274.       WriteLn(IO, 'For  Verb# or Name#=', i, '  Noun#=', NounNumber, '  Object#=',
  275.               ObjectNumber);
  276.     END;
  277.     Last := EndingIndex[i];       {last in range of Special commands to perform}
  278.     CMDnum := StartingIndex[i]-1;
  279.     IF Diag_Mode THEN WriteLn(IO, 'Verb#= ', i, '  StartIndex= ', StartingIndex[i], ' EndIndex= ',
  280.                               EndingIndex[i]);
  281.     IF Last < 0 THEN GOTO Leave;  {exit if no Special CMDs for this verb}
  282.     IF CMDnum > Last_CMD THEN CMDnum := Last_CMD; {Restrict CMDnum to 0..Last_CMD}
  283.     IF CMDnum < 0 THEN CMDnum := 0;
  284.     REPEAT                        {Until CMDnum = Last}
  285.       CMDnum := CMDnum+1;
  286.       i := SpecialCMD[CMDnum]^.VerbNum; {get verb number for this CMD}
  287.       {if i >= 2000 then this command is just data for prior command}
  288.       CMDverb := SpecialCMD[CMDnum]^.VerbCMD; {get verb for this CMD}
  289.       CMDnoun := SpecialCMD[CMDnum]^.NounCMD; {get noun for this CMD}
  290.       CMDobject := SpecialCMD[CMDnum]^.ObjectCMD; {get object for this CMD}
  291.       IF (((TempVerb = CMDverb) OR (CMDverb = 'ANY')) AND
  292.           ((TempNoun = CMDnoun) OR (CMDnoun = 'ANY')) AND
  293.           ((TempObject = CMDobject) OR (CMDobject = 'ANY')) AND (i < 2000)) THEN
  294.         BEGIN                     {OK to execute this Special CMD}
  295.           IF Diag_Mode THEN
  296.             BEGIN
  297.               WriteLn(IO, ' ');
  298.               WriteLn(IO, 'Considering CMD #', CMDnum, ' ', CMDverb, ' ', CMDnoun, ' ', CMDobject);
  299.             END;
  300.           J := 1;                 {index into SpecialCMD.data array}
  301.           Condition := True;
  302.           OR_Condition := False;
  303.           Doing_OR := False;
  304.           WHILE Condition DO
  305.             BEGIN
  306.               loc1 := SpecialCMD[CMDnum]^.Data[J]; {token number}
  307.               CurrentToken := Token(SpecialCMD[CMDnum]^.Data[J]);
  308.               IF CurrentToken = LogicalNOT THEN
  309.                 BEGIN
  310.                   ReverseCondition := True;
  311.                   IF Diag_Mode THEN Write(IO, 'NOT ');
  312.                   J := J+1;
  313.                   loc1 := SpecialCMD[CMDnum]^.Data[J]; {token number}
  314.                   CurrentToken := Token(SpecialCMD[CMDnum]^.Data[J]);
  315.                 END
  316.               ELSE ReverseCondition := False;
  317.               loc2 := P[CurrentToken]; {number of parameters}
  318.               IF loc2 > 0 THEN
  319.                 num1 := SpecialCMD[CMDnum]^.Data[J+1]; {get first parameter}
  320.               IF loc2 > 1 THEN
  321.                 num2 := SpecialCMD[CMDnum]^.Data[J+2]; {get second parameter}
  322.               {may not use these -- but it saves code to get them here}
  323.               IF Diag_Mode THEN
  324.                 BEGIN
  325.                   Write(IO, 'Token #', loc1, ' ', loc2, ' parameters ');
  326.                   IF (loc2 > 0) THEN Write(IO, num1, ' ');
  327.                   IF (loc2 > 1) THEN Write(IO, num2, ' ');
  328.                   WriteLn(IO, ' ');
  329.                 END;
  330.               CASE CurrentToken OF
  331.                 {**************************************}
  332.                 {*  C O N D I T I O N    T O K E N S  *}
  333.                 {**************************************}
  334.                 VerbIsDirection {none} {Global Verb (NOT "ANY") is direction}
  335.                 : Condition := Is_Direction(verb);
  336.                 NounIsCreature    {TRUE if noun is a creature}
  337.                 : Condition := Is_Creature(noun);
  338.                 ObjectIsCreature  {TRUE if object is a creature}
  339.                 : Condition := Is_Creature(object_word);
  340.                 ObjectPresent     {TRUE if object is present in room}
  341.                 : Condition := (Is_Visible(ObjectNumber));
  342.                 AtLocation {loc#} {Player is located at room loc#}
  343.                 : Condition := (Current_room = num1);
  344.                 AtLocationGT {loc#} {In room greater than loc#}
  345.                 : Condition := (Current_room > num1);
  346.                 AtLocationLT {loc#} {In room less than loc#}
  347.                 : Condition := (Current_room < num1);
  348.                 FirstVisitToRoom {None} {Player is in current room for first time}
  349.                 : Condition := FirstVisitFlag;
  350.                 NewLife {None}    {Player is starting game or has just been resurrected}
  351.                 : Condition := NewLifeFlag;
  352.                 IsCarryingSomething {None} {Player is carrying something}
  353.                 : Condition := (Items_Being_Carried > 0);
  354.                 IsCarryingNothing {None} {Player is carrying nothing}
  355.                 : Condition := (Items_Being_Carried < 1);
  356.                 IsCarryingTreasure {PTS#} {Player is carrying something}
  357.                 {worth at least PTS#}
  358.                 : BEGIN
  359.                     Condition := False;
  360.                     FOR num2 := First_noun TO MaxNoun DO
  361.                       IF (ImmediateLocation(num2) = Player) AND (N[num2]^.points >= num1)
  362.                       THEN Condition := True;
  363.                   END;
  364.                 IsWearingSomething {None} {Player is wearing something}
  365.                 : Condition := (Items_Being_Worn > 0);
  366.                 IsWearingNothing {None} {Player is wearing nothing}
  367.                 : Condition := (Items_Being_Worn < 1);
  368.                 LoadWeightEquals {num#} {Load weighs equals}
  369.                 : Condition := (Load_Weight = num1);
  370.                 LoadWeightGT {num#} {Load weighs more than num#}
  371.                 : Condition := (Load_Weight > num1);
  372.                 LoadWeightLT {num#} {Load weighs less than num#}
  373.                 : Condition := (Load_Weight < num1);
  374.                 Present {ITEM#}   {ITEM is in room, carried or worn}
  375.                 : Condition := (Is_Visible(num1));
  376.                 IsWearing {ITEM#} {ITEM is being worn}
  377.                 : Condition := (location(num1) = Wearing);
  378.                 IsCarrying {ITEM#} {ITEM is being carried}
  379.                 : Condition := (location(num1) = Player);
  380.                 IsNowhere {ITEM#} {ITEM is located NOWHERE (room 0)}
  381.                 : Condition := (location(num1) = Nowhere);
  382.                 IsSomewhere {ITEM#} {ITEM is located somewhere}
  383.                 : Condition := NOT(location(num1) = Nowhere);
  384.                 InRoom {ITEM#}    {ITEM is located in current room}
  385.                 : Condition := (location(num1) = Current_room);
  386.                 IsLocated {ITEM# loc#} {ITEM# is located in room loc#}
  387.                 : Condition := (ImmediateLocation(num1) = num2);
  388.                 Together {ITEM# ITEM#} {ITEM# and ITEM# are in same room}
  389.                 : Condition := (location(num1) = location(num2));
  390.                 IsON {ITEM#}      {ITEM is ON}
  391.                 : Condition := N[num1]^.on;
  392.                 IsOFF {ITEM#}     {ITEM is OFF}
  393.                 : Condition := NOT N[num1]^.on;
  394.                 IsGroupMember {ITEM#} {ITEM is a member of the group}
  395.                 : Condition := M[num1]^.groupmember;
  396.                 IsOpen {ITEM#}    {ITEM is Open}
  397.                 : Condition := N[num1]^.open;
  398.                 IsClosed {ITEM#}  {ITEM is Closed}
  399.                 : Condition := NOT N[num1]^.open;
  400.                 IsLocked {ITEM#}  {ITEM is Locked}
  401.                 : Condition := N[num1]^.locked;
  402.                 IsUnLocked {ITEM#} {ITEM is UnLocked}
  403.                 : Condition := NOT N[num1]^.locked;
  404.                 IsEdible {ITEM#}  {ITEM is Edible}
  405.                 : Condition := N[num1]^.edible;
  406.                 IsDrinkable {ITEM#} {ITEM is Drinkable}
  407.                 : Condition := N[num1]^.drinkable;
  408.                 IsPoisonous {ITEM#} {ITEM is Poisonous}
  409.                 : Condition := N[num1]^.poisonous;
  410.                 IsMovable {ITEM#} {ITEM is Movable}
  411.                 : Condition := N[num1]^.movable;
  412.                 NOUNPresent {none} {NOUN is in room, carried or worn}
  413.                 : Condition := (Is_Visible(NounNumber));
  414.                 NOUNIsWearing {none} {NOUN is being worn}
  415.                 : Condition := (location(NounNumber) = Wearing);
  416.                 NOUNIsCarrying {none} {NOUN is being carried}
  417.                 : Condition := (location(NounNumber) = Player);
  418.                 NOUNIsNowhere {none} {NOUN ITEM is located NOWHERE (room 0)}
  419.                 : Condition := (location(NounNumber) = Nowhere);
  420.                 NOUNIsSomewhere {none} {NOUN ITEM is located somewhere}
  421.                 : Condition := NOT(location(NounNumber) = Nowhere);
  422.                 NOUNInRoom {none} {NOUN ITEM is located in current room}
  423.                 : Condition := (location(NounNumber) = Current_room);
  424.                 NOUNIsLocated {loc#} {NOUN ITEM is located in room loc#}
  425.                 : Condition := (ImmediateLocation(NounNumber) = num1);
  426.                 NOUNIsON {none}   {NOUN ITEM is ON}
  427.                 : Condition := N[NounNumber]^.on;
  428.                 NOUNIsOFF {none}  {NOUN ITEM is OFF}
  429.                 : Condition := NOT N[NounNumber]^.on;
  430.                 NOUNIsOpen {none} {NOUN ITEM is Open}
  431.                 : Condition := N[NounNumber]^.open;
  432.                 NOUNIsClosed {none} {NOUN ITEM is Closed}
  433.                 : Condition := NOT N[NounNumber]^.open;
  434.                 NOUNIsLocked {none} {NOUN ITEM is Locked}
  435.                 : Condition := N[NounNumber]^.locked;
  436.                 NOUNIsUnLocked {none} {NOUN ITEM is UnLocked}
  437.                 : Condition := NOT N[NounNumber]^.locked;
  438.                 NOUNIsEdible {none} {NOUN ITEM is Edible}
  439.                 : Condition := N[NounNumber]^.edible;
  440.                 NOUNIsDrinkable {none} {NOUN ITEM is Drinkable}
  441.                 : Condition := N[NounNumber]^.drinkable;
  442.                 NOUNIsPoisonous {none} {NOUN ITEM is Poisonous}
  443.                 : Condition := N[NounNumber]^.poisonous;
  444.                 NOUNIsMovable {none} {NOUN ITEM is Movable}
  445.                 : Condition := N[NounNumber]^.movable;
  446.                 NOUNpointsEquals {num#} {NOUN points equal num#}
  447.                 : Condition := (N[NounNumber]^.points = num1);
  448.                 NOUNpointsGT {num#} {NOUN points are greater than num#}
  449.                 : Condition := (N[NounNumber]^.points > num1);
  450.                 NOUNpointsLT {num#} {NOUN points are less than num#}
  451.                 : Condition := (N[NounNumber]^.points < num1);
  452.                 NOUNweightEquals {num#} {NOUN weight equals num#}
  453.                 : Condition := (N[NounNumber]^.weight = num1);
  454.                 NOUNweightGT {num#} {NOUN weight is greater than num#}
  455.                 : Condition := (N[NounNumber]^.weight > num1);
  456.                 NOUNweightLT {num#} {NOUN weight is less than num#}
  457.                 : Condition := (N[NounNumber]^.weight < num1);
  458.                 LightPresent {none} {Room has necessary light}
  459.                 : Condition := LightIsHere;
  460.                 RoomNeedsLight {none} {Current room needs a light}
  461.                 : Condition := (Room[Current_room]^.light > 0);
  462.                 FlagON {flag#}    {Flag# is ON}
  463.                 : Condition := Flag[num1];
  464.                 FlagOFF {flag#}   {Flag# is OFF}
  465.                 : Condition := NOT Flag[num1];
  466.                 ScoreEquals {num} {current score is equal to num}
  467.                 : Condition := (ScoreValue = num1);
  468.                 ScoreGT {num}     {score is greater than num}
  469.                 : Condition := (ScoreValue > num1);
  470.                 ScoreLT {num}     {score is less than num}
  471.                 : Condition := (ScoreValue < num1);
  472.                 NumberEquals {num} {input number is equal to num}
  473.                 : Condition := (NumberInput = num1);
  474.                 NumberGT {num}    {number is greater than num}
  475.                 : Condition := (NumberInput > num1);
  476.                 NumberLT {num}    {number is less than num}
  477.                 : Condition := (NumberInput < num1);
  478.                 AnswerIsCorrect {num} {last answer was correct}
  479.                 : Condition := QuestionStatus;
  480.                 AnswerIsWrong {num} {last answer was wrong}
  481.                 : Condition := NOT QuestionStatus;
  482.                 TurnsEquals {num} {Turns score is equal to num}
  483.                 : Condition := (Num_turns = num1);
  484.                 TurnsGT {num}     {Turns is greater than num}
  485.                 : Condition := (Num_turns > num1);
  486.                 TurnsLT {num}     {Turns is less than num}
  487.                 : Condition := (Num_turns < num1);
  488.                 CounterEquals {ctr# num} {Counter # is equal to num}
  489.                 : Condition := (counter[num1] = num2);
  490.                 CounterGT {ctr# num} {Counter # is greater than num}
  491.                 : Condition := (counter[num1] > num2);
  492.                 CounterLT {ctr# num} {Counter # is less than num}
  493.                 : Condition := (counter[num1] < num2);
  494.                 VariableEquals {var# num} {Variable # is equal to num}
  495.                 : Condition := (Variable[num1] = num2);
  496.                 VariableGT {var# num} {Variable # is greater than num}
  497.                 : Condition := (Variable[num1] > num2);
  498.                 VariableLT {var# num} {Variable # is less than num}
  499.                 : Condition := (Variable[num1] < num2);
  500.                 CompareVariables  {TRUE if V1 < V2 }
  501.                 : Condition := (Variable[num1] < Variable[num2]);
  502.                 VariableChance    {TRUE if V < Random(1..N)}
  503.                 : Condition := (Variable[num1] < Random(num2+1));
  504.                 NamePresent       {TRUE if Name being addressed is at location}
  505.                 : Condition := ((NameNum <> 0) AND (Is_Visible(NameNum)));
  506.                 NameIsNumber      {TRUE if Name being addressed is Number num1}
  507.                 : Condition := (NameNum = num1);
  508.                 NOUNIsNumber      {TRUE if NOUN is Number num}
  509.                 : Condition := (NounNumber = num1);
  510.                 ObjectIsNumber    {TRUE if Object is Number num}
  511.                 : Condition := (ObjectNumber = num1);
  512.                 SomethingInside   {TRUE if there is something inside Object Num}
  513.                 : Condition := (Things_Here(num1) > 0);
  514.                 Chance {percent}  {Odds are percent, i.e. 10 %}
  515.                 : Condition := (Random(100) < num1);
  516.                 PromptForYES {none} {Prompts for Y or N -- Ok if Yes}
  517.                 : Condition := (PromptYorN = 'Y');
  518.                 PromptForNO {none} {Prompts for Y or N -- Ok if No}
  519.                 : Condition := (PromptYorN = 'N');
  520.                 {**************************************}
  521.                 {*     A C T I O N    T O K E N S     *}
  522.                 {**************************************}
  523.                 {**************************************}
  524.                 {*  ******   W A R N I N G   *******  *}
  525.                 {*  Unless otherwised noted -- NONE   *}
  526.                 {*  of these actions are accompanied  *}
  527.                 {*  by any messages or condition      *}
  528.                 {*  checking --- the action is        *}
  529.                 {*  just taken without any 'fanfare'. *}
  530.                 {*  If you want a message of some kind*}
  531.                 {*  you must print it yourself.       *}
  532.                 {*  If you want to check on the       *}
  533.                 {*  feasiblity of the action, (e.g.,  *}
  534.                 {*  an ITEM is in the room you must   *}
  535.                 {*  check it yourself.                *}
  536.                 {**************************************}
  537.                 QuitThisCMD {none} {Quit evaluating this CMD}
  538.                 : Condition := False;
  539.                 QuitAllCMDs {none} {Finished with all special CMDs}
  540.                 : BEGIN
  541.                     Condition := False;
  542.                     CMDnum := Last; {will exit from procedure}
  543.                   END;
  544.                 DoneWithTurn {none} {All Done this turn -- get new input}
  545.                 : BEGIN
  546.                     Condition := False;
  547.                     CMDnum := Last; {will exit from procedure}
  548.                     DoNormalCMD := False; {will skip remainder of this turn}
  549.                   END;
  550.                 GoToRoom {loc#}   {Send player to loc#}
  551.                 : BEGIN
  552.                     MoveGroup(Current_room, num1); {move group}
  553.                     Current_room := num1;
  554.                   END;
  555.                 GoToRandomRoom {R1 R2} {Send player to Room >= R1 and <= R2}
  556.                 : BEGIN
  557.                     k := Current_room;
  558.                     REPEAT
  559.                       l := Random(num2-num1+1);
  560.                       k := num1+l;
  561.                     UNTIL k <> Current_room;
  562.                     {make sure Random Room is different than Current Room}
  563.                     MoveGroup(Current_room, k); {move group}
  564.                     Current_room := k;
  565.                   END;
  566.                 GetIt {ITEM#}     {ITEM# is now being carried}
  567.                 : MoveIt(num1, Player);
  568.                 WearIt {ITEM#}    {ITEM# is now being worn}
  569.                 : MoveIt(num1, Wearing);
  570.                 DropIt {ITEM#}    {Drops ITEM# into current room}
  571.                 : MoveIt(num1, Current_room);
  572.                 RemoveIt {ITEM#}  {Removes ITEM and drops into room}
  573.                 : MoveIt(num1, Current_room);
  574.                 GetNOUN {none}    {NOUN is now being carried}
  575.                 : MoveIt(NounNumber, Player);
  576.                 WearNOUN {none}   {NOUN is now being worn}
  577.                 : MoveIt(NounNumber, Wearing);
  578.                 DropNOUN {none}   {Drops NOUN into current room}
  579.                 : MoveIt(NounNumber, Current_room);
  580.                 RemoveNOUN {none} {Removes NOUN and drops into room}
  581.                 : MoveIt(NounNumber, Current_room);
  582.                 DropEverything {none} {Drop all items being carried}
  583.                 : FOR num1 := First_noun TO MaxNoun DO
  584.                     IF ImmediateLocation(num1) = Player
  585.                     THEN MoveIt(num1, Current_room);
  586.                 RemoveEverything {none} {Remove all items being worn}
  587.                 : FOR num1 := First_noun TO MaxNoun DO
  588.                     IF ImmediateLocation(num1) = Wearing
  589.                     THEN MoveIt(num1, Current_room);
  590.                 KillPlayer {none} {Makes player dead, exit and finish turn}
  591.                 : BEGIN
  592.                     player_dead := True;
  593.                     Condition := False;
  594.                     CMDnum := Last; {will exit from procedure}
  595.                     DoNormalCMD := False; {will skip remainder of this turn}
  596.                   END;
  597.                 PutInCurrentRoom {ITEM#} {Put ITEM# in current room}
  598.                 : MoveIt(num1, Current_room);
  599.                 SendToRoom {ITEM# loc#} {Put ITEM# in room loc#}
  600.                 : MoveIt(num1, num2);
  601.                 PutNOUNInCurrentRoom {none} {Put NOUN in current room}
  602.                 : MoveIt(NounNumber, Current_room);
  603.                 SendNOUNToRoom {loc#} {Put NOUN in room loc#}
  604.                 : MoveIt(NounNumber, num1);
  605.                 SendAllToRoom, {loc#} {Send all carried ITEMs to loc#}
  606.                 SendTreasuresToRoom {loc# pts#} {Send all carried ITEMs whose}
  607.                 {points > pts# to loc#}
  608.                 : BEGIN
  609.                     IF CurrentToken = SendAllToRoom
  610.                     THEN loc2 := -1
  611.                     ELSE loc2 := num2;
  612.                     FOR num2 := First_noun TO MaxNoun DO
  613.                       IF (ImmediateLocation(num2) = Player) AND (N[num2]^.points > loc2)
  614.                       THEN MoveIt(num2, num1);
  615.                   END;
  616.                 RelocateAll {loc1 loc2} {Move all items at loc1 to loc2}
  617.                 : FOR loc2 := First_noun TO MaxNoun DO
  618.                     IF ImmediateLocation(loc2) = num1
  619.                     THEN MoveIt(loc2, num2);
  620.                 Destroy {ITEM#}   {ITEM# is now NOWHERE (room 0)}
  621.                 : MoveIt(num1, Nowhere);
  622.                 DestroyNOUN {none} {NOUN is now NOWHERE (room 0)}
  623.                 : MoveIt(NounNumber, Nowhere);
  624.                 SwapLocations {ITEM1 ITEM2} {swap locations of ITEM1 & ITEM2}
  625.                 : BEGIN
  626.                     loc1 := ImmediateLocation(num1);
  627.                     loc2 := ImmediateLocation(num2);
  628.                     MoveIt(num1, loc2);
  629.                     MoveIt(num2, loc1);
  630.                   END;
  631.                 SendToItem {ITEM1 ITEM2} {Put ITEM1 in location of ITEM2}
  632.                 : BEGIN
  633.                     loc2 := ImmediateLocation(num2);
  634.                     MoveIt(num1, loc2);
  635.                   END;
  636.                 SendNOUNToItem {ITEM} {Put NOUN in location of ITEM}
  637.                 : BEGIN
  638.                     loc1 := ImmediateLocation(num1);
  639.                     MoveIt(NounNumber, loc1);
  640.                   END;
  641.                 AddToGroup {Itme#} {Add item# to group}
  642.                 : M[num1]^.groupmember := True;
  643.                 RemoveFromGroup {Itme#} {Remove item# from group}
  644.                 : M[num1]^.groupmember := False;
  645.                 MoveTheGroup {loc#} {Send group to loc#}
  646.                 : MoveGroup(Current_room, num1); {move group -- NOT the player}
  647.                 ReDirectTo        {Re-direct to another VERB-NOUN-OBJECT}
  648.                 : BEGIN
  649.                     TempNameNumber := NameNum;
  650.                     TempNounNumber := NounNumber;
  651.                     TempObjectNumber := ObjectNumber;
  652.                     CMDnum := CMDnum+1; {advance to next command to get data}
  653.                     i := SpecialCMD[CMDnum]^.VerbNum-2000;
  654.                     {get verb num being redirected to}
  655.                     TempVWord := SpecialCMD[CMDnum]^.VerbCMD; {get redirected verb}
  656.                     TempNWord := SpecialCMD[CMDnum]^.NounCMD; {get redirected noun}
  657.                     TempOWord := SpecialCMD[CMDnum]^.ObjectCMD; {get redirected object}
  658.                     {Now check for Verb being ReDirected to $VERB$, $NOUN$, OBJECT$, or $NAME$}
  659.                     IF TempVWord = 'VERB' THEN TempVWord := TempVerb
  660.                     ELSE IF TempVWord = 'NOUN' THEN TempVWord := TempNoun
  661.                     ELSE IF TempNWord = 'OBJECT' THEN
  662.                       BEGIN
  663.                         TempNWord := TempObject;
  664.                         TempNounNumber := ObjectNumber;
  665.                       END
  666.                     ELSE IF TempVWord = 'NAME' THEN
  667.                       BEGIN
  668.                         TempVWord := NameStr;
  669.                         Capitalize(TempVWord);
  670.                       END;
  671.                     {Now check for Noun being ReDirected to $VERB$, $NOUN$, OBJECT$, or $NAME$}
  672.                     IF TempNWord = 'VERB' THEN TempNWord := TempVerb
  673.                     ELSE IF TempNWord = 'NOUN' THEN TempNWord := TempNoun
  674.                     ELSE IF TempNWord = 'OBJECT' THEN TempNWord := TempObject
  675.                     ELSE IF TempNWord = 'NAME' THEN
  676.                       BEGIN
  677.                         TempNWord := NameStr;
  678.                         TempNounNumber := NameNum;
  679.                         Capitalize(TempNWord);
  680.                       END;
  681.                     {Now check for Object being ReDirected to $VERB$, $NOUN$, OBJECT$, or $NAME$}
  682.                     IF TempOWord = 'VERB' THEN TempOWord := TempVerb
  683.                     ELSE IF TempOWord = 'NOUN' THEN
  684.                       BEGIN
  685.                         TempOWord := TempNoun;
  686.                         TempObjectNumber := NounNumber;
  687.                       END
  688.                     ELSE IF TempOWord = 'OBJECT' THEN TempOWord := TempObject
  689.                     ELSE IF TempOWord = 'NAME' THEN
  690.                       BEGIN
  691.                         TempOWord := NameStr;
  692.                         TempObjectNumber := NameNum;
  693.                         Capitalize(TempOWord);
  694.                       END;
  695.                     TempVerb := TempVWord; {Finally do redirection}
  696.                     TempNoun := TempNWord;
  697.                     TempObject := TempOWord;
  698.                     NameNum := TempNameNumber; {Map various numbers also}
  699.                     NounNumber := TempNounNumber;
  700.                     ObjectNumber := TempObjectNumber;
  701.                     CMDnum := StartingIndex[i]-1; {new starting index}
  702.                     Last := EndingIndex[i]; {new ending index}
  703.                     IF Last < 0 THEN GOTO Leave; {exit if no Special CMDs for this verb}
  704.                     IF CMDnum > Last_CMD THEN CMDnum := Last_CMD; {Restrict CMDnum to 0..Last_CMD}
  705.                     IF CMDnum < 0 THEN CMDnum := 0;
  706.                     Condition := False; {finish processing this command}
  707.                     Doing_OR := False;
  708.                     IF Diag_Mode THEN
  709.                       BEGIN
  710.                         WriteLn(IO, 'Re-Directing to ', TempVerb, ' ', TempNoun, ' ', TempObject);
  711.                         WriteLn(IO, 'Verb# = ', i, '  Start = ', StartingIndex[i], '  End = ', Last);
  712.                       END;
  713.                   END;
  714.                 RandomMessage     {num1 num2}
  715.                 {Randomly select message between num1 and num2 and print it}
  716.                 : BEGIN
  717.                     num2 := Random(num2-num1+1);
  718.                     num1 := num1+num2;
  719.                     Describe_It('MESSAGE', num1);
  720.                   END;
  721.                 ShowContents      {Display list of things inside Object Num}
  722.                 : List_Contents(num1, 1);
  723.                 OpenIt {ITEM}     {ITEM# is now open}
  724.                 : N[num1]^.open := True;
  725.                 CloseIt {ITEM}    {ITEM# is now closed}
  726.                 : N[num1]^.open := False;
  727.                 LockIt {ITEM}     {ITEM# is now locked}
  728.                 : N[num1]^.locked := True;
  729.                 UnlockIt {ITEM}   {ITEM# is now unlocked}
  730.                 : N[num1]^.locked := False;
  731.                 OpenNOUN {none}   {NOUN is now open}
  732.                 : N[NounNumber]^.open := True;
  733.                 CloseNOUN {none}  {NOUN is now closed}
  734.                 : N[NounNumber]^.open := False;
  735.                 LockNOUN {none}   {NOUN is now locked}
  736.                 : N[NounNumber]^.locked := True;
  737.                 UnlockNOUN {none} {NOUN is now unlocked}
  738.                 : N[NounNumber]^.locked := False;
  739.                 ShowScore {none}  {Show current SCORE}
  740.                 : show_score;
  741.                 PlusScore {num}   {Add num to current SCORE}
  742.                 : ScoreAdjustment := ScoreAdjustment+num1;
  743.                 MinusScore {num}  {Subtract num from current SCORE}
  744.                 : ScoreAdjustment := ScoreAdjustment-num1;
  745.                 ShowInventory {none} {Show current INVENTORY}
  746.                 : Inventory;
  747.                 WaitForReturn {none} {Prints 'Hit RETURN' message}
  748.                 : Pause;
  749.                 TimePasses {none} {Show 'Time passes...' message}
  750.                 : Do_Nothing;
  751.                 xDelay {num}      {Delay for num seconds}
  752.                 : DELAY(1000*num1);
  753.                 CLEARSCREEN {none} {Clears screen}
  754.                 : BEGIN
  755.                     CLRSCR;
  756.                     morecount := 0;
  757.                   END;
  758.                 DescribeThing {num} {Describe thing num (whatever)}
  759.                 : BEGIN
  760.                     IF (num1 >= First_Room) AND (num1 <= MaxRoom)
  761.                     THEN Describe_It('ROOM_DESCR', num1);
  762.                     IF (num1 >= First_noun) AND (num1 <= MaxNoun)
  763.                     THEN Describe_It('NOUN_DESCR', num1);
  764.                     IF (num1 >= First_creature) AND (num1 <= MaxCreature)
  765.                     THEN Describe_It('CREATURE_DESCR', num1);
  766.                   END;
  767.                 LookAtRoom {none} {Cause a VERBOSE look at room}
  768.                 :
  769.                   BEGIN
  770.                     Room[Current_room]^.has_seen := False;
  771.                     Previous_room := -1;
  772.                     Describe_scene;
  773.                   END;
  774.                 WinGame {none}    {Player wins game at end of turn}
  775.                 : Room[Current_room]^.game_win := True;
  776.                 EndGame {none}    {game ends at end of turn}
  777.                 : Room[Current_room]^.game_end := True;
  778.                 PrintMessage {num} {Prints message num}
  779.                 : Describe_It('MESSAGE', num1);
  780.                 BlankLine {none}  {Prints Blank Line}
  781.                 : BEGIN
  782.                     WriteLn(IO, ' ');
  783.                     morecount := morecount+1;
  784.                   END;
  785.                 Tone {H M}        {makes a sound at H hertz for M milliseconds}
  786.                 : BEGIN
  787.                     Sound(num1);
  788.                     DELAY(num2);
  789.                     NoSound;
  790.                   END;
  791.                 GetNumberInput {num1 num2} {Get input num1 <= input <= num2}
  792.                 : BEGIN
  793.                     REPEAT
  794.                       NumOK := False;
  795.                       Write(IO, 'What number');
  796.                       IF num1 = num2
  797.                       THEN Write(IO, ' ? ')
  798.                       ELSE Write(IO, ' (from ', num1, ' to ', num2, ') ? ');
  799.                       st := GetInputString;
  800.                       TestNum := Value(st);
  801.                       IF num1 = num2
  802.                       THEN NumOK := True
  803.                       ELSE IF ((TestNum >= num1) AND (TestNum <= num2))
  804.                       THEN NumOK := True;
  805.                     UNTIL NumOK;
  806.                     NumberInput := TestNum;
  807.                   END;
  808.                 AskQuestion {num} {ask question num and set QuestionStatus}
  809.                 : BEGIN
  810.                     QuestionStatus := False;
  811.                     IF ((num1 <= MaxQuestion) AND (Question[num1] <> 'NONE')) THEN
  812.                       BEGIN
  813.                         REPEAT
  814.                           num2 := POS('  ', Answer[num1]);
  815.                           IF (num2 <> 0) THEN Delete(Answer[num1], num2, 1);
  816.                         UNTIL num2 = 0;
  817.                         Answer[num1] := ' '+Answer[num1]+' ';
  818.                         {add single leading and trailing blank}
  819.                         WHILE (POS(' ', Question[num1]) = 1) DO Delete(Question[num1], 1, 1);
  820.                         {strip off leading blanks in question}
  821.                         Write(IO, Question[num1]);
  822.                         st := GetInputString;
  823.                         st := ' '+st+' ';
  824.                         IF (Length(Answer[num1]) <= Length(st))
  825.                         THEN IF (POS(Answer[num1], st) <> 0)
  826.                           THEN QuestionStatus := True;
  827.                         IF (Length(Answer[num1]) >= Length(st))
  828.                         THEN IF (POS(st, Answer[num1]) <> 0)
  829.                           THEN QuestionStatus := True;
  830.                       END;
  831.                   END;
  832.                 TurnFlagON {flag#} {Turn Flag# ON}
  833.                 : IF num1 <= MaxFlag THEN Flag[num1] := True;
  834.                 TurnFlagOFF {flag#} {Turn Flag# OFF}
  835.                 : IF num1 <= MaxFlag THEN Flag[num1] := False;
  836.                 ToggleFlag {flag#} {Toggle Flag#}
  837.                 : IF num1 <= MaxFlag THEN
  838.                     IF Flag[num1]
  839.                     THEN Flag[num1] := False
  840.                     ELSE Flag[num1] := True;
  841.                 TurnCounterON {ctr#} {Turn counter# ON -- sets to 1}
  842.                 : IF num1 <= MaxCounter THEN counter[num1] := 1;
  843.                 TurnCounterOFF {ctr#} {Turn counter# OFF -- sets to 0}
  844.                 : IF num1 <= MaxCounter THEN counter[num1] := 0;
  845.                 SetVariableTo {var# num#} {Set Variable var# to num#}
  846.                 : IF num1 <= MaxVariable THEN Variable[num1] := num2;
  847.                 AddToVariable {var# num#} {Add num# to Variable var#}
  848.                 : IF num1 <= MaxVariable THEN Variable[num1] := Variable[num1]+num2;
  849.                 SubtractFromVariable {var# num#} {Subtract num# from Variable #}
  850.                 : IF num1 <= MaxVariable THEN Variable[num1] := Variable[num1]-num2;
  851.                 AddVariables {V1 V2} {Add V2 to V1 and put answer in V1}
  852.                 : Variable[num1] := Variable[num1]+Variable[num2];
  853.                 SubtractVariables {V1 V2} {Subtract V2 from V1 and put answer in V1}
  854.                 : Variable[num1] := Variable[num1]-Variable[num2];
  855.                 RandomVariable {V N} {Set variable V to random number [1 .. N]}
  856.                 : Variable[num1] := Random(num2+1);
  857.                 MakeVarRoomNum    {Var# -- will make Var# equal current room number}
  858.                 : Variable[num1] := Current_room;
  859.                 MakeVarNounNum    {Var# -- will make Var# equal current noun number}
  860.                 : Variable[num1] := NounNumber;
  861.                 MakeVarObjectNum  {Var# -- will make Var# equal object room number}
  862.                 : Variable[num1] := ObjectNumber;
  863.                 GoToVariableRoom  {Var# -- will send player to room number Var#}
  864.                 : BEGIN
  865.                     MoveGroup(Current_room, Variable[num1]); {move group}
  866.                     Current_room := Variable[num1];
  867.                   END;
  868.                 SendToVariableRoom {Item# Var# -- will send Item# to room number Var#}
  869.                 : MoveIt(num1, Variable[num2]);
  870.                 GetVariableIt     {Var# -- will get Var# item for player}
  871.                 : MoveIt(Variable[num1], Player);
  872.                 PrintVariableMessage {Var# -- will print message number Var#}
  873.                 : Describe_It('MESSAGE', Variable[num1]);
  874.                 NounToVariable {var#} {Convert Noun to Variable #}
  875.                 : BEGIN
  876.                     Val(TempNoun, num2, code);
  877.                     IF code <> 0 THEN num2 := 0; {If noun is not a number, set var# to 0}
  878.                     Variable[num1] := num2;
  879.                   END;
  880.                 ObjectToVariable {var#} {Convert Object to Variable #}
  881.                 : BEGIN
  882.                     Val(TempObject, num2, code);
  883.                     IF code <> 0 THEN num2 := 0; {If object is not a number, set var# to 0}
  884.                     Variable[num1] := num2;
  885.                   END;
  886.                 ChangePassageway {dir# loc#} {Creates or closes a passageway}
  887.                 {from current_room to loc# via dir#}
  888.                 {dir# = 1 = north ... 12 = exit}
  889.                 {If loc# = 0 then closes passage}
  890.                 : IF (num1 > 0) AND (num1 < 13) AND
  891.                   (((num2 >= First_Room) AND (num2 <= MaxRoom)) OR (num2 = 0))
  892.                   THEN BEGIN
  893.                     Dir := Direction(num1-1); {get requested direction}
  894.                     OpDir := OppositeDirection(Dir); {get its opposite}
  895.                     loc1 := Room[Current_room]^.Path[Dir]; {currently linked room}
  896.                     IF Diag_Mode THEN
  897.                       BEGIN
  898.                         WriteLn(IO, 'Direction   = ', Ord(Dir));
  899.                         WriteLn(IO, 'Opposite    = ', Ord(OpDir));
  900.                         WriteLn(IO, 'Target Room = ', num2);
  901.                         WriteLn(IO, 'Linked Room = ', loc1);
  902.                       END;
  903.                     IF num2 = 0
  904.                     THEN BEGIN    {Close passageway at both ends}
  905.                       Room[Current_room]^.Path[Dir] := 0; {Close passageway}
  906.                       IF (loc1 >= First_Room)
  907.                       THEN Room[loc1]^.Path[OpDir] := 0; {Close passageway}
  908.                     END
  909.                     ELSE BEGIN    {open passageway between rooms}
  910.                       Room[Current_room]^.Path[Dir] := num2; {open passage to num2}
  911.                       Room[num2]^.Path[OpDir] := Current_room; {open passage to current room}
  912.                     END;
  913.                   END;
  914.               ELSE                {token case}
  915.                 BEGIN
  916.                   num1 := SpecialCMD[CMDnum]^.Data[J];
  917.                   WriteLn(IO, 'ERROR: Illegal Token # ', num1, ' in CMD # ', CMDnum);
  918.                 END;
  919.               END;                {token case}
  920.               IF ReverseCondition THEN Condition := NOT Condition; {Apply NOT}
  921.               J := J+P[CurrentToken]+1; {skip past parameters for this token}
  922.               NextToken := Token(SpecialCMD[CMDnum]^.Data[J]);
  923.               IF (Doing_OR) THEN  {Some OR processing required}
  924.                 BEGIN
  925.                   Prior_Condition := (Condition AND Prior_Condition);
  926.                   Condition := True; {want to continue unless Action and OR_Cond=FALSE}
  927.                   IF (NextToken > LogicalOR) {i.e., an action} THEN
  928.                     BEGIN         {Action Token ends the OR clause}
  929.                       Condition := (OR_Condition OR Prior_Condition);
  930.                       Doing_OR := False;
  931.                       OR_Condition := False; {in case we have another series of OR's}
  932.                     END;
  933.                 END;              {Doing_OR}
  934.               IF (NextToken = LogicalOR) THEN
  935.                 BEGIN
  936.                   IF Diag_Mode THEN WriteLn(IO, 'OR');
  937.                   IF (Doing_OR)
  938.                   THEN OR_Condition := (OR_Condition OR Prior_Condition)
  939.                   ELSE OR_Condition := (OR_Condition OR Condition); {first OR}
  940.                   Doing_OR := True;
  941.                   Condition := True; {I.E., we want to continue regardless}
  942.                   Prior_Condition := True; {start with TRUE at each OR}
  943.                   J := J+1;       {want to skip by OR to get next real Token}
  944.                 END;              {NextToken = LogicalOR}
  945.             END;                  {WHILE Condition is TRUE}
  946.         END;                      {OF IF --- OK to execute this particular Special CMD}
  947.     UNTIL (CMDnum >= Last) OR (CMDnum >= MaxCommand); {REPEAT thru all Special CMD for Verb}
  948.  
  949. Leave: {Jumped to if no Special CMDs for this Verb}
  950.  
  951.   END;                            {PERFORM_Special_CMDS}
  952.  
  953.