Merge pull request from colobot/dev-scoreboard-sort

Add realtime scoreboard sorting
1008-fix
krzys_h 2018-05-07 20:42:02 +02:00 committed by GitHub
commit 099a906b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 9 deletions

View File

@ -28,6 +28,7 @@
#include "common/resources/resourcemanager.h" #include "common/resources/resourcemanager.h"
#include "level/robotmain.h" #include "level/robotmain.h"
#include "level/scoreboard.h"
#include "level/parser/parser.h" #include "level/parser/parser.h"
@ -954,6 +955,26 @@ int CLevelParserParam::AsResearchFlag(int def)
return AsResearchFlag(); return AsResearchFlag();
} }
SortType CLevelParserParam::ToSortType(std::string value)
{
if (value == "Points" ) return SortType::SORT_POINTS;
if (value == "Name" ) return SortType::SORT_ID;
return SortType::SORT_ID;
}
SortType CLevelParserParam::AsSortType()
{
if (m_empty)
throw CLevelParserExceptionMissingParam(this);
return ToSortType(m_value);
}
SortType CLevelParserParam::AsSortType(SortType def)
{
if (m_empty)
return def;
return AsSortType();
}
Gfx::PyroType CLevelParserParam::ToPyroType(std::string value) Gfx::PyroType CLevelParserParam::ToPyroType(std::string value)
{ {

View File

@ -31,6 +31,8 @@
#include "graphics/engine/pyro_type.h" #include "graphics/engine/pyro_type.h"
#include "graphics/engine/water.h" #include "graphics/engine/water.h"
#include "level/scoreboard.h"
#include "math/point.h" #include "math/point.h"
#include "object/drive_type.h" #include "object/drive_type.h"
@ -85,6 +87,7 @@ public:
Gfx::EngineObjectType AsTerrainType(); Gfx::EngineObjectType AsTerrainType();
int AsBuildFlag(); int AsBuildFlag();
int AsResearchFlag(); int AsResearchFlag();
SortType AsSortType();
Gfx::PyroType AsPyroType(); Gfx::PyroType AsPyroType();
Gfx::CameraType AsCameraType(); Gfx::CameraType AsCameraType();
MissionType AsMissionType(); MissionType AsMissionType();
@ -108,6 +111,7 @@ public:
Gfx::EngineObjectType AsTerrainType(Gfx::EngineObjectType def); Gfx::EngineObjectType AsTerrainType(Gfx::EngineObjectType def);
int AsBuildFlag(int def); int AsBuildFlag(int def);
int AsResearchFlag(int def); int AsResearchFlag(int def);
SortType AsSortType(SortType def);
Gfx::PyroType AsPyroType(Gfx::PyroType def); Gfx::PyroType AsPyroType(Gfx::PyroType def);
Gfx::CameraType AsCameraType(Gfx::CameraType def); Gfx::CameraType AsCameraType(Gfx::CameraType def);
MissionType AsMissionType(MissionType def); MissionType AsMissionType(MissionType def);
@ -139,6 +143,7 @@ private:
Gfx::EngineObjectType ToTerrainType(std::string value); Gfx::EngineObjectType ToTerrainType(std::string value);
int ToBuildFlag(std::string value); int ToBuildFlag(std::string value);
int ToResearchFlag(std::string value); int ToResearchFlag(std::string value);
SortType ToSortType(std::string value);
Gfx::PyroType ToPyroType(std::string value); Gfx::PyroType ToPyroType(std::string value);
Gfx::CameraType ToCameraType(std::string value); Gfx::CameraType ToCameraType(std::string value);
MissionType ToMissionType(std::string value); MissionType ToMissionType(std::string value);

View File

@ -3565,6 +3565,13 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
} }
continue; continue;
} }
if (line->GetCommand() == "ScoreboardSortType" && !resetObject)
{
m_scoreboard->SetSortType(static_cast<SortType>(line->GetParam("sort")->AsSortType() ) );
continue;
}
if (line->GetCommand() == "ScoreboardKillRule" && !resetObject) if (line->GetCommand() == "ScoreboardKillRule" && !resetObject)
{ {
if (!m_scoreboard) if (!m_scoreboard)
@ -4965,7 +4972,7 @@ Error CRobotMain::ProcessEndMissionTake()
{ {
if (!details.empty()) if (!details.empty())
details += ", "; details += ", ";
details += StrUtils::Format(details_line.c_str(), GetTeamName(team).c_str(), m_scoreboard->GetScore(team)); details += StrUtils::Format(details_line.c_str(), GetTeamName(team).c_str(), m_scoreboard->GetScore(team).points);
} }
m_ui->GetDialog()->StartInformation( m_ui->GetDialog()->StartInformation(
title, title,
@ -5873,7 +5880,7 @@ void CRobotMain::CreateCodeBattleInterface()
: static_cast<Ui::CControl*>(pw->CreateEdit( pos, ddim, 0, static_cast<EventType>(EVENT_SCOREBOARD+2*(numTeams-i-1)+1))); : static_cast<Ui::CControl*>(pw->CreateEdit( pos, ddim, 0, static_cast<EventType>(EVENT_SCOREBOARD+2*(numTeams-i-1)+1)));
pl->SetTextAlign(Gfx::TEXT_ALIGN_RIGHT); pl->SetTextAlign(Gfx::TEXT_ALIGN_RIGHT);
pl->SetFontSize(m_codeBattleStarted ? Gfx::FONT_SIZE_SMALL : Gfx::FONT_SIZE_SMALL*0.75f); pl->SetFontSize(m_codeBattleStarted ? Gfx::FONT_SIZE_SMALL : Gfx::FONT_SIZE_SMALL*0.75f);
m_codeBattleStarted ? pl->SetName(StrUtils::ToString<int>(m_scoreboard->GetScore(team))) : static_cast<Ui::CEdit*>(pl)->SetText(StrUtils::ToString<int>(m_scoreboard->GetScore(team))); m_codeBattleStarted ? pl->SetName(StrUtils::ToString<int>(m_scoreboard->GetScore(team).points)) : static_cast<Ui::CEdit*>(pl)->SetText(StrUtils::ToString<int>(m_scoreboard->GetScore(team).points));
pos.x -= 57.5f/640.0f; pos.x -= 57.5f/640.0f;
pos.y += ddim.y; pos.y += ddim.y;
i++; i++;
@ -5913,9 +5920,22 @@ void CRobotMain::UpdateCodeBattleInterface()
Ui::CWindow* pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW6)); Ui::CWindow* pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW6));
assert(pw != nullptr); assert(pw != nullptr);
std::set<int> teams = GetAllTeams();
std::vector<int> 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; int i = 0;
for (int team : GetAllTeams()) for (int team : sortedTeams)
{ {
Ui::CControl* pl; Ui::CControl* pl;
@ -5925,7 +5945,7 @@ void CRobotMain::UpdateCodeBattleInterface()
pl = pw->SearchControl(static_cast<EventType>(EVENT_SCOREBOARD+2*i+1)); pl = pw->SearchControl(static_cast<EventType>(EVENT_SCOREBOARD+2*i+1));
assert(pl != nullptr); assert(pl != nullptr);
pl->SetName(StrUtils::ToString<int>(m_scoreboard->GetScore(team))); pl->SetName(StrUtils::ToString<int>(m_scoreboard->GetScore(team).points));
i++; i++;
} }

