Manipulating the Parser - Part 2 - Addressing Actors
Built on 'Manipulating the Parser - Part 1' we now will add support for addressing other actors in the game, usually in the form of giving them commands, like 'troll, put the axe on the ground'
Since the built-in parser only splits an input into 3 different parts in a Said() string (Ex: 'put the axe on the ground' would create a Said() string of 'put/axe/ground') it does give us enough to direct the command at an actor/individual (in our case, the troll)
Quick solution run-down:
Using our 'preprocessing' functionality on the user input from Part 1, we will check the input string & see if an actor is the first token. If it is, we will set the actor variable & strip it from the input string, allowing the parser to handle the rest. Then we can put in some additional smarts at the time we evaluate the input & direct it to the actor in question. If no actor is referenced we will default the actor to the 'player'.
- 1. Create a new text resource file & put all the actors of the game in it
Examples: graham, troll, thief, grue
- 2. In the game.sh file, define a new constant ACTORS_TEXT and assign it the number corresponding to your text resource file above. Then create a constant for each actor, corresponding to it's location in the text resource. Example:
... (define COMPLEXNOUN_TEXT 0) // Text.000 - from Part 1 (define ACTORS_TEXT 1) // Text.001 (define ACTOR_PLAYER 0) // Actor in position 0 of the actors text resource (Text.001) (define ACTOR_TROLL 1) // Actor in position 1 of the actors text resource (Text.001) (define ACTOR_THIEF 2) // Actor in position 2 of the actors text resource (Text.001) (define ACTOR_GRUE 3) // Actor in position 3 of the actors text resource (Text.001)
- 3. Add a new global variable 'gActor' in the Main.sc file (in the 'local' section with the other 'g' variables). Compile it.
- 4. Modify the ManipulateParse.sc file that you created in Part 1, adding the do/while loop for the actor handling
(procedure public (manipulateParse inputStr pEvent) (var i, complexNounFull, complexNounStripped, actor, newInputStr) // add the actor variable /* do/while loop for handling the complex nouns is here... */ // Determine the actor = gActor ACTOR_PLAYER // set the default actor to the player in case user did not specify an actor at the beginning of the input = i 0 (do GetFarText( ACTORS_TEXT i @actor) (if (containsStr(newInputStr @actor STARTS_WITH)) = gActor i // Strip out of the actor name from the input string findAndReplace(newInputStr newInputStr @actor "") // Strip any leading commas findAndReplace(newInputStr newInputStr "," "" STARTS_WITH) ) ++i ) while ( > StrLen(@actor) 0) /* Parse command is here, at bottom of manipulateParse procedure */
- 5. Don't forget to recompile the ManipulateParse.sc script. You can now use logic like this in your room scripts (or where-ever):
(if (== gActor ACTOR_PLAYER) (if(Said('dance') // User input: 'dance' // User input could also be: 'graham, dance' // User input could also be: 'graham dance' - the user can use the comma or omit it Print("You don't feel like dancing today...") ) (if(Said('take/basketofgoodies') // User input is 'take basket of goodies' Print("You pick up the goodie basket.") ) ) (if (== gActor ACTOR_TROLL) (if(Said('dance') // User input: 'troll, dance' or 'troll dance' Print("The troll dances a jig, then with a swift stroke of his axe, removes your head.") ) (if(Said('take/basketofgoodies') // Note that we can combine the actor logic with the 'complex' noun logic... Print("The troll picks up the goodie basket and swings it into your midsection, knocking the wind out of you.") ) ) // ...etc for each actor that needs handling
Special note, whenever you compile the main script, compile ALL scripts afterwards otherwise you might run into problems.