aboutsummaryrefslogtreecommitdiff
path: root/engines/hugo/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hugo/parser.cpp')
-rw-r--r--engines/hugo/parser.cpp799
1 files changed, 0 insertions, 799 deletions
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index d116dda5f3..0a4ca3a5a8 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -30,17 +30,11 @@
*
*/
-// parser.c - handles all keyboard/command input
-
#include "common/system.h"
-#include "common/keyboard.h"
-#include "hugo/game.h"
#include "hugo/hugo.h"
#include "hugo/parser.h"
-#include "hugo/global.h"
#include "hugo/file.h"
-#include "hugo/schedule.h"
#include "hugo/display.h"
#include "hugo/route.h"
#include "hugo/util.h"
@@ -205,395 +199,6 @@ void Parser::command(const char *format, ...) {
lineHandler();
}
-Parser_v1w::Parser_v1w(HugoEngine &vm) : Parser(vm) {
-}
-
-Parser_v1w::~Parser_v1w() {
-}
-
-// Test whether command line contains a verb allowed by this object.
-// If it does, and the object is near and passes the tests in the command
-// list then carry out the actions in the action list and return TRUE
-bool Parser_v1w::isObjectVerb(object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment);
-
- // First, find matching verb in cmd list
- uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
- if (cmdIndex == 0) // No commands for this obj
- return false;
-
- int i;
- for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
- if (isWordPresent(_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex])) // Was this verb used?
- break;
- }
-
- if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
- return false;
-
- // Verb match found. Check if object is Near
- char *verb = *_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex];
- if (!isNear(obj, verb, comment))
- return false;
-
- // Check all required objects are being carried
- cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd
- if (cmnd->reqIndex) { // At least 1 thing in list
- uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
- for (i = 0; reqs[i]; i++) { // for each obj
- if (!isCarrying(reqs[i])) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
- return true;
- }
- }
- }
-
- // Required objects are present, now check state is correct
- if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
- return true;
- }
-
- // Everything checked. Change the state and carry out any actions
- if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
- obj->state = cmnd->newState;
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
- _vm.scheduler().insertActionList(cmnd->actIndex);
-
- // See if any additional generic actions
- if ((verb == _vm._arrayVerbs[_vm._look][0]) || (verb == _vm._arrayVerbs[_vm._take][0]) || (verb == _vm._arrayVerbs[_vm._drop][0]))
- isGenericVerb(obj, comment);
- return true;
-}
-
-// Test whether command line contains one of the generic actions
-bool Parser_v1w::isGenericVerb(object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment);
-
- if (!obj->genericCmd)
- return false;
-
- // Following is equivalent to switch, but couldn't do one
- if (isWordPresent(_vm._arrayVerbs[_vm._look]) && isNear(obj, _vm._arrayVerbs[_vm._look][0], comment)) {
- // Test state-dependent look before general look
- if ((obj->genericCmd & LOOK_S) == LOOK_S) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[obj->stateDataIndex[obj->state]]);
- warning("isGenericVerb: use of state dependant look - To be validated");
- } else {
- if ((LOOK & obj->genericCmd) == LOOK) {
- if (_vm._textData[obj->dataIndex])
- Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
- else
- return false;
- } else {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual]);
- }
- }
- } else if (isWordPresent(_vm._arrayVerbs[_vm._take]) && isNear(obj, _vm._arrayVerbs[_vm._take][0], comment)) {
- if (obj->carriedFl)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
- else if ((TAKE & obj->genericCmd) == TAKE)
- takeObject(obj);
- else if (obj->cmdIndex != 0) // No comment if possible commands
- return false;
- else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context!
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
- else
- return false;
- } else if (isWordPresent(_vm._arrayVerbs[_vm._drop])) {
- if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
- else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
- dropObject(obj);
- else if (obj->cmdIndex == 0)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
- else
- return false;
- } else { // It was not a generic cmd
- return false;
- }
-
- return true;
-}
-
-// Test whether hero is close to object. Return TRUE or FALSE
-// If object not near, return suitable comment; may be another object close
-// If radius is -1, treat radius as infinity
-// Verb is included to determine correct comment if not near
-bool Parser_v1w::isNear(object_t *obj, char *verb, char *comment) {
- debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment);
-
- if (obj->carriedFl) // Object is being carried
- return true;
-
- if (obj->screenIndex != *_vm._screen_p) {
- // Not in same screen
- if (obj->objValue)
- strcpy(comment, _vm._textParser[kCmtAny1]);
- else
- strcpy(comment, _vm._textParser[kCmtAny2]);
- return false;
- }
-
- if (obj->cycling == INVISIBLE) {
- if (obj->seqNumb) {
- // There is an image
- strcpy(comment, _vm._textParser[kCmtAny3]);
- return false;
- } else {
- // No image, assume visible
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is not close enough
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny1]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- return false;
- }
- }
- }
-
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is not close enough
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny1]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- return false;
- }
- return true;
-}
-
-// Do all things necessary to carry an object
-void Parser_v1w::takeObject(object_t *obj) {
- debugC(1, kDebugParser, "takeObject(object_t *obj)");
-
- obj->carriedFl = true;
- if (obj->seqNumb) { // Don't change if no image to display
- obj->cycling = INVISIBLE;
- }
- _vm.adjustScore(obj->objValue);
-
- if (obj->seqNumb > 0) // If object has an image, force walk to dropped
- obj->viewx = -1; // (possibly moved) object next time taken!
- Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
-}
-
-// Do all necessary things to drop an object
-void Parser_v1w::dropObject(object_t *obj) {
- debugC(1, kDebugParser, "dropObject(object_t *obj)");
-
- obj->carriedFl = false;
- obj->screenIndex = *_vm._screen_p;
- if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1))
- obj->cycling = CYCLE_FORWARD;
- else
- obj->cycling = NOT_CYCLING;
- obj->x = _vm._hero->x - 1;
- obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
- obj->y = (obj->y + obj->currImagePtr->y2 < YPIX) ? obj->y : YPIX - obj->currImagePtr->y2 - 10;
- _vm.adjustScore(-obj->objValue);
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
-}
-
-// Search for matching verbs in background command list.
-// Noun is not required. Return TRUE if match found
-// Note that if the background command list has match set TRUE then do not
-// print text if there are any recognizable nouns in the command line
-bool Parser_v1w::isCatchallVerb(objectList_t obj) {
- debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)");
-
- for (int i = 0; obj[i].verbIndex != 0; i++) {
- if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 &&
- (!obj[i].matchFl || !findNoun()) &&
- ((obj[i].roomState == DONT_CARE) ||
- (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- _vm.scheduler().processBonus(obj[i].bonusIndex);
-
- // If this is LOOK (without a noun), show any takeable objects
- if (*(_vm._arrayVerbs[obj[i].verbIndex]) == _vm._arrayVerbs[_vm._look][0])
- showTakeables();
-
- return true;
- }
- }
- return false;
-}
-
-// Search for matching verb/noun pairs in background command list
-// Print text for possible background object. Return TRUE if match found
-bool Parser_v1w::isBackgroundWord(objectList_t obj) {
- debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)");
-
- for (int i = 0; obj[i].verbIndex != 0; i++) {
- if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) &&
- isWordPresent(_vm._arrayNouns[obj[i].nounIndex]) &&
- ((obj[i].roomState == DONT_CARE) ||
- (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- _vm.scheduler().processBonus(obj[i].bonusIndex);
- return true;
- }
- }
- return false;
-}
-
-// Parse the user's line of text input. Generate events as necessary
-void Parser_v1w::lineHandler() {
- debugC(1, kDebugParser, "lineHandler()");
-
- status_t &gameStatus = _vm.getGameStatus();
-
- // Toggle God Mode
- if (!strncmp(_line, "PPG", 3)) {
- _vm.sound().playSound(!_vm._soundTest, BOTH_CHANNELS, HIGH_PRI);
- gameStatus.godModeFl ^= 1;
- return;
- }
-
- Utils::strlwr(_line); // Convert to lower case
-
- // God Mode cheat commands:
- // goto <screen> Takes hero to named screen
- // fetch <object name> Hero carries named object
- // fetch all Hero carries all possible objects
- // find <object name> Takes hero to screen containing named object
- if (gameStatus.godModeFl) {
- // Special code to allow me to go straight to any screen
- if (strstr(_line, "goto")) {
- for (int i = 0; i < _vm._numScreens; i++) {
- if (!strcmp(&_line[strlen("goto") + 1], _vm._screenNames[i])) {
- _vm.scheduler().newScreen(i);
- return;
- }
- }
- }
-
- // Special code to allow me to get objects from anywhere
- if (strstr(_line, "fetch all")) {
- for (int i = 0; i < _vm._numObj; i++) {
- if (_vm._objects[i].genericCmd & TAKE)
- takeObject(&_vm._objects[i]);
- }
- return;
- }
-
- if (strstr(_line, "fetch")) {
- for (int i = 0; i < _vm._numObj; i++) {
- if (!strcmp(&_line[strlen("fetch") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
- takeObject(&_vm._objects[i]);
- return;
- }
- }
- }
-
- // Special code to allow me to goto objects
- if (strstr(_line, "find")) {
- for (int i = 0; i < _vm._numObj; i++) {
- if (!strcmp(&_line[strlen("find") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
- _vm.scheduler().newScreen(_vm._objects[i].screenIndex);
- return;
- }
- }
- }
- }
-
- // Special meta commands
- // EXIT/QUIT
- if (!strcmp("exit", _line) || strstr(_line, "quit")) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBExit]);
- return;
- }
-
- // SAVE/RESTORE
- if (!strcmp("save", _line) && gameStatus.viewState == V_PLAY) {
- _vm.file().saveGame(gameStatus.saveSlot, "Current game");
- return;
- }
-
- if (!strcmp("restore", _line) && (gameStatus.viewState == V_PLAY || gameStatus.viewState == V_IDLE)) {
- _vm.file().restoreGame(gameStatus.saveSlot);
- _vm.scheduler().restoreScreen(*_vm._screen_p);
- gameStatus.viewState = V_PLAY;
- return;
- }
-
- // Empty line
- if (*_line == '\0') // Empty line
- return;
- if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
- return;
-
- if (gameStatus.gameOverFl) {
- // No commands allowed!
- Utils::gameOverMsg();
- return;
- }
-
- char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
-
- // Test for nearby objects referenced explicitly
- for (int i = 0; i < _vm._numObj; i++) {
- object_t *obj = &_vm._objects[i];
- if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) {
- if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
- return;
- }
- }
-
- // Test for nearby objects that only require a verb
- // Note comment is unused if not near.
- for (int i = 0; i < _vm._numObj; i++) {
- object_t *obj = &_vm._objects[i];
- if (obj->verbOnlyFl) {
- char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
- if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
- return;
- }
- }
-
- // No objects match command line, try background and catchall commands
- if (isBackgroundWord(_vm._backgroundObjects[*_vm._screen_p]))
- return;
- if (isCatchallVerb(_vm._backgroundObjects[*_vm._screen_p]))
- return;
- if (isBackgroundWord(_vm._catchallList))
- return;
- if (isCatchallVerb(_vm._catchallList))
- return;
-
- // If a not-near comment was generated, print it
- if (*farComment != '\0') {
- Utils::Box(BOX_ANY, "%s", farComment);
- return;
- }
-
- // Nothing matches. Report recognition success to user.
- char *verb = findVerb();
- char *noun = findNoun();
- if (verb == _vm._arrayVerbs[_vm._look][0] && _maze.enabledFl) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
- showTakeables();
- } else if (verb && noun) { // A combination I didn't think of
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoPoint]);
- } else if (noun) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
- } else if (verb) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBVerb]);
- } else {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh]);
- }
-}
-
// Locate any member of object name list appearing in command line
bool Parser::isWordPresent(char **wordArr) {
debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
@@ -697,408 +302,4 @@ void Parser::showDosInventory() {
Utils::Box(BOX_ANY, "%s", buffer);
}
-Parser_v1d::Parser_v1d(HugoEngine &vm) : Parser(vm) {
-}
-
-Parser_v1d::~Parser_v1d() {
-}
-
-// Locate word in list of nouns and return ptr to string in noun list
-// If n is NULL, start at beginning of list, else with n
-char *Parser_v1d::findNextNoun(char *noun) {
- debugC(1, kDebugParser, "findNextNoun(%s)", noun);
-
- int currNounIndex = -1;
- if (noun) { // If noun not NULL, find index
- for (currNounIndex = 0; _vm._arrayNouns[currNounIndex]; currNounIndex++) {
- if (noun == _vm._arrayNouns[currNounIndex][0])
- break;
- }
- }
- for (int i = currNounIndex + 1; _vm._arrayNouns[i]; i++) {
- for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) {
- if (strstr(_line, _vm._arrayNouns[i][j]))
- return _vm._arrayNouns[i][0];
- }
- }
- return 0;
-}
-
-// Test whether hero is close to object. Return TRUE or FALSE
-// If no noun specified, check context flag in object before other tests.
-// If object not near, return suitable string; may be similar object closer
-// If radius is -1, treat radius as infinity
-bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isNear(%s, %s, obj, %s)", verb, noun, comment);
-
- if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive
- return false;
- } else if (noun && (noun != _vm._arrayNouns[obj->nounIndex][0])) { // Noun specified & not same as object
- return false;
- } else if (obj->carriedFl) { // Object is being carried
- return true;
- } else if (obj->screenIndex != *_vm._screen_p) { // Not in same screen
- if (obj->objValue)
- strcpy (comment, _vm._textParser[kCmtAny4]);
- return false;
- }
-
- if (obj->cycling == INVISIBLE) {
- if (obj->seqNumb) { // There is an image
- strcpy(comment, _vm._textParser[kCmtAny5]);
- return false;
- } else { // No image, assume visible
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is either not close enough (stationary, valueless objects)
- // or is not carrying it (small, portable objects of value)
- if (noun) { // Don't say unless object specified
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny4]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- }
- return false;
- }
- }
- }
-
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is either not close enough (stationary, valueless objects)
- // or is not carrying it (small, portable objects of value)
- if (noun) { // Don't say unless object specified
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny4]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- }
- return false;
- }
-
- return true;
-}
-
-// Test whether supplied verb is one of the common variety for this object
-// say_ok needed for special case of take/drop which may be handled not only
-// here but also in a cmd_list with a donestr string simultaneously
-bool Parser_v1d::isGenericVerb(char *word, object_t *obj) {
- debugC(1, kDebugParser, "isGenericVerb(%s, object_t *obj)", word);
-
- if (!obj->genericCmd)
- return false;
-
- // Following is equivalent to switch, but couldn't do one
- if (word == _vm._arrayVerbs[_vm._look][0]) {
- if ((LOOK & obj->genericCmd) == LOOK)
- Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
- else
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual_1d]);
- } else if (word == _vm._arrayVerbs[_vm._take][0]) {
- if (obj->carriedFl)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
- else if ((TAKE & obj->genericCmd) == TAKE)
- takeObject(obj);
- else if (!obj->verbOnlyFl) // Make sure not taking object in context!
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
- else
- return false;
- } else if (word == _vm._arrayVerbs[_vm._drop][0]) {
- if (!obj->carriedFl)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
- else if ((DROP & obj->genericCmd) == DROP)
- dropObject(obj);
- else
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
- } else { // It was not a generic cmd
- return false;
- }
-
- return true;
-}
-
-// Test whether supplied verb is included in the list of allowed verbs for
-// this object. If it is, then perform the tests on it from the cmd list
-// and if it passes, perform the actions in the action list. If the verb
-// is catered for, return TRUE
-bool Parser_v1d::isObjectVerb(char *word, object_t *obj) {
- debugC(1, kDebugParser, "isObjectVerb(%s, object_t *obj)", word);
-
- // First, find matching verb in cmd list
- uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
- if (!cmdIndex) // No commands for this obj
- return false;
-
- int i;
- for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
- if (!strcmp(word, _vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex][0])) // Is this verb catered for?
- break;
- }
-
- if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No
- return false;
-
- // Verb match found, check all required objects are being carried
- cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd
- if (cmnd->reqIndex) { // At least 1 thing in list
- uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
- for (i = 0; reqs[i]; i++) { // for each obj
- if (!isCarrying(reqs[i])) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
- return true;
- }
- }
- }
-
- // Required objects are present, now check state is correct
- if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)){
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
- return true;
- }
-
- // Everything checked. Change the state and carry out any actions
- if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
- obj->state = cmnd->newState;
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
- _vm.scheduler().insertActionList(cmnd->actIndex);
- // Special case if verb is Take or Drop. Assume additional generic actions
- if ((word == _vm._arrayVerbs[_vm._take][0]) || (word == _vm._arrayVerbs[_vm._drop][0]))
- isGenericVerb(word, obj);
- return true;
-}
-
-// Print text for possible background object. Return TRUE if match found
-// Only match if both verb and noun found. Test_ca will match verb-only
-bool Parser_v1d::isBackgroundWord(char *noun, char *verb, objectList_t obj) {
- debugC(1, kDebugParser, "isBackgroundWord(%s, %s, object_list_t obj)", noun, verb);
-
- if (!noun)
- return false;
-
- for (int i = 0; obj[i].verbIndex; i++) {
- if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && (noun == _vm._arrayNouns[obj[i].nounIndex][0])) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- return true;
- }
- }
- return false;
-}
-
-// Do all things necessary to carry an object
-void Parser_v1d::takeObject(object_t *obj) {
- debugC(1, kDebugParser, "takeObject(object_t *obj)");
-
- obj->carriedFl = true;
- if (obj->seqNumb) // Don't change if no image to display
- obj->cycling = ALMOST_INVISIBLE;
-
- _vm.adjustScore(obj->objValue);
-
- Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
-}
-
-// Do all necessary things to drop an object
-void Parser_v1d::dropObject(object_t *obj) {
- debugC(1, kDebugParser, "dropObject(object_t *obj)");
-
- obj->carriedFl = false;
- obj->screenIndex = *_vm._screen_p;
- if (obj->seqNumb) // Don't change if no image to display
- obj->cycling = NOT_CYCLING;
- obj->x = _vm._hero->x - 1;
- obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
- _vm.adjustScore(-obj->objValue);
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
-}
-
-// Print text for possible background object. Return TRUE if match found
-// If test_noun TRUE, must have a noun given
-bool Parser_v1d::isCatchallVerb(bool testNounFl, char *noun, char *verb, objectList_t obj) {
- debugC(1, kDebugParser, "isCatchallVerb(%d, %s, %s, object_list_t obj)", (testNounFl) ? 1 : 0, noun, verb);
-
- if (testNounFl && !noun)
- return false;
-
- for (int i = 0; obj[i].verbIndex; i++) {
- if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && ((noun == _vm._arrayNouns[obj[i].nounIndex][0]) || (obj[i].nounIndex == 0))) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- return true;
- }
- }
- return false;
-}
-
-// Parse the user's line of text input. Generate events as necessary
-void Parser_v1d::lineHandler() {
- debugC(1, kDebugParser, "lineHandler()");
-
- object_t *obj;
- status_t &gameStatus = _vm.getGameStatus();
- char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
-
-// Reset_prompt_line ();
- Utils::strlwr(_line); // Convert to lower case
-
- if (!strcmp("exit", _line) || strstr(_line, "quit")) {
- if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
- _vm.endGame();
- return;
- }
-
- // SAVE/RESTORE
- if (!strcmp("save", _line)) {
- if (gameStatus.gameOverFl)
- Utils::gameOverMsg();
- else
-// _vm.file().saveOrRestore(true);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (!strcmp("restore", _line)) {
-// _vm.file().saveOrRestore(false);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (*_line == '\0') // Empty line
- return;
-
- if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
- return;
-
- if (gameStatus.gameOverFl) { // No commands allowed!
- Utils::gameOverMsg();
- return;
- }
-
- // Find the first verb in the line
- char *verb = findVerb();
- char *noun = 0; // Noun not found yet
-
- if (verb) { // OK, verb found. Try to match with object
- do {
- noun = findNextNoun(noun); // Find a noun in the line
- // Must try at least once for objects allowing verb-context
- for (int i = 0; i < _vm._numObj; i++) {
- obj = &_vm._objects[i];
- if (isNear(verb, noun, obj, farComment)) {
- if (isObjectVerb(verb, obj) // Foreground object
- || isGenericVerb(verb, obj)) // Common action type
- return;
- }
- }
- if ((*farComment == '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
- return;
- } while (noun);
- }
- noun = findNextNoun(noun);
- if (*farComment != '\0') // An object matched but not near enough
- Utils::Box(BOX_ANY, "%s", farComment);
- else if (!isCatchallVerb(true, noun, verb, _vm._catchallList) &&
- !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p]) &&
- !isCatchallVerb(false, noun, verb, _vm._catchallList))
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_1d]);
-}
-
-Parser_v2d::Parser_v2d(HugoEngine &vm) : Parser_v1d(vm) {
-}
-
-Parser_v2d::~Parser_v2d() {
-}
-
-// Parse the user's line of text input. Generate events as necessary
-void Parser_v2d::lineHandler() {
- debugC(1, kDebugParser, "lineHandler()");
-
- object_t *obj;
- status_t &gameStatus = _vm.getGameStatus();
- char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
-
-// Reset_prompt_line ();
- Utils::strlwr(_line); // Convert to lower case
-
- if (!strcmp("exit", _line) || strstr(_line, "quit")) {
- if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
- _vm.endGame();
- else
- return;
- }
-
- // SAVE/RESTORE
- if (!strcmp("save", _line)) {
- _config.soundFl = false;
- if (gameStatus.gameOverFl)
- Utils::gameOverMsg();
- else
-// _vm.file().saveOrRestore(true);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (!strcmp("restore", _line)) {
- _config.soundFl = false;
-// _vm.file().saveOrRestore(false);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (!strlen(_line)) // Empty line
- return;
-
- if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
- return;
-
- if (gameStatus.gameOverFl) { // No commands allowed!
- Utils::gameOverMsg();
- return;
- }
-
- // Find the first verb in the line
- char *verb = findVerb();
- char *noun = 0; // Noun not found yet
-
- if (verb) { // OK, verb found. Try to match with object
- do {
- noun = findNextNoun(noun); // Find a noun in the line
- // Must try at least once for objects allowing verb-context
- for (int i = 0; i < _vm._numObj; i++) {
- obj = &_vm._objects[i];
- if (isNear(verb, noun, obj, farComment)) {
- if (isObjectVerb(verb, obj) // Foreground object
- || isGenericVerb(verb, obj)) // Common action type
- return;
- }
- }
- if ((*farComment != '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
- return;
- } while (noun);
- }
-
- noun = findNextNoun(noun);
- if ( !isCatchallVerb(true, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
- && !isCatchallVerb(true, noun, verb, _vm._catchallList)
- && !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
- && !isCatchallVerb(false, noun, verb, _vm._catchallList)) {
- if (*farComment != '\0') { // An object matched but not near enough
- Utils::Box(BOX_ANY, "%s", farComment);
- } else if (_maze.enabledFl && (verb == _vm._arrayVerbs[_vm._look][0])) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
- showTakeables();
- } else if (verb && noun) { // A combination I didn't think of
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse_2d]);
- } else if (verb || noun) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
- } else {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_2d]);
- }
- }
-}
-
} // End of namespace Hugo