Implement ScoreboardObjectRule

1008-fix
krzys-h 2018-05-08 23:44:23 +02:00
parent 05bdd74bef
commit f03c3dbc10
5 changed files with 76 additions and 16 deletions

View File

@ -2527,6 +2527,8 @@ bool CRobotMain::EventFrame(const Event &event)
{ {
CheckEndMission(true); CheckEndMission(true);
UpdateAudio(true); UpdateAudio(true);
if (m_scoreboard)
m_scoreboard->UpdateObjectCount();
} }
if (m_winDelay > 0.0f && !m_editLock) if (m_winDelay > 0.0f && !m_editLock)
@ -3608,6 +3610,15 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_scoreboard->AddKillRule(std::move(rule)); m_scoreboard->AddKillRule(std::move(rule));
continue; continue;
} }
if (line->GetCommand() == "ScoreboardObjectRule" && !resetObject)
{
if (!m_scoreboard)
throw CLevelParserException("ScoreboardObjectRule encountered but scoreboard is not enabled");
auto rule = MakeUnique<CScoreboard::CScoreboardObjectRule>();
rule->Read(line.get());
m_scoreboard->AddObjectRule(std::move(rule));
continue;
}
if (line->GetCommand() == "ScoreboardEndTakeRule" && !resetObject) if (line->GetCommand() == "ScoreboardEndTakeRule" && !resetObject)
{ {
if (!m_scoreboard) if (!m_scoreboard)

View File

@ -112,6 +112,18 @@ bool CObjectCondition::CheckForObject(CObject* obj)
return false; return false;
} }
int CObjectCondition::CountObjects()
{
int nb = 0;
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if (!obj->GetActive()) continue;
if (!CheckForObject(obj)) continue;
nb ++;
}
return nb;
}
void CSceneCondition::Read(CLevelParserLine* line) void CSceneCondition::Read(CLevelParserLine* line)
{ {
CObjectCondition::Read(line); CObjectCondition::Read(line);
@ -124,18 +136,6 @@ void CSceneCondition::Read(CLevelParserLine* line)
this->max = line->GetParam("max")->AsInt(9999); this->max = line->GetParam("max")->AsInt(9999);
} }
int CSceneCondition::CountObjects()
{
int nb = 0;
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if (!obj->GetActive()) continue;
if (!CheckForObject(obj)) continue;
nb ++;
}
return nb;
}
bool CSceneCondition::Check() bool CSceneCondition::Check()
{ {
int nb = CountObjects(); int nb = CountObjects();

View File

@ -58,6 +58,9 @@ public:
//! Checks if this condition is met //! Checks if this condition is met
bool CheckForObject(CObject* obj); bool CheckForObject(CObject* obj);
//! Count all object matching the conditions
int CountObjects();
}; };
/** /**
@ -75,10 +78,6 @@ public:
//! Checks if this condition is met //! Checks if this condition is met
bool Check(); bool Check();
protected:
//! Count all object matching the conditions
int CountObjects();
}; };
/** /**

View File

@ -43,6 +43,13 @@ void CScoreboard::CScoreboardKillRule::Read(CLevelParserLine* line)
CObjectCondition::Read(line); CObjectCondition::Read(line);
} }
void CScoreboard::CScoreboardObjectRule::Read(CLevelParserLine* line)
{
CScoreboardRule::Read(line);
CObjectCondition::Read(line);
this->winTeam = line->GetParam("winTeam")->AsInt();
}
void CScoreboard::CScoreboardEndTakeRule::Read(CLevelParserLine* line) void CScoreboard::CScoreboardEndTakeRule::Read(CLevelParserLine* line)
{ {
CScoreboardRule::Read(line); CScoreboardRule::Read(line);
@ -55,6 +62,11 @@ void CScoreboard::AddKillRule(std::unique_ptr<CScoreboardKillRule> rule)
m_rulesKill.push_back(std::move(rule)); m_rulesKill.push_back(std::move(rule));
} }
void CScoreboard::AddObjectRule(std::unique_ptr<CScoreboard::CScoreboardObjectRule> rule)
{
m_rulesObject.push_back(std::move(rule));
}
void CScoreboard::AddEndTakeRule(std::unique_ptr<CScoreboardEndTakeRule> rule) void CScoreboard::AddEndTakeRule(std::unique_ptr<CScoreboardEndTakeRule> rule)
{ {
m_rulesEndTake.push_back(std::move(rule)); m_rulesEndTake.push_back(std::move(rule));
@ -75,6 +87,22 @@ void CScoreboard::ProcessKill(CObject* target, CObject* killer)
} }
} }
void CScoreboard::UpdateObjectCount()
{
for (auto& rule : m_rulesObject)
{
assert(rule->winTeam != 0);
int count = rule->CountObjects();
int countDiff = count - rule->lastCount;
printf("%d %d\n", count, countDiff);
if (countDiff != 0)
{
rule->lastCount = count;
AddPoints(rule->winTeam, rule->score * countDiff);
}
}
}
void CScoreboard::ProcessEndTake(int team) void CScoreboard::ProcessEndTake(int team)
{ {
if (team == 0) return; if (team == 0) return;

View File

@ -64,6 +64,7 @@ enum class SortType
* ScoreboardSortType sort=Name // sort teams alphabetically, another option is sort=Points, sorting teams in order of points * 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
* ScoreboardObjectRule pos=0.0;0.5 dist=5.0 type=Titanium winTeam=1 score=5 // each Titanium within 5 meters of 0;0 gives team 1 5 points, losing Titanium gives -5
* 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
* \endcode * \endcode
*/ */
@ -102,6 +103,22 @@ public:
void Read(CLevelParserLine* line) override; void Read(CLevelParserLine* line) override;
}; };
/**
* \class CScoreboardObjectRule
* \brief Scoreboard rule for counting objects
* \see CScoreboard::AddObjectRule()
*/
class CScoreboardObjectRule final : public CScoreboardRule, public CObjectCondition
{
public:
int winTeam = 0;
//! Read from line in scene file
void Read(CLevelParserLine* line) override;
int lastCount = 0;
};
/** /**
* \class CScoreboardEndTakeRule * \class CScoreboardEndTakeRule
* \brief Scoreboard rule for EndMissionTake rewards * \brief Scoreboard rule for EndMissionTake rewards
@ -120,6 +137,8 @@ public:
public: public:
//! Add ScoreboardKillRule //! Add ScoreboardKillRule
void AddKillRule(std::unique_ptr<CScoreboardKillRule> rule); void AddKillRule(std::unique_ptr<CScoreboardKillRule> rule);
//! Add ScoreboardObjectRule
void AddObjectRule(std::unique_ptr<CScoreboardObjectRule> rule);
//! Add ScoreboardEndTakeRule //! Add ScoreboardEndTakeRule
void AddEndTakeRule(std::unique_ptr<CScoreboardEndTakeRule> rule); void AddEndTakeRule(std::unique_ptr<CScoreboardEndTakeRule> rule);
@ -127,6 +146,8 @@ public:
//! \param target The object that has just been destroyed //! \param target The object that has just been destroyed
//! \param killer The object that caused the destruction, can be null //! \param killer The object that caused the destruction, can be null
void ProcessKill(CObject* target, CObject* killer = nullptr); void ProcessKill(CObject* target, CObject* killer = nullptr);
//! Updates the object count rules
void UpdateObjectCount();
//! Called after EndTake contition has been met, used to handle ScoreboardEndTakeRule //! Called after EndTake contition has been met, used to handle ScoreboardEndTakeRule
void ProcessEndTake(int team); void ProcessEndTake(int team);
@ -139,6 +160,7 @@ public:
private: private:
std::vector<std::unique_ptr<CScoreboardKillRule>> m_rulesKill = {}; std::vector<std::unique_ptr<CScoreboardKillRule>> m_rulesKill = {};
std::vector<std::unique_ptr<CScoreboardObjectRule>> m_rulesObject = {};
std::vector<std::unique_ptr<CScoreboardEndTakeRule>> m_rulesEndTake = {}; std::vector<std::unique_ptr<CScoreboardEndTakeRule>> m_rulesEndTake = {};
std::map<int, Score> m_score; std::map<int, Score> m_score;
int m_finishCounter = 0; int m_finishCounter = 0;