From c68f5e276f88d81cf2f455172f5bc9e20ed74ca8 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Fri, 19 May 2017 21:11:43 +0200 Subject: [PATCH] Add live scoreboard display --- src/common/event.h | 3 ++ src/level/robotmain.cpp | 98 ++++++++++++++++++++++++++++++++--------- src/level/robotmain.h | 6 +++ 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/src/common/event.h b/src/common/event.h index c67b7c3d..ba9a905e 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -187,6 +187,9 @@ enum EventType EVENT_LOADING = 120, + EVENT_SCOREBOARD = 130, + EVENT_SCOREBOARD_MAX = 169, + EVENT_TOOLTIP = 200, EVENT_DIALOG_OK = 300, diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 6530311d..3cd13e16 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -2569,6 +2569,8 @@ bool CRobotMain::EventFrame(const Event &event) m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE)); } + + UpdateCodeBattleInterface(); } return true; @@ -4929,31 +4931,23 @@ Error CRobotMain::ProcessEndMissionTakeForGroup(std::vector Error CRobotMain::ProcessEndMissionTake() { // Sort end conditions by teams - std::map> teams; + std::map> teamsEndTake; for (std::unique_ptr& endTake : m_endTake) - teams[endTake->winTeam].push_back(endTake.get()); + teamsEndTake[endTake->winTeam].push_back(endTake.get()); - int teamCount = 0; - bool usesTeamConditions = false; - for (auto it : teams) - { - int team = it.first; - if (team == 0) continue; - usesTeamConditions = true; - if (m_teamFinished[team]) continue; - teamCount++; - } + // This is just a smart way to check if we have any map values other than 0 defined + bool usesTeamConditions = teamsEndTake.size() > teamsEndTake.count(0); if (!usesTeamConditions) { - m_missionResult = ProcessEndMissionTakeForGroup(teams[0]); + m_missionResult = ProcessEndMissionTakeForGroup(teamsEndTake[0]); } else { // Special handling for teams m_missionResult = ERR_MISSION_NOTERM; - if (teamCount == 0) + if (GetAllActiveTeams().empty()) { GetLogger()->Info("All teams died, mission ended\n"); if (m_scoreboard) @@ -4963,10 +4957,8 @@ Error CRobotMain::ProcessEndMissionTake() GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_TEXT, text); GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_LINE, details_line); std::string details = ""; - for (auto it : teams) + for (int team : GetAllTeams()) { - int team = it.first; - if (team == 0) continue; if (!details.empty()) details += ", "; details += StrUtils::Format(details_line.c_str(), GetTeamName(team).c_str(), m_scoreboard->GetScore(team)); @@ -4990,7 +4982,7 @@ Error CRobotMain::ProcessEndMissionTake() } else { - for (auto it : teams) + for (auto it : teamsEndTake) { int team = it.first; if (team == 0) continue; @@ -5792,12 +5784,16 @@ void CRobotMain::StartDetectEffect(COldObject* object, CObject* target) void CRobotMain::CreateCodeBattleInterface() { - if(m_phase == PHASE_SIMUL) + if (m_phase == PHASE_SIMUL) { Math::Point pos, ddim; + int numTeams = m_scoreboard ? GetAllTeams().size() : 0; + assert(numTeams < EVENT_SCOREBOARD_MAX-EVENT_SCOREBOARD+1); + float textHeight = m_engine->GetText()->GetAscent(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL); + ddim.x = 100.0f/640.0f; - ddim.y = 100.0f/480.0f; + ddim.y = 100.0f/480.0f + numTeams * textHeight; pos.x = 540.0f/640.0f; pos.y = 100.0f/480.0f; Ui::CWindow* pw = m_interface->CreateWindows(pos, ddim, 3, EVENT_WINDOW6); @@ -5805,7 +5801,7 @@ void CRobotMain::CreateCodeBattleInterface() ddim.x = 100.0f/640.0f; ddim.y = 16.0f/480.0f; pos.x = 540.0f/640.0f; - pos.y = 178.0f/480.0f; + pos.y = 178.0f/480.0f + numTeams * textHeight; pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, "Code battle"); float titleBarSize = (11.0f/64.0f); // this is from the texture @@ -5821,9 +5817,47 @@ void CRobotMain::CreateCodeBattleInterface() { pw->CreateButton(pos, ddim, 13, EVENT_CODE_BATTLE_SPECTATOR); } + + pos.y += ddim.y; + ddim.y = textHeight; + for (int i = 0; i < numTeams; i++) + { + Ui::CLabel* pl; + pl = pw->CreateLabel(pos, ddim, 0, static_cast(EVENT_SCOREBOARD+2*(numTeams-i-1)+0), "XXXXX"); + pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT); + pl = pw->CreateLabel(pos, ddim, 0, static_cast(EVENT_SCOREBOARD+2*(numTeams-i-1)+1), "???"); + pl->SetTextAlign(Gfx::TEXT_ALIGN_RIGHT); + pos.y += ddim.y; + } } } +void CRobotMain::UpdateCodeBattleInterface() +{ + assert(GetMissionType() == MISSION_CODE_BATTLE); + if (!m_scoreboard) return; + + Ui::CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW6)); + assert(pw != nullptr); + + int i = 0; + for (int team : GetAllTeams()) + { + Ui::CLabel* pl; + + pl = static_cast(pw->SearchControl(static_cast(EVENT_SCOREBOARD+2*i+0))); + assert(pl != nullptr); + pl->SetName(GetTeamName(team)); + + pl = static_cast(pw->SearchControl(static_cast(EVENT_SCOREBOARD+2*i+1))); + assert(pl != nullptr); + pl->SetName(StrUtils::ToString(m_scoreboard->GetScore(team))); + + i++; + } + +} + void CRobotMain::DestroyCodeBattleInterface() { m_interface->DeleteControl(EVENT_WINDOW6); @@ -5897,3 +5931,25 @@ CScoreboard* CRobotMain::GetScoreboard() { return m_scoreboard.get(); } + +std::set CRobotMain::GetAllTeams() +{ + std::set teams = GetAllActiveTeams(); + for(auto& it : m_teamFinished) + { + teams.insert(it.first); + } + return teams; +} + +std::set CRobotMain::GetAllActiveTeams() +{ + std::set teams; + for (CObject* obj : m_objMan->GetAllObjects()) + { + int team = obj->GetTeam(); + if (team == 0) continue; + teams.insert(team); + } + return teams; +} diff --git a/src/level/robotmain.h b/src/level/robotmain.h index 6bde5f6b..b1e69c97 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -468,6 +468,11 @@ public: //! Check if crash sphere debug rendering is enabled bool GetDebugCrashSpheres(); + //! Returns a set of all team IDs in the current level + std::set GetAllTeams(); + //! Returns a set of all team IDs in the current level that are still active + std::set GetAllActiveTeams(); + protected: bool EventFrame(const Event &event); bool EventObject(const Event &event); @@ -512,6 +517,7 @@ protected: //! \name Code battle interface //@{ void CreateCodeBattleInterface(); + void UpdateCodeBattleInterface(); void DestroyCodeBattleInterface(); void SetCodeBattleSpectatorMode(bool mode); //@}