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)
|
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 == "Portico" ) return OBJECT_PORTICO;
|
||||||
if (value == "SpaceShip" ) return OBJECT_BASE;
|
if (value == "SpaceShip" ) return OBJECT_BASE;
|
||||||
if (value == "PracticeBot" ) return OBJECT_MOBILEwt;
|
if (value == "PracticeBot" ) return OBJECT_MOBILEwt;
|
||||||
|
|
|
@ -153,6 +153,32 @@ std::vector<CObject*> CObjectManager::GetObjectsOfTeam(int team)
|
||||||
return result;
|
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)
|
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;
|
std::vector<ObjectType> types;
|
||||||
|
|
|
@ -148,6 +148,13 @@ public:
|
||||||
//! Gets all objects of given team
|
//! Gets all objects of given team
|
||||||
std::vector<CObject*> GetObjectsOfTeam(int 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
|
//! Returns all objects
|
||||||
inline CObjectContainerProxy GetAllObjects()
|
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
|
//! Checks if the mission is over
|
||||||
Error CRobotMain::CheckEndMission(bool frame)
|
Error CRobotMain::CheckEndMission(bool frame)
|
||||||
{
|
{
|
||||||
// Process EndMissionTake, unless we are using MissionController
|
// Process EndMissionTake, unless we are using MissionController
|
||||||
if (m_controller == nullptr)
|
if (m_controller == nullptr)
|
||||||
{
|
{
|
||||||
m_missionResult = ERR_OK;
|
// Sort end conditions by teams
|
||||||
for (std::unique_ptr<CSceneEndCondition>& endTake : m_endTake)
|
std::map<int, std::vector<CSceneEndCondition*>> teams;
|
||||||
{
|
for (std::unique_ptr<CSceneEndCondition>& endTake : m_endTake) {
|
||||||
Error result = endTake->GetMissionResult();
|
teams[endTake->winTeam].push_back(endTake.get());
|
||||||
if(result != ERR_OK || endTake->immediat) {
|
}
|
||||||
m_missionResult = result;
|
|
||||||
break;
|
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 UpdateAudio(bool frame);
|
||||||
void SetEndMission(Error result, float delay);
|
void SetEndMission(Error result, float delay);
|
||||||
Error CheckEndMission(bool frame);
|
Error CheckEndMission(bool frame);
|
||||||
|
Error CheckEndMissionForGroup(std::vector<CSceneEndCondition*>& endTakes);
|
||||||
int GetObligatoryToken();
|
int GetObligatoryToken();
|
||||||
char* GetObligatoryToken(int i);
|
char* GetObligatoryToken(int i);
|
||||||
int IsObligatoryToken(const char* token);
|
int IsObligatoryToken(const char* token);
|
||||||
|
|
|
@ -36,6 +36,7 @@ void CSceneCondition::Read(CLevelParserLine* line)
|
||||||
this->tool = line->GetParam("tool")->AsToolType(ToolType::Other);
|
this->tool = line->GetParam("tool")->AsToolType(ToolType::Other);
|
||||||
this->drive = line->GetParam("drive")->AsDriveType(DriveType::Other);
|
this->drive = line->GetParam("drive")->AsDriveType(DriveType::Other);
|
||||||
this->countTransported = line->GetParam("countTransported")->AsBool(true);
|
this->countTransported = line->GetParam("countTransported")->AsBool(true);
|
||||||
|
this->team = line->GetParam("team")->AsInt(0);
|
||||||
|
|
||||||
this->min = line->GetParam("min")->AsInt(1);
|
this->min = line->GetParam("min")->AsInt(1);
|
||||||
this->max = line->GetParam("max")->AsInt(9999);
|
this->max = line->GetParam("max")->AsInt(9999);
|
||||||
|
@ -88,6 +89,10 @@ int CSceneCondition::CountObjects()
|
||||||
this->type != OBJECT_NULL)
|
this->type != OBJECT_NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if ((this->team > 0 && obj->GetTeam() != this->team) ||
|
||||||
|
(this->team < 0 && obj->GetTeam() == -(this->team)))
|
||||||
|
continue;
|
||||||
|
|
||||||
float energyLevel = -1;
|
float energyLevel = -1;
|
||||||
CObject* power = obj->GetPower();
|
CObject* power = obj->GetPower();
|
||||||
if (power != nullptr)
|
if (power != nullptr)
|
||||||
|
@ -128,6 +133,7 @@ bool CSceneCondition::Check()
|
||||||
void CSceneEndCondition::Read(CLevelParserLine* line)
|
void CSceneEndCondition::Read(CLevelParserLine* line)
|
||||||
{
|
{
|
||||||
CSceneCondition::Read(line);
|
CSceneCondition::Read(line);
|
||||||
|
this->winTeam = line->GetParam("winTeam")->AsInt(0);
|
||||||
this->lost = line->GetParam("lost")->AsInt(-1);
|
this->lost = line->GetParam("lost")->AsInt(-1);
|
||||||
this->immediat = line->GetParam("immediat")->AsBool(false);
|
this->immediat = line->GetParam("immediat")->AsBool(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
ToolType tool = ToolType::Other;
|
ToolType tool = ToolType::Other;
|
||||||
DriveType drive = DriveType::Other;
|
DriveType drive = DriveType::Other;
|
||||||
bool countTransported = true;
|
bool countTransported = true;
|
||||||
|
int team = 0;
|
||||||
|
|
||||||
int min = 1; // wins if >
|
int min = 1; // wins if >
|
||||||
int max = 9999; // wins if <
|
int max = 9999; // wins if <
|
||||||
|
@ -71,6 +72,8 @@ protected:
|
||||||
class CSceneEndCondition : public CSceneCondition
|
class CSceneEndCondition : public CSceneCondition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
int winTeam = 0;
|
||||||
|
|
||||||
int lost = -1; // lost if <=
|
int lost = -1; // lost if <=
|
||||||
|
|
||||||
bool immediat = false;
|
bool immediat = false;
|
||||||
|
|
Loading…
Reference in New Issue