diff options
author | Marisa-Chan | 2013-10-25 17:12:08 +0700 |
---|---|---|
committer | Marisa-Chan | 2013-10-25 17:12:08 +0700 |
commit | c0a709dc23c689b094c2dab1038447267d6fb8bd (patch) | |
tree | a02f21c942a2f8b95c351be980144f897102d8fe /engines/zvision | |
parent | 8e4070c68b9a6a5e81d80f6805a199c2872089fe (diff) | |
download | scummvm-rg350-c0a709dc23c689b094c2dab1038447267d6fb8bd.tar.gz scummvm-rg350-c0a709dc23c689b094c2dab1038447267d6fb8bd.tar.bz2 scummvm-rg350-c0a709dc23c689b094c2dab1038447267d6fb8bd.zip |
ZVISION: Refactoring script manager, massive changes.
Diffstat (limited to 'engines/zvision')
-rw-r--r-- | engines/zvision/actions.cpp | 7 | ||||
-rw-r--r-- | engines/zvision/console.cpp | 1 | ||||
-rw-r--r-- | engines/zvision/save_manager.cpp | 5 | ||||
-rw-r--r-- | engines/zvision/scr_file_handling.cpp | 36 | ||||
-rw-r--r-- | engines/zvision/script_manager.cpp | 410 | ||||
-rw-r--r-- | engines/zvision/script_manager.h | 34 |
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); }; |