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

  1.  
  2.   {SPCTOOLS.PA2 -- special GAGS tools}
  3.  
  4.   { Is_verb }
  5.   {Searches verb list via ascii name. }
  6.   {Returns TRUE if found and FALSE otherwise}
  7.   {NOTE: Synonyms have already been taken care of in PARSE}
  8.  
  9.   FUNCTION Is_Verb(w : words) : Boolean;
  10.  
  11.   VAR i : Integer;                {index to verbs array}
  12.     match : Boolean;
  13.   BEGIN
  14.     i := 0;                       {start with 'ANY'}
  15.     match := False;
  16.     REPEAT
  17.       match := (V[i] = w);
  18.       i := i+1;
  19.     UNTIL ((i > MaxVerb) OR (match)); {exits if match found}
  20.     IF NOT match THEN IF w = 'VERB' THEN match := True;
  21.     Is_Verb := match;
  22.   END;                            {Is_Verb}
  23.  
  24.   { Is_direction }
  25.   {Searches direction list via ascii name. }
  26.   {Returns TRUE if found and FALSE otherwise}
  27.  
  28.   FUNCTION Is_Direction(w : words) : Boolean;
  29.  
  30.   VAR i : Integer;
  31.     match : Boolean;
  32.   BEGIN
  33.     i := 1;
  34.     match := False;
  35.     REPEAT
  36.       match := (V[i] = w);
  37.       i := i+1;
  38.     UNTIL ((i > Num_Dirs) OR (match)); {exits if match found}
  39.     Is_Direction := match;
  40.   END;                            {Is_Verb}
  41.  
  42.   { Is_noun }
  43.   {Searches noun.name list via ascii name. }
  44.   {Also matches for valid synonyms to valid nouns.}
  45.   {Returns TRUE if found and FALSE otherwise. }
  46.   {Also Returns TRUE if word is number. }
  47.   FUNCTION Is_Noun(w : words) : Boolean;
  48.   VAR i, code : Integer;
  49.     match : Boolean;
  50.   BEGIN
  51.     Capitalize(w);
  52.     match := False;
  53.     Val(w, i, code);
  54.     IF code = 0 THEN match := True {If noun is a number, then OK noun}
  55.     ELSE BEGIN                    {not number -- so search list of nouns}
  56.       i := First_noun;
  57.       IF w <> '' THEN
  58.         WHILE (i <= MaxNoun) AND
  59.         (NOT match) DO
  60.           BEGIN
  61.             IF N[i]^.Has_Synonyms
  62.             THEN match := (POS(' '+w+' ', N[i]^.synonyms) <> 0)
  63.               {noun name also in synonym list}
  64.             ELSE match := (N[i]^.name = w);
  65.             i := i+1;
  66.           END;                    {exits if match found}
  67.       IF NOT match THEN
  68.         IF w = 'ALL' THEN match := True ELSE
  69.           IF w = 'EXITS' THEN match := True ELSE
  70.             IF w = 'DOORS' THEN match := True ELSE
  71.               IF w = 'GAME' THEN match := True ELSE
  72.                 IF w = 'IT' THEN match := True ELSE
  73.                   IF w = 'THEM' THEN match := True ELSE
  74.                     IF w = 'HIM' THEN match := True ELSE
  75.                       IF w = 'HER' THEN match := True ELSE
  76.                         IF w = 'VERB' THEN match := True ELSE
  77.                           IF w = 'NAME' THEN match := True ELSE
  78.                             IF w = 'NOUN' THEN match := True ELSE
  79.                               IF w = 'OBJECT' THEN match := True ELSE
  80.                                 IF w = 'ANY' THEN match := True ELSE
  81.                                   IF w = 'DOOR' THEN match := True;
  82.     END;                          {not number}
  83.     Is_Noun := match;
  84.   END;                            {Is_Noun}
  85.  
  86.   { Is_creature }
  87.   {Searches creature.name list via ascii name}
  88.   {Returns TRUE if found and FALSE otherwise.}
  89.  
  90.   FUNCTION Is_Creature(w : words) : Boolean;
  91.  
  92.   VAR i : Integer;                {index to creature array}
  93.     match : Boolean;
  94.   BEGIN
  95.     i := First_creature;
  96.     match := False;
  97.     IF w <> '' THEN
  98.       WHILE (i <= MaxCreature) AND
  99.       (NOT match) DO
  100.         BEGIN
  101.           IF M[i]^.Has_Synonyms
  102.           THEN match := (POS(' '+w+' ', M[i]^.synonyms) <> 0)
  103.             {creature name also in synonym list}
  104.           ELSE match := (M[i]^.name = w);
  105.           i := i+1;
  106.         END;
  107.     Is_Creature := match;
  108.   END;                            {Is_Creature}
  109.  
  110.   { Is_prep }
  111.   {Checks word against hard-coded list of preps.}
  112.   {Returns TRUE if found and FALSE otherwise. }
  113.  
  114.   FUNCTION Is_Prep(w : words) : Boolean;
  115.  
  116.   BEGIN
  117.     Is_Prep := ((w = 'IN')
  118.                 OR (w = 'ON')
  119.                 OR (w = 'OFF')
  120.                 OR (w = 'UP')
  121.                 OR (w = 'DOWN')
  122.                 OR (w = 'THRU')
  123.                 OR (w = 'THROUGH')
  124.                 OR (w = 'INSIDE')
  125.                 OR (w = 'NEAR')
  126.                 OR (w = 'BESIDE')
  127.                 OR (w = 'BY')
  128.                 OR (w = 'UNDER')
  129.                 OR (w = 'OVER')
  130.                 OR (w = 'ACROSS')
  131.                 OR (w = 'BEHIND')
  132.                 OR (w = 'ANY')
  133.                 OR (w = 'ABOUT')
  134.                 OR (w = 'AT')
  135.                 OR (w = 'FROM')
  136.                 OR (w = 'FOR')
  137.                 OR (w = 'WITH')
  138.                 OR (w = 'INTO')
  139.                 OR (w = 'TO'));
  140.   END;                            {Is_Prep}
  141.  
  142.  
  143.   { Function Verb_Number }
  144.   {Searches verb list via ascii name. }
  145.   {Returns number if found and 0 otherwise}
  146.  
  147.   FUNCTION Verb_Number(w : words) : Integer;
  148.  
  149.   VAR i : Integer;                {index to verbs array}
  150.     match : Boolean;
  151.   BEGIN
  152.     i := 0;
  153.     match := False;
  154.     REPEAT
  155.       match := (V[i] = w);
  156.       i := i+1;
  157.     UNTIL ((i > MaxVerb) OR (match)); {exits if match found}
  158.     IF match
  159.     THEN Verb_Number := i-1
  160.     ELSE Verb_Number := 0;
  161.   END;                            {Verb_Number}
  162.  
  163.   { Function Location }
  164.   {Given an integer, returns its ROOM location }
  165.   {unless it's in a closed noun. If it's inside }
  166.   {a closed noun, that noun's number is returned,}
  167.   {else the room number is returned. Basically, }
  168.   {returns the location at which it is visible. }
  169.  
  170.   FUNCTION location(num : Integer) : Integer;
  171.  
  172.   VAR i : Integer;
  173.   BEGIN
  174.     IF num = 0 THEN location := 0
  175.     ELSE
  176.       IF num <= MaxNoun
  177.       THEN
  178.         BEGIN
  179.           i := N[num]^.location;
  180.           IF (i > MaxRoom) AND (i <> Wearing)
  181.           THEN IF N[i]^.open
  182.             THEN i := location(i);
  183.           location := i;
  184.         END
  185.       ELSE
  186.         BEGIN
  187.           i := M[num]^.location;
  188.           IF (i > MaxRoom) AND (i <> Wearing)
  189.           THEN IF N[i]^.open
  190.             THEN i := location(i);
  191.           location := i;
  192.         END;
  193.   END;                            {fn.Location}
  194.  
  195.   { Function Is_Visible }
  196.   {Given a noun number, returns true if the noun}
  197.   {is present in the room and is not inside a }
  198.   {closed noun -- i.e. if it can be seen by the }
  199.   {player in his/her current location. }
  200.  
  201.   FUNCTION Is_Visible(num : Integer) : Boolean;
  202.  
  203.   VAR i : Integer;
  204.   BEGIN
  205.     i := location(num);
  206.     IF ((i = Current_room) OR (i = Player) OR (i = Wearing))
  207.     THEN Is_Visible := True
  208.     ELSE Is_Visible := False;
  209.   END;                            {fn.Is_Visible}
  210.  
  211.  
  212.   { Function Noun_Number }
  213.   {Given a string (of type words), checks to see }
  214.   {if it's a noun or a creature. If it is, returns}
  215.   {the integer value of that noun or creature; }
  216.   {else it returns the value 0. }
  217.  
  218.   {This function will work with nouns that have }
  219.   {the same names. It does this by matching on }
  220.   {the adjective (if one has been entered) as well}
  221.   {as the noun. This function also looks at where}
  222.   {the noun is, i.e., if only one of the nouns }
  223.   {(with the same name) is in the room, being }
  224.   {carried or being worn -- that is assumed to be }
  225.   {the correct noun. If there is more than one }
  226.   {noun (with the same name) present, then an }
  227.   {error message asks the player to repeat his }
  228.   {command and be more specific about which noun }
  229.   {is meant. }
  230.   {Also matches for valid synonyms to valid nouns.}
  231.  
  232.   FUNCTION Noun_Number(w : words) : Integer;
  233.  
  234.   VAR i, J, k, Answer, RightOne, LastOne : Integer;
  235.     NumWithRightAdj, NounWithAdj : Integer;
  236.     match, FoundIt, FoundRightOne : Boolean;
  237.     TempAdj : words;
  238.   BEGIN
  239.     {$V-} Capitalize(w); {$V+}
  240.     Duplicate := False;
  241.     FoundIt := False;
  242.     NumWithRightAdj := 0;
  243.     NounWithAdj := 0;
  244.     IF MaxCreature > MaxNoun
  245.     THEN LastOne := MaxCreature
  246.     ELSE LastOne := MaxNoun;
  247.     IF w = '' THEN
  248.       Answer := 0
  249.     ELSE
  250.       IF (w = noun) AND (NounNumber <> 0)
  251.       THEN Answer := NounNumber ELSE
  252.         IF (w = object_word) AND (ObjectNumber <> 0)
  253.         THEN Answer := ObjectNumber
  254.         ELSE BEGIN
  255.           {main routine}
  256.           i := First_noun-1;
  257.           FoundRightOne := False;
  258.           J := 0;                 {number of matches}
  259.           k := 0;                 {number of first match}
  260.           WHILE (i <= MaxNoun) AND
  261.           (NOT FoundRightOne) DO
  262.             BEGIN
  263.               i := i+1;
  264.               IF N[i]^.Has_Synonyms
  265.               THEN match := (POS(' '+w+' ', N[i]^.synonyms) <> 0) {noun name also in list}
  266.               ELSE match := (N[i]^.name = w);
  267.               IF match THEN
  268.                 BEGIN
  269.                   J := J+1;
  270.                   IF J = 1 THEN k := i;
  271.                   IF Adjective = N[i]^.adj THEN
  272.                     BEGIN
  273.                       FoundRightOne := True;
  274.                       k := i;
  275.                       NumWithRightAdj := NumWithRightAdj+1;
  276.                       NounWithAdj := i;
  277.                       IF Is_Visible(i) THEN J := 1;
  278.                       {This is it -- visible and right adjective}
  279.                     END;
  280.                 END;              {match}
  281.             END;                  {exits if match found}
  282.           IF ((NOT FoundRightOne) AND (MaxCreature > MaxNoun)) THEN
  283.             BEGIN
  284.               i := First_creature-1;
  285.               WHILE (i <= MaxCreature) AND
  286.               (NOT FoundRightOne) DO
  287.                 BEGIN
  288.                   i := i+1;
  289.                   IF M[i]^.Has_Synonyms
  290.                   THEN match := (POS(' '+w+' ', M[i]^.synonyms) <> 0)
  291.                     {creature name also in synonym list}
  292.                   ELSE match := (M[i]^.name = w);
  293.                   IF match THEN
  294.                     BEGIN
  295.                       J := J+1;
  296.                       IF J = 1 THEN k := i;
  297.                       IF Adjective = M[i]^.adj THEN
  298.                         BEGIN
  299.                           FoundRightOne := True;
  300.                           k := i;
  301.                           NumWithRightAdj := NumWithRightAdj+1;
  302.                           NounWithAdj := i;
  303.                           IF Is_Visible(i) THEN J := 1;
  304.                           {This is it -- visible and right adjective}
  305.                         END;
  306.                     END;          {match}
  307.                 END;
  308.             END;                  {NOT FoundRightOne}
  309.           Duplicate := (J > 1);   {j = number of matches -- duplicates if > 1}
  310.           i := k;                 {i = first (maybe only) match}
  311.           IF NumWithRightAdj = 1 THEN {only one with right adjective - it is it}
  312.             BEGIN
  313.               i := NounWithAdj;
  314.               Duplicate := False;
  315.               J := 1;
  316.             END;
  317.           IF (NOT Duplicate) THEN
  318.             IF J = 1
  319.             THEN Answer := i
  320.             ELSE Answer := 0;
  321.           IF Duplicate THEN
  322.             BEGIN
  323.               IF Is_Visible(i)    {i is first occurrance of name}
  324.               THEN BEGIN
  325.                 NumberInRoom := 1;
  326.                 DuplicatesInRoom[1].num := i;
  327.                 IF i <= MaxNoun
  328.                 THEN
  329.                   BEGIN
  330.                     DuplicatesInRoom[1].adj := N[i]^.adj;
  331.                     DuplicatesInRoom[1].name := N[i]^.name;
  332.                   END
  333.                 ELSE
  334.                   BEGIN
  335.                     DuplicatesInRoom[1].adj := M[i]^.adj;
  336.                     DuplicatesInRoom[1].name := M[i]^.name;
  337.                   END;
  338.               END                 {Is_Visible}
  339.               ELSE NumberInRoom := 0;
  340.               RightOne := i;      {to start with}
  341.               J := i;
  342.               REPEAT
  343.                 J := J+1;
  344.                 IF J <= MaxNoun
  345.                 THEN BEGIN        {noun}
  346.                   IF N[J]^.Has_Synonyms
  347.                   THEN match := (POS(' '+w+' ', N[J]^.synonyms) <> 0) {noun name also in list}
  348.                   ELSE match := (N[J]^.name = w);
  349.                   TempAdj := N[J]^.adj;
  350.                 END
  351.                 ELSE BEGIN        {creature}
  352.                   IF M[J]^.Has_Synonyms
  353.                   THEN match := (POS(' '+w+' ', M[J]^.synonyms) <> 0)
  354.                     {creature name also in synonym list}
  355.                   ELSE match := (M[J]^.name = w);
  356.                   TempAdj := M[J]^.adj;
  357.                 END;
  358.                 IF match AND (TempAdj = Adjective) {correct Adjective and match}
  359.                 THEN BEGIN
  360.                   FoundIt := True;
  361.                   RightOne := J;
  362.                 END;
  363.                 IF match AND (NOT FoundIt) AND Is_Visible(J) THEN
  364.                   BEGIN
  365.                     NumberInRoom := NumberInRoom+1;
  366.                     IF NumberInRoom <= MaxDupsInRoom THEN
  367.                       BEGIN
  368.                         DuplicatesInRoom[NumberInRoom].num := J;
  369.                         IF J <= MaxNoun
  370.                         THEN
  371.                           BEGIN
  372.                             DuplicatesInRoom[NumberInRoom].adj := N[J]^.adj;
  373.                             DuplicatesInRoom[NumberInRoom].name := N[J]^.name;
  374.                           END
  375.                         ELSE
  376.                           BEGIN
  377.                             DuplicatesInRoom[NumberInRoom].adj := M[J]^.adj;
  378.                             DuplicatesInRoom[NumberInRoom].name := M[J]^.name;
  379.                           END;
  380.                       END;
  381.                     RightOne := J;
  382.                   END;
  383.                 IF J = MaxNoun THEN J := Last_noun;
  384.               UNTIL ((J >= LastOne) OR FoundIt);
  385.               Answer := RightOne;
  386.               IF NumberInRoom < 2 THEN Duplicate := False;
  387.               IF FoundIt THEN Duplicate := False;
  388.             END;                  {IF Duplicate}
  389.         END;                      {main routine}
  390.     Noun_Number := Answer;
  391.   END;                            {Fn.Noun_Number}
  392.  
  393.  
  394.   { Function Creature_Number }
  395.   {Given a string (of type words), checks to see}
  396.   {if it's a creature. If it is, returns }
  397.   {the integer value of that creature; else }
  398.   {it returns the value 0. }
  399.  
  400.   FUNCTION Creature_Number(w : words) : Integer;
  401.  
  402.   VAR i : Integer;                {index to creature array}
  403.   BEGIN
  404.     i := Noun_Number(w);          {also handles duplicate names}
  405.     IF (i >= First_creature) AND (i <= MaxCreature)
  406.     THEN Creature_Number := i
  407.     ELSE Creature_Number := 0;
  408.   END;                            {Creature_Number}
  409.  
  410.   { Function Name }
  411.   {Given an integer, returns a lowercase string}
  412.   {corresponding to the name of the room, noun,}
  413.   {or creature that has that number. }
  414.  
  415.   FUNCTION name(num : Integer) : names;
  416.  
  417.   VAR st : names;
  418.   BEGIN
  419.     IF num < First_noun           {then it's a room}
  420.     THEN st := Room[num]^.name
  421.     ELSE
  422.       IF num < First_creature
  423.       THEN st := N[num]^.name
  424.       ELSE st := M[num]^.name;
  425.     Normalize(st);
  426.     name := st;
  427.   END;                            {fn.name}
  428.  
  429.  
  430.   { Room_Location }
  431.   {Returns room location where a noun number}
  432.   {if located }
  433.  
  434.   FUNCTION Room_Location(num : Integer) : Integer;
  435.  
  436.   BEGIN
  437.     IF (num >= First_noun) AND
  438.     (num <> Wearing) THEN         { avoids index overflow }
  439.       Room_Location := Room_Location(location(num))
  440.     ELSE
  441.       Room_Location := num;
  442.   END;
  443.  
  444.   {Load_Weight}
  445.  
  446.   FUNCTION Load_Weight : Integer;
  447.  
  448.   VAR i, lw : Integer;
  449.   BEGIN
  450.     lw := 0;
  451.     FOR i := First_noun TO MaxNoun DO
  452.       IF Room_Location(i) = Player THEN { consider adding Wearing to total? }
  453.         lw := lw+N[i]^.weight;
  454.     Load_Weight := lw;
  455.   END;
  456.  
  457.   {Load_Size}
  458.  
  459.   FUNCTION Load_Size : Integer;
  460.  
  461.   VAR i, ls : Integer;
  462.   BEGIN
  463.     ls := 0;
  464.     FOR i := First_noun TO MaxNoun DO
  465.       IF Room_Location(i) = Player THEN ls := ls+N[i]^.size;
  466.     Load_Size := ls;
  467.   END;
  468.  
  469.  
  470.   { Adjust_Count }
  471.   {Adjusts count of number items at PLACE}
  472.   {by added INCREMENT. }
  473.  
  474.   PROCEDURE Adjust_Count(PLACE, INCREMENT : Integer);
  475.  
  476.   BEGIN
  477.     IF PLACE = Wearing THEN Items_Being_Worn := Items_Being_Worn+INCREMENT;
  478.     IF PLACE = Player THEN Items_Being_Carried := Items_Being_Carried+INCREMENT;
  479.     IF (PLACE >= First_Room) AND (PLACE <= MaxRoom)
  480.     THEN Room[PLACE]^.nouns_inside := Room[PLACE]^.nouns_inside+INCREMENT;
  481.     IF (PLACE >= First_noun) AND (PLACE <= MaxNoun)
  482.     THEN N[PLACE]^.nouns_inside := N[PLACE]^.nouns_inside+INCREMENT;
  483.     IF (PLACE >= First_creature) AND (PLACE <= MaxCreature)
  484.     THEN M[PLACE]^.nouns_inside := M[PLACE]^.nouns_inside+INCREMENT;
  485.   END;                            {Adjust_Count}
  486.  
  487.  
  488.  
  489.   { Things_Here }
  490.   {Returns count of number items at PLACE}
  491.  
  492.   FUNCTION Things_Here(PLACE : Integer) : Integer;
  493.  
  494.   BEGIN
  495.     IF PLACE = Wearing THEN
  496.       Things_Here := Items_Being_Worn
  497.     ELSE IF PLACE = Player THEN
  498.       Things_Here := Items_Being_Carried
  499.     ELSE IF (PLACE >= First_Room) AND (PLACE <= MaxRoom) THEN
  500.       Things_Here := Room[PLACE]^.nouns_inside
  501.     ELSE IF (PLACE >= First_noun) AND (PLACE <= MaxNoun) THEN
  502.       Things_Here := N[PLACE]^.nouns_inside
  503.     ELSE IF (PLACE >= First_creature) AND (PLACE <= MaxCreature) THEN
  504.       Things_Here := M[PLACE]^.nouns_inside
  505.     ELSE
  506.       Things_Here := 0;
  507.   END;                            {Things_Here}
  508.  
  509.   { Things_Adjective }
  510.   {Returns adj for noun or creature}
  511.  
  512.   FUNCTION Things_Adjective(num : Integer) : words;
  513.  
  514.   VAR Answer : words;
  515.   BEGIN
  516.     IF (num >= First_noun) AND (num <= MaxNoun)
  517.     THEN Answer := N[num]^.adj
  518.     ELSE IF (num >= First_creature) AND (num <= MaxCreature)
  519.     THEN Answer := M[num]^.adj
  520.     ELSE Answer := ' ';
  521.     Normalize(Answer);
  522.     IF Answer = ' '
  523.     THEN Things_Adjective := ''
  524.     ELSE Things_Adjective := Answer;
  525.   END;
  526.  
  527.   { Consume }
  528.   {Eat or drink, and checks for poison}
  529.   {Only cause food or drink to disappear if it is movable.}
  530.   {Allows player to drink from lake without having the water disappear}
  531.   {(if and only if the lake had been specified as unmovable.)}
  532.  
  533.   PROCEDURE Consume(noun : words);
  534.  
  535.   VAR n_num : Integer;
  536.     sentence : s;
  537.   BEGIN
  538.     WriteLn(IO, 'The ', noun,
  539.             ' slides down your throat, and your stomach quickly is full.');
  540.     sentence := noun; Capitalize(sentence); noun := sentence;
  541.     n_num := Noun_Number(noun);
  542.     IF N[n_num]^.movable THEN N[n_num]^.location := Nowhere;
  543.     {Only cause food or drink to disappear if it is movable.}
  544.     {Allows player to drink from lake without having the water disappear}
  545.     {(if and only if the lake had been specified as unmovable.)}
  546.     IF N[n_num]^.poisonous
  547.     THEN
  548.       BEGIN
  549.         WriteLn(IO, 'After only a moment, you begin to sense a bitter taste,');
  550.         WriteLn(IO, 'and your vision blurs. In only seconds, you slip to your');
  551.         WriteLn(IO, 'knees and your throat closes. You gasp unsuccessfully');
  552.         WriteLn(IO, 'for air.');
  553.         player_dead := True;
  554.       END;
  555.   END;
  556.  
  557.