//////////////////////////////////////////////////////////// // PlayingTurn //////////////////////////////////////////////////////////// PlayingTurn::PlayingTurn(my_context ctx) : Base(ctx) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingTurn"; Client().Register(Client().GetClientUI()->GetMapWnd()); Client().GetClientUI()->GetMapWnd()->InitTurn(); Client().GetClientUI()->GetMapWnd()->RegisterWindows(); // only useful at game start but InitTurn() takes a long time, don't want to display windows before content is ready. could go in WaitingForGameStart dtor but what if it is given e.g. an error reaction? // TODO: reselect last fleet if stored in save game ui data? Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate( boost::io::str(FlexibleFormat(UserString("TURN_BEGIN")) % CurrentTurn()) + "\n"); Client().GetClientUI()->GetMessageWnd()->HandlePlayerStatusUpdate(Message::PLAYING_TURN, Client().PlayerID()); Client().GetClientUI()->GetPlayerListWnd()->Refresh(); Client().GetClientUI()->GetPlayerListWnd()->HandlePlayerStatusUpdate(Message::PLAYING_TURN, Client().PlayerID()); if (Client().GetApp()->GetClientType() != Networking::CLIENT_TYPE_HUMAN_OBSERVER) Client().GetClientUI()->GetMapWnd()->EnableOrderIssuing(true); if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_OBSERVER) { // observers can't do anything but wait for the next update, and need to // be back in WaitingForTurnData, so posting TurnEnded here has the effect // of keeping observers in the WaitingForTurnData state so they can receive // updates from the server. post_event(TurnEnded()); } else if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_PLAYER) { if (Client().GetClientUI()->GetMapWnd()->AutoEndTurnEnabled()) { // if in-game-GUI auto turn advance enabled, set auto turn counter to 1 Client().InitAutoTurns(1); } if (Client().AutoTurnsLeft() <= 0 && GetOptionsDB().Get<bool>("auto-quit")) { // if no auto turns left, and supposed to quit after that, quit DebugLogger() << "auto-quit ending game."; std::cout << "auto-quit ending game." << std::endl; Client().EndGame(true); throw HumanClientApp::CleanQuit(); } // if there are still auto turns left, advance the turn automatically, // and decrease the auto turn counter if (Client().AutoTurnsLeft() > 0) { post_event(AdvanceTurn()); Client().DecAutoTurns(); } } }
boost::statechart::result PlayingTurn::react(const PlayerStatus& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingTurn.PlayerStatus"; int about_player_id; Message::PlayerStatus status; ExtractMessageData(msg.m_message, about_player_id, status); Client().SetPlayerStatus(about_player_id, status); Client().GetClientUI()->GetMessageWnd()->HandlePlayerStatusUpdate(status, about_player_id); Client().GetClientUI()->GetPlayerListWnd()->HandlePlayerStatusUpdate(status, about_player_id); if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_MODERATOR && Client().GetClientUI()->GetMapWnd()->AutoEndTurnEnabled()) { // check status of all non-mod non-obs players: are they all done their turns? bool all_participants_waiting = true; const std::map<int, Message::PlayerStatus>& player_status = Client().PlayerStatus(); const std::map<int, PlayerInfo>& players = Client().Players(); for (std::map<int, PlayerInfo>::const_iterator it = players.begin(); it != players.end(); ++it) { int player_id = it->first; if (it->second.client_type != Networking::CLIENT_TYPE_AI_PLAYER && it->second.client_type != Networking::CLIENT_TYPE_HUMAN_PLAYER) { continue; } // only active participants matter... std::map<int, Message::PlayerStatus>::const_iterator status_it = player_status.find(player_id); if (status_it == player_status.end()) { all_participants_waiting = false; break; } if (status_it->second != Message::WAITING) { all_participants_waiting = false; break; } } // if all participants waiting, can end turn immediately if (all_participants_waiting) post_event(AdvanceTurn()); } return discard_event(); }
void ChooseTeamPhase::AssignTeam(CommitSession& session, Player& player, RaceType race, Colour colour) { LiveGame& game = GetGame(); game.GetTeam(player).Assign(race, colour, game); AdvanceTurn(); session.GetController().SendMessage(Output::ChooseTeam(game, false), player); bool allAssigned = true; for (auto& team : game.GetTeams()) allAssigned &= team->GetColour() != Colour::None; if (allAssigned) { session.DoAndPushRecord(RecordPtr(new StartGameRecord)); game.StartMainGamePhase(); // Deletes this. session.GetController().SendUpdateGame(game); } else UpdateClient(session.GetController(), nullptr); }