void CThreatMap::EnemyEnterLOS(CEnemyUnit* enemy) { // Possible cases: // (1) Unknown enemy that has been detected for the first time // (2) Unknown enemy that was only in radar enters LOS // (3) Known enemy that already was in LOS enters again enemy->SetInLOS(); if (enemy->GetDPS() < 0.1f) { if (enemy->GetThreat() > .0f) { // (2) // threat prediction failed when enemy was unknown if (enemy->IsHidden()) { enemy->ClearHidden(); } else { DelEnemyUnitAll(enemy); } hostileUnits.erase(enemy->GetId()); peaceUnits[enemy->GetId()] = enemy; enemy->SetThreat(.0f); enemy->SetRange(0); enemy->SetDecloakRange(GetCloakRange(enemy)); } else if (peaceUnits.find(enemy->GetId()) == peaceUnits.end()) { peaceUnits[enemy->GetId()] = enemy; enemy->SetDecloakRange(GetCloakRange(enemy)); } else if (enemy->IsHidden()) { enemy->ClearHidden(); } else { DelDecloaker(enemy); } AIFloat3 pos = enemy->GetUnit()->GetPos(); circuit->GetTerrainManager()->CorrectPosition(pos); enemy->SetPos(pos); enemy->SetKnown(); AddDecloaker(enemy); return; } if (hostileUnits.find(enemy->GetId()) == hostileUnits.end()) { hostileUnits[enemy->GetId()] = enemy; } else if (enemy->IsHidden()) { enemy->ClearHidden(); } else if (enemy->IsKnown()) { DelEnemyUnit(enemy); } else { DelEnemyUnitAll(enemy); } AIFloat3 pos = enemy->GetUnit()->GetPos(); circuit->GetTerrainManager()->CorrectPosition(pos); enemy->SetPos(pos); enemy->SetRange(GetEnemyUnitRange(enemy)); enemy->SetDecloakRange(GetCloakRange(enemy)); enemy->SetThreat(GetEnemyUnitThreat(enemy)); enemy->SetKnown(); AddEnemyUnit(enemy); }
void CThreatMap::EnemyEnterRadar(CEnemyUnit* enemy) { // Possible cases: // (1) Unknown enemy wanders at radars // (2) Known enemy that once was in los wandering at radar // (3) EnemyEnterRadar invoked right after EnemyEnterLOS in area with no radar enemy->SetInRadar(); if (enemy->IsInLOS()) { // (3) return; } if (enemy->GetDPS() < 0.1f) { // (2) if (enemy->IsHidden()) { enemy->ClearHidden(); } else { DelDecloaker(enemy); } AIFloat3 pos = enemy->GetUnit()->GetPos(); circuit->GetTerrainManager()->CorrectPosition(pos); enemy->SetPos(pos); AddDecloaker(enemy); return; } bool isNew = false; auto it = hostileUnits.find(enemy->GetId()); if (it == hostileUnits.end()) { // (1) std::tie(it, isNew) = hostileUnits.emplace(enemy->GetId(), enemy); } else if (enemy->IsHidden()) { enemy->ClearHidden(); } else { DelEnemyUnit(enemy); } AIFloat3 pos = enemy->GetUnit()->GetPos(); circuit->GetTerrainManager()->CorrectPosition(pos); enemy->SetPos(pos); if (isNew) { // unknown enemy enters radar for the first time enemy->SetThreat(enemy->GetDPS()); // TODO: Randomize enemy->SetRange(CEnemyUnit::RangeType::MAX, rangeDefault); enemy->SetRange(CEnemyUnit::RangeType::AIR, rangeDefault); enemy->SetRange(CEnemyUnit::RangeType::LAND, rangeDefault); enemy->SetRange(CEnemyUnit::RangeType::WATER, rangeDefault); enemy->SetRange(CEnemyUnit::RangeType::CLOAK, distCloak); } AddEnemyUnit(enemy); }
void CThreatMap::EnemyDestroyed(CEnemyUnit* enemy) { auto it = hostileUnits.find(enemy->GetId()); if (it == hostileUnits.end()) { if (!enemy->IsHidden()) { DelDecloaker(enemy); } peaceUnits.erase(enemy->GetId()); return; } if (!enemy->IsHidden()) { DelEnemyUnit(enemy); } hostileUnits.erase(it); }
void CThreatMap::DelEnemyUnit(const CEnemyUnit* e) { CCircuitDef* cdef = e->GetCircuitDef(); if (cdef == nullptr) { DelEnemyUnitAll(e); return; } if (cdef->HasAntiAir()) { DelEnemyAir(e); } if (cdef->HasAntiLand() || cdef->HasAntiWater()) { DelEnemyAmph(e); } DelDecloaker(e); }
void CThreatMap::DelEnemyUnitAll(const CEnemyUnit* e) { DelEnemyAir(e); DelEnemyAmph(e); DelDecloaker(e); }