void ResourceProvider::shutdown() { _stateProvider->clear(); // Flush the locations list for (CurrentList::const_iterator it = _locations.begin(); it != _locations.end(); it++) { Current *location = *it; _archiveLoader->returnRoot(_archiveLoader->buildArchiveName(location->getLevel(), location->getLocation())); _archiveLoader->returnRoot(_archiveLoader->buildArchiveName(location->getLevel())); delete location; } _locations.clear(); // Return the global resources if (_global->getLevel()) { _archiveLoader->returnRoot(_archiveLoader->buildArchiveName(_global->getLevel())); _global->setLevel(nullptr); } if (_global->getRoot()) { _archiveLoader->returnRoot("x.xarc"); _global->setRoot(nullptr); } _global->setCurrent(nullptr); _global->setInventory(nullptr); _global->setApril(nullptr); _archiveLoader->unloadUnused(); }
void ResourceProvider::commitActiveLocationsState() { // Save active location states for (CurrentList::const_iterator it = _locations.begin(); it != _locations.end(); it++) { _stateProvider->saveLocationState((*it)->getLevel(), (*it)->getLocation()); _stateProvider->saveLevelState((*it)->getLevel()); } _stateProvider->saveLevelState(_global->getLevel()); // Save the current location "extended" state, to be able to restore them to the exact same state. Current *location = _global->getCurrent(); _stateProvider->saveCurrentLocationState(location->getLevel(), location->getLocation()); _stateProvider->saveCurrentLevelState(location->getLevel()); _stateProvider->saveGlobalState(_global->getLevel()); }
void ResourceProvider::purgeOldLocations() { while (_locations.size() > 2) { Current *location = _locations.front(); _stateProvider->saveLocationState(location->getLevel(), location->getLocation()); _stateProvider->saveLevelState(location->getLevel()); _archiveLoader->returnRoot(_archiveLoader->buildArchiveName(location->getLevel(), location->getLocation())); _archiveLoader->returnRoot(_archiveLoader->buildArchiveName(location->getLevel())); delete location; _locations.pop_front(); } _archiveLoader->unloadUnused(); }
void ResourceProvider::performLocationChange() { Current *current = _locations.back(); Current *previous = _global->getCurrent(); bool levelChanged = !previous || previous->getLevel() != current->getLevel(); // Exit the previous location if (previous) { // Trigger location change scripts if (levelChanged) { runLocationChangeScripts(previous->getLevel(), Resources::Script::kCallModeExitLocation); } runLocationChangeScripts(previous->getLocation(), Resources::Script::kCallModeExitLocation); // Resources lifecycle update previous->getLocation()->onExitLocation(); previous->getLevel()->onExitLocation(); _global->getLevel()->onExitLocation(); } // Clear all pointers to location objects in the UI instances StarkUserInterface->clearLocationDependentState(); // Set the new current location _global->setCurrent(current); // Resources lifecycle update _global->getLevel()->onEnterLocation(); current->getLevel()->onEnterLocation(); current->getLocation()->onEnterLocation(); if (current->getLocation()->has3DLayer()) { // Fetch the scene item for April current->setInteractive(Resources::Object::cast<Resources::ModelItem>(_global->getApril()->getSceneInstance())); } if (_restoreCurrentState) { _stateProvider->restoreGlobalState(_global->getLevel()); _stateProvider->restoreCurrentLevelState(current->getLevel()); _stateProvider->restoreCurrentLocationState(current->getLevel(), current->getLocation()); _restoreCurrentState = false; } else { setAprilInitialPosition(); setScrollInitialPosition(); // Trigger location change scripts if (levelChanged) { runLocationChangeScripts(current->getLevel(), Resources::Script::kCallModeEnterLocation); } runLocationChangeScripts(current->getLocation(), Resources::Script::kCallModeEnterLocation); } purgeOldLocations(); _locationChangeRequest = false; }
void ResourceProvider::requestLocationChange(uint16 level, uint16 location) { Current *currentLocation = new Current(); _locations.push_back(currentLocation); // Retrieve the level archive name Resources::Root *root = _global->getRoot(); Resources::Level *rootLevelResource = root->findChildWithIndex<Resources::Level>(level); Common::String levelArchive = _archiveLoader->buildArchiveName(rootLevelResource); // Load the archive, and get the resource sub-tree root bool newlyLoaded = _archiveLoader->load(levelArchive); currentLocation->setLevel(_archiveLoader->useRoot<Resources::Level>(levelArchive)); // If we just loaded a resource tree, restore its state if (newlyLoaded) { currentLocation->getLevel()->onAllLoaded(); _stateProvider->restoreLevelState(currentLocation->getLevel()); } // Retrieve the location archive name Resources::Level *levelResource = currentLocation->getLevel(); Resources::Location *levelLocationResource = levelResource->findChildWithIndex<Resources::Location>(location); Common::String locationArchive = _archiveLoader->buildArchiveName(levelResource, levelLocationResource); // Load the archive, and get the resource sub-tree root newlyLoaded = _archiveLoader->load(locationArchive); currentLocation->setLocation(_archiveLoader->useRoot<Resources::Location>(locationArchive)); if (currentLocation->getLocation()->has3DLayer()) { Resources::Layer3D *layer = currentLocation->getLocation()->findChildWithSubtype<Resources::Layer3D>(Resources::Layer::kLayer3D); currentLocation->setFloor(layer->findChild<Resources::Floor>()); currentLocation->setCamera(layer->findChild<Resources::Camera>()); } else { currentLocation->setFloor(nullptr); currentLocation->setCamera(nullptr); } // If we just loaded a resource tree, restore its state if (newlyLoaded) { currentLocation->getLocation()->onAllLoaded(); _stateProvider->restoreLocationState(currentLocation->getLevel(), currentLocation->getLocation()); } _locationChangeRequest = true; }
Resources::Level *ResourceProvider::getLevel(uint16 level) const { Current *current = findLevel(level); if (current) { return current->getLevel(); } return nullptr; }
bool Console::Cmd_Location(int argc, const char **argv) { if (argc != 1) { debugPrintf("Display the current location.\n"); debugPrintf("Usage :\n"); debugPrintf("location\n"); return true; } Current *current = StarkGlobal->getCurrent(); debugPrintf("location: %02x %02x\n", current->getLevel()->getIndex(), current->getLocation()->getIndex()); return true; }
void GameInterface::skipCurrentSpeeches() { Current *current = StarkGlobal->getCurrent(); if (!current) { return; // No current location, nothing to do } // Get all speeches Common::Array<Resources::Speech *> speeches; speeches.push_back(StarkGlobal->getLevel()->listChildrenRecursive<Resources::Speech>()); speeches.push_back(current->getLevel()->listChildrenRecursive<Resources::Speech>()); speeches.push_back(current->getLocation()->listChildrenRecursive<Resources::Speech>()); // Stop them for (uint i = 0; i < speeches.size(); i++) { Resources::Speech *speech = speeches[i]; if (speech->isPlaying()) { speech->stop(); } } }