aboutsummaryrefslogtreecommitdiff
path: root/engines/mutationofjb
diff options
context:
space:
mode:
authorĽubomír Remák2018-07-21 15:17:17 +0200
committerEugene Sandulenko2018-08-25 23:12:01 +0200
commit6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3 (patch)
tree76ac2bd31d15cb278162d803a1403388abafc6a5 /engines/mutationofjb
parent215b87ccca4c4888cd70c990271fe62177d054f0 (diff)
downloadscummvm-rg350-6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3.tar.gz
scummvm-rg350-6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3.tar.bz2
scummvm-rg350-6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3.zip
MUTATIONOFJB: Implement multiple speeches in one response line.
Diffstat (limited to 'engines/mutationofjb')
-rw-r--r--engines/mutationofjb/commands/talkcommand.cpp5
-rw-r--r--engines/mutationofjb/commands/talkcommand.h5
-rw-r--r--engines/mutationofjb/conversationlinelist.h3
-rw-r--r--engines/mutationofjb/game.cpp2
-rw-r--r--engines/mutationofjb/module.mk1
-rw-r--r--engines/mutationofjb/tasks/conversationtask.cpp55
-rw-r--r--engines/mutationofjb/tasks/conversationtask.h11
-rw-r--r--engines/mutationofjb/tasks/sequentialtask.cpp62
-rw-r--r--engines/mutationofjb/tasks/sequentialtask.h45
-rw-r--r--engines/mutationofjb/tasks/task.h7
-rw-r--r--engines/mutationofjb/tasks/taskmanager.cpp17
-rw-r--r--engines/mutationofjb/tasks/taskmanager.h8
12 files changed, 187 insertions, 34 deletions
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 18ce956696..8411e9080a 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -56,14 +56,13 @@ bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &,
Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx) {
if (!_task) {
- _task = new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo);
+ _task = TaskPtr(new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo, _mode));
scriptExeCtx.getGame().getTaskManager().addTask(_task);
}
if (_task->getState() == Task::FINISHED) {
scriptExeCtx.getGame().getTaskManager().removeTask(_task);
- delete _task;
- _task = nullptr;
+ _task.reset();
return Command::Finished;
}
diff --git a/engines/mutationofjb/commands/talkcommand.h b/engines/mutationofjb/commands/talkcommand.h
index 09424b2f06..15b185c613 100644
--- a/engines/mutationofjb/commands/talkcommand.h
+++ b/engines/mutationofjb/commands/talkcommand.h
@@ -25,6 +25,7 @@
#include "mutationofjb/commands/seqcommand.h"
#include "common/scummsys.h"
+#include "mutationofjb/tasks/task.h"
namespace MutationOfJB {
@@ -43,13 +44,13 @@ public:
CARNIVAL_TICKET_SELLER_MODE
};
- TalkCommand(Mode mode) : _mode(mode), _task(nullptr) {}
+ TalkCommand(Mode mode) : _mode(mode) {}
virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
private:
Mode _mode;
- ConversationTask *_task;
+ TaskPtr _task;
};
}
diff --git a/engines/mutationofjb/conversationlinelist.h b/engines/mutationofjb/conversationlinelist.h
index 9ec446e4b4..0f8346f69a 100644
--- a/engines/mutationofjb/conversationlinelist.h
+++ b/engines/mutationofjb/conversationlinelist.h
@@ -39,8 +39,9 @@ public:
bool isSecondSpeaker() const { return _text.firstChar() == '`'; }
};
+ typedef Common::Array<Speech> Speeches;
struct Line {
- Common::Array<Speech> _speeches;
+ Speeches _speeches;
Common::String _extra;
};
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 652336fff2..9f5f469c15 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -61,7 +61,7 @@ Game::Game(MutationOfJBEngine *vm)
_gui.init();
- _taskManager.addTask(new ObjectAnimationTask);
+ _taskManager.addTask(TaskPtr(new ObjectAnimationTask));
}
Common::RandomSource &Game::getRandomSource() {
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 1913fc62cd..60d450e3e7 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -25,6 +25,7 @@ MODULE_OBJS := \
tasks/conversationtask.o \
tasks/objectanimationtask.o \
tasks/saytask.o \
+ tasks/sequentialtask.o \
tasks/taskmanager.o \
widgets/buttonwidget.o \
widgets/conversationwidget.o \
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index d675b2eb47..a2a0a73bf0 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -23,12 +23,12 @@
#include "mutationofjb/tasks/conversationtask.h"
#include "mutationofjb/assets.h"
-#include "mutationofjb/conversationlinelist.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
#include "mutationofjb/script.h"
#include "mutationofjb/tasks/saytask.h"
+#include "mutationofjb/tasks/sequentialtask.h"
#include "mutationofjb/tasks/taskmanager.h"
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/conversationwidget.h"
@@ -55,8 +55,7 @@ void ConversationTask::update() {
if (_sayTask) {
if (_sayTask->getState() == Task::FINISHED) {
getTaskManager()->removeTask(_sayTask);
- delete _sayTask;
- _sayTask = nullptr;
+ _sayTask.reset();
switch (_substate) {
case SAYING_NO_CHOICES:
@@ -66,9 +65,9 @@ void ConversationTask::update() {
const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
- _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_RESPONSE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
break;
}
case SAYING_RESPONSE: {
@@ -102,14 +101,14 @@ void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint
convWidget->clearChoices();
const ConversationLineList& toSayList = getTaskManager()->getGame().getAssets().getToSayList();
- const ConversationLineList::Speech &speech = toSayList.getLine(item._choice)->_speeches[0];
+ const ConversationLineList::Line *line = toSayList.getLine(item._choice);
- _sayTask = new SayTask(speech._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_CHOICE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
_currentItem = &item;
- if (!speech.isRepeating()) {
+ if (!line->_speeches[0].isRepeating()) {
getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
}
}
@@ -176,9 +175,9 @@ void ConversationTask::showChoicesOrPick() {
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
- _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_CHOICE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
@@ -191,9 +190,9 @@ void ConversationTask::showChoicesOrPick() {
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
const ConversationLineList::Line *const line = responseList.getLine(item._response);
- _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_RESPONSE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
_currentItem = &item;
_haveChoices = true;
@@ -204,7 +203,7 @@ void ConversationTask::showChoicesOrPick() {
if (_haveChoices) {
finish();
} else {
- _sayTask = new SayTask("Nothing to talk about.", _convInfo._color); // TODO: This is hardcoded in executable. Load it.
+ _sayTask = TaskPtr(new SayTask("Nothing to talk about.", _convInfo._color)); // TODO: This is hardcoded in executable. Load it.
getTaskManager()->addTask(_sayTask);
_substate = SAYING_NO_CHOICES;
_currentItem = nullptr;
@@ -256,4 +255,32 @@ void ConversationTask::gotoNextLine() {
}
}
+void ConversationTask::createSayTasks(const ConversationLineList::Line *line) {
+ if (line->_speeches.size() == 1) {
+ const ConversationLineList::Speech &speech = line->_speeches[0];
+ _sayTask = TaskPtr(new SayTask(speech._text, getSpeechColor(speech)));
+ } else {
+ TaskPtrs tasks;
+ for (ConversationLineList::Speeches::const_iterator it = line->_speeches.begin(); it != line->_speeches.end(); ++it) {
+ tasks.push_back(TaskPtr(new SayTask(it->_text, getSpeechColor(*it))));
+ }
+ _sayTask = TaskPtr(new SequentialTask(tasks));
+ }
+}
+
+uint8 ConversationTask::getSpeechColor(const ConversationLineList::Speech &speech) {
+ uint8 color = WHITE;
+ if (_substate == SAYING_RESPONSE) {
+ color = _convInfo._color;
+ if (_mode == TalkCommand::RAY_AND_BUTTLEG_MODE) {
+ if (speech.isFirstSpeaker()) {
+ color = GREEN;
+ } else if (speech.isSecondSpeaker()) {
+ color = LIGHTBLUE;
+ }
+ }
+ }
+ return color;
+}
+
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index 41c82849ee..e4bbdc3276 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -20,8 +20,10 @@
*
*/
-#include "mutationofjb/tasks/task.h"
+#include "mutationofjb/commands/talkcommand.h"
+#include "mutationofjb/conversationlinelist.h"
#include "mutationofjb/gamedata.h"
+#include "mutationofjb/tasks/task.h"
#include "mutationofjb/widgets/conversationwidget.h"
namespace MutationOfJB {
@@ -31,7 +33,7 @@ class ScriptExecutionContext;
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- ConversationTask(uint8 sceneId, const ConversationInfo& convInfo) : _sceneId(sceneId), _convInfo(convInfo), _currentLineIndex(0), _currentItem(nullptr), _sayTask(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo& convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentLineIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
@@ -44,12 +46,15 @@ private:
void finish();
void startExtra();
void gotoNextLine();
+ void createSayTasks(const ConversationLineList::Line *line);
+ uint8 getSpeechColor(const ConversationLineList::Speech &speech);
uint8 _sceneId;
const ConversationInfo &_convInfo;
+ TalkCommand::Mode _mode;
uint _currentLineIndex;
const ConversationInfo::Item *_currentItem;
- SayTask* _sayTask;
+ TaskPtr _sayTask;
enum Substate {
IDLE,
diff --git a/engines/mutationofjb/tasks/sequentialtask.cpp b/engines/mutationofjb/tasks/sequentialtask.cpp
new file mode 100644
index 0000000000..57efbb50d2
--- /dev/null
+++ b/engines/mutationofjb/tasks/sequentialtask.cpp
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mutationofjb/tasks/sequentialtask.h"
+
+#include "mutationofjb/tasks/taskmanager.h"
+
+namespace MutationOfJB {
+
+SequentialTask::SequentialTask(const TaskPtrs &tasks) : _tasks(tasks) {
+}
+
+void SequentialTask::start() {
+ setState(RUNNING);
+ runTasks();
+}
+
+void SequentialTask::update() {
+ runTasks();
+}
+
+void SequentialTask::runTasks() {
+ while (true) {
+ if (_tasks.empty()) {
+ setState(FINISHED);
+ return;
+ }
+
+ const TaskPtr &task = _tasks.front();
+ switch (task->getState()) {
+ case IDLE:
+ getTaskManager()->addTask(task);
+ break;
+ case RUNNING:
+ return;
+ case FINISHED:
+ _tasks.remove_at(0);
+ break;
+ }
+ }
+}
+
+}
diff --git a/engines/mutationofjb/tasks/sequentialtask.h b/engines/mutationofjb/tasks/sequentialtask.h
new file mode 100644
index 0000000000..078fd8aa41
--- /dev/null
+++ b/engines/mutationofjb/tasks/sequentialtask.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MUTATIONOFJB_SEQUENTIALTASK_H
+#define MUTATIONOFJB_SEQUENTIALTASK_H
+
+#include "mutationofjb/tasks/task.h"
+
+namespace MutationOfJB {
+
+class SequentialTask : public Task {
+public:
+ SequentialTask(const TaskPtrs &tasks);
+
+ virtual void start() override;
+ virtual void update() override;
+
+private:
+ void runTasks();
+
+ TaskPtrs _tasks;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index 1b98097b9c..9f2acb3d6b 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -24,6 +24,8 @@
#define MUTATIONOFJB_TASK_H
#include "common/scummsys.h"
+#include "common/ptr.h"
+#include "common/array.h"
namespace MutationOfJB {
@@ -37,7 +39,7 @@ public:
FINISHED
};
- Task() : _taskManager(nullptr) {}
+ Task() : _taskManager(nullptr), _state(IDLE) {}
virtual ~Task() {}
virtual void start() = 0;
@@ -56,6 +58,9 @@ private:
State _state;
};
+typedef Common::SharedPtr<Task> TaskPtr;
+typedef Common::Array<Common::SharedPtr<Task> > TaskPtrs;
+
}
#endif
diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp
index 7fbf64dc9b..11675007db 100644
--- a/engines/mutationofjb/tasks/taskmanager.cpp
+++ b/engines/mutationofjb/tasks/taskmanager.cpp
@@ -25,24 +25,31 @@
namespace MutationOfJB {
-void TaskManager::addTask(Task *task) {
+void TaskManager::addTask(const TaskPtr &task) {
_tasks.push_back(task);
task->setTaskManager(this);
task->start();
}
-void TaskManager::removeTask(Task *task) {
- Tasks::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
+void TaskManager::removeTask(const TaskPtr &task) {
+ TaskPtrs::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
if (it != _tasks.end()) {
_tasks.erase(it);
}
}
void TaskManager::update() {
- for (Tasks::const_iterator it = _tasks.begin(); it != _tasks.end(); ++it) {
- if ((*it)->getState() == Task::RUNNING) {
+ for (TaskPtrs::iterator it = _tasks.begin(); it != _tasks.end();) {
+ const Task::State state = (*it)->getState();
+ if (state == Task::RUNNING) {
(*it)->update();
}
+
+ if (state == Task::FINISHED) {
+ it = _tasks.erase(it);
+ } else {
+ ++it;
+ }
}
}
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
index 1f6be36ced..299a271711 100644
--- a/engines/mutationofjb/tasks/taskmanager.h
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -24,6 +24,7 @@
#define MUTATIONOFJB_TASKMANAGER_H
#include "common/array.h"
+#include "task.h"
namespace MutationOfJB {
@@ -34,15 +35,14 @@ class TaskManager {
public:
TaskManager(Game &game) : _game(game) {}
- void addTask(Task *task);
- void removeTask(Task *task);
+ void addTask(const TaskPtr &task);
+ void removeTask(const TaskPtr &task);
void update();
Game &getGame() { return _game; }
private:
- typedef Common::Array<Task *> Tasks;
- Tasks _tasks;
+ TaskPtrs _tasks;
Game &_game;
};