From 128d30c91c114d771e7777963716d3625be8cfeb Mon Sep 17 00:00:00 2001 From: Ľubomír Remák Date: Sun, 25 Mar 2018 01:04:44 +0100 Subject: MUTATIONOFJB: Run action when clicking on static or door. --- engines/mutationofjb/debug.cpp | 201 ++++++++++++++++++++++++---------- engines/mutationofjb/debug.h | 3 + engines/mutationofjb/game.cpp | 58 ++++++++++ engines/mutationofjb/game.h | 6 + engines/mutationofjb/gamedata.cpp | 8 +- engines/mutationofjb/gamedata.h | 12 +- engines/mutationofjb/mutationofjb.cpp | 33 ++++-- engines/mutationofjb/script.cpp | 29 +---- engines/mutationofjb/script.h | 19 ++-- 9 files changed, 258 insertions(+), 111 deletions(-) (limited to 'engines/mutationofjb') diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp index e5333392ea..f533a94ffb 100644 --- a/engines/mutationofjb/debug.cpp +++ b/engines/mutationofjb/debug.cpp @@ -22,6 +22,7 @@ #include "mutationofjb/debug.h" #include "mutationofjb/game.h" +#include "mutationofjb/gamedata.h" #include "mutationofjb/mutationofjb.h" #include "mutationofjb/script.h" #include "mutationofjb/commands/command.h" @@ -63,6 +64,9 @@ Console::Console(MutationOfJBEngine *vm) : _vm(vm) { registerCmd("liststartups", WRAP_METHOD(Console, cmd_liststartups)); registerCmd("showstartup", WRAP_METHOD(Console, cmd_showstartup)); registerCmd("changescene", WRAP_METHOD(Console, cmd_changescene)); + registerCmd("dumpsceneinfo", WRAP_METHOD(Console, cmd_dumpsceneinfo)); + registerCmd("dumpobjectinfo", WRAP_METHOD(Console, cmd_dumpobjectinfo)); + registerCmd("dumpstaticinfo", WRAP_METHOD(Console, cmd_dumpstaticinfo)); } bool Console::cmd_showallcommands(int argc, const char **argv) { @@ -86,40 +90,40 @@ bool Console::cmd_listsections(int argc, const char **argv) { if (argc == 3) { Script *const script = getScriptFromArg(argv[1]); if (script) { + ActionInfo::Action action; + const char *word = nullptr; if (strcmp(argv[2], "L") == 0) { - const ActionInfos &actionInfos = script->getLookActionInfos(); - for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { - const ActionInfo &actionInfo = *it; - debugPrintf(_("Look %s\n"), convertToASCII(actionInfo._object1Name).c_str()); - } + action = ActionInfo::Look; + word = _("Look"); } else if (strcmp(argv[2], "W") == 0) { - const ActionInfos &actionInfos = script->getWalkActionInfos(); - for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { - const ActionInfo &actionInfo = *it; - debugPrintf(_("Walk %s\n"), convertToASCII(actionInfo._object1Name).c_str()); - } + action = ActionInfo::Walk; + word = _("Walk"); } else if (strcmp(argv[2], "T") == 0) { - const ActionInfos &actionInfos = script->getTalkActionInfos(); - for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { - const ActionInfo &actionInfo = *it; - debugPrintf(_("Talk %s\n"), convertToASCII(actionInfo._object1Name).c_str()); - } + action = ActionInfo::Talk; + word = _("Talk"); } else if (strcmp(argv[2], "U") == 0) { - const ActionInfos &actionInfos = script->getUseActionInfos(); + action = ActionInfo::Use; + word = _("Use"); + } else if (strcmp(argv[2], "P") == 0) { + action = ActionInfo::PickUp; + word = _("Pick up"); + } else { + debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n")); + } + if (word) { + const ActionInfos &actionInfos = script->getActionInfos(action); for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { const ActionInfo &actionInfo = *it; - if (actionInfo._object2Name.empty()) { - debugPrintf(_("Use %s\n"), convertToASCII(actionInfo._object1Name).c_str()); + if (action != ActionInfo::Use || actionInfo._entity2Name.empty()) { + debugPrintf("%s %s\n", word, convertToASCII(actionInfo._entity1Name).c_str()); } else { - debugPrintf(_("Use %s %s\n"), convertToASCII(actionInfo._object1Name).c_str(), convertToASCII(actionInfo._object2Name).c_str()); + debugPrintf("%s %s %s\n", word, convertToASCII(actionInfo._entity1Name).c_str(), convertToASCII(actionInfo._entity2Name).c_str()); } } - } else { - debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n")); } } } else { - debugPrintf(_("listsections \n")); + debugPrintf(_("listsections \n")); } return true; } @@ -156,61 +160,47 @@ bool Console::cmd_showsection(int argc, const char **argv) { Script *const script = getScriptFromArg(argv[1]); if (script) { Command *command = nullptr; + ActionInfo::Action action; + bool correctAction = true; bool found = false; + if (strcmp(argv[2], "L") == 0) { - const ActionInfos &actionInfos = script->getLookActionInfos(); - for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { - const ActionInfo &actionInfo = *it; - if (convertToASCII(actionInfo._object1Name) == argv[3]) { - found = true; - command = actionInfo._command; - break; - } - } + action = ActionInfo::Look; } else if (strcmp(argv[2], "W") == 0) { - const ActionInfos &actionInfos = script->getWalkActionInfos(); - for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { - const ActionInfo &actionInfo = *it; - if (convertToASCII(actionInfo._object1Name) == argv[3]) { - found = true; - command = actionInfo._command; - break; - } - } + action = ActionInfo::Walk; } else if (strcmp(argv[2], "T") == 0) { - const ActionInfos &actionInfos = script->getTalkActionInfos(); - for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { - const ActionInfo &actionInfo = *it; - if (convertToASCII(actionInfo._object1Name) == argv[3]) { - found = true; - command = actionInfo._command; - break; - } - } + action = ActionInfo::Talk; } else if (strcmp(argv[2], "U") == 0) { - const ActionInfos &actionInfos = script->getUseActionInfos(); + action = ActionInfo::Use; + } else if (strcmp(argv[2], "P") == 0) { + action = ActionInfo::PickUp; + } else { + debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n")); + correctAction = false; + } + + if (correctAction) { + const ActionInfos &actionInfos = script->getActionInfos(action); for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) { const ActionInfo &actionInfo = *it; - if (convertToASCII(actionInfo._object1Name) == argv[3] && ((argc == 4 && actionInfo._object2Name.empty()) || (argc > 4 && convertToASCII(actionInfo._object2Name) == argv[4]))) { + if (convertToASCII(actionInfo._entity1Name) == argv[3] && (action != ActionInfo::Use || ((argc == 4 && actionInfo._entity2Name.empty()) || (argc > 4 && convertToASCII(actionInfo._entity2Name) == argv[4])))) { found = true; command = actionInfo._command; break; } } - } else { - debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n")); - } - if (found) { - if (command) { - showCommands(command); + if (found) { + if (command) { + showCommands(command); + } + } else { + debugPrintf("Section not found.\n"); } - } else { - debugPrintf("Section not found.\n"); } } } else { - debugPrintf(_("showsection \n")); + debugPrintf(_("showsection \n")); } return true; @@ -310,6 +300,97 @@ bool Console::cmd_changescene(int argc, const char **argv) { return true; } +bool Console::cmd_dumpsceneinfo(int argc, const char **argv) { + if (argc == 2) { + const uint8 sceneId = atoi(argv[1]); + Scene *scene = _vm->getGame().getGameData().getScene(sceneId); + if (scene) { + debugPrintf("Startup: %u\n", (unsigned int) scene->_startup); + debugPrintf("Delay: %u\n", (unsigned int) scene->_DL); + debugPrintf("Doors: %u\n", (unsigned int) scene->_noDoors); + debugPrintf("Objects: %u\n", (unsigned int) scene->_noObjects); + debugPrintf("Statics: %u\n", (unsigned int) scene->_noStatics); + debugPrintf("ObstacleY1: %u\n", (unsigned int) scene->_obstacleY1); + debugPrintf("PalRotStart: %u\n", (unsigned int) scene->_palRotStart); + debugPrintf("PalRotEnd: %u\n", (unsigned int) scene->_palRotEnd); + debugPrintf("PalRotPeriod: %u\n", (unsigned int) scene->_palRotPeriod); + } else { + debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId); + } + } else { + debugPrintf(_("dumpsceneinfo \n")); + } + + return true; +} + +bool Console::cmd_dumpobjectinfo(int argc, const char **argv) { + if (argc == 3) { + const uint8 sceneId = atoi(argv[1]); + const uint8 objectId = atoi(argv[2]); + + Scene *const scene = _vm->getGame().getGameData().getScene(sceneId); + if (scene) { + Object *const object = scene->getObject(objectId); + if (object) { + debugPrintf("AC: %u\n", (unsigned int) object->_AC); + debugPrintf("FA: %u\n", (unsigned int) object->_FA); + debugPrintf("FR: %u\n", (unsigned int) object->_FR); + debugPrintf("NA: %u\n", (unsigned int) object->_NA); + debugPrintf("FS: %u\n", (unsigned int) object->_FS); + debugPrintf("Unknown: %u\n", (unsigned int) object->_unknown); + debugPrintf("CA: %u\n", (unsigned int) object->_CA); + debugPrintf("X: %u\n", (unsigned int) object->_x); + debugPrintf("Y: %u\n", (unsigned int) object->_y); + debugPrintf("XL: %u\n", (unsigned int) object->_XL); + debugPrintf("YL: %u\n", (unsigned int) object->_YL); + debugPrintf("WX: %u\n", (unsigned int) object->_WX); + debugPrintf("WY: %u\n", (unsigned int) object->_WY); + debugPrintf("SP: %u\n", (unsigned int) object->_SP); + } else { + debugPrintf(_("Object %u not found.\n"), (unsigned int) objectId); + } + } else { + debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId); + } + } else { + debugPrintf(_("dumpobjectinfo \n")); + } + + return true; +} + +bool Console::cmd_dumpstaticinfo(int argc, const char **argv) { + if (argc == 3) { + const uint8 sceneId = atoi(argv[1]); + const uint8 staticId = atoi(argv[2]); + + Scene *const scene = _vm->getGame().getGameData().getScene(sceneId); + if (scene) { + Static *const stat = scene->getStatic(staticId, true); + if (stat) { + debugPrintf("Active: %u\n", (unsigned int) stat->_active); + debugPrintf("Name: '%s'\n", convertToASCII(stat->_name).c_str()); + debugPrintf("X: %u\n", (unsigned int) stat->_x); + debugPrintf("Y: %u\n", (unsigned int) stat->_y); + debugPrintf("Width: %u\n", (unsigned int) stat->_width); + debugPrintf("Height: %u\n", (unsigned int) stat->_height); + debugPrintf("WalkToX: %u\n", (unsigned int) stat->_walkToY); + debugPrintf("WalkToY: %u\n", (unsigned int) stat->_walkToX); + debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_SP); + } else { + debugPrintf(_("Static %u not found.\n"), (unsigned int) staticId); + } + } else { + debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId); + } + } else { + debugPrintf(_("dumpstaticinfo \n")); + } + + return true; +} + Script *Console::getScriptFromArg(const char *arg) { Script *script = nullptr; if (strcmp(arg, "G") == 0) { diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h index 8df51679bf..e57b787a6d 100644 --- a/engines/mutationofjb/debug.h +++ b/engines/mutationofjb/debug.h @@ -44,6 +44,9 @@ private: bool cmd_liststartups(int argc, const char **argv); bool cmd_showstartup(int argc, const char **argv); bool cmd_changescene(int argc, const char **argv); + bool cmd_dumpsceneinfo(int argc, const char **argv); + bool cmd_dumpobjectinfo(int argc, const char **argv); + bool cmd_dumpstaticinfo(int argc, const char **argv); void showIndent(int indentLevel); void showCommands(Command *command, int indentLevel = 0); diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp index c5fa7b3342..156c0205d5 100644 --- a/engines/mutationofjb/game.cpp +++ b/engines/mutationofjb/game.cpp @@ -122,6 +122,64 @@ Script *Game::changeSceneDelayScript(uint8 sceneId, bool partB) { return _delayedLocalScript; } +Door *Game::findDoor(int16 x, int16 y) { + Scene *scene = _gameData->getCurrentScene(); + if (!scene) + return nullptr; + + for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) { + Door &door = scene->_doors[i]; + if ((x >= door._x) && (x < door._x + door._width) && (y >= door._y) && (y < door._y + door._height)) { + return &door; + } + } + + return nullptr; +} + +Static *Game::findStatic(int16 x, int16 y) { + Scene *scene = _gameData->getCurrentScene(); + if (!scene) + return nullptr; + + for (int i = 0; i < MIN(ARRAYSIZE(scene->_statics), (int) scene->_noStatics); ++i) { + Static &stat = scene->_statics[i]; + if ((x >= stat._x) && (x < stat._x + stat._width) && (y >= stat._y) && (y < stat._y + stat._height)) { + return &stat; + } + } + + return nullptr; +} + +static Command *findActionInfoCommand(const ActionInfos &infos, const Common::String &entity1Name, const Common::String &entity2Name = Common::String()) { + for (ActionInfos::const_iterator it = infos.begin(); it != infos.end(); ++it) { + if (it->_entity1Name == entity1Name && it->_entity2Name == entity2Name) { + return it->_command; + } + } + return nullptr; +} + +bool Game::startActionSection(ActionInfo::Action action, const Common::String &entity1Name, const Common::String &entity2Name) { + Script *const localScript = getLocalScript(); + Script *const globalScript = getGlobalScript(); + + Command *command = nullptr; + if (localScript) { + command = findActionInfoCommand(localScript->getActionInfos(action), entity1Name, entity2Name); + } + if (!command && globalScript) { + command = findActionInfoCommand(globalScript->getActionInfos(action), entity1Name, entity2Name); + } + if (command) { + _scriptExecCtx.startCommand(command); + return true; + } + + return false; +} + void Game::update() { Command::ExecuteResult res = _scriptExecCtx.runActiveCommand(); if (res == Command::Finished && _delayedLocalScript) { diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h index 2855704b3b..503cde98e4 100644 --- a/engines/mutationofjb/game.h +++ b/engines/mutationofjb/game.h @@ -37,6 +37,8 @@ class MutationOfJBEngine; class GameData; class Script; class Room; +class Door; +class Static; class Game { public: @@ -49,6 +51,10 @@ public: void changeScene(uint8 sceneId, bool partB); Script *changeSceneDelayScript(uint8 sceneId, bool partB); + Door *findDoor(int16 x, int16 y); + Static *findStatic(int16 x, int16 y); + bool startActionSection(ActionInfo::Action action, const Common::String &entity1Name, const Common::String &entity2Name = Common::String()); + void update(); private: diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp index 314eb569b5..acca555bbc 100644 --- a/engines/mutationofjb/gamedata.cpp +++ b/engines/mutationofjb/gamedata.cpp @@ -150,8 +150,8 @@ Door *Scene::getDoor(uint8 doorId) { return &_doors[doorId - 1]; } -Object *Scene::getObject(uint8 objectId) { - if (objectId == 0 || objectId > _noObjects) { +Object *Scene::getObject(uint8 objectId, bool ignoreNo) { + if (objectId == 0 || objectId > (!ignoreNo ? MIN(_noObjects, (uint8) ARRAYSIZE(_objects)) : ARRAYSIZE(_objects))) { warning(_("Object %d does not exist"), objectId); return nullptr; } @@ -159,8 +159,8 @@ Object *Scene::getObject(uint8 objectId) { return &_objects[objectId - 1]; } -Static *Scene::getStatic(uint8 staticId) { - if (staticId == 0 || staticId > _noStatics) { +Static *Scene::getStatic(uint8 staticId, bool ignoreNo) { + if (staticId == 0 || staticId > (!ignoreNo ? MIN(_noStatics, (uint8) ARRAYSIZE(_statics)) : ARRAYSIZE(_statics))) { warning(_("Static %d does not exist"), staticId); return nullptr; } diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h index eb474f8478..473575328d 100644 --- a/engines/mutationofjb/gamedata.h +++ b/engines/mutationofjb/gamedata.h @@ -34,6 +34,14 @@ namespace MutationOfJB { static const uint8 MAX_STR_LENGTH = 0x14; +/* + There are 4 types of entities present in the game data: + - Door + - Object + - Static + - Bitmap +*/ + struct Door { /* Door name. @@ -115,8 +123,8 @@ struct Bitmap { struct Scene { Door *getDoor(uint8 objectId); - Object *getObject(uint8 objectId); - Static *getStatic(uint8 staticId); + Object *getObject(uint8 objectId, bool ignoreNo = false); + Static *getStatic(uint8 staticId, bool ignoreNo = false); uint8 _startup; uint8 _unknown001; diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp index 1bd08dd706..622be67a8c 100644 --- a/engines/mutationofjb/mutationofjb.cpp +++ b/engines/mutationofjb/mutationofjb.cpp @@ -77,6 +77,7 @@ Common::Error MutationOfJBEngine::run() { _console = new Console(this); _screen = new Graphics::Screen(); _game = new Game(this); + ActionInfo::Action currentAction = ActionInfo::Walk; setupCursor(); @@ -94,17 +95,35 @@ Common::Error MutationOfJBEngine::run() { } case Common::EVENT_LBUTTONDOWN: { - const Scene *const scene = _game->getGameData().getScene(_game->getGameData()._currentScene); - if (scene) { - for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) { - const Door &door = scene->_doors[i]; - if ((event.mouse.x >= door._x) && (event.mouse.x < door._x + door._width) && (event.mouse.y >= door._y) && (event.mouse.y < door._y + door._height)) { - _game->changeScene(door._destSceneId, false); - } + if (Door *const door = _game->findDoor(event.mouse.x, event.mouse.y)) { + if (!_game->startActionSection(currentAction, door->_name) && currentAction == ActionInfo::Walk && door->_destSceneId != 0) { + _game->changeScene(door->_destSceneId, _game->getGameData()._partB); } + } else if (Static *const stat = _game->findStatic(event.mouse.x, event.mouse.y)) { + _game->startActionSection(currentAction, stat->_name); } break; } + case Common::EVENT_KEYUP: + { + switch (event.kbd.ascii) { + case 'g': + currentAction = ActionInfo::Walk; + break; + case 'r': + currentAction = ActionInfo::Talk; + break; + case 's': + currentAction = ActionInfo::Look; + break; + case 'b': + currentAction = ActionInfo::Use; + break; + case 'n': + currentAction = ActionInfo::PickUp; + break; + } + } default: break; } diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp index b9b1515414..f213de98be 100644 --- a/engines/mutationofjb/script.cpp +++ b/engines/mutationofjb/script.cpp @@ -221,18 +221,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) { } for (ActionInfos::iterator it = parseCtx._actionInfos.begin(); it != parseCtx._actionInfos.end(); ++it) { - if (it->_action == ActionInfo::Look) { - _lookActionInfos.push_back(*it); - } - if (it->_action == ActionInfo::Walk) { - _walkActionInfos.push_back(*it); - } - if (it->_action == ActionInfo::Talk) { - _talkActionInfos.push_back(*it); - } - if (it->_action == ActionInfo::Use) { - _useActionInfos.push_back(*it); - } + _actionInfos[it->_action].push_back(*it); } _macros = parseCtx._macros; @@ -252,20 +241,8 @@ Script::~Script() { destroy(); } -const ActionInfos &Script::getLookActionInfos() const { - return _lookActionInfos; -} - -const ActionInfos &Script::getWalkActionInfos() const { - return _walkActionInfos; -} - -const ActionInfos &Script::getTalkActionInfos() const { - return _talkActionInfos; -} - -const ActionInfos &Script::getUseActionInfos() const { - return _useActionInfos; +const ActionInfos &Script::getActionInfos(ActionInfo::Action action) { + return _actionInfos[action]; } const Commands &Script::getAllCommands() const { diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h index 09aa9425de..8a15a48887 100644 --- a/engines/mutationofjb/script.h +++ b/engines/mutationofjb/script.h @@ -48,15 +48,16 @@ typedef Common::Array Commands; struct ActionInfo { enum Action { + Look, Walk, Talk, - Look, - Use + Use, + PickUp }; Action _action; - Common::String _object1Name; - Common::String _object2Name; + Common::String _entity1Name; + Common::String _entity2Name; bool _walkTo; Command *_command; }; @@ -125,10 +126,7 @@ public: bool loadFromStream(Common::SeekableReadStream &stream); ~Script(); - const ActionInfos &getLookActionInfos() const; - const ActionInfos &getWalkActionInfos() const; - const ActionInfos &getTalkActionInfos() const; - const ActionInfos &getUseActionInfos() const; + const ActionInfos &getActionInfos(ActionInfo::Action action); const Commands &getAllCommands() const; const Macros &getMacros() const; const Startups &getStartups() const; @@ -138,10 +136,7 @@ public: private: void destroy(); Commands _allCommands; - ActionInfos _lookActionInfos; - ActionInfos _walkActionInfos; - ActionInfos _talkActionInfos; - ActionInfos _useActionInfos; + ActionInfos _actionInfos[5]; Macros _macros; Startups _startups; }; -- cgit v1.2.3