From 6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3 Mon Sep 17 00:00:00 2001 From: Ľubomír Remák Date: Sat, 21 Jul 2018 15:17:17 +0200 Subject: MUTATIONOFJB: Implement multiple speeches in one response line. --- engines/mutationofjb/commands/talkcommand.cpp | 5 +- engines/mutationofjb/commands/talkcommand.h | 5 +- engines/mutationofjb/conversationlinelist.h | 3 +- engines/mutationofjb/game.cpp | 2 +- engines/mutationofjb/module.mk | 1 + engines/mutationofjb/tasks/conversationtask.cpp | 55 ++++++++++++++++------ engines/mutationofjb/tasks/conversationtask.h | 11 +++-- engines/mutationofjb/tasks/sequentialtask.cpp | 62 +++++++++++++++++++++++++ engines/mutationofjb/tasks/sequentialtask.h | 45 ++++++++++++++++++ engines/mutationofjb/tasks/task.h | 7 ++- engines/mutationofjb/tasks/taskmanager.cpp | 17 +++++-- engines/mutationofjb/tasks/taskmanager.h | 8 ++-- 12 files changed, 187 insertions(+), 34 deletions(-) create mode 100644 engines/mutationofjb/tasks/sequentialtask.cpp create mode 100644 engines/mutationofjb/tasks/sequentialtask.h (limited to 'engines') 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 Speeches; struct Line { - Common::Array _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 TaskPtr; +typedef Common::Array > 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 Tasks; - Tasks _tasks; + TaskPtrs _tasks; Game &_game; }; -- cgit v1.2.3