[Scummvm-cvs-logs] SF.net SVN: scummvm:[54853] scummvm/trunk/engines/hugo

strangerke at users.sourceforge.net strangerke at users.sourceforge.net
Fri Dec 10 08:08:54 CET 2010


Revision: 54853
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54853&view=rev
Author:   strangerke
Date:     2010-12-10 07:08:54 +0000 (Fri, 10 Dec 2010)

Log Message:
-----------
HUGO: Enable the use of the icon based inventory

In Win versions, F6 now opens the directory. Not perfect yet... 

Modified Paths:
--------------
    scummvm/trunk/engines/hugo/inventory.cpp
    scummvm/trunk/engines/hugo/object.cpp
    scummvm/trunk/engines/hugo/parser.cpp
    scummvm/trunk/engines/hugo/parser.h
    scummvm/trunk/engines/hugo/parser_v1w.cpp
    scummvm/trunk/engines/hugo/parser_v3d.cpp

Modified: scummvm/trunk/engines/hugo/inventory.cpp
===================================================================
--- scummvm/trunk/engines/hugo/inventory.cpp	2010-12-10 07:03:24 UTC (rev 54852)
+++ scummvm/trunk/engines/hugo/inventory.cpp	2010-12-10 07:08:54 UTC (rev 54853)
@@ -73,7 +73,7 @@
 	// Copy inventory icons to remaining positions
 	int16 displayed = 0;
 	int16 carried = 0;
