diff options
author | Ľubomír Remák | 2018-07-21 20:29:11 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2018-08-25 23:12:01 +0200 |
commit | 3306cbfeaa2f1c6fd471daaee054290df7e44280 (patch) | |
tree | 56379cb27336281e9ca92b12d6db7ab6d84c31e8 /engines | |
parent | 2e656e69b3b9416f5164f0963951df203f4978e5 (diff) | |
download | scummvm-rg350-3306cbfeaa2f1c6fd471daaee054290df7e44280.tar.gz scummvm-rg350-3306cbfeaa2f1c6fd471daaee054290df7e44280.tar.bz2 scummvm-rg350-3306cbfeaa2f1c6fd471daaee054290df7e44280.zip |
MUTATIONOFJB: Implement SayCommand::execute.
Diffstat (limited to 'engines')
-rw-r--r-- | engines/mutationofjb/commands/saycommand.cpp | 21 | ||||
-rw-r--r-- | engines/mutationofjb/commands/talkcommand.cpp | 3 | ||||
-rw-r--r-- | engines/mutationofjb/font.cpp | 2 | ||||
-rw-r--r-- | engines/mutationofjb/game.cpp | 15 | ||||
-rw-r--r-- | engines/mutationofjb/game.h | 11 | ||||
-rw-r--r-- | engines/mutationofjb/gamedata.cpp | 3 | ||||
-rw-r--r-- | engines/mutationofjb/gamedata.h | 12 | ||||
-rw-r--r-- | engines/mutationofjb/script.cpp | 1 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/conversationtask.cpp | 11 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/saytask.cpp | 30 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/saytask.h | 2 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/sequentialtask.cpp | 2 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/task.h | 1 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/taskmanager.cpp | 26 | ||||
-rw-r--r-- | engines/mutationofjb/tasks/taskmanager.h | 26 |
15 files changed, 130 insertions, 36 deletions
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp index 854c957b1b..0474a3e1ac 100644 --- a/engines/mutationofjb/commands/saycommand.cpp +++ b/engines/mutationofjb/commands/saycommand.cpp @@ -21,7 +21,13 @@ */ #include "mutationofjb/commands/saycommand.h" + +#include "mutationofjb/game.h" +#include "mutationofjb/gamedata.h" #include "mutationofjb/script.h" +#include "mutationofjb/tasks/saytask.h" +#include "mutationofjb/tasks/taskmanager.h" + #include "common/str.h" #include "common/debug.h" #include "common/debug-channels.h" @@ -140,9 +146,18 @@ bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &par } -Command::ExecuteResult SayCommand::execute(ScriptExecutionContext &) { - // TODO: Actual implementation. - debug("%s [%s]", _lineToSay.c_str(), _voiceFile.c_str()); +Command::ExecuteResult SayCommand::execute(ScriptExecutionContext &scriptExecCtx) { + Game &game = scriptExecCtx.getGame(); + + if (_waitForPrevious) { + if (game.getActiveSayTask()) { + return InProgress; + } + } + + TaskPtr task(new SayTask(_lineToSay, game.getGameData()._color)); + game.getTaskManager().startTask(task); + return Finished; } diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp index 8411e9080a..6a3b204bb5 100644 --- a/engines/mutationofjb/commands/talkcommand.cpp +++ b/engines/mutationofjb/commands/talkcommand.cpp @@ -57,11 +57,10 @@ bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &, Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx) { if (!_task) { _task = TaskPtr(new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo, _mode)); - scriptExeCtx.getGame().getTaskManager().addTask(_task); + scriptExeCtx.getGame().getTaskManager().startTask(_task); } if (_task->getState() == Task::FINISHED) { - scriptExeCtx.getGame().getTaskManager().removeTask(_task); _task.reset(); return Command::Finished; diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp index 4350b19850..4f4a0ee82b 100644 --- a/engines/mutationofjb/font.cpp +++ b/engines/mutationofjb/font.cpp @@ -77,7 +77,7 @@ bool Font::load(const Common::String &fileName) { void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const { GlyphMap::iterator it = _glyphs.find(glyph); if (it == _glyphs.end()) { - warning("Glyph %d not found", glyph); + // Missing glyph is a common situation in the game and it's okay to ignore it. return; } diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp index 9f5f469c15..787bb7b121 100644 --- a/engines/mutationofjb/game.cpp +++ b/engines/mutationofjb/game.cpp @@ -42,8 +42,8 @@ Game::Game(MutationOfJBEngine *vm) _randomSource("mutationofjb"), _delayedLocalScript(nullptr), _gui(*this, _vm->getScreen()), - _scriptExecCtx(*this), _currentAction(ActionInfo::Walk), + _scriptExecCtx(*this), _taskManager(*this), _assets(*this) { @@ -61,7 +61,7 @@ Game::Game(MutationOfJBEngine *vm) _gui.init(); - _taskManager.addTask(TaskPtr(new ObjectAnimationTask)); + _taskManager.startTask(TaskPtr(new ObjectAnimationTask)); } Common::RandomSource &Game::getRandomSource() { @@ -240,9 +240,16 @@ Assets &Game::getAssets() { return _assets; } -Graphics::Screen &Game::getScreen() -{ +Graphics::Screen &Game::getScreen() { return *_vm->getScreen(); } +TaskPtr Game::getActiveSayTask() const { + return _activeSayTask; +} + +void Game::setActiveSayTask(const TaskPtr &sayTask) { + _activeSayTask = sayTask; +} + } diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h index d70bd09d9a..316dc759fc 100644 --- a/engines/mutationofjb/game.h +++ b/engines/mutationofjb/game.h @@ -23,13 +23,15 @@ #ifndef MUTATIONOFJB_GAME_H #define MUTATIONOFJB_GAME_H -#include "common/random.h" -#include "common/scummsys.h" #include "mutationofjb/assets.h" #include "mutationofjb/gui.h" #include "mutationofjb/script.h" #include "mutationofjb/tasks/taskmanager.h" +#include "common/ptr.h" +#include "common/random.h" +#include "common/scummsys.h" + namespace Common { class String; } @@ -44,6 +46,7 @@ class Room; class Door; class Static; class Bitmap; +class SayTask; class Game { public: @@ -75,6 +78,9 @@ public: Graphics::Screen &getScreen(); + TaskPtr getActiveSayTask() const; + void setActiveSayTask(const TaskPtr &sayTask); + private: bool loadGameData(bool partB); void runActiveCommand(); @@ -96,6 +102,7 @@ private: TaskManager _taskManager; Assets _assets; + TaskPtr _activeSayTask; }; } diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp index b6295a7b04..54335d1514 100644 --- a/engines/mutationofjb/gamedata.cpp +++ b/engines/mutationofjb/gamedata.cpp @@ -247,7 +247,8 @@ GameData::GameData() : _currentScene(0), _lastScene(0), _partB(false), - _inventory() + _inventory(), + _color(WHITE) {} Scene *GameData::getScene(uint8 sceneId) { diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h index 99174ee25d..47272c670f 100644 --- a/engines/mutationofjb/gamedata.h +++ b/engines/mutationofjb/gamedata.h @@ -323,14 +323,16 @@ public: bool loadFromStream(Common::ReadStream &stream); - uint8 _currentScene; + uint8 _currentScene; // Persistent. uint8 _lastScene; - bool _partB; - Inventory _inventory; - Common::String _currentAPK; + bool _partB; // Persistent. + Inventory _inventory; // Persistent. + Common::String _currentAPK; // Persistent. ConversationInfo _conversationInfo; + /** Current SayCommand color. */ + uint8 _color; private: - Scene _scenes[45]; + Scene _scenes[45]; // Persistent. }; enum Colors { diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp index 39c485991b..069545cd55 100644 --- a/engines/mutationofjb/script.cpp +++ b/engines/mutationofjb/script.cpp @@ -154,6 +154,7 @@ Command::ExecuteResult ScriptExecutionContext::startCommand(Command *cmd) { warning(_("Trying to start command while another one is running.")); return Command::Finished; } + getGameData()._color = WHITE; // The original game resets the color to WHITE beforing running script sections. clear(); _activeCommand = cmd; return runActiveCommand(); diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp index a2a0a73bf0..d4fab56dc3 100644 --- a/engines/mutationofjb/tasks/conversationtask.cpp +++ b/engines/mutationofjb/tasks/conversationtask.cpp @@ -54,7 +54,6 @@ void ConversationTask::start() { void ConversationTask::update() { if (_sayTask) { if (_sayTask->getState() == Task::FINISHED) { - getTaskManager()->removeTask(_sayTask); _sayTask.reset(); switch (_substate) { @@ -67,7 +66,7 @@ void ConversationTask::update() { _substate = SAYING_RESPONSE; createSayTasks(line); - getTaskManager()->addTask(_sayTask); + getTaskManager()->startTask(_sayTask); break; } case SAYING_RESPONSE: { @@ -105,7 +104,7 @@ void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint _substate = SAYING_CHOICE; createSayTasks(line); - getTaskManager()->addTask(_sayTask); + getTaskManager()->startTask(_sayTask); _currentItem = &item; if (!line->_speeches[0].isRepeating()) { @@ -177,7 +176,7 @@ void ConversationTask::showChoicesOrPick() { _substate = SAYING_CHOICE; createSayTasks(line); - getTaskManager()->addTask(_sayTask); + getTaskManager()->startTask(_sayTask); _currentItem = &item; if (!line->_speeches[0].isRepeating()) { @@ -192,7 +191,7 @@ void ConversationTask::showChoicesOrPick() { _substate = SAYING_RESPONSE; createSayTasks(line); - getTaskManager()->addTask(_sayTask); + getTaskManager()->startTask(_sayTask); _currentItem = &item; _haveChoices = true; @@ -204,7 +203,7 @@ void ConversationTask::showChoicesOrPick() { finish(); } else { _sayTask = TaskPtr(new SayTask("Nothing to talk about.", _convInfo._color)); // TODO: This is hardcoded in executable. Load it. - getTaskManager()->addTask(_sayTask); + getTaskManager()->startTask(_sayTask); _substate = SAYING_NO_CHOICES; _currentItem = nullptr; } diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp index bd89805c68..cfa412b3b1 100644 --- a/engines/mutationofjb/tasks/saytask.cpp +++ b/engines/mutationofjb/tasks/saytask.cpp @@ -34,21 +34,31 @@ namespace MutationOfJB { -SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(1000) {} +SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(50 * toSay.size()) {} void SayTask::start() { + Game &game = getTaskManager()->getGame(); + if (game.getActiveSayTask()) { + getTaskManager()->stopTask(game.getActiveSayTask()); + } + game.setActiveSayTask(getTaskManager()->getTask(this)); + + setState(RUNNING); drawSubtitle(_toSay, 160, 0, _color); // TODO: Respect PTALK and LTALK commands. _timer.start(); - setState(RUNNING); } void SayTask::update() { _timer.update(); if (_timer.isFinished()) { - getTaskManager()->getGame().getRoom().redraw(); // TODO: Only redraw the area occupied by the text. - setState(FINISHED); - return; + finish(); + } +} + +void SayTask::stop() { + if (getState() == RUNNING) { + finish(); } } @@ -89,4 +99,14 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, _boundingBox.setHeight(lines.size() * font.getLineHeight()); } +void SayTask::finish() { + getTaskManager()->getGame().getRoom().redraw(); // TODO: Only redraw the area occupied by the text. + setState(FINISHED); + + Game &game = getTaskManager()->getGame(); + if (game.getActiveSayTask().get() == this) { + game.setActiveSayTask(Common::SharedPtr<SayTask>()); + } +} + } diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h index 17e773defc..2200436b86 100644 --- a/engines/mutationofjb/tasks/saytask.h +++ b/engines/mutationofjb/tasks/saytask.h @@ -38,9 +38,11 @@ public: virtual void start() override; virtual void update() override; + virtual void stop() override; private: void drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color); + void finish(); Common::String _toSay; uint8 _color; diff --git a/engines/mutationofjb/tasks/sequentialtask.cpp b/engines/mutationofjb/tasks/sequentialtask.cpp index 57efbb50d2..20b5290d5d 100644 --- a/engines/mutationofjb/tasks/sequentialtask.cpp +++ b/engines/mutationofjb/tasks/sequentialtask.cpp @@ -48,7 +48,7 @@ void SequentialTask::runTasks() { const TaskPtr &task = _tasks.front(); switch (task->getState()) { case IDLE: - getTaskManager()->addTask(task); + getTaskManager()->startTask(task); break; case RUNNING: return; diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h index 9f2acb3d6b..8c9c0e85b4 100644 --- a/engines/mutationofjb/tasks/task.h +++ b/engines/mutationofjb/tasks/task.h @@ -44,6 +44,7 @@ public: virtual void start() = 0; virtual void update() = 0; + virtual void stop() { assert(false); } // Assert by default - stopping might not be safe for all tasks. void setTaskManager(TaskManager *taskMan) { _taskManager = taskMan; } TaskManager *getTaskManager() { return _taskManager; } diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp index 11675007db..a6d4dc1e84 100644 --- a/engines/mutationofjb/tasks/taskmanager.cpp +++ b/engines/mutationofjb/tasks/taskmanager.cpp @@ -21,21 +21,39 @@ */ #include "mutationofjb/tasks/taskmanager.h" + #include "mutationofjb/tasks/task.h" +#include "common/translation.h" + namespace MutationOfJB { -void TaskManager::addTask(const TaskPtr &task) { +void TaskManager::startTask(const TaskPtr &task) { _tasks.push_back(task); task->setTaskManager(this); task->start(); } -void TaskManager::removeTask(const TaskPtr &task) { +void TaskManager::stopTask(const TaskPtr &task) { TaskPtrs::iterator it = Common::find(_tasks.begin(), _tasks.end(), task); - if (it != _tasks.end()) { - _tasks.erase(it); + if (it == _tasks.end()) { + warning(_("Task is not registered in TaskManager.")); + return; + } + + task->stop(); + assert(task->getState() != Task::RUNNING); + _tasks.erase(it); +} + +TaskPtr TaskManager::getTask(Task *const task) { + for (TaskPtrs::iterator it = _tasks.begin(); it != _tasks.end(); ++it) { + if (it->get() == task) { + return *it; + } } + + return TaskPtr(); } void TaskManager::update() { diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h index 299a271711..29e854a313 100644 --- a/engines/mutationofjb/tasks/taskmanager.h +++ b/engines/mutationofjb/tasks/taskmanager.h @@ -35,8 +35,30 @@ class TaskManager { public: TaskManager(Game &game) : _game(game) {} - void addTask(const TaskPtr &task); - void removeTask(const TaskPtr &task); + /** + * Adds the task to the internal list and starts it. + * + * When the task is finished, it is automatically removed from the list. + * stopTask does not need to be called for that. + */ + void startTask(const TaskPtr &task); + + /** + * Stops the task and removes it from the internal list. + * + * Call this only if you need to explicitly stop the task (usually before it's finished). + */ + void stopTask(const TaskPtr &task); + + /** + * Gets task shared pointer from raw pointer. + * + * Since task lifetime is under control of SharedPtr, raw pointers shouldn't be used. + * However, if only a raw pointer is available (e.g. this), + * the method can be used to obtain a SharedPtr. + */ + TaskPtr getTask(Task* task); + void update(); Game &getGame() { return _game; } |