void HexagonGame::newGame(const string& mId, bool mFirstPlay, float mDifficultyMult) { initFlashEffect(); firstPlay = mFirstPlay; setLevelData(assets.getLevelData(mId), mFirstPlay); difficultyMult = mDifficultyMult; // Audio cleanup assets.stopSounds(); stopLevelMusic(); assets.playSound("go.ogg"); playLevelMusic(); if(Config::getMusicSpeedDMSync()) { auto current(assets.getMusicPlayer().getCurrent()); if(current != nullptr) current->setPitch(pow(difficultyMult, 0.12f)); } // Events cleanup messageText.setString(""); eventTimeline.clear(); eventTimeline.reset(); messageTimeline.clear(); messageTimeline.reset(); // Manager cleanup manager.clear(); factory.createPlayer(); // Timeline cleanup timeline.clear(); timeline.reset(); effectTimelineManager.clear(); mustChangeSides = false; // FPSWatcher reset fpsWatcher.reset(); if(Config::getOfficial()) fpsWatcher.enable(); // LUA context and game status cleanup status = HexagonGameStatus{}; if(!mFirstPlay) runLuaFunction<void>("onUnload"); lua = Lua::LuaContext{}; initLua(); runLuaFile(levelData->luaScriptPath); runLuaFunction<void>("onInit"); runLuaFunction<void>("onLoad"); restartId = mId; restartFirstTime = false; setSides(levelStatus.sides); // Reset zoom overlayCamera.setView({{Config::getWidth() / 2.f, Config::getHeight() / 2.f}, Vec2f(Config::getWidth(), Config::getHeight())}); backgroundCamera.setView({ssvs::zeroVec2f, {Config::getWidth() * Config::getZoomFactor(), Config::getHeight() * Config::getZoomFactor()}}); backgroundCamera.setRotation(0); // 3D Cameras cleanup depthCameras.clear(); auto depth(styleData._3dDepth); if(depth > Config::get3DMaxDepth()) depth = Config::get3DMaxDepth(); for(auto i(0u); i < depth; ++i) depthCameras.push_back({window, {}}); }
void HexagonGame::newGame(string mId, bool mFirstPlay) { clearMessages(); setLevelData(getLevelData(mId), mFirstPlay); stopAllSounds(); playSound("play"); pm->resetAdj(); stopLevelMusic(); playLevelMusic(); rotationDirection = getRnd(0, 100) > 50 ? true : false; scripts.clear(); timeStop = 0; randomSideChangesEnabled = true; incrementEnabled = true; maxPulse = 85; minPulse = 75; pulseSpeedBackwards = 1; pulseSpeed = 1; hasDied = false; mustRestart = false; currentTime = 0; incrementTime = 0; setSides(levelData.getSides()); radius = minPulse; manager.clear(); createPlayer(manager, this, centerPos); scriptsTimeline = Timeline{}; messagesTimeline = Timeline{}; timeline = Timeline{}; }
void HexagonGame::newGame(const string& mId, bool mFirstPlay, float mDifficultyMult) { firstPlay = mFirstPlay; setLevelData(getLevelData(mId), mFirstPlay); difficultyMult = mDifficultyMult; // Audio cleanup stopAllSounds(); playSound("go.ogg"); stopLevelMusic(); playLevelMusic(); // Events cleanup clearMessage(); for(auto eventPtr : eventPtrs) delete eventPtr; eventPtrs.clear(); while(!eventPtrQueue.empty()) { delete eventPtrQueue.front(); eventPtrQueue.pop(); } eventPtrQueue = queue<EventData*>{}; // Game status cleanup status = HexagonGameStatus{}; restartId = mId; restartFirstTime = false; setSides(levelData.getSides()); // Manager cleanup manager.clear(); factory.createPlayer(); // Timeline cleanup timeline.clear(); timeline.reset(); messageTimeline.clear(); messageTimeline.reset(); effectTimelineManager.clear(); // FPSWatcher reset fpsWatcher.reset(); if(getOfficial()) fpsWatcher.enable(); // LUA context cleanup if(!mFirstPlay) runLuaFunction<void>("onUnload"); lua = Lua::LuaContext{}; initLua(); runLuaFile(levelData.getValueString("lua_file")); runLuaFunction<void>("onLoad"); // Random rotation direction if(getRnd(0, 100) > 50) setRotationSpeed(getRotationSpeed() * -1); // Reset zoom overlayCamera.setView({{getWidth() / 2.f, getHeight() / 2.f}, sf::Vector2f(getWidth(), getHeight())}); backgroundCamera.setView({{0, 0}, {getWidth() * getZoomFactor(), getHeight() * getZoomFactor()}}); backgroundCamera.setRotation(0); // 3D Cameras cleanup depthCameras.clear(); unsigned int depth{styleData.get3DDepth()}; if(depth > get3DMaxDepth()) depth = get3DMaxDepth(); for(unsigned int i{0}; i < depth; ++i) depthCameras.push_back({window, {}}); }
void GetTriforce::update() { if(counter==40) { actiontype oldaction = (actiontype)link.getAction(); ALLOFF(true, false); link.setAction(oldaction); // have to reset this } if(counter>=40 && counter<88) { if(get_bit(quest_rules,qr_FADE)) { if((counter&3)==0) { fade_interpolate(RAMpal,flash_pal,RAMpal,42,0,CSET(6)-1); refreshpal=true; } if((counter&3)==2) { loadpalset(0,0); loadpalset(1,1); loadpalset(5,5); if(currscr<128) loadlvlpal(DMaps[currdmap].color); else loadlvlpal(0xB); // TODO: Cave/Item Cellar distinction? } } else { if((counter&7)==0) { for(int cs2=2; cs2<5; cs2++) { for(int i=1; i<16; i++) { RAMpal[CSET(cs2)+i]=flash_pal[CSET(cs2)+i]; } } refreshpal=true; } if((counter&7)==4) { if(currscr<128) loadlvlpal(DMaps[currdmap].color); else loadlvlpal(0xB); loadpalset(5,5); } } } if(itemsbuf[triforceID].flags & ITEM_GAMEDATA) { if(counter==88) { refill_what=REFILL_ALL; refill_why=triforceID; link.StartRefill(REFILL_ALL); link.refill(); } if(counter==89) { if(link.refill()) counter--; } } if(itemsbuf[triforceID].flags & ITEM_FLAG1) // Warp out flag { if(counter>=208 && counter<288) { x2++; counter2++; switch(counter2) { case 5: counter2=0; case 0: case 2: case 3: x2++; break; } } do_dcounters(); if(counter<288) { int curtain_x=x2&0xF8; draw_screen_clip_rect_x1=curtain_x; draw_screen_clip_rect_x2=255-curtain_x; } } counter++; if(counter<408) return; if(midi_pos > 0 || (zcmusic && zcmusic->position<800)) // 800 may not be just right, but it works return; finish(); draw_screen_clip_rect_x1=0; draw_screen_clip_rect_x2=255; show_subscreen_items=true; if(itemsbuf[triforceID].flags & ITEM_FLAG1 && currscr < 128) { link.setScrollDir(link.dir); link.dowarp(1,0); //side warp } else playLevelMusic(); }
void GanonIntro::update() { /* ************************ * GANON INTRO SEQUENCE * ************************ -25 DOT updates -24 LINK in 0 TRIFORCE overhead - code begins at this point (counter == 0) 47 GANON in 58 LIGHT step 68 LIGHT step 78 LIGHT step 255 TRIFORCE out 256 TRIFORCE in 270 TRIFORCE out 271 GANON out, LINK face up */ if(counter==47) { music_stop(); stop_sfx(WAV_ROAR); sfx(WAV_GASP); sfx(WAV_GANON); int Id=0; for(int i=0; i<eMAXGUYS; i++) { if(guysbuf[i].flags2&eneflag_ganon) { Id=i; break; } } if(current_item(itype_ring)) addenemy(160,96,Id,0); else addenemy(80,32,Id,0); } else if(counter==48) { lighting(true,true); // Hmm. -L counter += 30; } //NES Z1, the triforce vanishes for one frame in two cases //while still showing Link's two-handed overhead sprite. else if(counter==255 || counter==270) link.setHeldItem(-1); else if(counter==256) link.setHeldItem(getItemID(itemsbuf,itype_triforcepiece,1)); counter++; if(counter<271) return; link.setAction(none); link.dir=up; if(!getmapflag() && (tunes[MAXMIDIS-1].data)) jukebox(MAXMIDIS-1); else playLevelMusic(); currcset=DMaps[currdmap].color; showCurrentDMapIntro(); cont_sfx(WAV_ROAR); finish(); }
void HexagonGame::initLua() { // Utils lua.writeVariable("u_log", [=](string mLog) { lo("lua") << mLog << "\n"; }); lua.writeVariable("u_execScript", [=](string mName) { runLuaFile(levelData->packPath + "Scripts/" + mName); }); lua.writeVariable("u_playSound", [=](string mId) { assets.playSound(mId); }); lua.writeVariable("u_setMusic", [=](string mId) { musicData = assets.getMusicData(mId); musicData.firstPlay = true; stopLevelMusic(); playLevelMusic(); }); lua.writeVariable("u_isKeyPressed", [=](int mKey) { return window.getInputState()[KKey(mKey)]; }); lua.writeVariable("u_isFastSpinning", [=] { return status.fastSpin > 0; }); lua.writeVariable("u_forceIncrement", [=] { incrementDifficulty(); }); lua.writeVariable("u_kill", [=] { timeline.append<Do>([=] { death(true); }); }); lua.writeVariable("u_eventKill", [=] { eventTimeline.append<Do>([=] { death(true); }); }); lua.writeVariable("u_getDifficultyMult", [=] { return difficultyMult; }); lua.writeVariable("u_getSpeedMultDM", [=] { return getSpeedMultDM(); }); lua.writeVariable("u_getDelayMultDM", [=] { return getDelayMultDM(); }); // Messages lua.writeVariable("m_messageAdd", [=](string mMsg, float mDuration) { eventTimeline.append<Do>([=] { if(firstPlay && Config::getShowMessages()) addMessage(mMsg, mDuration); }); }); lua.writeVariable("m_messageAddImportant", [=](string mMsg, float mDuration) { eventTimeline.append<Do>([=] { if(Config::getShowMessages()) addMessage(mMsg, mDuration); }); }); // Main timeline control lua.writeVariable("t_wait", [=](float mDuration) { timeline.append<Wait>(mDuration); }); lua.writeVariable("t_waitS", [=](float mDuration) { timeline.append<Wait>(ssvu::getSecondsToFT(mDuration)); }); lua.writeVariable("t_waitUntilS", [=](float mDuration) { timeline.append<Wait>(10); timeline.append<Do>([=] { if(status.currentTime < mDuration) timeline.jumpTo(timeline.getCurrentIndex() - 2); }); }); // Event timeline control lua.writeVariable("e_eventStopTime", [=](float mDuration) { eventTimeline.append<Do>([=] { status.timeStop = mDuration; }); }); lua.writeVariable("e_eventStopTimeS", [=](float mDuration) { eventTimeline.append<Do>([=] { status.timeStop = ssvu::getSecondsToFT(mDuration); }); }); lua.writeVariable("e_eventWait", [=](float mDuration) { eventTimeline.append<Wait>(mDuration); }); lua.writeVariable("e_eventWaitS", [=](float mDuration) { eventTimeline.append<Wait>(ssvu::getSecondsToFT(mDuration)); }); lua.writeVariable("e_eventWaitUntilS", [=](float mDuration) { eventTimeline.append<Wait>(10); eventTimeline.append<Do>([=] { if(status.currentTime < mDuration) eventTimeline.jumpTo( eventTimeline.getCurrentIndex() - 2); }); }); // Level control lua.writeVariable("l_setSpeedMult", [=](float mValue) { levelStatus.speedMult = mValue; }); lua.writeVariable("l_setSpeedInc", [=](float mValue) { levelStatus.speedInc = mValue; }); lua.writeVariable("l_setRotationSpeed", [=](float mValue) { levelStatus.rotationSpeed = mValue; }); lua.writeVariable("l_setRotationSpeedMax", [=](float mValue) { levelStatus.rotationSpeedMax = mValue; }); lua.writeVariable("l_setRotationSpeedInc", [=](float mValue) { levelStatus.rotationSpeedInc = mValue; }); lua.writeVariable("l_setDelayMult", [=](float mValue) { levelStatus.delayMult = mValue; }); lua.writeVariable("l_setDelayInc", [=](float mValue) { levelStatus.delayInc = mValue; }); lua.writeVariable("l_setFastSpin", [=](float mValue) { levelStatus.fastSpin = mValue; }); lua.writeVariable("l_setSides", [=](unsigned int mValue) { levelStatus.sides = mValue; }); lua.writeVariable("l_setSidesMin", [=](unsigned int mValue) { levelStatus.sidesMin = mValue; }); lua.writeVariable("l_setSidesMax", [=](unsigned int mValue) { levelStatus.sidesMax = mValue; }); lua.writeVariable("l_setIncTime", [=](float mValue) { levelStatus.incTime = mValue; }); lua.writeVariable("l_setPulseMin", [=](float mValue) { levelStatus.pulseMin = mValue; }); lua.writeVariable("l_setPulseMax", [=](float mValue) { levelStatus.pulseMax = mValue; }); lua.writeVariable("l_setPulseSpeed", [=](float mValue) { levelStatus.pulseSpeed = mValue; }); lua.writeVariable("l_setPulseSpeedR", [=](float mValue) { levelStatus.pulseSpeedR = mValue; }); lua.writeVariable("l_setPulseDelayMax", [=](float mValue) { levelStatus.pulseDelayMax = mValue; }); lua.writeVariable("l_setBeatPulseMax", [=](float mValue) { levelStatus.beatPulseMax = mValue; }); lua.writeVariable("l_setBeatPulseDelayMax", [=](float mValue) { levelStatus.beatPulseDelayMax = mValue; }); lua.writeVariable("l_setWallSkewLeft", [=](float mValue) { levelStatus.wallSkewLeft = mValue; }); lua.writeVariable("l_setWallSkewRight", [=](float mValue) { levelStatus.wallSkewRight = mValue; }); lua.writeVariable("l_setWallAngleLeft", [=](float mValue) { levelStatus.wallAngleLeft = mValue; }); lua.writeVariable("l_setWallAngleRight", [=](float mValue) { levelStatus.wallAngleRight = mValue; }); lua.writeVariable("l_setRadiusMin", [=](float mValue) { levelStatus.radiusMin = mValue; }); lua.writeVariable("l_setSwapEnabled", [=](bool mValue) { levelStatus.swapEnabled = mValue; }); lua.writeVariable("l_setTutorialMode", [=](bool mValue) { levelStatus.tutorialMode = mValue; }); lua.writeVariable("l_setIncEnabled", [=](bool mValue) { levelStatus.incEnabled = mValue; }); lua.writeVariable("l_setMaxInc", [=](SizeT mValue) { levelStatus.maxIncrements = mValue; }); lua.writeVariable("l_addTracked", [=](string mVar, string mName) { levelStatus.trackedVariables.emplace_back(mVar, mName); }); lua.writeVariable("l_enableRndSideChanges", [=](bool mValue) { levelStatus.rndSideChangesEnabled = mValue; }); lua.writeVariable("l_getRotationSpeed", [=] { return levelStatus.rotationSpeed; }); lua.writeVariable("l_setRotation", [=](float mValue) { backgroundCamera.setRotation(mValue); }); lua.writeVariable("l_getRotation", [=] { return backgroundCamera.getRotation(); }); lua.writeVariable("l_getSides", [=] { return levelStatus.sides; }); lua.writeVariable("l_getSpeedMult", [=] { return levelStatus.speedMult; }); lua.writeVariable("l_getDelayMult", [=] { return levelStatus.delayMult; }); lua.writeVariable("l_getMaxInc", [=] { return levelStatus.maxIncrements; }); lua.writeVariable("l_getLevelTime", [=] { return (float)status.currentTime; }); lua.writeVariable("l_getOfficial", [=] { return Config::getOfficial(); }); // TODO: test and consider re-enabling /* lua.writeVariable("l_setLevel", [=](string mId) { setLevelData(assets.getLevelData(mId), true); stopLevelMusic(); playLevelMusic(); }); */ // Style control lua.writeVariable("s_setPulseInc", [=](float mValue) { styleData.pulseIncrement = mValue; }); lua.writeVariable("s_setHueInc", [=](float mValue) { styleData.hueIncrement = mValue; }); lua.writeVariable("s_getHueInc", [=] { return styleData.hueIncrement; }); lua.writeVariable("s_setCameraShake", [=](int mValue) { levelStatus.cameraShake = mValue; }); lua.writeVariable("s_getCameraShake", [=] { return levelStatus.cameraShake; }); lua.writeVariable("s_setStyle", [=](string mId) { styleData = assets.getStyleData(mId); }); // Wall creation lua.writeVariable("w_wall", [=](int mSide, float mThickness) { timeline.append<Do>([=] { factory.createWall( mSide, mThickness, {getSpeedMultDM()}); }); }); lua.writeVariable("w_wallAdj", [=](int mSide, float mThickness, float mSpeedAdj) { timeline.append<Do>([=] { factory.createWall( mSide, mThickness, mSpeedAdj * getSpeedMultDM()); }); }); lua.writeVariable("w_wallAcc", [=](int mSide, float mThickness, float mSpeedAdj, float mAcceleration, float mMinSpeed, float mMaxSpeed) { timeline.append<Do>([=] { factory.createWall(mSide, mThickness, {mSpeedAdj * getSpeedMultDM(), mAcceleration, mMinSpeed * getSpeedMultDM(), mMaxSpeed * getSpeedMultDM()}); }); }); lua.writeVariable( "w_wallHModSpeedData", [=](float mHMod, int mSide, float mThickness, float mSAdj, float mSAcc, float mSMin, float mSMax, bool mSPingPong) { timeline.append<Do>([=] { factory.createWall(mSide, mThickness, {mSAdj * getSpeedMultDM(), mSAcc, mSMin, mSMax, mSPingPong}, mHMod); }); }); lua.writeVariable( "w_wallHModCurveData", [=](float mHMod, int mSide, float mThickness, float mCAdj, float mCAcc, float mCMin, float mCMax, bool mCPingPong) { timeline.append<Do>([=] { factory.createWall(mSide, mThickness, {getSpeedMultDM()}, {mCAdj, mCAcc, mCMin, mCMax, mCPingPong}, mHMod); }); }); }
void runGameLoop(const bpo::variables_map& variables) { FARender::Renderer& renderer = *FARender::Renderer::get(); Input::InputManager& input = *Input::InputManager::get(); Engine::ThreadManager& threadManager = *Engine::ThreadManager::get(); DiabloExe::DiabloExe exe; if (!exe.isLoaded()) { renderer.stop(); return; } FAWorld::World world; FALevelGen::FAsrand(time(NULL)); std::vector<Level::Level*> levels(9); int32_t currentLevel = variables["level"].as<int32_t>(); Level::Level* level = NULL; FARender::Tileset tileset; FAWorld::Player* player = world.getPlayer(); FAGui::initGui(); // -1 represents the main menu if(currentLevel != -1) { if(!(level = getLevel(currentLevel, exe))) { done = true; } else { tileset = renderer.getTileset(*level); levels[currentLevel] = level; setLevel(currentLevel, exe, world, level); } player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); FAGui::showIngameGui(); playLevelMusic(currentLevel, threadManager); } else { paused = true; FAGui::showMainMenu(); threadManager.playMusic("music/dintro.wav"); } boost::posix_time::ptime last = boost::posix_time::microsec_clock::local_time(); std::pair<size_t, size_t> destination = player->mPos.current(); //bpt::ptree hotkeypt; Misc::readIni("resources/hotkeys.ini", hotkeypt); quit_key = Input::Hotkey("Quit", hotkeypt); noclip_key = Input::Hotkey("Noclip", hotkeypt); changelvlup_key = Input::Hotkey("Changelvlup", hotkeypt); changelvldwn_key = Input::Hotkey("Changelvldwn", hotkeypt); // Main game logic loop while(!done) { input.processInput(paused); boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time(); while((size_t)(now.time_of_day().total_milliseconds() - last.time_of_day().total_milliseconds()) < 1000/FAWorld::World::ticksPerSecond) { boost::this_thread::yield(); now = boost::posix_time::microsec_clock::local_time(); } last = now; if(!paused) { if(mouseDown) { destination = renderer.getClickedTile(xClick, yClick, *level, player->mPos); if(click) level->activate(destination.first, destination.second); click = false; } if(changeLevel) { int32_t tmp = currentLevel + changeLevel; if(tmp >= 0 && tmp < (int32_t)levels.size()) { currentLevel = tmp; if(levels[currentLevel] == NULL) levels[currentLevel] = getLevel(currentLevel, exe); level = levels[currentLevel]; if(changeLevel == -1) player->mPos = FAWorld::Position(level->downStairsPos().first, level->downStairsPos().second); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); destination = player->mPos.current(); setLevel(currentLevel, exe, world, level); tileset = renderer.getTileset(*level); playLevelMusic(currentLevel, threadManager); } changeLevel = 0; } if(player->mPos.current() != destination) { if(player->mPos.mDist == 0) { std::pair<float, float> vector = Misc::getVec(player->mPos.current(), destination); if(!player->mPos.mMoving) { player->mPos.mMoving = true; player->setAnimation(FAWorld::AnimState::walk); } player->mPos.mDirection = Misc::getVecDir(vector); } } else if(player->mPos.mMoving && player->mPos.mDist == 0) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } FAWorld::Actor* actorAtNext = world.getActorAt(player->mPos.next().first, player->mPos.next().second); if(!noclip && (!(*level)[player->mPos.next().first][player->mPos.next().second].passable() || (actorAtNext != NULL && actorAtNext != player))) { player->mPos.mMoving = false; destination = player->mPos.current(); player->setAnimation(FAWorld::AnimState::idle); } world.update(); } FAGui::updateGui(); FARender::RenderState* state = renderer.getFreeState(); if(state) { state->mPos = player->mPos; state->tileset = tileset; state->level = level; world.fillRenderState(state); Render::updateGuiBuffer(&state->guiDrawBuffer); } else { Render::updateGuiBuffer(NULL); } renderer.setCurrentState(state); } renderer.stop(); for(size_t i = 0; i < levels.size(); i++) { if(levels[i]) delete levels[i]; } }