Implement ScoreboardObjectRule
parent
05bdd74bef
commit
f03c3dbc10
|
@ -2527,6 +2527,8 @@ bool CRobotMain::EventFrame(const Event &event)
|
|||
{
|
||||
CheckEndMission(true);
|
||||
UpdateAudio(true);
|
||||
if (m_scoreboard)
|
||||
m_scoreboard->UpdateObjectCount();
|
||||
}
|
||||
|
||||
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));
|
||||
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 (!m_scoreboard)
|
||||
|
|
|
@ -112,6 +112,18 @@ bool CObjectCondition::CheckForObject(CObject* obj)
|
|||
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)
|
||||
{
|
||||
CObjectCondition::Read(line);
|
||||
|
@ -124,18 +136,6 @@ void CSceneCondition::Read(CLevelParserLine* line)
|
|||
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()
|
||||
{
|
||||
int nb = CountObjects();
|
||||
|
|
|
@ -58,6 +58,9 @@ public:
|
|||
|
||||
//! Checks if this condition is met
|
||||
bool CheckForObject(CObject* obj);
|
||||
|
||||
//! Count all object matching the conditions
|
||||
int CountObjects();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -75,10 +78,6 @@ public:
|
|||
|
||||
//! Checks if this condition is met
|
||||
bool Check();
|
||||
|
||||
protected:
|
||||
//! Count all object matching the conditions
|
||||
int CountObjects();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,6 +43,13 @@ void CScoreboard::CScoreboardKillRule::Read(CLevelParserLine* 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)
|
||||
{
|
||||
CScoreboardRule::Read(line);
|
||||
|
@ -55,6 +62,11 @@ void CScoreboard::AddKillRule(std::unique_ptr<CScoreboardKillRule> 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (team == 0) return;
|
||||
|
|
|
@ -64,6 +64,7 @@ enum class SortType
|
|||
* 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=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
|
||||
* \endcode
|
||||
*/
|
||||
|
@ -102,6 +103,22 @@ public:
|
|||
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
|
||||
* \brief Scoreboard rule for EndMissionTake rewards
|
||||
|
@ -120,6 +137,8 @@ public:
|
|||
public:
|
||||
//! Add ScoreboardKillRule
|
||||
void AddKillRule(std::unique_ptr<CScoreboardKillRule> rule);
|
||||
//! Add ScoreboardObjectRule
|
||||
void AddObjectRule(std::unique_ptr<CScoreboardObjectRule> rule);
|
||||
//! Add ScoreboardEndTakeRule
|
||||
void AddEndTakeRule(std::unique_ptr<CScoreboardEndTakeRule> rule);
|
||||
|
||||
|
@ -127,6 +146,8 @@ public:
|
|||
//! \param target The object that has just been destroyed
|
||||
//! \param killer The object that caused the destruction, can be null
|
||||
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
|
||||
void ProcessEndTake(int team);
|
||||
|
||||
|
@ -139,6 +160,7 @@ public:
|
|||
|
||||
private:
|
||||
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::map<int, Score> m_score;
|
||||
int m_finishCounter = 0;
|
||||
|
|
Loading…
Reference in New Issue