diff --git a/src/level/parser/parserparam.cpp b/src/level/parser/parserparam.cpp index 48cc9ae8..c4ee9b31 100644 --- a/src/level/parser/parserparam.cpp +++ b/src/level/parser/parserparam.cpp @@ -955,21 +955,21 @@ int CLevelParserParam::AsResearchFlag(int def) return AsResearchFlag(); } -SortType CLevelParserParam::ToSortType(std::string value) +CScoreboard::SortType CLevelParserParam::ToSortType(std::string value) { - if (value == "Points") return SortType::SORT_POINTS; - if (value == "Name" ) return SortType::SORT_ID; - return SortType::SORT_ID; + if (value == "Points") return CScoreboard::SortType::SORT_POINTS; + if (value == "Name" ) return CScoreboard::SortType::SORT_ID; + return CScoreboard::SortType::SORT_ID; } -SortType CLevelParserParam::AsSortType() +CScoreboard::SortType CLevelParserParam::AsSortType() { if (m_empty) throw CLevelParserExceptionMissingParam(this); return ToSortType(m_value); } -SortType CLevelParserParam::AsSortType(SortType def) +CScoreboard::SortType CLevelParserParam::AsSortType(CScoreboard::SortType def) { if (m_empty) return def; diff --git a/src/level/parser/parserparam.h b/src/level/parser/parserparam.h index d011c669..62838dc7 100644 --- a/src/level/parser/parserparam.h +++ b/src/level/parser/parserparam.h @@ -87,7 +87,7 @@ public: Gfx::EngineObjectType AsTerrainType(); int AsBuildFlag(); int AsResearchFlag(); - SortType AsSortType(); + CScoreboard::SortType AsSortType(); Gfx::PyroType AsPyroType(); Gfx::CameraType AsCameraType(); MissionType AsMissionType(); @@ -111,7 +111,7 @@ public: Gfx::EngineObjectType AsTerrainType(Gfx::EngineObjectType def); int AsBuildFlag(int def); int AsResearchFlag(int def); - SortType AsSortType(SortType def); + CScoreboard::SortType AsSortType(CScoreboard::SortType def); Gfx::PyroType AsPyroType(Gfx::PyroType def); Gfx::CameraType AsCameraType(Gfx::CameraType def); MissionType AsMissionType(MissionType def); @@ -143,7 +143,7 @@ private: Gfx::EngineObjectType ToTerrainType(std::string value); int ToBuildFlag(std::string value); int ToResearchFlag(std::string value); - SortType ToSortType(std::string value); + CScoreboard::SortType ToSortType(std::string value); Gfx::PyroType ToPyroType(std::string value); Gfx::CameraType ToCameraType(std::string value); MissionType ToMissionType(std::string value); diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 03fb5314..5e6a548f 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -2704,6 +2704,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_endTakeImmediat = false; m_endTakeResearch = 0; m_endTakeTimeout = -1.0f; + m_endTakeTeamImmediateWin = false; m_endTakeWinDelay = 2.0f; m_endTakeLostDelay = 2.0f; m_teamFinished.clear(); @@ -3574,6 +3575,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) } continue; } + if (line->GetCommand() == "EndMissionTeams" && !resetObject) + { + m_endTakeTeamImmediateWin = line->GetParam("immediateWin")->AsBool(false); // false = finishing removes the team that finished, true = finishing for one team ends the whole game + continue; + } if (line->GetCommand() == "EndMissionDelay" && !resetObject) { m_endTakeWinDelay = line->GetParam("win")->AsFloat(2.0f); @@ -5050,11 +5056,11 @@ Error CRobotMain::ProcessEndMissionTake() } GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_LINE, details_line); std::string details = ""; - for (int team : GetAllTeams()) + for (std::pair team : m_scoreboard->GetSortedScores()) { if (!details.empty()) details += ", "; - details += StrUtils::Format(details_line.c_str(), GetTeamName(team).c_str(), m_scoreboard->GetScore(team).points); + details += StrUtils::Format(details_line.c_str(), GetTeamName(team.first).c_str(), team.second.points); } m_ui->GetDialog()->StartInformation( title, @@ -5125,6 +5131,18 @@ Error CRobotMain::ProcessEndMissionTake() m_scoreboard->ProcessEndTake(team); m_objMan->DestroyTeam(team, DestructionType::Win); m_teamFinished[team] = true; + if (m_endTakeTeamImmediateWin) + { + // All other teams fail + for(int other_team : GetAllActiveTeams()) + { + m_displayText->SetEnable(false); // To prevent "bot destroyed" messages + m_objMan->DestroyTeam(other_team); + m_displayText->SetEnable(true); + + m_teamFinished[other_team] = true; + } + } } } } @@ -6006,32 +6024,19 @@ void CRobotMain::UpdateCodeBattleInterface() Ui::CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW6)); assert(pw != nullptr); - std::set teams = GetAllTeams(); - std::vector sortedTeams(teams.begin(), teams.end()); - if(m_scoreboard->GetSortType() == SortType::SORT_POINTS) - { - std::sort(sortedTeams.begin(), sortedTeams.end(), [this](int teamA, int teamB) - { - if (m_scoreboard->GetScore(teamA).points > m_scoreboard->GetScore(teamB).points) return true; //Team A have more points than B? - if (m_scoreboard->GetScore(teamA).points < m_scoreboard->GetScore(teamB).points) return false; //Team A have less points than B? - - if (m_scoreboard->GetScore(teamA).time < m_scoreboard->GetScore(teamB).time) return true; //Team A scored faster than B? - else return false; //Team A scored slower than B? - }); - } int i = 0; - for (int team : sortedTeams) + for (std::pair team : m_scoreboard->GetSortedScores()) { Ui::CControl* pl; pl = pw->SearchControl(static_cast(EVENT_SCOREBOARD+2*i+0)); assert(pl != nullptr); - pl->SetName(GetTeamName(team)); + pl->SetName(GetTeamName(team.first)); pl = pw->SearchControl(static_cast(EVENT_SCOREBOARD+2*i+1)); assert(pl != nullptr); - pl->SetName(StrUtils::ToString(m_scoreboard->GetScore(team).points)); + pl->SetName(StrUtils::ToString(team.second.points)); i++; } diff --git a/src/level/robotmain.h b/src/level/robotmain.h index 7f0111ea..d067d0e0 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -673,6 +673,7 @@ protected: bool m_endTakeImmediat = false; long m_endTakeResearch = 0; float m_endTakeTimeout = -1.0f; + bool m_endTakeTeamImmediateWin = false; float m_endTakeWinDelay = 0.0f; float m_endTakeLostDelay = 0.0f; //! Set to true for teams that have already finished diff --git a/src/level/scoreboard.cpp b/src/level/scoreboard.cpp index 78afa482..1df0d0a3 100644 --- a/src/level/scoreboard.cpp +++ b/src/level/scoreboard.cpp @@ -133,7 +133,7 @@ void CScoreboard::AddPoints(int team, int points) m_score[team].time = main->GetGameTime(); } -Score CScoreboard::GetScore(int team) +CScoreboard::Score CScoreboard::GetScore(int team) { return m_score[team]; } @@ -143,12 +143,33 @@ void CScoreboard::SetScore(int team, int points) m_score[team].points = points; } -SortType CScoreboard::GetSortType() +CScoreboard::SortType CScoreboard::GetSortType() { - return m_sorttype; + return m_sortType; } void CScoreboard::SetSortType(SortType type) { - m_sorttype = type; + m_sortType = type; +} + +std::vector> CScoreboard::GetSortedScores() +{ + CRobotMain* main = CRobotMain::GetInstancePointer(); + std::set teams = main->GetAllTeams(); + std::vector> sortedTeams(teams.size()); + std::transform(teams.begin(), teams.end(), sortedTeams.begin(), [&](int team) { + return *m_score.find(team); + }); + if (m_sortType == SortType::SORT_POINTS) + { + std::sort(sortedTeams.begin(), sortedTeams.end(), [&](std::pair teamA, std::pair teamB) + { + if (teamA.second.points > teamB.second.points) return true; // Team A have more points than B? + if (teamA.second.points < teamB.second.points) return false; // Team A have less points than B? + + return teamA.second.time < teamB.second.time; // Team A scored slower than B? + }); + } + return sortedTeams; } diff --git a/src/level/scoreboard.h b/src/level/scoreboard.h index 4a094912..98f94b60 100644 --- a/src/level/scoreboard.h +++ b/src/level/scoreboard.h @@ -32,22 +32,6 @@ class CObject; -/** - * \struct Score - * \brief Struct containing score of individual team and additional variables to allow sorting teams through different criteria -*/ -struct Score -{ - int points = 0; //! Team score - float time = 0; //! Time when points were scored -}; - -enum class SortType -{ - SORT_ID, //Sort by team ID - SORT_POINTS, //Sort by points -}; - /** * \class CScoreboard * \brief Scoreboard used to score complex code battles @@ -71,6 +55,26 @@ enum class SortType class CScoreboard { public: + /** + * \struct Score + * \brief Struct containing score of individual team and additional variables to allow sorting teams through different criteria + */ + struct Score + { + int points = 0; //!< Team score + float time = 0; //!< Time when points were scored + }; + + /** + * \enum SortType + * \brief Enum defining the scoreboard sorting criteria + */ + enum class SortType + { + SORT_ID, //!< Sort by team ID + SORT_POINTS, //!< Sort by points + }; + //! Creates the scoreboard //! The scoreboard exists only if enabled in level file CScoreboard() {}; @@ -160,11 +164,13 @@ public: SortType GetSortType(); void SetSortType(SortType type); + std::vector> GetSortedScores(); + private: std::vector> m_rulesKill = {}; std::vector> m_rulesObject = {}; std::vector> m_rulesEndTake = {}; std::map m_score; int m_finishCounter = 0; - SortType m_sorttype = SortType::SORT_ID; + SortType m_sortType = SortType::SORT_ID; };