aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarisa-Chan2013-10-25 17:12:08 +0700
committerMarisa-Chan2013-10-25 17:12:08 +0700
commitc0a709dc23c689b094c2dab1038447267d6fb8bd (patch)
treea02f21c942a2f8b95c351be980144f897102d8fe
parent8e4070c68b9a6a5e81d80f6805a199c2872089fe (diff)
downloadscummvm-rg350-c0a709dc23c689b094c2dab1038447267d6fb8bd.tar.gz
scummvm-rg350-c0a709dc23c689b094c2dab1038447267d6fb8bd.tar.bz2
scummvm-rg350-c0a709dc23c689b094c2dab1038447267d6fb8bd.zip
ZVISION: Refactoring script manager, massive changes.
-rw-r--r--engines/zvision/actions.cpp7
-rw-r--r--engines/zvision/console.cpp1
-rw-r--r--engines/zvision/save_manager.cpp5
-rw-r--r--engines/zvision/scr_file_handling.cpp36
-rw-r--r--engines/zvision/script_manager.cpp410
-rw-r--r--engines/zvision/script_manager.h34
6 files changed, 222 insertions, 271 deletions
diff --git a/engines/zvision/actions.cpp b/engines/zvision/actions.cpp
index 4976bd4862..3c0adb4082 100644
--- a/engines/zvision/actions.cpp
+++ b/engines/zvision/actions.cpp
@@ -124,7 +124,6 @@ ActionDisableControl::ActionDisableControl(const Common::String &line) {
bool ActionDisableControl::execute(ZVision *engine) {
debug("Disabling control %u", _key);
- engine->getScriptManager()->disableControl(_key);
return true;
}
@@ -141,7 +140,6 @@ ActionEnableControl::ActionEnableControl(const Common::String &line) {
bool ActionEnableControl::execute(ZVision *engine) {
debug("Enabling control %u", _key);
- engine->getScriptManager()->enableControl(_key);
return true;
}
@@ -220,8 +218,6 @@ bool ActionPreloadAnimation::execute(ZVision *engine) {
// TODO: Check if the Control already exists
// Create the control, but disable it until PlayPreload is called
- engine->getScriptManager()->addControl(new AnimationControl(engine, _key, _fileName));
- engine->getScriptManager()->disableControl(_key);
return true;
}
@@ -267,9 +263,6 @@ bool ActionPlayPreloadAnimation::execute(ZVision *engine) {
control->setXPos(_x1);
control->setYPost(_y1);
- // Enable the control. ScriptManager will take care of the rest
- control->enable();
-
return true;
}
diff --git a/engines/zvision/console.cpp b/engines/zvision/console.cpp
index a095d3fa6a..400dcb3f39 100644
--- a/engines/zvision/console.cpp
+++ b/engines/zvision/console.cpp
@@ -197,7 +197,6 @@ bool Console::cmdParseAllScrFiles(int argc, const char **argv) {
SearchMan.listMatchingMembers(list, "*.scr");
for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
- _engine->getScriptManager()->parseScrFile((*iter)->getName());
}
return true;
diff --git a/engines/zvision/save_manager.cpp b/engines/zvision/save_manager.cpp
index 528dd0f35b..e8947d8d16 100644
--- a/engines/zvision/save_manager.cpp
+++ b/engines/zvision/save_manager.cpp
@@ -128,8 +128,6 @@ void SaveManager::writeSaveGameData(Common::OutSaveFile *file) {
// Write out the current state table values
scriptManager->serializeStateTable(file);
- // Write out any controls needing to save state
- scriptManager->serializeControls(file);
}
Common::Error SaveManager::loadGame(uint slot) {
@@ -160,9 +158,6 @@ Common::Error SaveManager::loadGame(uint slot) {
// Load the room
scriptManager->changeLocation(world, room, node, view, offset);
- // Update the controls
- scriptManager->deserializeControls(saveFile);
-
return Common::kNoError;
}
diff --git a/engines/zvision/scr_file_handling.cpp b/engines/zvision/scr_file_handling.cpp
index 5fed820103..4d18306ce4 100644
--- a/engines/zvision/scr_file_handling.cpp
+++ b/engines/zvision/scr_file_handling.cpp
@@ -37,7 +37,7 @@
namespace ZVision {
-void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal) {
+void ScriptManager::parseScrFile(const Common::String &fileName, script_scope &scope) {
Common::File file;
if (!file.open(fileName)) {
warning("Script file not found: %s", fileName.c_str());
@@ -58,17 +58,18 @@ void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal)
if (line.matchString("puzzle:*", true)) {
Puzzle *puzzle = new Puzzle();
sscanf(line.c_str(), "puzzle:%u", &(puzzle->key));
-
+ if (getStateFlag(puzzle->key) & Puzzle::ONCE_PER_INST)
+ setStateValue(puzzle->key, 0);
parsePuzzle(puzzle, file);
- if (isGlobal) {
- _globalPuzzles.push_back(puzzle);
- } else {
- _activePuzzles.push_back(puzzle);
- }
+ scope._puzzles.push_back(puzzle);
+
} else if (line.matchString("control:*", true)) {
- parseControl(line, file);
+ Control *ctrl = parseControl(line, file);
+ if (ctrl)
+ scope._controls.push_back(ctrl);
}
}
+ scope.proc_count = 0;
}
void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream) {
@@ -81,12 +82,14 @@ void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stre
} else if (line.matchString("results {", true)) {
parseResults(stream, puzzle->resultActions);
} else if (line.matchString("flags {", true)) {
- puzzle->flags = parseFlags(stream);
+ setStateFlag(puzzle->key, parseFlags(stream));
}
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
}
+
+ puzzle->addedBySetState = 0;
}
bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const {
@@ -273,7 +276,7 @@ uint ScriptManager::parseFlags(Common::SeekableReadStream &stream) const {
return flags;
}
-void ScriptManager::parseControl(Common::String &line, Common::SeekableReadStream &stream) {
+Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadStream &stream) {
uint32 key;
char controlTypeBuffer[20];
@@ -282,21 +285,20 @@ void ScriptManager::parseControl(Common::String &line, Common::SeekableReadStrea
Common::String controlType(controlTypeBuffer);
if (controlType.equalsIgnoreCase("push_toggle")) {
- _activeControls.push_back(new PushToggleControl(_engine, key, stream));
- return;
+ return new PushToggleControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("flat")) {
Control::parseFlatControl(_engine);
- return;
+ return NULL;
} else if (controlType.equalsIgnoreCase("pana")) {
Control::parsePanoramaControl(_engine, stream);
- return;
+ return NULL;
} else if (controlType.equalsIgnoreCase("tilt")) {
Control::parseTiltControl(_engine, stream);
- return;
+ return NULL;
} else if (controlType.equalsIgnoreCase("lever")) {
- _activeControls.push_back(new LeverControl(_engine, key, stream));
- return;
+ return new LeverControl(_engine, key, stream);
}
+ return NULL;
}
} // End of namespace ZVision
diff --git a/engines/zvision/script_manager.cpp b/engines/zvision/script_manager.cpp
index 01a6e6d09e..74035fd41f 100644
--- a/engines/zvision/script_manager.cpp
+++ b/engines/zvision/script_manager.cpp
@@ -41,69 +41,86 @@ namespace ZVision {
ScriptManager::ScriptManager(ZVision *engine)
: _engine(engine),
- _currentlyFocusedControl(0) {
+ _currentlyFocusedControl(0),
+ _activeControls(NULL) {
}
ScriptManager::~ScriptManager() {
- for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
- delete(*iter);
- }
- for (PuzzleList::iterator iter = _globalPuzzles.begin(); iter != _globalPuzzles.end(); ++iter) {
- delete(*iter);
- }
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- delete(*iter);
- }
+ cleanScriptScope(universe);
+ cleanScriptScope(world);
+ cleanScriptScope(room);
+ cleanScriptScope(nodeview);
}
void ScriptManager::initialize() {
- parseScrFile("universe.scr", true);
+ cleanScriptScope(universe);
+ cleanScriptScope(world);
+ cleanScriptScope(room);
+ cleanScriptScope(nodeview);
+
+ _currentLocation.node = '0';
+ _currentLocation.world = '0';
+ _currentLocation.room = '0';
+ _currentLocation.view = '0';
+
+ parseScrFile("universe.scr", universe);
changeLocation('g', 'a', 'r', 'y', 0);
}
void ScriptManager::update(uint deltaTimeMillis) {
+ if (_currentLocation.node != _nextLocation.node ||
+ _currentLocation.room != _nextLocation.room ||
+ _currentLocation.view != _nextLocation.view ||
+ _currentLocation.world != _nextLocation.world)
+ do_changeLocation();
+
updateNodes(deltaTimeMillis);
- checkPuzzleCriteria();
+ execScope(nodeview);
+ execScope(room);
+ execScope(world);
+ execScope(universe);
+ updateControls(deltaTimeMillis);
+}
+
+void ScriptManager::execScope(script_scope &scope) {
+ // Swap queues
+ PuzzleList *tmp = scope.exec_queue;
+ scope.exec_queue = scope.scope_queue;
+ scope.scope_queue = tmp;
+
+ for (PuzzleList::iterator PuzzleIter = scope._puzzles.begin(); PuzzleIter != scope._puzzles.end(); ++PuzzleIter)
+ (*PuzzleIter)->addedBySetState = 0;
+
+ if (scope.proc_count < 2 || getStateValue(76)) {
+ for (PuzzleList::iterator PuzzleIter = scope._puzzles.begin(); PuzzleIter != scope._puzzles.end(); ++PuzzleIter)
+ checkPuzzleCriteria(*PuzzleIter, scope.proc_count);
+ } else {
+ for (PuzzleList::iterator PuzzleIter = scope.exec_queue->begin(); PuzzleIter != scope.exec_queue->end(); ++PuzzleIter)
+ checkPuzzleCriteria(*PuzzleIter, scope.proc_count);
+ }
+
+ scope.exec_queue->clear();
+
+ if (scope.proc_count < 2) {
+ scope.proc_count++;
+ }
}
-void ScriptManager::createReferenceTable() {
+void ScriptManager::addPuzzlesToReferenceTable(script_scope &scope) {
// Iterate through each local Puzzle
- for (PuzzleList::iterator activePuzzleIter = _activePuzzles.begin(); activePuzzleIter != _activePuzzles.end(); ++activePuzzleIter) {
- Puzzle *puzzlePtr = (*activePuzzleIter);
+ for (PuzzleList::iterator PuzzleIter = scope._puzzles.begin(); PuzzleIter != scope._puzzles.end(); ++PuzzleIter) {
+ Puzzle *puzzlePtr = (*PuzzleIter);
- // Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*activePuzzleIter)->criteriaList.begin(); criteriaIter != (*activePuzzleIter)->criteriaList.end(); ++criteriaIter) {
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
- _referenceTable[entryIter->key].push_back(puzzlePtr);
-
- // If the argument is a key, add a reference to it as well
- if (entryIter->argumentIsAKey) {
- _referenceTable[entryIter->argument].push_back(puzzlePtr);
- }
- }
- }
- }
+ puzzle_ref ref;
+ ref.scope = &scope;
+ ref.puz = puzzlePtr;
- // Iterate through each global Puzzle
- for (PuzzleList::iterator globalPuzzleIter = _globalPuzzles.begin(); globalPuzzleIter != _globalPuzzles.end(); ++globalPuzzleIter) {
- Puzzle *puzzlePtr = (*globalPuzzleIter);
+ _referenceTable[puzzlePtr->key].push_back(ref);
// Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*globalPuzzleIter)->criteriaList.begin(); criteriaIter != (*globalPuzzleIter)->criteriaList.end(); ++criteriaIter) {
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
- _referenceTable[entryIter->key].push_back(puzzlePtr);
-
- // If the argument is a key, add a reference to it as well
- if (entryIter->argumentIsAKey) {
- _referenceTable[entryIter->argument].push_back(puzzlePtr);
- }
- }
- }
- }
-
- // Remove duplicate entries
- for (PuzzleMap::iterator referenceTableIter = _referenceTable.begin(); referenceTableIter != _referenceTable.end(); ++referenceTableIter) {
- removeDuplicateEntries(referenceTableIter->_value);
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*PuzzleIter)->criteriaList.begin(); criteriaIter != (*PuzzleIter)->criteriaList.end(); ++criteriaIter)
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter)
+ _referenceTable[entryIter->key].push_back(ref);
}
}
@@ -118,90 +135,85 @@ void ScriptManager::updateNodes(uint deltaTimeMillis) {
++iter;
}
}
- // If process() returns true, it means the node can be deleted
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end();) {
- if ((*iter)->process(deltaTimeMillis)) {
- delete(*iter);
- // Remove the node
- iter = _activeControls.erase(iter);
- } else {
- ++iter;
- }
- }
}
-void ScriptManager::checkPuzzleCriteria() {
- while (!_puzzlesToCheck.empty()) {
- Puzzle *puzzle = _puzzlesToCheck.pop();
+void ScriptManager::updateControls(uint deltaTimeMillis) {
+ if (!_activeControls)
+ return;
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); iter++)
+ (*iter)->process(deltaTimeMillis);
+}
- // Check if the puzzle is already finished
- // Also check that the puzzle isn't disabled
- if (getStateValue(puzzle->key) == 1 &&
- (puzzle->flags & Puzzle::DISABLED) == 0) {
- continue;
- }
+void ScriptManager::checkPuzzleCriteria(Puzzle *puzzle, uint counter) {
+ // Check if the puzzle is already finished
+ // Also check that the puzzle isn't disabled
+ if (getStateValue(puzzle->key) == 1 &&
+ (getStateFlag(puzzle->key) & Puzzle::DISABLED) == 0) {
+ return;
+ }
- // Check each Criteria
-
- bool criteriaMet = false;
- for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = puzzle->criteriaList.begin(); criteriaIter != puzzle->criteriaList.end(); ++criteriaIter) {
- criteriaMet = false;
-
- for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
- // Get the value to compare against
- uint argumentValue;
- if (entryIter->argumentIsAKey)
- argumentValue = getStateValue(entryIter->argument);
- else
- argumentValue = entryIter->argument;
-
- // Do the comparison
- switch (entryIter->criteriaOperator) {
- case Puzzle::EQUAL_TO:
- criteriaMet = getStateValue(entryIter->key) == argumentValue;
- break;
- case Puzzle::NOT_EQUAL_TO:
- criteriaMet = getStateValue(entryIter->key) != argumentValue;
- break;
- case Puzzle::GREATER_THAN:
- criteriaMet = getStateValue(entryIter->key) > argumentValue;
- break;
- case Puzzle::LESS_THAN:
- criteriaMet = getStateValue(entryIter->key) < argumentValue;
- break;
- }
-
- // If one check returns false, don't keep checking
- if (!criteriaMet) {
- break;
- }
+ // Check each Criteria
+ if (counter == 0 && (getStateFlag(puzzle->key) & Puzzle::DO_ME_NOW) == 0)
+ return;
+
+ bool criteriaMet = false;
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = puzzle->criteriaList.begin(); criteriaIter != puzzle->criteriaList.end(); ++criteriaIter) {
+ criteriaMet = false;
+
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
+ // Get the value to compare against
+ uint argumentValue;
+ if (entryIter->argumentIsAKey)
+ argumentValue = getStateValue(entryIter->argument);
+ else
+ argumentValue = entryIter->argument;
+
+ // Do the comparison
+ switch (entryIter->criteriaOperator) {
+ case Puzzle::EQUAL_TO:
+ criteriaMet = getStateValue(entryIter->key) == argumentValue;
+ break;
+ case Puzzle::NOT_EQUAL_TO:
+ criteriaMet = getStateValue(entryIter->key) != argumentValue;
+ break;
+ case Puzzle::GREATER_THAN:
+ criteriaMet = getStateValue(entryIter->key) > argumentValue;
+ break;
+ case Puzzle::LESS_THAN:
+ criteriaMet = getStateValue(entryIter->key) < argumentValue;
+ break;
}
- // If any of the Criteria are *fully* met, then execute the results
- if (criteriaMet) {
+ // If one check returns false, don't keep checking
+ if (!criteriaMet) {
break;
}
}
- // criteriaList can be empty. Aka, the puzzle should be executed immediately
- if (puzzle->criteriaList.empty() || criteriaMet) {
- debug(1, "Puzzle %u criteria passed. Executing its ResultActions", puzzle->key);
+ // If any of the Criteria are *fully* met, then execute the results
+ if (criteriaMet) {
+ break;
+ }
+ }
- // Set the puzzle as completed
- setStateValue(puzzle->key, 1);
+ // criteriaList can be empty. Aka, the puzzle should be executed immediately
+ if (puzzle->criteriaList.empty() || criteriaMet) {
+ debug(1, "Puzzle %u criteria passed. Executing its ResultActions", puzzle->key);
- bool shouldContinue = true;
- for (Common::List<ResultAction *>::iterator resultIter = puzzle->resultActions.begin(); resultIter != puzzle->resultActions.end(); ++resultIter) {
- shouldContinue = shouldContinue && (*resultIter)->execute(_engine);
- if (!shouldContinue) {
- break;
- }
- }
+ // Set the puzzle as completed
+ setStateValue(puzzle->key, 1);
+ bool shouldContinue = true;
+ for (Common::List<ResultAction *>::iterator resultIter = puzzle->resultActions.begin(); resultIter != puzzle->resultActions.end(); ++resultIter) {
+ shouldContinue = shouldContinue && (*resultIter)->execute(_engine);
if (!shouldContinue) {
break;
}
}
+
+ if (!shouldContinue) {
+ return;
+ }
}
}
@@ -242,6 +254,13 @@ uint ScriptManager::getStateValue(uint32 key) {
}
void ScriptManager::queuePuzzles(uint32 key) {
+ if (_referenceTable.contains(key)) {
+ for (Common::Array<puzzle_ref>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter)
+ if (!iter->puz->addedBySetState) {
+ iter->scope->scope_queue->push_back(iter->puz);
+ iter->puz->addedBySetState = true;
+ }
+ }
}
void ScriptManager::setStateValue(uint32 key, uint value) {
@@ -281,40 +300,16 @@ void ScriptManager::addToStateValue(uint32 key, uint valueToAdd) {
_globalState[key] += valueToAdd;
}
-void ScriptManager::addControl(Control *control) {
- _activeControls.push_back(control);
-}
Control *ScriptManager::getControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->getKey() == key) {
- return (*iter);
- }
- }
return nullptr;
}
-void ScriptManager::enableControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->getKey() == key) {
- (*iter)->enable();
- break;
- }
- }
-}
-
-void ScriptManager::disableControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->getKey() == key) {
- (*iter)->disable();
- break;
- }
- }
-}
-
void ScriptManager::focusControl(uint32 key) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if (!_activeControls)
+ return;
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
uint32 controlKey = (*iter)->getKey();
if (controlKey == key) {
@@ -342,20 +337,26 @@ SideFX *ScriptManager::getSideFX(uint32 key) {
}
void ScriptManager::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if (!_activeControls)
+ return;
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
(*iter)->onMouseDown(screenSpacePos, backgroundImageSpacePos);
}
}
void ScriptManager::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if (!_activeControls)
+ return;
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
(*iter)->onMouseUp(screenSpacePos, backgroundImageSpacePos);
}
}
bool ScriptManager::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_activeControls)
+ return false;
bool cursorWasChanged = false;
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
cursorWasChanged = cursorWasChanged || (*iter)->onMouseMove(screenSpacePos, backgroundImageSpacePos);
}
@@ -363,35 +364,56 @@ bool ScriptManager::onMouseMove(const Common::Point &screenSpacePos, const Commo
}
void ScriptManager::onKeyDown(Common::KeyState keyState) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if (!_activeControls)
+ return;
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
(*iter)->onKeyDown(keyState);
}
}
void ScriptManager::onKeyUp(Common::KeyState keyState) {
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if (!_activeControls)
+ return;
+ for (ControlList::iterator iter = _activeControls->begin(); iter != _activeControls->end(); ++iter) {
(*iter)->onKeyUp(keyState);
}
}
-void ScriptManager::changeLocation(char world, char room, char node, char view, uint32 offset) {
- assert(world != 0);
- debug(1, "Changing location to: %c %c %c %c %u", world, room, node, view, offset);
+void ScriptManager::changeLocation(char _world, char _room, char _node, char _view, uint32 offset) {
+ _nextLocation.world = _world;
+ _nextLocation.room = _room;
+ _nextLocation.node = _node;
+ _nextLocation.view = _view;
+ _nextLocation.offset = offset;
+}
+
+void ScriptManager::do_changeLocation() {
+ assert(_nextLocation.world != 0);
+ debug(1, "Changing location to: %c %c %c %c %u", _nextLocation.world, _nextLocation.room, _nextLocation.node, _nextLocation.view, _nextLocation.offset);
// Auto save
- _engine->getSaveManager()->autoSave();
+ //_engine->getSaveManager()->autoSave();
// Clear all the containers
_referenceTable.clear();
- _puzzlesToCheck.clear();
- for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
- delete(*iter);
- }
- _activePuzzles.clear();
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- delete(*iter);
- }
- _activeControls.clear();
+ cleanScriptScope(nodeview);
+ cleanScriptScope(room);
+ cleanScriptScope(world);
+
+ // Parse into puzzles and controls
+ Common::String fileName = Common::String::format("%c%c%c%c.scr", _nextLocation.world, _nextLocation.room, _nextLocation.node, _nextLocation.view);
+ parseScrFile(fileName, nodeview);
+ addPuzzlesToReferenceTable(nodeview);
+
+ fileName = Common::String::format("%c%c.scr", _nextLocation.world, _nextLocation.room);
+ parseScrFile(fileName, room);
+ addPuzzlesToReferenceTable(room);
+
+ fileName = Common::String::format("%c.scr", _nextLocation.world);
+ parseScrFile(fileName, world);
+ addPuzzlesToReferenceTable(world);
+
+ _activeControls = &nodeview._controls;
// Revert to the idle cursor
_engine->getCursorManager()->revertToIdle();
@@ -402,50 +424,14 @@ void ScriptManager::changeLocation(char world, char room, char node, char view,
// Remove any alphaEntries
_engine->getRenderManager()->clearAlphaEntries();
- // Clean the global state table
- cleanStateTable();
-
- // Parse into puzzles and controls
- Common::String fileName = Common::String::format("%c%c%c%c.scr", world, room, node, view);
- parseScrFile(fileName);
-
// Change the background position
- _engine->getRenderManager()->setBackgroundPosition(offset);
+ _engine->getRenderManager()->setBackgroundPosition(_nextLocation.offset);
- // Enable all the controls
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->enable();
- }
-
- // Add all the local puzzles to the queue to be checked
- for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
- // Reset any Puzzles that have the flag ONCE_PER_INST
- if (((*iter)->flags & Puzzle::ONCE_PER_INST) == Puzzle::ONCE_PER_INST) {
- setStateValue((*iter)->key, 0);
- }
-
- _puzzlesToCheck.push((*iter));
- }
-
- // Add all the global puzzles to the queue to be checked
- for (PuzzleList::iterator iter = _globalPuzzles.begin(); iter != _globalPuzzles.end(); ++iter) {
- // Reset any Puzzles that have the flag ONCE_PER_INST
- if (((*iter)->flags & Puzzle::ONCE_PER_INST) == Puzzle::ONCE_PER_INST) {
- setStateValue((*iter)->key, 0);
- }
-
- _puzzlesToCheck.push((*iter));
- }
-
- // Create the puzzle reference table
- createReferenceTable();
+ execScope(room);
+ execScope(nodeview);
// Update _currentLocation
- _currentLocation.world = world;
- _currentLocation.room = room;
- _currentLocation.node = node;
- _currentLocation.view = view;
- _currentLocation.offset = offset;
+ _currentLocation = _nextLocation;
}
void ScriptManager::serializeStateTable(Common::WriteStream *stream) {
@@ -474,36 +460,6 @@ void ScriptManager::deserializeStateTable(Common::SeekableReadStream *stream) {
}
}
-void ScriptManager::serializeControls(Common::WriteStream *stream) {
- // Count how many controls need to save their data
- // Because WriteStream isn't seekable
- uint32 numberOfControlsNeedingSerialization = 0;
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->needsSerialization()) {
- numberOfControlsNeedingSerialization++;
- }
- }
- stream->writeUint32LE(numberOfControlsNeedingSerialization);
-
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- (*iter)->serialize(stream);
- }
-}
-
-void ScriptManager::deserializeControls(Common::SeekableReadStream *stream) {
- uint32 numberOfControls = stream->readUint32LE();
-
- for (uint32 i = 0; i < numberOfControls; ++i) {
- uint32 key = stream->readUint32LE();
- for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
- if ((*iter)->getKey() == key) {
- (*iter)->deserialize(stream);
- break;
- }
- }
- }
-}
-
Location ScriptManager::getCurrentLocation() const {
Location location = _currentLocation;
location.offset = _engine->getRenderManager()->getCurrentBackgroundOffset();
diff --git a/engines/zvision/script_manager.h b/engines/zvision/script_manager.h
index 71fefaf41f..90df2ccee5 100644
--- a/engines/zvision/script_manager.h
+++ b/engines/zvision/script_manager.h
@@ -105,7 +105,6 @@ struct Location {
uint32 offset;
};
-typedef Common::HashMap<uint32, Common::Array<Puzzle *> > PuzzleMap;
typedef Common::List<Puzzle *> PuzzleList;
typedef Common::Queue<Puzzle *> PuzzleQueue;
typedef Common::List<Control *> ControlList;
@@ -137,6 +136,8 @@ private:
script_scope *scope;
};
+ typedef Common::HashMap<uint32, Common::Array<puzzle_ref> > PuzzleMap;
+
/**
* Holds the global state variable. Do NOT directly modify this. Use the accessors and
* mutators getStateValue() and setStateValue(). This ensures that Puzzles that reference a
@@ -147,18 +148,19 @@ private:
StateMap _globalStateFlags;
/** References _globalState keys to Puzzles */
PuzzleMap _referenceTable;
- /** Holds the Puzzles that should be checked this frame */
- PuzzleQueue _puzzlesToCheck;
- /** Holds the currently active puzzles */
- PuzzleList _activePuzzles;
- /** Holds the global puzzles */
- PuzzleList _globalPuzzles;
/** Holds the currently active controls */
- ControlList _activeControls;
+ ControlList *_activeControls;
+
+ script_scope universe;
+ script_scope world;
+ script_scope room;
+ script_scope nodeview;
+
/** Holds the currently active timers, musics, other */
SideFXList _activeSideFx;
Location _currentLocation;
+ Location _nextLocation;
uint32 _currentlyFocusedControl;
@@ -221,21 +223,25 @@ public:
*/
void onKeyUp(Common::KeyState keyState);
+ /** Mark next location */
void changeLocation(char world, char room, char node, char view, uint32 offset);
void serializeStateTable(Common::WriteStream *stream);
void deserializeStateTable(Common::SeekableReadStream *stream);
- void serializeControls(Common::WriteStream *stream);
- void deserializeControls(Common::SeekableReadStream *stream);
Location getCurrentLocation() const;
private:
- void createReferenceTable();
+ void addPuzzlesToReferenceTable(script_scope &scope);
void updateNodes(uint deltaTimeMillis);
- void checkPuzzleCriteria();
+ void updateControls(uint deltaTimeMillis);
+ void checkPuzzleCriteria(Puzzle *puzzle, uint counter);
void cleanStateTable();
void cleanScriptScope(script_scope &scope);
+ void execScope(script_scope &scope);
+
+ /** Perform change location */
+ void do_changeLocation();
// TODO: Make this private. It was only made public so Console::cmdParseAllScrFiles() could use it
public:
@@ -245,7 +251,7 @@ public:
* @param fileName Name of the .scr file
* @param isGlobal Are the puzzles included in the file global (true). AKA, the won't be purged during location changes
*/
- void parseScrFile(const Common::String &fileName, bool isGlobal = false);
+ void parseScrFile(const Common::String &fileName, script_scope &scope);
private:
/**
@@ -291,7 +297,7 @@ private:
* @param line The line initially read
* @param stream Scr file stream
*/
- void parseControl(Common::String &line, Common::SeekableReadStream &stream);
+ Control *parseControl(Common::String &line, Common::SeekableReadStream &stream);
};