View File

@ -99,15 +99,26 @@ void CScoreboard::AddPoints(int team, int points)
text = StrUtils::Format(text.c_str(), main->GetTeamName(team).c_str(), points); text = StrUtils::Format(text.c_str(), main->GetTeamName(team).c_str(), points);
main->GetDisplayText()->DisplayText(text.c_str(), Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 10.0f, Ui::TT_WARNING); main->GetDisplayText()->DisplayText(text.c_str(), Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 10.0f, Ui::TT_WARNING);
m_score[team] += points; m_score[team].points += points;
m_score[team].time = main->GetGameTime();
} }
int CScoreboard::GetScore(int team) Score CScoreboard::GetScore(int team)
{ {
return m_score[team]; return m_score[team];
} }
void CScoreboard::SetScore(int team, int points) void CScoreboard::SetScore(int team, int points)
{ {
m_score[team] = points; m_score[team].points = points;
}
SortType CScoreboard::GetSortType()
{
return m_sorttype;
}
void CScoreboard::SetSortType(SortType type)
{
m_sorttype = type;
} }

View File

@ -32,6 +32,22 @@
class CObject; 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 * \class CScoreboard
* \brief Scoreboard used to score complex code battles * \brief Scoreboard used to score complex code battles
@ -45,6 +61,7 @@ class CObject;
* \section example Usage example * \section example Usage example
* \code{.scene} * \code{.scene}
* Scoreboard enable=true // enable the scoreboard * Scoreboard enable=true // enable the scoreboard
* ScoreboardSortType sort=Name // sort teams alphabetically, another option is sort=Points, sorting teams in order of points
* ScoreboardKillRule type=WheeledShooter team=1 score=500 // destruction of team 1's WheeledShooter gives 100 points to the team that destroyed it * ScoreboardKillRule type=WheeledShooter team=1 score=500 // destruction of team 1's WheeledShooter gives 100 points to the team that destroyed it
* ScoreboardKillRule type=TargetBot score=100 // destruction of TargetBot (any team) gives 100 points * ScoreboardKillRule type=TargetBot score=100 // destruction of TargetBot (any team) gives 100 points
* ScoreboardEndTakeRule score=1000 // completion of EndMissionTake objectives for any team results in 1000 points for that team * ScoreboardEndTakeRule score=1000 // completion of EndMissionTake objectives for any team results in 1000 points for that team
@ -114,12 +131,16 @@ public:
void ProcessEndTake(int team); void ProcessEndTake(int team);
void AddPoints(int team, int points); void AddPoints(int team, int points);
int GetScore(int team); Score GetScore(int team);
void SetScore(int team, int points); void SetScore(int team, int points);
SortType GetSortType();
void SetSortType(SortType type);
private: private:
std::vector<std::unique_ptr<CScoreboardKillRule>> m_rulesKill = {}; std::vector<std::unique_ptr<CScoreboardKillRule>> m_rulesKill = {};
std::vector<std::unique_ptr<CScoreboardEndTakeRule>> m_rulesEndTake = {}; std::vector<std::unique_ptr<CScoreboardEndTakeRule>> m_rulesEndTake = {};
std::map<int, int> m_score; std::map<int, Score> m_score;
int m_finishCounter = 0; int m_finishCounter = 0;
SortType m_sorttype = SortType::SORT_ID;
}; };