aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiroslav Remák2018-07-14 21:42:57 +0200
committerEugene Sandulenko2018-08-25 23:12:01 +0200
commit3b614f08327441d5252add7c16f4955652e32d0a (patch)
tree9b1351d2e733bdde8d5fcd9ff29d103323d6f315
parentfebff83a4edc89e1dbc6f4c56f5531f0eb8f3287 (diff)
downloadscummvm-rg350-3b614f08327441d5252add7c16f4955652e32d0a.tar.gz
scummvm-rg350-3b614f08327441d5252add7c16f4955652e32d0a.tar.bz2
scummvm-rg350-3b614f08327441d5252add7c16f4955652e32d0a.zip
MUTATIONOFJB: Implement RANDOM command.
-rw-r--r--engines/mutationofjb/commands/endblockcommand.cpp2
-rw-r--r--engines/mutationofjb/commands/randomcommand.cpp110
-rw-r--r--engines/mutationofjb/commands/randomcommand.h70
-rw-r--r--engines/mutationofjb/debug.cpp9
-rw-r--r--engines/mutationofjb/game.cpp9
-rw-r--r--engines/mutationofjb/game.h5
-rw-r--r--engines/mutationofjb/module.mk1
-rw-r--r--engines/mutationofjb/script.cpp6
-rw-r--r--engines/mutationofjb/script.h3
9 files changed, 210 insertions, 5 deletions
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 3b4c25bf51..5fcccd390b 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -56,7 +56,7 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
}
const char firstChar = line.firstChar();
- if (firstChar != '#' && firstChar != '=' && firstChar != '-') {
+ if (firstChar != '#' && firstChar != '=' && firstChar != '-' && firstChar != '\\') {
return false;
}
diff --git a/engines/mutationofjb/commands/randomcommand.cpp b/engines/mutationofjb/commands/randomcommand.cpp
new file mode 100644
index 0000000000..ff03e96cc6
--- /dev/null
+++ b/engines/mutationofjb/commands/randomcommand.cpp
@@ -0,0 +1,110 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mutationofjb/commands/randomcommand.h"
+
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+#include "common/debug.h"
+#include "common/random.h"
+#include "common/translation.h"
+
+/*
+ "RANDOM " <numChoices>
+
+ RANDOM command randomly picks one of the command blocks that
+ follow it and jumps to its start.
+
+ These blocks start with "/" and end with "\". The end of a random
+ block also ends the current section. The number of blocks must
+ match numChoices.
+*/
+
+namespace MutationOfJB {
+
+bool RandomCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+ if (line.size() < 8 || !line.hasPrefix("RANDOM")) {
+ return false;
+ }
+
+ int numChoices = atoi(line.c_str() + 7);
+ if (parseCtx._pendingRandomCommand) {
+ // Nested RANDOM commands are unused and not properly supported by the original game.
+ warning(_("Ignoring nested RANDOM command."));
+ } else if (numChoices >= 1) {
+ RandomCommand *randomCommand = new RandomCommand(static_cast<uint>(numChoices));
+ parseCtx._pendingRandomCommand = randomCommand;
+ command = randomCommand;
+ } else {
+ warning(_("Ignoring malformed RANDOM command with %d choices."), numChoices);
+ }
+
+ return true;
+}
+
+bool RandomBlockStartParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&) {
+ if (line != "/") {
+ return false;
+ }
+
+ if (!parseCtx._pendingRandomCommand) {
+ warning(_("Unexpected start of RANDOM block"));
+ }
+
+ return true;
+}
+
+void RandomBlockStartParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand, CommandParser *) {
+ if (newCommand && parseCtx._pendingRandomCommand) {
+ parseCtx._pendingRandomCommand->_choices.push_back(newCommand);
+ }
+}
+
+RandomCommand::RandomCommand(uint numChoices)
+ : _numChoices(numChoices),
+ _chosenNext(nullptr)
+{
+ _choices.reserve(numChoices);
+}
+
+Command::ExecuteResult RandomCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ assert(!_choices.empty());
+
+ Common::RandomSource &rng = scriptExecCtx.getGame().getRandomSource();
+ uint choice = rng.getRandomNumber(_choices.size() - 1);
+ _chosenNext = _choices[choice];
+ return Finished;
+}
+
+Command *RandomCommand::next() const {
+ return _chosenNext;
+}
+
+Common::String RandomCommand::debugString() const {
+ return Common::String::format("RANDOM %u", _numChoices);
+}
+
+const RandomCommand::Choices &RandomCommand::getChoices() const {
+ return _choices;
+}
+
+}
diff --git a/engines/mutationofjb/commands/randomcommand.h b/engines/mutationofjb/commands/randomcommand.h
new file mode 100644
index 0000000000..ffe9fc2374
--- /dev/null
+++ b/engines/mutationofjb/commands/randomcommand.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MUTATIONOFJB_RANDOMCOMMAND_H
+#define MUTATIONOFJB_RANDOMCOMMAND_H
+
+#include "mutationofjb/commands/command.h"
+#include "common/array.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class RandomCommandParser : public CommandParser {
+public:
+ RandomCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class RandomBlockStartParser : public CommandParser {
+public:
+ RandomBlockStartParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
+};
+
+class RandomCommand : public Command {
+ friend class RandomBlockStartParser;
+
+public:
+ typedef Common::Array<Command *> Choices;
+
+ RandomCommand(uint numChoices);
+
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Command *next() const override;
+
+ virtual Common::String debugString() const override;
+
+ const Choices &getChoices() const;
+
+private:
+ uint _numChoices;
+ Choices _choices;
+ Command *_chosenNext;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 171eca58f5..b1c96efd3a 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -30,6 +30,7 @@
#include "mutationofjb/commands/seqcommand.h"
#include "mutationofjb/commands/conditionalcommand.h"
#include "mutationofjb/commands/callmacrocommand.h"
+#include "mutationofjb/commands/randomcommand.h"
#include "common/debug-channels.h"
#include "common/translation.h"
#include "common/scummsys.h"
@@ -152,6 +153,14 @@ void Console::showCommands(Command *command, int indentLevel) {
command = nullptr;
} else if (CallMacroCommand* const callMacroCmd = dynamic_cast<CallMacroCommand *>(command)) {
command = callMacroCmd->getReturnCommand();
+ } else if (RandomCommand* const randomCmd = dynamic_cast<RandomCommand *>(command)) {
+ const RandomCommand::Choices &choices = randomCmd->getChoices();
+ for (RandomCommand::Choices::size_type i = 0; i < choices.size(); ++i) {
+ showIndent(indentLevel + 1);
+ debugPrintf("CASE %u\n", i);
+ showCommands(choices[i], indentLevel + 2);
+ }
+ command = nullptr;
} else {
command = nullptr;
}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 69647f2ef3..190b62e240 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -36,6 +36,7 @@ namespace MutationOfJB {
Game::Game(MutationOfJBEngine *vm)
: _vm(vm),
+ _randomSource("mutationofjb"),
_delayedLocalScript(nullptr),
_gui(*this, _vm->getScreen()),
_scriptExecCtx(*this),
@@ -60,6 +61,10 @@ Game::Game(MutationOfJBEngine *vm)
changeScene(13, false); // Initial scene.
}
+Common::RandomSource &Game::getRandomSource() {
+ return _randomSource;
+}
+
GameData &Game::getGameData() {
return *_gameData;
}
@@ -222,11 +227,11 @@ uint8 Game::colorFromString(const char *colorStr) {
return 0x00;
}
-TaskManager& Game::getTaskManager() {
+TaskManager &Game::getTaskManager() {
return _taskManager;
}
-Assets& Game::getAssets() {
+Assets &Game::getAssets() {
return _assets;
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 056cffb757..d70bd09d9a 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -23,6 +23,7 @@
#ifndef MUTATIONOFJB_GAME_H
#define MUTATIONOFJB_GAME_H
+#include "common/random.h"
#include "common/scummsys.h"
#include "mutationofjb/assets.h"
#include "mutationofjb/gui.h"
@@ -47,6 +48,7 @@ class Bitmap;
class Game {
public:
Game(MutationOfJBEngine *vm);
+ Common::RandomSource &getRandomSource();
GameData &getGameData();
Room &getRoom();
Script *getGlobalScript() const;
@@ -68,7 +70,7 @@ public:
static uint8 colorFromString(const char *colorStr);
- TaskManager& getTaskManager();
+ TaskManager &getTaskManager();
Assets &getAssets();
Graphics::Screen &getScreen();
@@ -80,6 +82,7 @@ private:
Script *changeSceneLoadScript(uint8 sceneId, bool partB);
MutationOfJBEngine *_vm;
+ Common::RandomSource _randomSource;
GameData *_gameData;
Script *_globalScript;
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index f3a1d78784..2ac4fabbdb 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -21,6 +21,7 @@ MODULE_OBJS := \
commands/saycommand.o \
commands/seqcommand.o \
commands/talkcommand.o \
+ commands/randomcommand.o \
tasks/conversationtask.o \
tasks/saytask.o \
tasks/taskmanager.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 90146f64c6..d90f37e161 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -45,6 +45,7 @@
#include "mutationofjb/commands/renamecommand.h"
#include "mutationofjb/commands/definestructcommand.h"
#include "mutationofjb/commands/talkcommand.h"
+#include "mutationofjb/commands/randomcommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -71,6 +72,8 @@ static CommandParser **getParsers() {
new NewRoomCommandParser,
new GotoCommandParser,
new LabelCommandParser,
+ new RandomCommandParser,
+ new RandomBlockStartParser,
nullptr
};
@@ -81,7 +84,8 @@ static CommandParser **getParsers() {
ScriptParseContext::ScriptParseContext(Common::SeekableReadStream &stream) :
_stream(stream),
_currentCommand(nullptr),
- _lastCommand(nullptr)
+ _lastCommand(nullptr),
+ _pendingRandomCommand(nullptr)
{}
bool ScriptParseContext::readLine(Common::String &line) {
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 8a15a48887..3ef25f4b68 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -43,6 +43,7 @@ class GameData;
class GotoCommand;
class ConditionalCommand;
class Script;
+class RandomCommand;
typedef Common::Array<Command *> Commands;
@@ -92,6 +93,8 @@ public:
typedef Common::HashMap<Common::String, GotoCommands> PendingGotoMap;
PendingGotoMap _pendingGotos;
+ RandomCommand *_pendingRandomCommand;
+
ActionInfos _actionInfos;
Macros _macros;
Startups _startups;