-	for (int16 i = 0; i < imageTotNumb; i++) {
+	for (int16 i = 0; (i < imageTotNumb) && (displayed < displayNumb); i++) {
 		if (_vm->_object->isCarried(_vm->_invent[i])) {
 			// Check still room to display and past first scroll index
 			if (displayed < displayNumb && carried >= firstObjId) {

Modified: scummvm/trunk/engines/hugo/object.cpp
===================================================================
--- scummvm/trunk/engines/hugo/object.cpp	2010-12-10 07:03:24 UTC (rev 54852)
+++ scummvm/trunk/engines/hugo/object.cpp	2010-12-10 07:08:54 UTC (rev 54853)
@@ -113,7 +113,7 @@
 	} else {
 		// Use status.objid on objid
 		// Default to first cmd verb
-		sprintf(_line, "%s %s %s", _vm->_arrayVerbs[_vm->_cmdList[_objects[_vm->getGameStatus().inventoryObjId].cmdIndex][1].verbIndex][0],
+		sprintf(_line, "%s %s %s", _vm->_arrayVerbs[_vm->_cmdList[_objects[_vm->getGameStatus().inventoryObjId].cmdIndex][0].verbIndex][0],
 			                       _vm->_arrayNouns[_objects[_vm->getGameStatus().inventoryObjId].nounIndex][0],
 			                       _vm->_arrayNouns[obj->nounIndex][0]);
 
@@ -123,7 +123,7 @@
 				// Look for secondary object, if found use matching verb
 				bool foundFl = false;
 				for (target_t *target = use->targets; _vm->_arrayNouns[target->nounIndex] != 0; target++)
-					if (_vm->_arrayNouns[target->nounIndex][0] == _vm->_arrayNouns[obj->nounIndex][0]) {
+					if (target->nounIndex == obj->nounIndex) {
 						foundFl = true;
 						sprintf(_line, "%s %s %s", _vm->_arrayVerbs[target->verbIndex][0],
 							                       _vm->_arrayNouns[_objects[_vm->getGameStatus().inventoryObjId].nounIndex][0],

Modified: scummvm/trunk/engines/hugo/parser.cpp
===================================================================
--- scummvm/trunk/engines/hugo/parser.cpp	2010-12-10 07:03:24 UTC (rev 54852)
+++ scummvm/trunk/engines/hugo/parser.cpp	2010-12-10 07:08:54 UTC (rev 54853)
@@ -86,12 +86,6 @@
 			_vm->_screen->userHelp();
 		_checkDoubleF1Fl = !_checkDoubleF1Fl;
 		break;
-	case Common::KEYCODE_F6:                        // Inventory
-		showDosInventory();
-		break;
-	case Common::KEYCODE_F8:                        // Turbo mode
-		_config.turboFl = !_config.turboFl;
-		break;
 	case Common::KEYCODE_F2:                        // Toggle sound
 		_vm->_sound->toggleSound();
 		_vm->_sound->toggleMusic();
@@ -108,6 +102,12 @@
 		_vm->_scheduler->restoreScreen(*_vm->_screen_p);
 		gameStatus.viewState = V_PLAY;
 		break;
+	case Common::KEYCODE_F6:                        // Inventory
+		showDosInventory();
+		break;
+	case Common::KEYCODE_F8:                        // Turbo mode
+		_config.turboFl = !_config.turboFl;
+		break;
 	case Common::KEYCODE_F9:                        // Boss button
 		warning("STUB: F9 (DOS) - BossKey");
 		break;

Modified: scummvm/trunk/engines/hugo/parser.h
===================================================================
--- scummvm/trunk/engines/hugo/parser.h	2010-12-10 07:03:24 UTC (rev 54852)
+++ scummvm/trunk/engines/hugo/parser.h	2010-12-10 07:08:54 UTC (rev 54853)
@@ -47,11 +47,12 @@
 	Parser(HugoEngine *vm);
 	virtual ~Parser();
 
-	bool  isWordPresent(char **wordArr);
+	bool isWordPresent(char **wordArr);
 
-	void  charHandler();
-	void  command(const char *format, ...);
-	void  keyHandler(uint16 nChar, uint16 nFlags);
+	void charHandler();
+	void command(const char *format, ...);
+
+	virtual void keyHandler(uint16 nChar, uint16 nFlags);
 	virtual void lineHandler() = 0;
 
 protected:
@@ -60,35 +61,15 @@
 protected:
 	char *findNoun();
 	char *findVerb();
-
-private:
-	char   _ringBuffer[32];                         // Ring buffer
+	bool _checkDoubleF1Fl;                          // Flag used to display user help or instructions
 	uint16 _putIndex;
 	uint16 _getIndex;                               // Index into ring buffer
-	bool   _checkDoubleF1Fl;                        // Flag used to display user help or instructions
+	char   _ringBuffer[32];                         // Ring buffer
 
+private:
 	void  showDosInventory();
 };
 
-class Parser_v1w : public Parser {
-public:
-	Parser_v1w(HugoEngine *vm);
-	~Parser_v1w();
-
-	virtual void  lineHandler();
-
-protected:
-	bool  isBackgroundWord(objectList_t obj);
-	bool  isCatchallVerb(objectList_t obj);
-	bool  isGenericVerb(object_t *obj, char *comment);
-	bool  isObjectVerb(object_t *obj, char *comment);
-	void  takeObject(object_t *obj);
-
-private:
-	bool  isNear(object_t *obj, char *verb, char *comment);
-	void  dropObject(object_t *obj);
-};
-
 class Parser_v1d : public Parser {
 public:
 	Parser_v1d(HugoEngine *vm);
@@ -115,14 +96,33 @@
 	void lineHandler();
 };
 
-class Parser_v3d : public Parser_v1w {
+class Parser_v3d : public Parser {
 public:
 	Parser_v3d(HugoEngine *vm);
 	~Parser_v3d();
 
-	void lineHandler();
+	virtual void lineHandler();
+protected:
+	bool  isBackgroundWord(objectList_t obj);
+	bool  isCatchallVerb(objectList_t obj);
+	bool  isGenericVerb(object_t *obj, char *comment);
+	bool  isObjectVerb(object_t *obj, char *comment);
+	void  takeObject(object_t *obj);
+
+private:
+	bool  isNear(object_t *obj, char *verb, char *comment);
+	void  dropObject(object_t *obj);
 };
 
+class Parser_v1w : public Parser_v3d {
+public:
+	Parser_v1w(HugoEngine *vm);
+	~Parser_v1w();
+
+	void  keyHandler(uint16 nChar, uint16 nFlags);
+	void  lineHandler();
+};
+
 } // End of namespace Hugo
 
 #endif //HUGO_PARSER_H

Modified: scummvm/trunk/engines/hugo/parser_v1w.cpp
===================================================================
--- scummvm/trunk/engines/hugo/parser_v1w.cpp	2010-12-10 07:03:24 UTC (rev 54852)
+++ scummvm/trunk/engines/hugo/parser_v1w.cpp	2010-12-10 07:08:54 UTC (rev 54853)
@@ -38,267 +38,94 @@
 #include "hugo/parser.h"
 #include "hugo/file.h"
 #include "hugo/schedule.h"
+#include "hugo/route.h"
+#include "hugo/display.h"
 #include "hugo/util.h"
 #include "hugo/sound.h"
 #include "hugo/object.h"
 
 namespace Hugo {
-Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser(vm) {
+Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser_v3d(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);
+void Parser_v1w::keyHandler(uint16 nChar, uint16 nFlags) {
+	debugC(1, kDebugParser, "keyHandler(%d, %d)", nChar, nFlags);
 
-	// 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;
+	status_t &gameStatus = _vm->getGameStatus();
+	bool repeatedFl = (nFlags & 0x4000);            // TRUE if key is a repeat
 
-	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 (!_vm->_object->isCarrying(reqs[i])) {
-				Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataNoCarryIndex]);
-				return true;
-			}
+// Process key down event - called from OnKeyDown()
+	switch (nChar)  {                               // Set various toggle states
+	case Common::KEYCODE_ESCAPE:                    // Escape key, may want to QUIT
+		if (gameStatus.inventoryState == I_ACTIVE)  // Remove inventory, if displayed
+			gameStatus.inventoryState = I_UP;
+		gameStatus.inventoryObjId = -1;             // Deselect any dragged icon
+		break;
+	case Common::KEYCODE_END:
+	case Common::KEYCODE_HOME:
+	case Common::KEYCODE_LEFT:
+	case Common::KEYCODE_RIGHT:
+	case Common::KEYCODE_UP:
+	case Common::KEYCODE_DOWN:
+		if (!repeatedFl) {
+			gameStatus.routeIndex = -1;             // Stop any automatic route
+			_vm->_route->setWalk(nChar);             // Direction of hero travel
 		}
-	}
-
-	// 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]]);
-		} 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]);
+		break;
+	case Common::KEYCODE_F1:                        // User Help (DOS)
+		if (_checkDoubleF1Fl)
+			_vm->_file->instructions();
 		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;
+			_vm->_screen->userHelp();
+		_checkDoubleF1Fl = !_checkDoubleF1Fl;
+		break;
+	case Common::KEYCODE_F2:                        // Toggle sound
+		_vm->_sound->toggleSound();
+		_vm->_sound->toggleMusic();
+		break;
+	case Common::KEYCODE_F3:                        // Repeat last line
+		gameStatus.recallFl = true;
+		break;
+	case Common::KEYCODE_F4:                        // Save game
+		if (gameStatus.viewState == V_PLAY)
+			_vm->_file->saveGame(-1, Common::String());
+		break;
+	case Common::KEYCODE_F5:                        // Restore game
+		_vm->_file->restoreGame(-1);
+		_vm->_scheduler->restoreScreen(*_vm->_screen_p);
+		gameStatus.viewState = V_PLAY;
+		break;
+	case Common::KEYCODE_F6:                        // Inventory
+		gameStatus.inventoryState = I_DOWN;
+		gameStatus.viewState = V_INVENT;
+		break;
+	case Common::KEYCODE_F8:                        // Turbo mode
+		_config.turboFl = !_config.turboFl;
+		break;
+	case Common::KEYCODE_F9:                        // Boss button
+		warning("STUB: F9 (DOS) - BossKey");
+		break;
+	default:                                        // Any other key
+		if (!gameStatus.storyModeFl) {              // Keyboard disabled
+			// Add printable keys to ring buffer
+			uint16 bnext = _putIndex + 1;
+			if (bnext >= sizeof(_ringBuffer))
+				bnext = 0;
+			if (bnext != _getIndex) {
+				_ringBuffer[_putIndex] = nChar;
+				_putIndex = bnext;
 			}
 		}
+		break;
 	}
-
-	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;
+	if (_checkDoubleF1Fl && (nChar != Common::KEYCODE_F1))
+		_checkDoubleF1Fl = false;
 }
 
 /**
-* 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])
-				_vm->_object->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() {

Modified: scummvm/trunk/engines/hugo/parser_v3d.cpp
===================================================================
--- scummvm/trunk/engines/hugo/parser_v3d.cpp	2010-12-10 07:03:24 UTC (rev 54852)
+++ scummvm/trunk/engines/hugo/parser_v3d.cpp	2010-12-10 07:08:54 UTC (rev 54853)
@@ -44,7 +44,7 @@
 
 namespace Hugo {
 
-Parser_v3d::Parser_v3d(HugoEngine *vm) : Parser_v1w(vm) {
+Parser_v3d::Parser_v3d(HugoEngine *vm) : Parser(vm) {
 }
 
 Parser_v3d::~Parser_v3d() {
@@ -204,4 +204,253 @@
 	}
 }
 
+/**
+* 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_v3d::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 (!_vm->_object->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_v3d::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]]);
+		} 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_v3d::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_v3d::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_v3d::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_v3d::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])
+				_vm->_object->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_v3d::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;
+}
+
 } // End of namespace Hugo


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list