void NetManager::spawnPlayer(uint32_t id) { FAWorld::World& world = *FAWorld::World::get(); FAWorld::Player* newPlayer = new FAWorld::Player(); newPlayer->mPos = FAWorld::Position(76, 68); newPlayer->destination() = newPlayer->mPos.current(); newPlayer->setSpriteClass("warrior"); world.addPlayer(id, newPlayer); }
void EngineMain::runGameLoop(const bpo::variables_map& variables, const std::string& pathEXE) { FALevelGen::FAsrand(static_cast<int> (time(nullptr))); FAWorld::Player* player; FARender::Renderer& renderer = *FARender::Renderer::get(); Settings::Settings settings; if(!settings.loadUserSettings()) return; std::string characterClass = variables["character"].as<std::string>(); DiabloExe::DiabloExe exe(pathEXE); if (!exe.isLoaded()) { renderer.stop(); return; } FAWorld::ItemManager& itemManager = FAWorld::ItemManager::get(); FAWorld::World world(exe); FAWorld::PlayerFactory playerFactory(exe); bool isServer = variables["mode"].as<std::string>() == "server"; if(isServer) world.generateLevels(); itemManager.loadItems(&exe); player = playerFactory.create(characterClass); world.addCurrentPlayer(player); if (variables["invuln"].as<std::string>() == "on") player->setInvuln(true); mInputManager->registerKeyboardObserver(&world); mInputManager->registerMouseObserver(&world); int32_t currentLevel = variables["level"].as<int32_t>(); FAGui::GuiManager guiManager(*this, *player); world.setGuiManager (&guiManager); if (currentLevel == -1) currentLevel = 0; bool clientWaitingForLevel = false; // -1 represents the main menu if(currentLevel != -1 && isServer) world.setLevel(currentLevel); else clientWaitingForLevel = true; boost::asio::io_service io; NetManager netManager(isServer, playerFactory); // Main game logic loop while(!mDone) { boost::asio::deadline_timer timer(io, boost::posix_time::milliseconds(1000/FAWorld::World::ticksPerSecond)); if (clientWaitingForLevel) { clientWaitingForLevel = world.getCurrentLevel() != nullptr; } mInputManager->update(mPaused); if(!mPaused && !clientWaitingForLevel) { world.update(mNoclip); } nk_context* ctx = renderer.getNuklearContext(); netManager.update(); guiManager.update(mPaused, ctx); FAWorld::GameLevel* level = world.getCurrentLevel(); FARender::RenderState* state = renderer.getFreeState(); if(state) { state->mPos = player->getPos(); if(level != NULL) state->tileset = renderer.getTileset(*level); state->level = level; if(!FAGui::cursorPath.empty()) state->mCursorEmpty = false; else state->mCursorEmpty = true; state->mCursorFrame = FAGui::cursorFrame; state->mCursorSpriteGroup = renderer.loadImage("data/inv/objcurs.cel"); state->mCursorHotspot = FAGui::cursorHotspot; world.fillRenderState(state); state->nuklearData.fill(ctx); } std::vector<uint32_t> spritesToPreload; if (renderer.getAndClearSpritesNeedingPreloading(spritesToPreload)) ThreadManager::get()->sendSpritesForPreload(spritesToPreload); nk_clear(ctx); renderer.setCurrentState(state); auto remainingTickTime = timer.expires_from_now().total_milliseconds(); if(remainingTickTime < 0) std::cerr << "tick time exceeded by " << -remainingTickTime << "ms" << std::endl; timer.wait(); } renderer.stop(); renderer.waitUntilDone(); }
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]; } }
int realmain(int argc, char** argv) { while(!FARender::Renderer::get()) {} FARender::Renderer& renderer = *FARender::Renderer::get(); Input::InputManager& input = *Input::InputManager::get(); size_t levelNum; boost::program_options::options_description desc("Options"); desc.add_options() ("help,h", "Print help") ("level,l", boost::program_options::value<size_t>(&levelNum)->default_value(0), "Level number to load (0-4)"); boost::program_options::variables_map vm; try { boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); if(vm.count("help")) { std::cout << desc << std::endl; return 0; } boost::program_options::notify(vm); if(levelNum > 4) throw boost::program_options::validation_error( boost::program_options::validation_error::invalid_option_value, "level"); } catch(boost::program_options::error& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << desc << std::endl; return 1; } DiabloExe::DiabloExe exe; FAWorld::World world; FALevelGen::FAsrand(time(NULL)); std::vector<Level::Level*> levels(5); size_t currentLevel = levelNum; Level::Level* level; if(!(level = getLevel(levelNum, exe))) { done = true; } else { levels[currentLevel] = level; setLevel(levelNum, exe, world, renderer, *level); } FAWorld::Player* player = world.getPlayer(); if(levelNum == 0) player->mPos = FAWorld::Position(75, 68); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); boost::posix_time::ptime last = boost::posix_time::microsec_clock::local_time(); std::pair<size_t, size_t> destination = player->mPos.current(); // Main game logic loop while(!done) { if(mouseDown) { destination = renderer.getClickedTile(xClick, yClick); if(click) level->activate(destination.first, destination.second); click = false; } input.processInput(); 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 == 0 ? 0 : 1, 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); setLevel(currentLevel, exe, world, renderer, *level); } changeLevel = 0; } 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::sleep(boost::posix_time::milliseconds(1)); now = boost::posix_time::microsec_clock::local_time(); } last = now; 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); } if(!noclip && !(*level)[player->mPos.next().first][player->mPos.next().second].passable()) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } world.update(); FARender::RenderState* state = renderer.getFreeState(); state->mPos = player->mPos; world.fillRenderState(state); renderer.setCurrentState(state); } renderer.stop(); while(!renderDone) {} // have to wait until the renderer stops before destroying all our locals for(size_t i = 0; i < levels.size(); i++) delete levels[i]; return 0; }
void runGameLoop(const bpo::variables_map& variables) { while(!FARender::Renderer::get()) {} FARender::Renderer& renderer = *FARender::Renderer::get(); Input::InputManager input(&keyPress, NULL, &mouseClick, &mouseRelease, &mouseMove, renderer.getRocketContext()); DiabloExe::DiabloExe exe; FAWorld::World world; FALevelGen::FAsrand(time(NULL)); std::vector<Level::Level*> levels(5); size_t currentLevel = variables["level"].as<size_t>(); Level::Level* level; if(!(level = getLevel(currentLevel, exe))) { done = true; } else { levels[currentLevel] = level; setLevel(currentLevel, exe, world, renderer, *level); } FAWorld::Player* player = world.getPlayer(); if(currentLevel == 0) player->mPos = FAWorld::Position(75, 68); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); boost::posix_time::ptime last = boost::posix_time::microsec_clock::local_time(); std::pair<size_t, size_t> destination = player->mPos.current(); FAGui::initGui(); // Main game logic loop while(!done) { if(mouseDown) { destination = renderer.getClickedTile(xClick, yClick); if(click) level->activate(destination.first, destination.second); click = false; } input.processInput(paused); 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 == 0 ? 0 : 1, 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); setLevel(currentLevel, exe, world, renderer, *level); } changeLevel = 0; } 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::sleep(boost::posix_time::milliseconds(1)); now = boost::posix_time::microsec_clock::local_time(); } last = now; 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); } if(!noclip && !(*level)[player->mPos.next().first][player->mPos.next().second].passable()) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } if(!paused) world.update(); FAGui::updateGui(); FARender::RenderState* state = renderer.getFreeState(); state->mPos = player->mPos; world.fillRenderState(state); Render::updateGuiBuffer(state->guiDrawBuffer); renderer.setCurrentState(state); } FAGui::destroyGui(); renderer.stop(); while(!renderDone) {} // have to wait until the renderer stops before destroying all our locals for(size_t i = 0; i < levels.size(); i++) delete levels[i]; }