diff options
author | Ľubomír Remák | 2018-08-04 18:41:33 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2018-08-25 23:12:01 +0200 |
commit | 4633b8398642f3005827780313c25479689a72dc (patch) | |
tree | 5299a70ec917c73f5b477e5e4add3d6773e9d177 /engines/mutationofjb | |
parent | a25715a29b0587ae6795eef63a575172e2cb971d (diff) | |
download | scummvm-rg350-4633b8398642f3005827780313c25479689a72dc.tar.gz scummvm-rg350-4633b8398642f3005827780313c25479689a72dc.tar.bz2 scummvm-rg350-4633b8398642f3005827780313c25479689a72dc.zip |
MUTATIONOFJB: Improve documentation and naming.
Diffstat (limited to 'engines/mutationofjb')
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 ®, 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 ¤tGroup = 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) {} |