Here is the final result. I've moved (almost) all the logic out of the User.sc & Main.sc to keep it cleaner. I did find out the problem I was having earlier was due to the null-termination of the strings which totally fouled up my matching process.
1) Create a new text resource file & put the full text of the nouns to be handled there
Examples: basket of goodies, pieces of eight, pile of bodies
2) Add new nouns to the vocab.000 file according to what you put in the text resource, without any whitespace
Examples: basketofgoodies, piecesofeight, pileofbodies
3) In the game.sh file, define a new constant COMPLEXNOUN_TEXT and assign it the number corresponding
to your text resource file above
4) Add the following code into the User.sc script
(use "ComplexNoun") // add this near the top, we'll create this script in step 5
// Then find this code block below & insert the line for the 'handleComplexNoun' procedure call
(if( (self:getInput(pEvent)) and Parse(@inputStr pEvent))
handleComplexNoun(@inputStr pEvent)
(send pEvent:type(evSAID))
(self:said(pEvent))
)
5) Create a new script file called ComplexNoun.sc and include the following code
(include "sci.sh")
(include "game.sh")
/******************************************************************************/
(script 972) // This may need to be changed if this number is already in use
/******************************************************************************/
(use "main")
(local
findAndReplaceStr
)
(procedure public (handleComplexNoun inputStr pEvent)
(var i,complexNounFull[50], complexNounStripped[50])
= i 0
(do
GetFarText( COMPLEXNOUN_TEXT i @complexNounFull)
(if (containsStr(inputStr @complexNounFull))
findAndReplace(@complexNounFull " " "")
StrCpy(@complexNounStripped @findAndReplaceStr)
findAndReplace(inputStr @complexNounFull @complexNounStripped)
Parse(@findAndReplaceStr pEvent)
)
++i
) while ( > StrLen(@complexNounFull) 0)
)
(procedure public (findAndReplace sourceStr findStr replaceStr)
(var i, findStrIndex char )
StrCpy(@findAndReplaceStr "")
= findStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (<> StrAt(sourceStr i) StrAt(findStr findStrIndex) )
Format(char "%c" StrAt(sourceStr i))
StrCat(@findAndReplaceStr char)
= findStrIndex 0
) (else
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
// >= comparison to handle match at end of string (null terminator)
(if (>= findStrIndex StrLen(findStr))
StrCat(@findAndReplaceStr replaceStr)
= i (+ i (- findStrIndex 1))
= findStrIndex 0
) (else
Format(char "%c" StrAt(sourceStr i))
StrCat(@findAndReplaceStr char)
= findStrIndex 0
)
)
)
)
(procedure public (containsStr sourceStr findStr)
(var i, findStrIndex )
= findStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (== StrAt(sourceStr i) StrAt(findStr findStrIndex) )
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
(if (== findStrIndex (+ StrLen(findStr) 1))
return TRUE
) (else
= findStrIndex 0
)
)
)
return FALSE
)
6) Don't forget to recompile the User.sc script. You can now use logic like this in your room scripts (or whereever):
(if(Said('move/pileofbodies'))
Print("Probably better to just leave those poor souls alone."
)
(if(Said('eat/basketofgoodies'))
Print("You eat the basket of goodies, and promptly toss your cookies!")
)
(if(Said('take/piecesofeight'))
Print("You pick up the pieces of eight")
)