aboutsummaryrefslogtreecommitdiff
path: root/engines/mutationofjb
diff options
context:
space:
mode:
authorĽubomír Remák2018-07-21 20:29:11 +0200
committerEugene Sandulenko2018-08-25 23:12:01 +0200
commit3306cbfeaa2f1c6fd471daaee054290df7e44280 (patch)
tree56379cb27336281e9ca92b12d6db7ab6d84c31e8 /engines/mutationofjb
parent2e656e69b3b9416f5164f0963951df203f4978e5 (diff)
downloadscummvm-rg350-3306cbfeaa2f1c6fd471daaee054290df7e44280.tar.gz
scummvm-rg350-3306cbfeaa2f1c6fd471daaee054290df7e44280.tar.bz2
scummvm-rg350-3306cbfeaa2f1c6fd471daaee054290df7e44280.zip
MUTATIONOFJB: Implement SayCommand::execute.
Diffstat (limited to 'engines/mutationofjb')
-rw-r--r--engines/mutationofjb/commands/saycommand.cpp21
-rw-r--r--engines/mutationofjb/commands/talkcommand.cpp3
-rw-r--r--engines/mutationofjb/font.cpp2
-rw-r--r--engines/mutationofjb/game.cpp15
-rw-r--r--engines/mutationofjb/game.h11
-rw-r--r--engines/mutationofjb/gamedata.cpp3
-rw-r--r--engines/mutationofjb/gamedata.h12
-rw-r--r--engines/mutationofjb/script.cpp1
-rw-r--r--engines/mutationofjb/tasks/conversationtask.cpp11
-rw-r--r--engines/mutationofjb/tasks/saytask.cpp30
-rw-r--r--engines/mutationofjb/tasks/saytask.h2
-rw-r--r--engines/mutationofjb/tasks/sequentialtask.cpp2
-rw-r--r--engines/mutationofjb/tasks/task.h1
-rw-r--r--engines/mutationofjb/tasks/taskmanager.cpp26
-rw-r--r--engines/mutationofjb/tasks/taskmanager.h26
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; }