mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
MUTATIONOFJB: Don't store ActionInfo pointers, because they might be invalidated, and parse/show actions with two objects correctly.
This commit is contained in:
parent
5854d310ee
commit
37ae32e1d3
@ -42,33 +42,43 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
|
||||
|
||||
if (line.size() >= 4 && (line.hasPrefix("#L ") || line.hasPrefix("-L "))) {
|
||||
ActionInfo ai = {ActionInfo::Look, line.c_str() + 3, "", firstChar == '#', nullptr};
|
||||
parseCtx._lookActionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(&parseCtx._lookActionInfos.back());
|
||||
parseCtx._actionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
|
||||
} else if (line.size() >= 4 && (line.hasPrefix("#W ") || line.hasPrefix("-W "))) {
|
||||
ActionInfo ai = {ActionInfo::Walk, line.c_str() + 3, "", firstChar == '#', nullptr};
|
||||
parseCtx._walkActionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(&parseCtx._walkActionInfos.back());
|
||||
parseCtx._actionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
|
||||
} else if (line.size() >= 4 && (line.hasPrefix("#T ") || line.hasPrefix("-T "))) {
|
||||
ActionInfo ai = {ActionInfo::Talk, line.c_str() + 3, "", firstChar == '#', nullptr};
|
||||
parseCtx._talkActionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(&parseCtx._talkActionInfos.back());
|
||||
parseCtx._actionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
|
||||
} else if (line.size() >= 4 && (line.hasPrefix("#U ") || line.hasPrefix("-U "))) {
|
||||
int secondObjPos = -1;
|
||||
for (int i = 3; i < (int) line.size(); ++i) {
|
||||
for (uint i = 3; i < line.size(); ++i) {
|
||||
if (line[i] == ' ') {
|
||||
secondObjPos = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Common::String obj1;
|
||||
Common::String obj2;
|
||||
if (secondObjPos == -1) {
|
||||
obj1 = line.c_str() + 3;
|
||||
} else {
|
||||
obj1 = Common::String(line.c_str() + 3, secondObjPos - 4);
|
||||
obj2 = line.c_str() + secondObjPos;
|
||||
}
|
||||
|
||||
ActionInfo ai = {
|
||||
ActionInfo::Use,
|
||||
line.c_str() + 3,
|
||||
(secondObjPos != -1) ? line.c_str() + secondObjPos : "",
|
||||
obj1,
|
||||
obj2,
|
||||
firstChar == '#',
|
||||
nullptr
|
||||
};
|
||||
parseCtx._useActionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(&parseCtx._useActionInfos.back());
|
||||
parseCtx._actionInfos.push_back(ai);
|
||||
_pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
|
||||
} else if ((line.hasPrefix("#ELSE") || line.hasPrefix("=ELSE"))) {
|
||||
_elseFound = true;
|
||||
_ifTag = 0;
|
||||
@ -101,12 +111,13 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
|
||||
_ifTag = 0;
|
||||
}
|
||||
|
||||
if (!_pendingActionInfos.empty() && newCommandParser != this) {
|
||||
debug("Fixing pending action info.");
|
||||
for (Common::Array<ActionInfo *>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
|
||||
(*it)->_command = newCommand;
|
||||
if (newCommandParser != this) {
|
||||
if (!_pendingActionInfos.empty()) {
|
||||
for (Common::Array<uint>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
|
||||
parseCtx._actionInfos[*it]._command = newCommand;
|
||||
}
|
||||
_pendingActionInfos.clear();
|
||||
}
|
||||
_pendingActionInfos.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,8 @@ public:
|
||||
private:
|
||||
bool _elseFound;
|
||||
char _ifTag;
|
||||
Common::Array<ActionInfo*> _pendingActionInfos;
|
||||
|
||||
Common::Array<uint> _pendingActionInfos;
|
||||
};
|
||||
|
||||
class EndBlockCommand : public Command {
|
||||
|
@ -77,7 +77,11 @@ bool Console::cmd_listsections(int argc, const char **argv) {
|
||||
const ActionInfos &actionInfos = script->getUseActionInfos();
|
||||
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
|
||||
const ActionInfo &actionInfo = *it;
|
||||
debugPrintf(_("Use %s\n"), actionInfo._object1Name.c_str());
|
||||
if (actionInfo._object2Name.empty()) {
|
||||
debugPrintf(_("Use %s\n"), actionInfo._object1Name.c_str());
|
||||
} else {
|
||||
debugPrintf(_("Use %s %s\n"), actionInfo._object1Name.c_str(), actionInfo._object2Name.c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n"));
|
||||
@ -115,7 +119,7 @@ void Console::showCommands(Command *command, int indentLevel) {
|
||||
}
|
||||
|
||||
bool Console::cmd_showsection(int argc, const char **argv) {
|
||||
if (argc == 4) {
|
||||
if (argc >= 4) {
|
||||
Script *script = nullptr;
|
||||
if (strcmp(argv[1], "G") == 0) {
|
||||
script = _vm->getGlobalScript();
|
||||
@ -161,7 +165,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
|
||||
const ActionInfos &actionInfos = script->getUseActionInfos();
|
||||
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
|
||||
const ActionInfo &actionInfo = *it;
|
||||
if (actionInfo._object1Name == argv[3]) {
|
||||
if (actionInfo._object1Name == argv[3] && ((argc == 4 && actionInfo._object2Name.empty()) || (argc > 4 && actionInfo._object2Name == argv[4]))) {
|
||||
found = true;
|
||||
command = actionInfo._command;
|
||||
break;
|
||||
|
@ -122,10 +122,20 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
|
||||
lastParser = currentParser;
|
||||
}
|
||||
|
||||
_lookActionInfos = parseCtx._lookActionInfos;
|
||||
_walkActionInfos = parseCtx._walkActionInfos;
|
||||
_talkActionInfos = parseCtx._talkActionInfos;
|
||||
_useActionInfos = parseCtx._useActionInfos;
|
||||
for (ActionInfos::iterator it = parseCtx._actionInfos.begin(); it != parseCtx._actionInfos.end(); ++it) {
|
||||
if (it->_action == ActionInfo::Look) {
|
||||
_lookActionInfos.push_back(*it);
|
||||
}
|
||||
if (it->_action == ActionInfo::Walk) {
|
||||
_walkActionInfos.push_back(*it);
|
||||
}
|
||||
if (it->_action == ActionInfo::Talk) {
|
||||
_talkActionInfos.push_back(*it);
|
||||
}
|
||||
if (it->_action == ActionInfo::Use) {
|
||||
_useActionInfos.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
Common::HashMap<Common::String, Command *> macros;
|
||||
Common::HashMap<Common::String, Command *> labels;
|
||||
|
@ -74,10 +74,7 @@ public:
|
||||
|
||||
ConditionalCommandInfos _pendingCondCommands;
|
||||
|
||||
ActionInfos _lookActionInfos;
|
||||
ActionInfos _walkActionInfos;
|
||||
ActionInfos _talkActionInfos;
|
||||
ActionInfos _useActionInfos;
|
||||
ActionInfos _actionInfos;
|
||||
|
||||
private:
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user