aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorĽubomír Remák2018-08-04 18:41:33 +0200
committerEugene Sandulenko2018-08-25 23:12:01 +0200
commit4633b8398642f3005827780313c25479689a72dc (patch)
tree5299a70ec917c73f5b477e5e4add3d6773e9d177 /engines
parenta25715a29b0587ae6795eef63a575172e2cb971d (diff)
downloadscummvm-rg350-4633b8398642f3005827780313c25479689a72dc.tar.gz
scummvm-rg350-4633b8398642f3005827780313c25479689a72dc.tar.bz2
scummvm-rg350-4633b8398642f3005827780313c25479689a72dc.zip
MUTATIONOFJB: Improve documentation and naming.
Diffstat (limited to 'engines')
-rw-r--r--engines/mutationofjb/commands/camefromcommand.cpp2
-rw-r--r--engines/mutationofjb/commands/changecommand.cpp4
-rw-r--r--engines/mutationofjb/commands/command.h43
-rw-r--r--engines/mutationofjb/commands/definestructcommand.cpp26
-rw-r--r--engines/mutationofjb/commands/endblockcommand.cpp23
-rw-r--r--engines/mutationofjb/commands/ifitemcommand.cpp2
-rw-r--r--engines/mutationofjb/commands/removeitemcommand.cpp2
-rw-r--r--engines/mutationofjb/commands/saycommand.cpp6
-rw-r--r--engines/mutationofjb/commands/seqcommand.h3
-rw-r--r--engines/mutationofjb/commands/talkcommand.cpp11
-rw-r--r--engines/mutationofjb/gamedata.cpp18
-rw-r--r--engines/mutationofjb/gamedata.h41
-rw-r--r--engines/mutationofjb/tasks/conversationtask.cpp81
-rw-r--r--engines/mutationofjb/tasks/conversationtask.h12
-rw-r--r--engines/mutationofjb/tasks/objectanimationtask.cpp2
-rw-r--r--engines/mutationofjb/tasks/sequentialtask.h3
-rw-r--r--engines/mutationofjb/tasks/task.h3
-rw-r--r--engines/mutationofjb/tasks/taskmanager.h5
18 files changed, 186 insertions, 101 deletions
diff --git a/engines/mutationofjb/commands/camefromcommand.cpp b/engines/mutationofjb/commands/camefromcommand.cpp
index 485e0c54c9..67033b8a53 100644
--- a/engines/mutationofjb/commands/camefromcommand.cpp
+++ b/engines/mutationofjb/commands/camefromcommand.cpp
@@ -26,7 +26,7 @@
#include "common/str.h"
/** @file
- * "CAMEFROM" <sceneId>
+ * "CAMEFROM " <sceneId>
*
* This command tests whether last scene (the scene player came from) is sceneId.
* If true, the execution continues after this command.
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index 5d6833b82c..7d2e7e6910 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -25,8 +25,6 @@
#include "mutationofjb/gamedata.h"
#include "common/translation.h"
-namespace MutationOfJB {
-
/** @file
* "CHANGE" <entity> " " <register> " " <sceneId> " " <entityId> " " <value>
*
@@ -43,6 +41,8 @@ namespace MutationOfJB {
* <value> *B Value (variable length).
*/
+namespace MutationOfJB {
+
bool ChangeCommandParser::parseValueString(const Common::String &valueString, bool changeEntity, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister &reg, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv) {
if (changeEntity) {
if (valueString.size() < 8) {
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index 0133d52dd0..b407aa1119 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -33,18 +33,56 @@ class Command;
class ScriptExecutionContext;
class ScriptParseContext;
+/**
+ * Base class for command parsers.
+ *
+ * The parser's main job is to create a Command instance from input line.
+ */
class CommandParser {
public:
virtual ~CommandParser();
+
+ /**
+ * Parses the specified line and possibly returns a Command instance.
+ *
+ * @param line Line to parse.
+ * @param parseCtx Parse context.
+ * @param command Output parameter for newly created command.
+ * @return True if the line has been successfully parsed by this parser, false otherwise.
+ * @note You may return true and set command to nullptr.
+ * That means the line has been successfully parsed, but no command is needed.
+ */
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) = 0;
- /* Old command - created by this parser. */
+ /**
+ * Called when transitioning parsing between two commands.
+ *
+ * For example, cmdParserA->transition(parseCtx, cmdA, cmdB, cmdParserB) is called after command B is done parsing
+ * to notify command A parser about the transition from command A to command B.
+ * This is useful for sequential commands, because at the time command A is being parsed,
+ * we don't have any information about command B, so we cannot set the next pointer.
+ * Transition method can be used to set the next pointer after command B is available.
+ *
+ * @param parseCtx Parse context.
+ * @param oldCommand Old command (created by this parser).
+ * @param newCommand New command (created by newCommandParser).
+ * @param newCommandParser Command parser which created the new command.
+ */
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
- /* Called after parsing. */
+ /**
+ * Called after the whole script is parsed.
+ *
+ * Can be used for cleanup.
+ *
+ * @param parseCtx Parse context.
+ */
virtual void finish(ScriptParseContext &parseCtx);
};
+/**
+ * Base class for script commands.
+ */
class Command {
public:
enum ExecuteResult {
@@ -60,6 +98,7 @@ public:
virtual Common::String debugString() const = 0;
};
+
}
#endif
diff --git a/engines/mutationofjb/commands/definestructcommand.cpp b/engines/mutationofjb/commands/definestructcommand.cpp
index 4ccf2e8631..bea3497a3d 100644
--- a/engines/mutationofjb/commands/definestructcommand.cpp
+++ b/engines/mutationofjb/commands/definestructcommand.cpp
@@ -25,6 +25,22 @@
#include "mutationofjb/game.h"
#include "common/debug.h"
+/** @file
+ * "DEFINE_STRUCT " <numItemGroups> " " <context> " " <objectId> " " <colorString> <CRLF>
+ * <itemGroup> { <CRLF> <itemGroup> }
+ *
+ * item ::= <questionIndex> " " <responseIndex> " " <nextGroup>
+ * itemGroup ::= <item> " " <item> " " <item> " " <item> " " <item>
+ *
+ * Defines the flow of an interactive conversation.
+ *
+ * Every item group consists of 5 conversation items.
+ * "questionIndex" and "responseIndex" specify what the player and the responder say when the conversation item is selected.
+ * They refer to the line numbers of TOSAY.GER and RESPONSE.GER, respectively.
+ * "nextGroup" refers to the group that follows when the conversation item is selected. A value of 0 indicates end of
+ * conversation.
+ */
+
namespace MutationOfJB {
bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
@@ -52,19 +68,19 @@ bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseCon
const char *linePtr = convLineStr.c_str();
- ConversationInfo::Line convLine;
+ ConversationInfo::ItemGroup convGroup;
for (int j = 0; j < 5; ++j) {
ConversationInfo::Item convItem;
- convItem._choice = atoi(linePtr);
+ convItem._question = atoi(linePtr);
linePtr += 6;
convItem._response = atoi(linePtr);
linePtr += 6;
- convItem._nextLineIndex = atoi(linePtr);
+ convItem._nextGroupIndex = atoi(linePtr);
linePtr += 3;
- convLine._items.push_back(convItem);
+ convGroup.push_back(convItem);
}
- convInfo._lines.push_back(convLine);
+ convInfo._itemGroups.push_back(convGroup);
}
command = new DefineStructCommand(convInfo);
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index c7fbd41f00..8ad11f8946 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -28,16 +28,19 @@
#include "common/translation.h"
/** @file
- * ("#L " | "-L ") <object>
- * ("#W " | "-W ") <object>
- * ("#T " | "-T ") <object>
- * ("#P " | "-P ") <object1>
- * ("#U " | "-U ") <object1> [<object2>]
- * ("#ELSE" | "-ELSE") [<tag>]
- * "#MACRO " <name>
- * "#EXTRA" <name>
+ * <look> | <walk> | <talk> | <pickup> | <use> | <else> | <macro> | <extra> | <endRandom>
*
- * If a line starts with '#', '=', '-', it is treated as the end of a section.
+ * look ::= ("#L " | "-L ") <object>
+ * walk ::= ("#W " | "-W ") <object>
+ * talk ::= ("#T " | "-T ") <object>
+ * pickup ::= ("#P " | "-P ") <object1>
+ * use ::= ("#U " | "-U ") <object1> [<object2>]
+ * else ::= ("#ELSE" | "-ELSE") [<tag>]
+ * macro ::= "#MACRO " <name>
+ * extra ::= "#EXTRA" <name>
+ * endRandom ::= "\"
+ *
+ * If a line starts with '#', '=', '-', '\' it is treated as the end of a section.
* However, at the same time it can also start a new section depending on what follows.
*
* #L (look), #W (walk), #T (talk), #U (use) sections are executed
@@ -49,6 +52,8 @@
* #MACRO starts a new macro. Global script can call macros from local script and vice versa.
*
* #EXTRA defines an "extra" section. This is called from dialog responses ("TALK TO HIM" command).
+ *
+ * TODO: TIMERPROC.
*/
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index d70add9207..eec4621292 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -28,7 +28,7 @@
#include "common/translation.h"
/** @file
- * "IFITEM" <item> ["!"]
+ * "IFITEM " <item> [ "!" ]
*
* IFITEM command tests whether an item is in the inventory.
* If it is, execution continues to the next line.
diff --git a/engines/mutationofjb/commands/removeitemcommand.cpp b/engines/mutationofjb/commands/removeitemcommand.cpp
index 21d1123dc2..be8ea2359f 100644
--- a/engines/mutationofjb/commands/removeitemcommand.cpp
+++ b/engines/mutationofjb/commands/removeitemcommand.cpp
@@ -25,7 +25,7 @@
#include "mutationofjb/gamedata.h"
/** @file
- * "DELITEM" " " <item>
+ * "DELITEM " <item>
*
* Removes item from inventory.
*/
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
index e63ceb198e..e99b4f20a6 100644
--- a/engines/mutationofjb/commands/saycommand.cpp
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -33,8 +33,10 @@
#include "common/debug-channels.h"
/** @file
- * ("SM" | "SLM" | "NM" | "NLM") " " <lineToSay> ["<" <voiceFile> | "<!"]
- * <skipped> " " <lineToSay> ("<" <voiceFile> | "<!")
+ * <firstLine> { <CRLF> <additionalLine> }
+ *
+ * firstLine ::= ("SM" | "SLM" | "NM" | "NLM") " " <lineToSay> [ "<" <voiceFile> | "<!" ]
+ * additionalLine ::= <skipped> " " <lineToSay> ( "<" <voiceFile> | "<!" )
*
* Say command comes in four variants: SM, SLM, NM and NLM.
* Note: In script files, they are usually written as *SM.
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index 6c969e935f..e37f77ff70 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -33,6 +33,9 @@ public:
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
};
+/**
+ * Base class for sequential commands.
+ */
class SeqCommand : public Command {
public:
SeqCommand() : _nextCommand(nullptr) {}
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 5c7eb8e863..9857f38f9d 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -29,6 +29,17 @@
#include "common/str.h"
+/** @file
+ * "TALK TO HIM" [ " " <mode> ]
+ *
+ * Begins interactive conversation defined by DefineStructCommand.
+ * The command supports multiple modes:
+ * 0 - normal mode,
+ * 1 - Ray and Buttleg mode (two responders),
+ * 2 - unknown (unused) mode,
+ * 3 - carnival ticket seller mode (special animation).
+ */
+
namespace MutationOfJB {
bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index f25eff64d0..d91c0fbd8c 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -136,10 +136,10 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
_palRotFirst = stream.readByte();
_palRotLast = stream.readByte();
_palRotDelay = stream.readByte();
- _exhaustedChoiceNext = stream.readByte();
+ _exhaustedConvItemNext = stream.readByte();
for (i = 0; i < 79; ++i) {
- _exhaustedChoices[i]._encodedData = stream.readByte();
+ _exhaustedConvItems[i]._encodedData = stream.readByte();
}
return true;
@@ -226,15 +226,15 @@ Bitmap *Scene::findBitmap(int16 x, int16 y, int *index) {
return nullptr;
}
-void Scene::addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) {
- _exhaustedChoices[_exhaustedChoiceNext - 1] = ExhaustedChoice(context, choiceIndex, choiceIndexList);
- _exhaustedChoiceNext++;
+void Scene::addExhaustedConvItem(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) {
+ _exhaustedConvItems[_exhaustedConvItemNext - 1] = ExhaustedConvItem(context, convItemIndex, convGroupIndex);
+ _exhaustedConvItemNext++;
}
-bool Scene::isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) const {
- for (uint i = 0; i < _exhaustedChoiceNext - 1; ++i) {
- const ExhaustedChoice &choice = _exhaustedChoices[i];
- if (choice.getContext() == context && choice.getChoiceIndex() == choiceIndex && choice.getChoiceListIndex() == choiceListIndex) {
+bool Scene::isConvItemExhausted(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) const {
+ for (uint8 i = 0; i < _exhaustedConvItemNext - 1; ++i) {
+ const ExhaustedConvItem &convItem = _exhaustedConvItems[i];
+ if (convItem.getContext() == context && convItem.getConvItemIndex() == convItemIndex && convItem.getConvGroupIndex() == convGroupIndex) {
return true;
}
}
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 8783555fe5..8088969c9d 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -225,29 +225,29 @@ struct Bitmap {
};
/**
- * Encoded exhausted choice.
+ * Encoded exhausted convesation item.
*/
-struct ExhaustedChoice {
+struct ExhaustedConvItem {
/**
- * 1 bit - context
- * 3 bits - choice index
- * 4 bits - choice list index
+ * 1 bit - context.
+ * 3 bits - conversation item index.
+ * 4 bits - conversation group index.
*/
uint8 _encodedData;
uint8 getContext() const {
return (_encodedData >> 7) & 0x1;
}
- uint8 getChoiceIndex() const {
+ uint8 getConvItemIndex() const {
return (_encodedData >> 4) & 0x7;
}
- uint8 getChoiceListIndex() const {
+ uint8 getConvGroupIndex() const {
return _encodedData & 0xF;
}
- ExhaustedChoice() : _encodedData(0) {}
- ExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) :
- _encodedData(((context & 0x1) << 7) | ((choiceIndex & 0x7) << 4) | (choiceListIndex & 0xF)) {}
+ ExhaustedConvItem() : _encodedData(0) {}
+ ExhaustedConvItem(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) :
+ _encodedData(((context & 0x1) << 7) | ((convItemIndex & 0x7) << 4) | (convGroupIndex & 0xF)) {}
};
struct Scene {
@@ -263,8 +263,8 @@ struct Scene {
Static *findStatic(int16 x, int16 y, int *index = nullptr);
Bitmap *findBitmap(int16 x, int16 y, int *index = nullptr);
- void addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList);
- bool isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) const;
+ void addExhaustedConvItem(uint8 context, uint8 convItemIndex, uint8 convGroupIndex);
+ bool isConvItemExhausted(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) const;
/** Refers to the script block that will be executed when you enter this scene (DS register). */
uint8 _startup;
@@ -298,28 +298,25 @@ struct Scene {
uint8 _palRotDelay;
/**
- * Points to the first free item in exhausted choices list.
+ * Points to the first free item in exhausted conversation item array.
* @note Indexed from 1.
*/
- uint8 _exhaustedChoiceNext;
- ExhaustedChoice _exhaustedChoices[79];
+ uint8 _exhaustedConvItemNext;
+ ExhaustedConvItem _exhaustedConvItems[79];
bool loadFromStream(Common::ReadStream &stream);
};
struct ConversationInfo {
struct Item {
- uint8 _choice;
+ uint8 _question;
uint8 _response;
- uint8 _nextLineIndex;
+ uint8 _nextGroupIndex;
};
- typedef Common::Array<Item> Items;
- struct Line {
- Items _items;
- };
+ typedef Common::Array<Item> ItemGroup;
- Common::Array<Line> _lines;
+ Common::Array<ItemGroup> _itemGroups;
uint8 _context;
uint8 _objectId;
uint8 _color;
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 8c07b32a69..3b1dcc5246 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -46,7 +46,7 @@ void ConversationTask::start() {
widget.setCallback(this);
widget.setVisible(true);
- _currentLineIndex = 0;
+ _currentGroupIndex = 0;
showChoicesOrPick();
}
@@ -57,10 +57,10 @@ void ConversationTask::update() {
_sayTask.reset();
switch (_substate) {
- case SAYING_NO_CHOICES:
+ case SAYING_NO_QUESTIONS:
finish();
break;
- case SAYING_CHOICE: {
+ case SAYING_QUESTION: {
const ConversationLineList &responseList = getTaskManager()->getGame().getAssets().getResponseList();
const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
@@ -73,7 +73,7 @@ void ConversationTask::update() {
startExtra();
if (_substate != RUNNING_EXTRA) {
- gotoNextLine();
+ gotoNextGroup();
}
break;
}
@@ -89,25 +89,25 @@ void ConversationTask::update() {
delete _innerExecCtx;
_innerExecCtx = nullptr;
- gotoNextLine();
+ gotoNextGroup();
}
}
}
void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint32 data) {
- const ConversationInfo::Item &item = getCurrentLine()->_items[data];
+ const ConversationInfo::Item &item = getCurrentGroup()[data];
convWidget->clearChoices();
const ConversationLineList &toSayList = getTaskManager()->getGame().getAssets().getToSayList();
- const ConversationLineList::Line *line = toSayList.getLine(item._choice);
+ const ConversationLineList::Line *line = toSayList.getLine(item._question);
- _substate = SAYING_CHOICE;
+ _substate = SAYING_QUESTION;
createSayTasks(line);
getTaskManager()->startTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
- getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
+ getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedConvItem(_convInfo._context, data + 1, _currentGroupIndex + 1);
}
}
@@ -116,33 +116,33 @@ void ConversationTask::showChoicesOrPick() {
GameData &gameData = game.getGameData();
Scene *const scene = gameData.getScene(_sceneId);
- Common::Array<uint32> itemsWithValidChoices;
+ Common::Array<uint32> itemsWithValidQuestions;
Common::Array<uint32> itemsWithValidResponses;
Common::Array<uint32> itemsWithValidNext;
/*
- Collect valid "to say" choices (not exhausted and not empty).
+ Collect valid questions (not exhausted and not empty).
Collect valid responses (not exhausted and not empty).
- If there are at least two visible choices, we show them.
- If there is just one visible choice, pick it automatically ONLY if this is not the first choice in this conversation.
+ If there are at least two visible questions, we show them.
+ If there is just one visible question, pick it automatically ONLY if this is not the first question in this conversation.
Otherwise we don't start the conversation.
- If there are no visible choices, automatically pick first valid response.
+ If there are no visible questions, automatically pick the first valid response.
If nothing above applies, don't start the conversation.
*/
- const ConversationInfo::Line *const currentLine = getCurrentLine();
- for (ConversationInfo::Items::size_type i = 0; i < currentLine->_items.size(); ++i) {
- const ConversationInfo::Item &item = currentLine->_items[i];
+ const ConversationInfo::ItemGroup &currentGroup = getCurrentGroup();
+ for (ConversationInfo::ItemGroup::size_type i = 0; i < currentGroup.size(); ++i) {
+ const ConversationInfo::Item &item = currentGroup[i];
- if (scene->isChoiceExhausted(_convInfo._context, (uint8) i + 1, (uint8) _currentLineIndex + 1)) {
+ if (scene->isConvItemExhausted(_convInfo._context, (uint8) i + 1, (uint8) _currentGroupIndex + 1)) {
continue;
}
- const uint8 choice = item._choice;
+ const uint8 toSay = item._question;
const uint8 response = item._response;
- const uint8 next = item._nextLineIndex;
+ const uint8 next = item._nextGroupIndex;
- if (choice != 0) {
- itemsWithValidChoices.push_back(i);
+ if (toSay != 0) {
+ itemsWithValidQuestions.push_back(i);
}
if (response != 0) {
@@ -154,38 +154,38 @@ void ConversationTask::showChoicesOrPick() {
}
}
- if (itemsWithValidChoices.size() > 1) {
+ if (itemsWithValidQuestions.size() > 1) {
ConversationWidget &widget = game.getGui().getConversationWidget();
const ConversationLineList &toSayList = game.getAssets().getToSayList();
- for (Common::Array<uint32>::size_type i = 0; i < itemsWithValidChoices.size() && i < ConversationWidget::CONVERSATION_MAX_CHOICES; ++i) {
- const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices[i]];
- const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
+ for (Common::Array<uint32>::size_type i = 0; i < itemsWithValidQuestions.size() && i < ConversationWidget::CONVERSATION_MAX_CHOICES; ++i) {
+ const ConversationInfo::Item &item = currentGroup[itemsWithValidQuestions[i]];
+ const ConversationLineList::Line *const line = toSayList.getLine(item._question);
const Common::String widgetText = toUpperCP895(line->_speeches[0]._text);
- widget.setChoice((int) i, widgetText, itemsWithValidChoices[i]);
+ widget.setChoice((int) i, widgetText, itemsWithValidQuestions[i]);
}
_substate = IDLE;
_currentItem = nullptr;
_haveChoices = true;
- } else if (itemsWithValidChoices.size() == 1 && _haveChoices) {
+ } else if (itemsWithValidQuestions.size() == 1 && _haveChoices) {
const ConversationLineList &toSayList = game.getAssets().getToSayList();
- const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
- const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
+ const ConversationInfo::Item &item = currentGroup[itemsWithValidQuestions.front()];
+ const ConversationLineList::Line *const line = toSayList.getLine(item._question);
- _substate = SAYING_CHOICE;
+ _substate = SAYING_QUESTION;
createSayTasks(line);
getTaskManager()->startTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
- game.getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, itemsWithValidChoices.front() + 1, _currentLineIndex + 1);
+ game.getGameData().getCurrentScene()->addExhaustedConvItem(_convInfo._context, itemsWithValidQuestions.front() + 1, _currentGroupIndex + 1);
}
_haveChoices = true;
} else if (!itemsWithValidResponses.empty() && _haveChoices) {
const ConversationLineList &responseList = game.getAssets().getResponseList();
- const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
+ const ConversationInfo::Item &item = currentGroup[itemsWithValidResponses.front()];
const ConversationLineList::Line *const line = responseList.getLine(item._response);
_substate = SAYING_RESPONSE;
@@ -195,7 +195,7 @@ void ConversationTask::showChoicesOrPick() {
_haveChoices = true;
} else if (!itemsWithValidNext.empty() && _haveChoices) {
- _currentLineIndex = currentLine->_items[itemsWithValidNext.front()]._nextLineIndex - 1;
+ _currentGroupIndex = currentGroup[itemsWithValidNext.front()]._nextGroupIndex - 1;
showChoicesOrPick();
} else {
if (_haveChoices) {
@@ -203,14 +203,15 @@ void ConversationTask::showChoicesOrPick() {
} else {
_sayTask = TaskPtr(new SayTask("Nothing to talk about.", _convInfo._color)); // TODO: This is hardcoded in executable. Load it.
getTaskManager()->startTask(_sayTask);
- _substate = SAYING_NO_CHOICES;
+ _substate = SAYING_NO_QUESTIONS;
_currentItem = nullptr;
}
}
}
-const ConversationInfo::Line *ConversationTask::getCurrentLine() const {
- return &_convInfo._lines[_currentLineIndex];
+const ConversationInfo::ItemGroup &ConversationTask::getCurrentGroup() const {
+ assert(_currentGroupIndex < _convInfo._itemGroups.size());
+ return _convInfo._itemGroups[_currentGroupIndex];
}
void ConversationTask::finish() {
@@ -244,11 +245,11 @@ void ConversationTask::startExtra() {
}
}
-void ConversationTask::gotoNextLine() {
- if (_currentItem->_nextLineIndex == 0) {
+void ConversationTask::gotoNextGroup() {
+ if (_currentItem->_nextGroupIndex == 0) {
finish();
} else {
- _currentLineIndex = _currentItem->_nextLineIndex - 1;
+ _currentGroupIndex = _currentItem->_nextGroupIndex - 1;
showChoicesOrPick();
}
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index bdfa87533f..9522876a27 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -33,7 +33,7 @@ class ScriptExecutionContext;
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- 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) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo &convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentGroupIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
@@ -42,25 +42,25 @@ public:
virtual void onChoiceClicked(ConversationWidget *, int response, uint32 data) override;
private:
void showChoicesOrPick();
- const ConversationInfo::Line *getCurrentLine() const;
+ const ConversationInfo::ItemGroup &getCurrentGroup() const;
void finish();
void startExtra();
- void gotoNextLine();
+ void gotoNextGroup();
void createSayTasks(const ConversationLineList::Line *line);
uint8 getSpeechColor(const ConversationLineList::Speech &speech);
uint8 _sceneId;
const ConversationInfo &_convInfo;
TalkCommand::Mode _mode;
- uint _currentLineIndex;
+ uint _currentGroupIndex;
const ConversationInfo::Item *_currentItem;
TaskPtr _sayTask;
enum Substate {
IDLE,
- SAYING_CHOICE,
+ SAYING_QUESTION,
SAYING_RESPONSE,
- SAYING_NO_CHOICES,
+ SAYING_NO_QUESTIONS,
RUNNING_EXTRA
};
diff --git a/engines/mutationofjb/tasks/objectanimationtask.cpp b/engines/mutationofjb/tasks/objectanimationtask.cpp
index e93602c367..2b4bf80cd2 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.cpp
+++ b/engines/mutationofjb/tasks/objectanimationtask.cpp
@@ -56,7 +56,7 @@ void ObjectAnimationTask::update() {
* Additionally, there is a chance with each frame until _randomFrame that the animation may jump
* straight to _randomFrame and continue until the last frame, then wrap around to the first frame.
*
- * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occassionally
+ * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occasionally
* spreads its wings.
*/
void ObjectAnimationTask::updateObjects() {
diff --git a/engines/mutationofjb/tasks/sequentialtask.h b/engines/mutationofjb/tasks/sequentialtask.h
index 078fd8aa41..1c00751a61 100644
--- a/engines/mutationofjb/tasks/sequentialtask.h
+++ b/engines/mutationofjb/tasks/sequentialtask.h
@@ -27,6 +27,9 @@
namespace MutationOfJB {
+/**
+ * Queues multiple tasks.
+ */
class SequentialTask : public Task {
public:
SequentialTask(const TaskPtrs &tasks);
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index b14fc971aa..115668a2cc 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -31,6 +31,9 @@ namespace MutationOfJB {
class TaskManager;
+/**
+ * Base class for tasks.
+ */
class Task {
public:
enum State {
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
index 2f351c0bbf..c88da59a69 100644
--- a/engines/mutationofjb/tasks/taskmanager.h
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -31,6 +31,11 @@ namespace MutationOfJB {
class Game;
class Task;
+/**
+ * Handles task management.
+ *
+ * Tasks are a way run game logic asynchronously.
+ */
class TaskManager {
public:
TaskManager(Game &game) : _game(game) {}