aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mutationofjb/commands/endblockcommand.cpp27
-rw-r--r--engines/mutationofjb/commands/endblockcommand.h1
-rw-r--r--engines/mutationofjb/conversationlinelist.cpp4
-rw-r--r--engines/mutationofjb/mutationofjb.cpp1
-rw-r--r--engines/mutationofjb/script.cpp27
-rw-r--r--engines/mutationofjb/script.h5
-rw-r--r--engines/mutationofjb/tasks/conversationtask.cpp54
-rw-r--r--engines/mutationofjb/tasks/conversationtask.h9
8 files changed, 119 insertions, 9 deletions
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 5fcccd390b..b883beed48 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -35,6 +35,7 @@
("#U " | "-U ") <object1> [<object2>]
("#ELSE" | "-ELSE") [<tag>]
"#MACRO " <name>
+ "#EXTRA" <name>
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.
@@ -46,6 +47,8 @@
#ELSE is used by conditional commands (see comments for IfCommand and others).
#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).
*/
namespace MutationOfJB {
@@ -119,6 +122,9 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
const uint8 startupId = atoi(line.c_str() + 9);
IdAndCommand ic = {startupId, command};
_foundStartups.push_back(ic);
+ } else if (line.size() >= 7 && line.hasPrefix("#EXTRA")) {
+ NameAndCommand nc = {line.c_str() + 6, command};
+ _foundExtras.push_back(nc);
}
if (firstChar == '#') {
@@ -183,6 +189,23 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *ol
}
}
}
+ if (!_foundExtras.empty()) {
+ if (newCommand) {
+ for (NameAndCommandArray::iterator it = _foundExtras.begin(); it != _foundExtras.end();) {
+ if (it->_command != oldCommand) {
+ it++;
+ continue;
+ }
+
+ if (!parseCtx._extras.contains(it->_name)) {
+ parseCtx._extras[it->_name] = newCommand;
+ } else {
+ warning(_("Extra '%s' already exists"), it->_name.c_str());
+ }
+ it = _foundExtras.erase(it);
+ }
+ }
+ }
if (newCommandParser != this) {
if (!_pendingActionInfos.empty()) {
@@ -208,9 +231,13 @@ void EndBlockCommandParser::finish(ScriptParseContext &) {
if (!_foundStartups.empty()) {
debug("Problem: Found startups from end block parser is not empty!");
}
+ if (!_foundExtras.empty()) {
+ debug("Problem: Found extras from end block parser is not empty!");
+ }
_pendingActionInfos.clear();
_foundMacros.clear();
_foundStartups.clear();
+ _foundExtras.clear();
}
Command::ExecuteResult EndBlockCommand::execute(ScriptExecutionContext &scriptExecCtx) {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 4ca46dd97d..55656aa351 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -56,6 +56,7 @@ private:
typedef Common::Array<IdAndCommand> IdAndCommandArray;
NameAndCommandArray _foundMacros;
IdAndCommandArray _foundStartups;
+ NameAndCommandArray _foundExtras;
};
class EndBlockCommand : public Command {
diff --git a/engines/mutationofjb/conversationlinelist.cpp b/engines/mutationofjb/conversationlinelist.cpp
index 562c2d0e39..3164ff507b 100644
--- a/engines/mutationofjb/conversationlinelist.cpp
+++ b/engines/mutationofjb/conversationlinelist.cpp
@@ -56,8 +56,8 @@ bool ConversationLineList::parseFile(const Common::String &fileName) {
Common::String::iterator endIt = Common::find(lineStr.begin(), lineStr.end(), '|');
if (endIt != lineStr.end()) {
- Common::String extra = lineStr + endIt;
- if (*endIt == 'X') {
+ endIt++;
+ if (endIt != lineStr.end() && *endIt == 'X') {
line._extra = Common::String(endIt + 1, lineStr.end()); // Skip 'X' char.
}
}
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index e7f534edb0..986b00dfc9 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -202,6 +202,7 @@ Common::Error MutationOfJBEngine::run() {
_game->setCurrentAction(ActionInfo::PickUp);
break;
}
+ break;
}
default:
break;
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index d90f37e161..39c485991b 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -189,6 +189,23 @@ Command *ScriptExecutionContext::getMacro(const Common::String &name) const {
return cmd;
}
+Command *ScriptExecutionContext::getExtra(const Common::String &name) const {
+ Command *cmd = nullptr;
+
+ Script *const localScript = _localScriptOverride ? _localScriptOverride : _game.getLocalScript();
+ Script *const globalScript = _game.getGlobalScript();
+
+ if (localScript) {
+ cmd = localScript->getExtra(name);
+ }
+
+ if (!cmd && globalScript) {
+ cmd = globalScript->getExtra(name);
+ }
+
+ return cmd;
+}
+
bool Script::loadFromStream(Common::SeekableReadStream &stream) {
destroy();
@@ -236,6 +253,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
_macros = parseCtx._macros;
_startups = parseCtx._startups;
+ _extras = parseCtx._extras;
return true;
}
@@ -285,4 +303,13 @@ Command *Script::getStartup(uint8 startupId) const {
return it->_value;
}
+Command *Script::getExtra(const Common::String &name) const {
+ Extras::const_iterator it = _extras.find(name);
+ if (it == _extras.end()) {
+ return nullptr;
+ }
+
+ return it->_value;
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 3ef25f4b68..28e0e98526 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -67,6 +67,7 @@ typedef Common::Array<ActionInfo> ActionInfos;
typedef Common::Array<GotoCommand *> GotoCommands;
typedef Common::HashMap<Common::String, Command *> Macros;
typedef Common::HashMap<uint8, Command *> Startups;
+typedef Common::HashMap<Common::String, Command *> Extras;
class ScriptParseContext {
public:
@@ -98,6 +99,7 @@ public:
ActionInfos _actionInfos;
Macros _macros;
Startups _startups;
+ Extras _extras;
private:
};
@@ -116,6 +118,7 @@ public:
Game &getGame();
GameData &getGameData();
Command *getMacro(const Common::String &name) const;
+ Command *getExtra(const Common::String &name) const;
private:
Game &_game;
@@ -135,6 +138,7 @@ public:
const Startups &getStartups() const;
Command *getMacro(const Common::String &name) const;
Command *getStartup(uint8 startupId) const;
+ Command *getExtra(const Common::String &name) const;
private:
void destroy();
@@ -142,6 +146,7 @@ private:
ActionInfos _actionInfos[5];
Macros _macros;
Startups _startups;
+ Extras _extras;
};
}
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 512b38b710..47f27df247 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -27,11 +27,14 @@
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
+#include "mutationofjb/script.h"
#include "mutationofjb/tasks/saytask.h"
#include "mutationofjb/tasks/taskmanager.h"
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/conversationwidget.h"
+#include "common/translation.h"
+
namespace MutationOfJB {
void ConversationTask::start() {
@@ -69,11 +72,11 @@ void ConversationTask::update() {
break;
}
case SAYING_RESPONSE: {
- if (_currentItem->_nextLineIndex == 0) {
- finish();
- } else {
- _currentLineIndex = _currentItem->_nextLineIndex - 1;
- showChoicesOrPick();
+ startExtra();
+
+ if (_substate != RUNNING_EXTRA)
+ {
+ gotoNextLine();
}
break;
}
@@ -82,6 +85,16 @@ void ConversationTask::update() {
}
}
}
+
+ if (_innerExecCtx) {
+ Command::ExecuteResult res = _innerExecCtx->runActiveCommand();
+ if (res == Command::Finished) {
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+
+ gotoNextLine();
+ }
+ }
}
void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint32 data) {
@@ -203,4 +216,35 @@ void ConversationTask::finish() {
game.getGui().markDirty(); // TODO: Handle automatically when changing visibility.
}
+void ConversationTask::startExtra() {
+ const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
+ const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
+ if (!line->_extra.empty()) {
+ _innerExecCtx = new ScriptExecutionContext(getTaskManager()->getGame());
+ Command *const extraCmd = _innerExecCtx->getExtra(line->_extra);
+ if (extraCmd) {
+ Command::ExecuteResult res = _innerExecCtx->startCommand(extraCmd);
+ if (res == Command::InProgress) {
+ _substate = RUNNING_EXTRA;
+ } else {
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+ }
+ } else {
+ warning(_("Extra '%s' not found"), line->_extra.c_str());
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+ }
+ }
+}
+
+void ConversationTask::gotoNextLine() {
+ if (_currentItem->_nextLineIndex == 0) {
+ finish();
+ } else {
+ _currentLineIndex = _currentItem->_nextLineIndex - 1;
+ showChoicesOrPick();
+ }
+}
+
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index 3bcbb6f998..41c82849ee 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -27,10 +27,11 @@
namespace MutationOfJB {
class SayTask;
+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) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo& convInfo) : _sceneId(sceneId), _convInfo(convInfo), _currentLineIndex(0), _currentItem(nullptr), _sayTask(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
@@ -41,6 +42,8 @@ private:
void showChoicesOrPick();
const ConversationInfo::Line *getCurrentLine() const;
void finish();
+ void startExtra();
+ void gotoNextLine();
uint8 _sceneId;
const ConversationInfo &_convInfo;
@@ -52,11 +55,13 @@ private:
IDLE,
SAYING_CHOICE,
SAYING_RESPONSE,
- SAYING_NO_CHOICES
+ SAYING_NO_CHOICES,
+ RUNNING_EXTRA
};
Substate _substate;
bool _haveChoices;
+ ScriptExecutionContext *_innerExecCtx;
};
}