From 0b746971f103a620013dc9145ab6d3038e378192 Mon Sep 17 00:00:00 2001 From: Ľubomír Remák Date: Sun, 28 Oct 2018 14:57:53 +0100 Subject: MUTATIONOFJB: Implement implicit actions. Add implicit pick up action for certain statics. Respect disabled implicit walk action for doors. --- engines/mutationofjb/debug.cpp | 35 +++++++++++++++++-------------- engines/mutationofjb/gamedata.cpp | 12 +++++++++++ engines/mutationofjb/gamedata.h | 25 ++++++++++++++++++---- engines/mutationofjb/gamescreen.cpp | 23 ++++++++++++++++---- engines/mutationofjb/gamescreen.h | 4 ++-- engines/mutationofjb/widgets/gamewidget.h | 4 ++-- 6 files changed, 75 insertions(+), 28 deletions(-) (limited to 'engines/mutationofjb') diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp index 2a06cce49f..7068b6643f 100644 --- a/engines/mutationofjb/debug.cpp +++ b/engines/mutationofjb/debug.cpp @@ -312,24 +312,27 @@ bool Console::cmd_changescene(int argc, const char **argv) { } bool Console::cmd_dumpsceneinfo(int argc, const char **argv) { + uint8 sceneId = _vm->getGame().getGameData()._currentScene; + 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->_delay); - 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("PalRotFirst: %u\n", (unsigned int) scene->_palRotFirst); - debugPrintf("PalRotLast: %u\n", (unsigned int) scene->_palRotLast); - debugPrintf("PalRotDelay: %u\n", (unsigned int) scene->_palRotDelay); - } else { - debugPrintf("Scene %u not found.\n", (unsigned int) sceneId); - } + sceneId = atoi(argv[1]); + } else if (argc != 1) { + debugPrintf("dumpsceneinfo []\n"); + } + + if (Scene *const scene = _vm->getGame().getGameData().getScene(sceneId)) { + debugPrintf("Scene ID: %u\n", (unsigned int) sceneId); + debugPrintf("Startup: %u\n", (unsigned int) scene->_startup); + debugPrintf("Delay: %u\n", (unsigned int) scene->_delay); + 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("PalRotFirst: %u\n", (unsigned int) scene->_palRotFirst); + debugPrintf("PalRotLast: %u\n", (unsigned int) scene->_palRotLast); + debugPrintf("PalRotDelay: %u\n", (unsigned int) scene->_palRotDelay); } else { - debugPrintf("dumpsceneinfo \n"); + debugPrintf("Scene %u not found.\n", (unsigned int) sceneId); } return true; diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp index b0d3e7c328..40be8affd2 100644 --- a/engines/mutationofjb/gamedata.cpp +++ b/engines/mutationofjb/gamedata.cpp @@ -88,6 +88,14 @@ void Door::saveLoadWithSerializer(Common::Serializer &sz) { sz.syncAsByte(_SP); } +bool Door::allowsImplicitSceneChange() const { + const size_t length = strlen(_name); + if (length == 0) + return false; + + return _name[length - 1] != '+'; +} + bool Object::loadInitialState(Common::ReadStream &stream) { _active = stream.readByte(); _firstFrame = stream.readByte(); @@ -158,6 +166,10 @@ bool Static::isCombinable() const { return _name[length - 1] == '['; } +bool Static::allowsImplicitPickup() const { + return _name[0] == '~'; +} + bool Bitmap::loadInitialState(Common::ReadStream &stream) { _roomFrame = stream.readByte(); _isVisible = stream.readByte(); diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h index 9daefd8252..fb81518890 100644 --- a/engines/mutationofjb/gamedata.h +++ b/engines/mutationofjb/gamedata.h @@ -57,8 +57,6 @@ struct Door : public Common::Serializable { * * If it ends with '+', using the "go" verb on the door will not implicitly change the scene, * but the player will still walk towards the door. - * - * TODO: Implement the '+' restriction. */ char _name[MAX_ENTITY_NAME_LENGTH + 1]; /** @@ -82,7 +80,11 @@ struct Door : public Common::Serializable { uint16 _walkToX; /** Y coordinate for position player will walk towards after clicking the door (WY register). */ uint8 _walkToY; - /** Unknown for now - likely not even used. */ + /** + * Encoded player frames. + * 4 bits - destFrame + * 4 bits - walkToFrame + */ uint8 _SP; /** @@ -105,6 +107,13 @@ struct Door : public Common::Serializable { * @param sz Serializer. */ virtual void saveLoadWithSerializer(Common::Serializer &sz) override; + + /** + * Check whether walk action used on this door causes implicit scene change. + * + * @return True if door implicitly changes current scene, false otherwise. + */ + bool allowsImplicitSceneChange() const; }; /** @@ -216,7 +225,6 @@ struct Static : public Common::Serializable { * entity. * * TODO: Support '~' statics. - * TODO: Support combinable statics. */ char _name[MAX_ENTITY_NAME_LENGTH + 1]; /** X coordinate of the static rectangle (XX register). */ @@ -250,11 +258,20 @@ struct Static : public Common::Serializable { virtual void saveLoadWithSerializer(Common::Serializer &sz) override; /** + * Check whether this static is combinable. * Statics with names ending with '[' are allowed to be combined with other items. * * @return True if combinable, false otherwise. */ bool isCombinable() const; + + /** + * Check whether this static is implicitly picked up. + * Statics with names starting with '~' are implicitly picked up. + * + * @return Returns true if this static is implicitly picked up by pick up action, false otherwise. + */ + bool allowsImplicitPickup() const; }; /** diff --git a/engines/mutationofjb/gamescreen.cpp b/engines/mutationofjb/gamescreen.cpp index ef7e50baeb..739d260455 100644 --- a/engines/mutationofjb/gamescreen.cpp +++ b/engines/mutationofjb/gamescreen.cpp @@ -147,18 +147,23 @@ void GameScreen::handleEvent(const Common::Event &event) { switch (event.kbd.ascii) { case 'g': _currentAction = ActionInfo::Walk; + _currentPickedItem.clear(); break; case 'r': _currentAction = ActionInfo::Talk; + _currentPickedItem.clear(); break; case 's': _currentAction = ActionInfo::Look; + _currentPickedItem.clear(); break; case 'b': _currentAction = ActionInfo::Use; + _currentPickedItem.clear(); break; case 'n': _currentAction = ActionInfo::PickUp; + _currentPickedItem.clear(); break; } break; @@ -368,18 +373,20 @@ void GameScreen::onInventoryItemClicked(InventoryWidget *, int posInWidget) { } } -void GameScreen::onGameDoorClicked(GameWidget *, const Door *door) { +void GameScreen::onGameDoorClicked(GameWidget *, Door *door) { if (!_currentPickedItem.empty()) { _game.startActionSection(_currentAction, _currentPickedItem, door->_name); + _currentPickedItem.clear(); return; } if (!_game.startActionSection(_currentAction, door->_name) && _currentAction == ActionInfo::Walk && door->_destSceneId != 0) { - _game.changeScene(door->_destSceneId, _game.getGameData()._partB); + if (door->allowsImplicitSceneChange()) + _game.changeScene(door->_destSceneId, _game.getGameData()._partB); } } -void GameScreen::onGameStaticClicked(GameWidget *, const Static *stat) { +void GameScreen::onGameStaticClicked(GameWidget *, Static *stat) { if (_currentAction == ActionInfo::Use) { if (_currentPickedItem.empty()) { if (stat->isCombinable()) @@ -391,7 +398,15 @@ void GameScreen::onGameStaticClicked(GameWidget *, const Static *stat) { _currentPickedItem.clear(); } } else { - _game.startActionSection(_currentAction, stat->_name); + if (!_game.startActionSection(_currentAction, stat->_name)) { + if (_currentAction == ActionInfo::PickUp && stat->allowsImplicitPickup()) { + Common::String inventoryName(stat->_name); + inventoryName.setChar('`', 0); + + _game.getGameData().getInventory().addItem(inventoryName); + stat->_active = 0; + } + } } } diff --git a/engines/mutationofjb/gamescreen.h b/engines/mutationofjb/gamescreen.h index 686a504364..37d5251217 100644 --- a/engines/mutationofjb/gamescreen.h +++ b/engines/mutationofjb/gamescreen.h @@ -69,8 +69,8 @@ public: virtual void onButtonClicked(ButtonWidget *) override; virtual void onInventoryItemHovered(InventoryWidget *widget, int posInWidget) override; virtual void onInventoryItemClicked(InventoryWidget *widget, int posInWidget) override; - virtual void onGameDoorClicked(GameWidget *, const Door *door) override; - virtual void onGameStaticClicked(GameWidget *, const Static *stat) override; + virtual void onGameDoorClicked(GameWidget *, Door *door) override; + virtual void onGameStaticClicked(GameWidget *, Static *stat) override; virtual void onGameEntityHovered(GameWidget *, const Common::String &entity) override; ConversationWidget &getConversationWidget(); diff --git a/engines/mutationofjb/widgets/gamewidget.h b/engines/mutationofjb/widgets/gamewidget.h index e3fe08a818..c600d3aab6 100644 --- a/engines/mutationofjb/widgets/gamewidget.h +++ b/engines/mutationofjb/widgets/gamewidget.h @@ -34,8 +34,8 @@ struct Static; class GameWidgetCallback { public: virtual ~GameWidgetCallback() {} - virtual void onGameDoorClicked(GameWidget *, const Door *door) = 0; - virtual void onGameStaticClicked(GameWidget *, const Static *stat) = 0; + virtual void onGameDoorClicked(GameWidget *, Door *door) = 0; + virtual void onGameStaticClicked(GameWidget *, Static *stat) = 0; virtual void onGameEntityHovered(GameWidget *, const Common::String &entity) = 0; }; -- cgit v1.2.3