2017-05-17 16:22:27 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the Colobot: Gold Edition source code
|
2018-04-19 23:08:24 +00:00
|
|
|
* Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam
|
2017-05-17 16:22:27 +00:00
|
|
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see http://gnu.org/licenses
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "level/scoreboard.h"
|
|
|
|
|
2017-05-17 17:00:40 +00:00
|
|
|
#include "common/restext.h"
|
|
|
|
#include "common/stringutils.h"
|
|
|
|
|
2017-05-17 16:22:27 +00:00
|
|
|
#include "level/robotmain.h"
|
|
|
|
|
2018-04-19 23:31:11 +00:00
|
|
|
#include "level/parser/parserline.h"
|
|
|
|
|
2017-05-17 16:22:27 +00:00
|
|
|
#include "object/object.h"
|
|
|
|
|
|
|
|
#include "ui/displaytext.h"
|
|
|
|
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
|
|
|
|
void CScoreboard::CScoreboardRule::Read(CLevelParserLine* line)
|
|
|
|
{
|
|
|
|
this->score = line->GetParam("score")->AsInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CScoreboard::CScoreboardKillRule::Read(CLevelParserLine* line)
|
|
|
|
{
|
|
|
|
CScoreboardRule::Read(line);
|
|
|
|
CObjectCondition::Read(line);
|
2018-05-08 21:57:13 +00:00
|
|
|
this->friendlyFire = line->GetParam("friendlyFire")->AsBool(false);
|
2017-05-17 16:22:27 +00:00
|
|
|
}
|
|
|
|
|
2018-05-08 21:44:23 +00:00
|
|
|
void CScoreboard::CScoreboardObjectRule::Read(CLevelParserLine* line)
|
|
|
|
{
|
|
|
|
CScoreboardRule::Read(line);
|
|
|
|
CObjectCondition::Read(line);
|
|
|
|
this->winTeam = line->GetParam("winTeam")->AsInt();
|
|
|
|
}
|
|
|
|
|
2017-05-17 16:22:27 +00:00
|
|
|
void CScoreboard::CScoreboardEndTakeRule::Read(CLevelParserLine* line)
|
|
|
|
{
|
|
|
|
CScoreboardRule::Read(line);
|
|
|
|
this->team = line->GetParam("team")->AsInt(0);
|
2017-05-18 18:39:32 +00:00
|
|
|
this->order = line->GetParam("order")->AsInt(0);
|
2017-05-17 16:22:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CScoreboard::AddKillRule(std::unique_ptr<CScoreboardKillRule> rule)
|
|
|
|
{
|
|
|
|
m_rulesKill.push_back(std::move(rule));
|
|
|
|
}
|
|
|
|
|
2018-05-08 21:44:23 +00:00
|
|
|
void CScoreboard::AddObjectRule(std::unique_ptr<CScoreboard::CScoreboardObjectRule> rule)
|
|
|
|
{
|
|
|
|
m_rulesObject.push_back(std::move(rule));
|
|
|
|
}
|
|
|
|
|
2017-05-17 16:22:27 +00:00
|
|
|
void CScoreboard::AddEndTakeRule(std::unique_ptr<CScoreboardEndTakeRule> rule)
|
|
|
|
{
|
|
|
|
m_rulesEndTake.push_back(std::move(rule));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CScoreboard::ProcessKill(CObject* target, CObject* killer)
|
|
|
|
{
|
|
|
|
if (killer == nullptr) return;
|
|
|
|
if (killer->GetTeam() == 0) return;
|
|
|
|
for (auto& rule : m_rulesKill)
|
|
|
|
{
|
|
|
|
if ((rule->team == killer->GetTeam() || rule->team == 0) &&
|
2017-05-23 18:20:46 +00:00
|
|
|
killer->GetTeam() != 0 &&
|
2017-05-17 16:22:27 +00:00
|
|
|
rule->CheckForObject(target))
|
|
|
|
{
|
2018-05-08 21:57:13 +00:00
|
|
|
if (killer->GetTeam() == target->GetTeam() && !rule->friendlyFire)
|
|
|
|
continue;
|
2017-05-17 16:22:27 +00:00
|
|
|
AddPoints(killer->GetTeam(), rule->score);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-08 21:44:23 +00:00
|
|
|
void CScoreboard::UpdateObjectCount()
|
|
|
|
{
|
|
|
|
for (auto& rule : m_rulesObject)
|
|
|
|
{
|
|
|
|
assert(rule->winTeam != 0);
|
|
|
|
int count = rule->CountObjects();
|
|
|
|
int countDiff = count - rule->lastCount;
|
|
|
|
if (countDiff != 0)
|
|
|
|
{
|
|
|
|
rule->lastCount = count;
|
|
|
|
AddPoints(rule->winTeam, rule->score * countDiff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-17 16:22:27 +00:00
|
|
|
void CScoreboard::ProcessEndTake(int team)
|
|
|
|
{
|
2017-05-23 18:20:46 +00:00
|
|
|
if (team == 0) return;
|
2017-05-18 18:39:32 +00:00
|
|
|
m_finishCounter++;
|
2017-05-17 16:22:27 +00:00
|
|
|
for (auto& rule : m_rulesEndTake)
|
|
|
|
{
|
2017-05-18 18:39:32 +00:00
|
|
|
if ((rule->team == team || rule->team == 0) &&
|
|
|
|
(rule->order == m_finishCounter || rule->order == 0))
|
2017-05-17 16:22:27 +00:00
|
|
|
{
|
|
|
|
AddPoints(team, rule->score);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CScoreboard::AddPoints(int team, int points)
|
|
|
|
{
|
|
|
|
GetLogger()->Info("Team %d earned %d points\n", team, points);
|
2017-05-17 17:00:40 +00:00
|
|
|
|
|
|
|
CRobotMain* main = CRobotMain::GetInstancePointer();
|
|
|
|
std::string text;
|
|
|
|
GetResource(RES_ERR, INFO_TEAM_SCORE, text);
|
|
|
|
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);
|
|
|
|
|
2018-03-07 14:46:30 +00:00
|
|
|
m_score[team].points += points;
|
|
|
|
m_score[team].time = main->GetGameTime();
|
2017-05-17 16:22:27 +00:00
|
|
|
}
|
|
|
|
|
2018-05-09 16:28:25 +00:00
|
|
|
CScoreboard::Score CScoreboard::GetScore(int team)
|
2017-05-17 16:22:27 +00:00
|
|
|
{
|
|
|
|
return m_score[team];
|
|
|
|
}
|
2017-05-24 10:39:05 +00:00
|
|
|
|
|
|
|
void CScoreboard::SetScore(int team, int points)
|
|
|
|
{
|
2018-03-07 14:46:30 +00:00
|
|
|
m_score[team].points = points;
|
2017-05-24 10:39:05 +00:00
|
|
|
}
|
2018-03-07 20:25:35 +00:00
|
|
|
|
2018-05-09 16:28:25 +00:00
|
|
|
CScoreboard::SortType CScoreboard::GetSortType()
|
2018-03-07 20:25:35 +00:00
|
|
|
{
|
2018-05-09 16:28:25 +00:00
|
|
|
return m_sortType;
|
2018-03-07 20:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CScoreboard::SetSortType(SortType type)
|
|
|
|
{
|
2018-05-09 16:28:25 +00:00
|
|
|
m_sortType = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::pair<int, CScoreboard::Score>> CScoreboard::GetSortedScores()
|
|
|
|
{
|
|
|
|
CRobotMain* main = CRobotMain::GetInstancePointer();
|
|
|
|
std::set<int> teams = main->GetAllTeams();
|
|
|
|
std::vector<std::pair<int, Score>> 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<int, Score> teamA, std::pair<int, Score> 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;
|
2018-03-07 20:25:35 +00:00
|
|
|
}
|