mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
MUTATIONOFJB: Run extra sections from conversation.
This commit is contained in:
parent
d22da95282
commit
d358a65bbc
@ -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) {
|
||||
|
@ -56,6 +56,7 @@ private:
|
||||
typedef Common::Array<IdAndCommand> IdAndCommandArray;
|
||||
NameAndCommandArray _foundMacros;
|
||||
IdAndCommandArray _foundStartups;
|
||||
NameAndCommandArray _foundExtras;
|
||||
};
|
||||
|
||||
class EndBlockCommand : public Command {
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +202,7 @@ Common::Error MutationOfJBEngine::run() {
|
||||
_game->setCurrentAction(ActionInfo::PickUp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user