Permalink
Browse files

MUTATIONOFJB: Implement multiple speeches in one response line.

  • Loading branch information...
LubomirR committed Jul 21, 2018
1 parent 076b439 commit 562e2571cfea32a54ab328678fdbdf747c328b93
@@ -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;
}
@@ -25,6 +25,7 @@

#include "mutationofjb/commands/seqcommand.h"
#include "common/scummsys.h"
#include "mutationofjb/tasks/task.h"

namespace MutationOfJB {

@@ -43,13 +44,13 @@ class TalkCommand : public SeqCommand {
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;
};

}
@@ -39,8 +39,9 @@ class ConversationLineList {
bool isSecondSpeaker() const { return _text.firstChar() == '`'; }
};

typedef Common::Array<Speech> Speeches;
struct Line {
Common::Array<Speech> _speeches;
Speeches _speeches;
Common::String _extra;
};

@@ -61,7 +61,7 @@ Game::Game(MutationOfJBEngine *vm)

_gui.init();

_taskManager.addTask(new ObjectAnimationTask);
_taskManager.addTask(TaskPtr(new ObjectAnimationTask));
}

Common::RandomSource &Game::getRandomSource() {
@@ -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 \
@@ -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;
}

}
@@ -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 @@ class ConversationTask : public Task, public ConversationWidgetCallback {
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,
@@ -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;
}
}
}

}
@@ -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
@@ -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 @@ class Task {
FINISHED
};

Task() : _taskManager(nullptr) {}
Task() : _taskManager(nullptr), _state(IDLE) {}
virtual ~Task() {}

virtual void start() = 0;
@@ -56,6 +58,9 @@ class Task {
State _state;
};

typedef Common::SharedPtr<Task> TaskPtr;
typedef Common::Array<Common::SharedPtr<Task> > TaskPtrs;

}

#endif
Oops, something went wrong.

0 comments on commit 562e257

Please sign in to comment.