Added support for teams in EndMissionTake
Also fixed a bug in previous commit that caused lost= conditions to be skipped if previous min= max= condition was not metmaster
parent
a32efc09a2
commit
a3726799c4
|
@ -303,7 +303,7 @@ Math::Vector CLevelParserParam::AsPoint(Math::Vector def)
|
|||
|
||||
ObjectType CLevelParserParam::ToObjectType(std::string value)
|
||||
{
|
||||
if (value == "All" ) return OBJECT_NULL;
|
||||
if (value == "Any" ) return OBJECT_NULL; // For use in type= in ending conditions
|
||||
if (value == "Portico" ) return OBJECT_PORTICO;
|
||||
if (value == "SpaceShip" ) return OBJECT_BASE;
|
||||
if (value == "PracticeBot" ) return OBJECT_MOBILEwt;
|
||||
|
|
|
@ -153,6 +153,32 @@ std::vector<CObject*> CObjectManager::GetObjectsOfTeam(int team)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool CObjectManager::TeamExists(int team)
|
||||
{
|
||||
if(team == 0) return true;
|
||||
|
||||
for (CObject* object : GetAllObjects())
|
||||
{
|
||||
if (!object->GetActive())
|
||||
continue;
|
||||
|
||||
if (object->GetTeam() == team)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CObjectManager::DestroyTeam(int team)
|
||||
{
|
||||
assert(team != 0);
|
||||
|
||||
for (CObject* object : GetAllObjects())
|
||||
{
|
||||
if (object->GetTeam() == team)
|
||||
object->ExplodeObject(ExplosionType::Bang, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
CObject* CObjectManager::Radar(CObject* pThis, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
|
||||
{
|
||||
std::vector<ObjectType> types;
|
||||
|
|
|
@ -148,6 +148,13 @@ public:
|
|||
//! Gets all objects of given team
|
||||
std::vector<CObject*> GetObjectsOfTeam(int team);
|
||||
|
||||
//! Checks if any of team's objects exist
|
||||
bool TeamExists(int team);
|
||||
|
||||
//! Destroy all objects of team
|
||||
// TODO: This should be probably moved to separate class
|
||||
void DestroyTeam(int team);
|
||||
|
||||
//! Returns all objects
|
||||
inline CObjectContainerProxy GetAllObjects()
|
||||
{
|
||||
|
|
|
@ -5416,19 +5416,87 @@ void CRobotMain::SetEndMission(Error result, float delay)
|
|||
}
|
||||
}
|
||||
|
||||
Error CRobotMain::CheckEndMissionForGroup(std::vector<CSceneEndCondition*>& endTakes)
|
||||
{
|
||||
Error finalResult = ERR_OK;
|
||||
for (CSceneEndCondition* endTake : endTakes)
|
||||
{
|
||||
Error result = endTake->GetMissionResult();
|
||||
if(result != ERR_OK || endTake->immediat) {
|
||||
if(finalResult != INFO_LOST && finalResult != INFO_LOSTq)
|
||||
finalResult = result;
|
||||
}
|
||||
}
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
//! Checks if the mission is over
|
||||
Error CRobotMain::CheckEndMission(bool frame)
|
||||
{
|
||||
// Process EndMissionTake, unless we are using MissionController
|
||||
if (m_controller == nullptr)
|
||||
{
|
||||
m_missionResult = ERR_OK;
|
||||
for (std::unique_ptr<CSceneEndCondition>& endTake : m_endTake)
|
||||
{
|
||||
Error result = endTake->GetMissionResult();
|
||||
if(result != ERR_OK || endTake->immediat) {
|
||||
m_missionResult = result;
|
||||
break;
|
||||
// Sort end conditions by teams
|
||||
std::map<int, std::vector<CSceneEndCondition*>> teams;
|
||||
for (std::unique_ptr<CSceneEndCondition>& endTake : m_endTake) {
|
||||
teams[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_objMan->TeamExists(team)) continue;
|
||||
teamCount++;
|
||||
}
|
||||
|
||||
if(!usesTeamConditions) {
|
||||
m_missionResult = CheckEndMissionForGroup(teams[0]);
|
||||
} else {
|
||||
// Special handling for teams
|
||||
m_missionResult = ERR_MISSION_NOTERM;
|
||||
|
||||
if(teamCount == 0) {
|
||||
CLogger::GetInstancePointer()->Info("All teams died, mission ended with failure\n");
|
||||
m_missionResult = INFO_LOST;
|
||||
} else {
|
||||
for(auto it : teams) {
|
||||
int team = it.first;
|
||||
if(team == 0) continue;
|
||||
if(!m_objMan->TeamExists(team)) continue;
|
||||
|
||||
Error result = CheckEndMissionForGroup(it.second);
|
||||
if(result == INFO_LOST || result == INFO_LOSTq) {
|
||||
CLogger::GetInstancePointer()->Info("Team %d lost\n", team);
|
||||
m_displayText->DisplayText(("<<< Team "+boost::lexical_cast<std::string>(team)+" lost! >>>").c_str(), Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 10.0f, Ui::TT_ERROR);
|
||||
|
||||
m_displayText->SetEnable(false); // To prevent "bot destroyed" messages
|
||||
m_objMan->DestroyTeam(team);
|
||||
m_displayText->SetEnable(true);
|
||||
} else if(result == ERR_OK) {
|
||||
if (m_winDelay == 0.0f)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Info("Team %d won\n", team);
|
||||
|
||||
m_displayText->DisplayText(("<<< Team "+boost::lexical_cast<std::string>(team)+" won the game >>>").c_str(), Math::Vector(0.0f,0.0f,0.0f));
|
||||
if (m_missionTimerEnabled && m_missionTimerStarted)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Info("Mission time: %s\n", TimeFormat(m_missionTimer).c_str());
|
||||
m_displayText->DisplayText(("Time: " + TimeFormat(m_missionTimer)).c_str(), Math::Vector(0.0f,0.0f,0.0f));
|
||||
}
|
||||
m_missionTimerEnabled = m_missionTimerStarted = false;
|
||||
m_winDelay = m_endTakeWinDelay; // wins in two seconds
|
||||
m_lostDelay = 0.0f;
|
||||
if (m_exitAfterMission)
|
||||
m_eventQueue->AddEvent(Event(EVENT_QUIT));
|
||||
m_displayText->SetEnable(false);
|
||||
}
|
||||
m_missionResult = ERR_OK;
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
void UpdateAudio(bool frame);
|
||||
void SetEndMission(Error result, float delay);
|
||||
Error CheckEndMission(bool frame);
|
||||
Error CheckEndMissionForGroup(std::vector<CSceneEndCondition*>& endTakes);
|
||||
int GetObligatoryToken();
|
||||
char* GetObligatoryToken(int i);
|
||||
int IsObligatoryToken(const char* token);
|
||||
|
|
|
@ -36,6 +36,7 @@ void CSceneCondition::Read(CLevelParserLine* line)
|
|||
this->tool = line->GetParam("tool")->AsToolType(ToolType::Other);
|
||||
this->drive = line->GetParam("drive")->AsDriveType(DriveType::Other);
|
||||
this->countTransported = line->GetParam("countTransported")->AsBool(true);
|
||||
this->team = line->GetParam("team")->AsInt(0);
|
||||
|
||||
this->min = line->GetParam("min")->AsInt(1);
|
||||
this->max = line->GetParam("max")->AsInt(9999);
|
||||
|
@ -88,6 +89,10 @@ int CSceneCondition::CountObjects()
|
|||
this->type != OBJECT_NULL)
|
||||
continue;
|
||||
|
||||
if ((this->team > 0 && obj->GetTeam() != this->team) ||
|
||||
(this->team < 0 && obj->GetTeam() == -(this->team)))
|
||||
continue;
|
||||
|
||||
float energyLevel = -1;
|
||||
CObject* power = obj->GetPower();
|
||||
if (power != nullptr)
|
||||
|
@ -128,6 +133,7 @@ bool CSceneCondition::Check()
|
|||
void CSceneEndCondition::Read(CLevelParserLine* line)
|
||||
{
|
||||
CSceneCondition::Read(line);
|
||||
this->winTeam = line->GetParam("winTeam")->AsInt(0);
|
||||
this->lost = line->GetParam("lost")->AsInt(-1);
|
||||
this->immediat = line->GetParam("immediat")->AsBool(false);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
ToolType tool = ToolType::Other;
|
||||
DriveType drive = DriveType::Other;
|
||||
bool countTransported = true;
|
||||
int team = 0;
|
||||
|
||||
int min = 1; // wins if >
|
||||
int max = 9999; // wins if <
|
||||
|
@ -71,6 +72,8 @@ protected:
|
|||
class CSceneEndCondition : public CSceneCondition
|
||||
{
|
||||
public:
|
||||
int winTeam = 0;
|
||||
|
||||
int lost = -1; // lost if <=
|
||||
|
||||
bool immediat = false;
|
||||
|
|
Loading…
Reference in New Issue