diff --git a/include/server/Lobby.h b/include/server/Lobby.h index 286d9cb..3dd760c 100644 --- a/include/server/Lobby.h +++ b/include/server/Lobby.h @@ -12,7 +12,7 @@ class Server; class Lobby { private: Server* m_Server; - bool m_GameStarted = false; + bool m_LobbyOpened = false; std::uint64_t m_StartTimerTime = 0; std::vector m_Players; utils::AutoTimer m_Timer; @@ -22,6 +22,8 @@ public: void OnPlayerJoin(std::uint8_t playerID); void OnPlayerLeave(std::uint8_t playerID); + void OpenLobby(); + void SendTimeRemaining(); void Tick(); diff --git a/include/server/Server.h b/include/server/Server.h index c28fb3b..e4087f8 100644 --- a/include/server/Server.h +++ b/include/server/Server.h @@ -70,6 +70,8 @@ public: void Stop(); // force the server to stop void Close(); // at the end of a game + void Restart(); // go back to lobby state + bool LoadMap(const std::string& worldFilePath); bool IsMapLoaded(); diff --git a/include/td/game/World.h b/include/td/game/World.h index f1f50ca..e4e87e8 100644 --- a/include/td/game/World.h +++ b/include/td/game/World.h @@ -171,6 +171,8 @@ public: void Tick(std::uint64_t delta); + void Reset(); // clear mobs and towers + void SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir); TowerPtr PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder); diff --git a/src/server/Lobby.cpp b/src/server/Lobby.cpp index 05d49ac..0f7785a 100644 --- a/src/server/Lobby.cpp +++ b/src/server/Lobby.cpp @@ -32,13 +32,19 @@ Lobby::Lobby(Server* server) : m_Server(server), m_Timer(1000, std::bind(&Lobby: } +void Lobby::OpenLobby() { + m_Players.clear(); + m_LobbyOpened = true; + m_StartTimerTime = 0; +} + void Lobby::Tick() { - if (m_GameStarted || m_StartTimerTime == 0) + if (!m_LobbyOpened || m_StartTimerTime == 0) return; if (utils::GetTime() - m_StartTimerTime >= LobbyWaitingTime) { m_Server->GetGame().NotifyListeners(&game::GameListener::OnGameBegin); - m_GameStarted = true; + m_LobbyOpened = false; return; } @@ -51,8 +57,9 @@ void Lobby::SendTimeRemaining() { } void Lobby::OnPlayerJoin(std::uint8_t playerID) { - if (m_GameStarted) + if (!m_LobbyOpened) return; + utils::LOG("(Server) Player Joined Lobby !"); m_Players.push_back(playerID); if (m_Players.size() == MIN_PLAYER_WAITING) { // start timer if a second player join the match @@ -63,8 +70,9 @@ void Lobby::OnPlayerJoin(std::uint8_t playerID) { } void Lobby::OnPlayerLeave(std::uint8_t playerID) { - if (m_GameStarted) + if (!m_LobbyOpened) return; + utils::LOG("(Server) Player Leaved Lobby !"); auto it = std::find(m_Players.begin(), m_Players.end(), playerID); diff --git a/src/server/Server.cpp b/src/server/Server.cpp index bf45976..c0b528b 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -52,6 +52,12 @@ void Server::StartThread() { }); } +void Server::Restart() { + m_Game.GetWorld()->Reset(); + m_Lobby.OpenLobby(); + m_Game.SetGameState(game::GameState::Lobby); +} + void Server::Close() { StopThread(); } @@ -76,6 +82,7 @@ bool Server::Start(std::uint16_t port, bool blocking) { utils::LOG(utils::format("Server started at port %u !", port)); m_TickCounter.Reset(); m_ServerRunning = true; + m_Lobby.OpenLobby(); if (blocking) { ServerLoop(); } else { @@ -166,9 +173,9 @@ void Server::OnPlayerLeave(std::uint8_t id) { protocol::PlayerLeavePacket packet(id); BroadcastPacket(&packet); - if (GetPlayers().empty()) { - utils::LOG("All players left. Stopping server ..."); - Stop(); + if (GetPlayers().empty() && m_Game.GetGameState() != game::GameState::Lobby) { + utils::LOG("All players left. Go back to lobby ..."); + Restart(); } } diff --git a/src/server/game/ServerGame.cpp b/src/server/game/ServerGame.cpp index 5d70b0c..009cc0c 100644 --- a/src/server/game/ServerGame.cpp +++ b/src/server/game/ServerGame.cpp @@ -122,8 +122,8 @@ void ServerGame::OnGameClose() { protocol::DisconnectPacket packet("Game finished"); m_Server->BroadcastPacket(&packet); - // Closing server - m_Server->Close(); + // Put back to lobby state + m_Server->Restart(); } } // namespace game diff --git a/src/td/game/World.cpp b/src/td/game/World.cpp index 2718efd..e0b60ee 100644 --- a/src/td/game/World.cpp +++ b/src/td/game/World.cpp @@ -110,6 +110,11 @@ void World::Tick(std::uint64_t delta) { CleanDeadMobs(); } +void World::Reset() { + m_Towers.clear(); + m_Mobs.clear(); +} + void World::SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir) { MobPtr mob = MobFactory::CreateMob(id, type, level, sender); mob->SetCenter({ x, y });