void Parallaction_br::changeLocation() { if (_newLocationName.empty()) { return; } if (_nextPart != -1) { cleanupGame(); // more cleanup needed for part changes (see also saveload) _globalFlags = 0; cleanInventory(true); strcpy(_characterName1, "null"); _part = _nextPart; if (getFeatures() & GF_DEMO) { assert(_part == 1); } else { assert(_part >= 0 && _part <= 4); } _disk->selectArchive(_partNames[_part]); memset(_counters, 0, ARRAYSIZE(_counters)); _globalFlagsNames = _disk->loadTable("global"); _objectsNames = _disk->loadTable("objects"); _countersNames = _disk->loadTable("counters"); // TODO: maybe handle this into Disk delete _objects; if (getPlatform() == Common::kPlatformPC) { _objects = _disk->loadObjects("icone.ico"); } else { _objects = _disk->loadObjects("icons.ico", _part); } parseLocation("common.slf"); } freeLocation(false); // load new location strcpy(_location._name, _newLocationName.c_str()); parseLocation(_location._name); if (_location._startPosition.x != -1000) { _char._ani->setFoot(_location._startPosition); _char._ani->setF(_location._startFrame); } // re-link the follower animation setFollower(_followerName); if (_follower) { Common::Point p = _location._followerStartPosition; if (p.x == -1000) { _char._ani->getFoot(p); } _follower->setFoot(p); _follower->setF(_location._followerStartFrame); } _location._startPosition.x = -1000; _location._startPosition.y = -1000; _location._followerStartPosition.x = -1000; _location._followerStartPosition.y = -1000; _gfx->setScrollPosX(0); _gfx->setScrollPosY(0); if (_char._ani->gfxobj) { Common::Point foot; _char._ani->getFoot(foot); if (foot.x > 550) _gfx->setScrollPosX(320); if (foot.y > 350) _gfx->setScrollPosY(foot.y - 350); } // kFlagsRemove is cleared because the character is visible by default. // Commands can hide the character, anyway. _char._ani->_flags &= ~kFlagsRemove; _cmdExec->run(_location._commands); doLocationEnterTransition(); _cmdExec->run(_location._aCommands); // NOTE: music should not started here! // TODO: implement the music commands which control music execution _soundMan->execute(SC_PLAYMUSIC); _engineFlags &= ~kEngineChangeLocation; _newLocationName.clear(); _nextPart = -1; }
// changeLocation handles transitions between locations, and is able to display slides // between one and the other. // void Parallaction_ns::changeLocation() { if (_newLocationName.empty()) { return; } char location[200]; strcpy(location, _newLocationName.c_str()); strcpy(_location._name, _newLocationName.c_str()); debugC(1, kDebugExec, "changeLocation(%s)", location); MouseTriState oldMouseState = _input->getMouseState(); _input->setMouseState(MOUSE_DISABLED); if (!_intro) { // prevent music changes during the introduction _soundManI->playLocationMusic(location); } _input->stopHovering(); // this is still needed to remove the floatingLabel _gfx->freeLabels(); _zoneTrap.reset(); _input->setArrowCursor(); _gfx->showGfxObj(_char._ani->gfxobj, false); LocationName locname; locname.bind(location); freeLocation(false); if (locname.hasSlide()) { showSlide(locname.slide()); GfxObj *label = _gfx->createLabel(_menuFont, _location._slideText[0].c_str(), 1); _gfx->showLabel(label, CENTER_LABEL_HORIZONTAL, 14); _gfx->updateScreen(); _input->waitForButtonEvent(kMouseLeftUp); _gfx->unregisterLabel(label); delete label; } if (locname.hasCharacter()) { changeCharacter(locname.character()); } strcpy(g_saveData1, locname.location()); parseLocation(g_saveData1); if (_location._startPosition.x != -1000) { _char._ani->setX(_location._startPosition.x); _char._ani->setY(_location._startPosition.y); _char._ani->setF(_location._startFrame); _location._startPosition.y = -1000; _location._startPosition.x = -1000; } _gfx->setBlackPalette(); _gfx->updateScreen(); // BUG #1837503: kEngineChangeLocation flag must be cleared *before* commands // and acommands are executed, so that it can be set again if needed. g_engineFlags &= ~kEngineChangeLocation; _cmdExec->run(_location._commands); doLocationEnterTransition(); _cmdExec->run(_location._aCommands); if (_location._hasSound) _soundManI->playSfx(_location._soundFile, 0, true); if (!_intro) { _input->setMouseState(oldMouseState); // WORKAROUND: Fix a script bug in the Multilingual DOS version of // Nippon Safes: the mouse cursor is incorrectly hidden outside the // cave at the end of the game. Fix it here. if (!strcmp(_location._name, "ingressocav")) _input->setMouseState(MOUSE_ENABLED_SHOW); } debugC(1, kDebugExec, "changeLocation() done"); _newLocationName.clear(); }