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::Create() { //L("Creating threat Array"); Clear(); const int* Enemies = ai->sh->GetEnemiesList(); double totalthreat = 0; int NumOfEnemies = ai->sh->GetNumberOfEnemies(); for (int i = 0; i < NumOfEnemies; i++){ //L("adding enemy unit"); AddEnemyUnit(Enemies[i]); } for (int i = 0; i < TotalCells; i++){ totalthreat += ThreatArray[i]; } AverageThreat = totalthreat / TotalCells; // This is for making shure that there are no problems when the threat is too low. if(AverageThreat < 1.0) AverageThreat = 1; for (int i = 0; i < TotalCells; i++){ ThreatArray[i] += AverageThreat; } //L("Threat array created!"); //ai->debug->MakeBWTGA(ThreatArray,ThreatMapWidth,ThreatMapHeight,"ThreatMap",0.5); }
void CThreatMap::AddEnemyUnit(const CEnemyUnit* e, const float scale) { CCircuitDef* cdef = e->GetCircuitDef(); if (cdef == nullptr) { AddEnemyUnitAll(e, scale); return; } if (cdef->IsAntiAir()) { AddEnemyUnit(e, airThreat, scale); } if (cdef->IsAntiLand()) { AddEnemyUnit(e, landThreat, scale); } if (cdef->IsAntiWater()) { AddEnemyUnit(e, waterThreat, scale); } AddDecloaker(e, scale); }
void CThreatMap::EnemyDamaged(CEnemyUnit* enemy) { auto it = hostileUnits.find(enemy->GetId()); if ((it == hostileUnits.end()) || !enemy->IsInLOS()) { return; } DelEnemyUnit(enemy); enemy->SetThreat(GetEnemyUnitThreat(enemy)); AddEnemyUnit(enemy); }
void CThreatMap::EnemyDamaged(int enemyUnitID, int) { std::map<int, EnemyUnit>::iterator it = enemyUnits.find(enemyUnitID); if (it != enemyUnits.end()) { EnemyUnit& enemyUnit = it->second; DelEnemyUnit(enemyUnit); enemyUnit.threat = GetEnemyUnitThreat(enemyUnit); AddEnemyUnit(enemyUnit, 1.0f); } }
void CThreatMap::EnemyCreated(int enemyUnitID) { const UnitDef* ud = ai->ccb->GetUnitDef(enemyUnitID); EnemyUnit enemyUnit; enemyUnit.id = enemyUnitID; enemyUnit.pos = ai->ccb->GetUnitPos(enemyUnitID); enemyUnit.threat = GetEnemyUnitThreat(enemyUnit); enemyUnit.range = (ai->ut->GetMaxRange(ud) + 100.0f) / (SQUARE_SIZE * THREATRES); enemyUnits[enemyUnitID] = enemyUnit; AddEnemyUnit(enemyUnit, 1.0f); }
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::EnemyCreated(int enemyUnitID) { assert(!threatCellsRaw.empty()); assert(ai->ccb->GetUnitDef(enemyUnitID) != NULL); EnemyUnit enemyUnit; enemyUnit.id = enemyUnitID; enemyUnit.pos = ai->ccb->GetUnitPos(enemyUnitID); enemyUnit.threat = GetEnemyUnitThreat(enemyUnit); enemyUnit.range = (ai->ut->GetMaxRange(ai->ccb->GetUnitDef(enemyUnitID)) + 100.0f) / (SQUARE_SIZE * THREATRES); enemyUnits[enemyUnitID] = enemyUnit; AddEnemyUnit(enemyUnit, 1.0f); }
void CThreatMap::Update() { for (int i = 0; i < TotalCells; i++) { ThreatArray[i] = 0.0f; } currMaxThreat = 0.0f; // maximum threat (normalizer) currSumThreat = 0.0f; // threat summed over all cells const int numEnemies = ai->ccb->GetEnemyUnits(&ai->unitIDs[0]); for (int i = 0; i < numEnemies; i++) { AddEnemyUnit(ai->unitIDs[i]); } for (int i = 0; i < TotalCells; i++) { currSumThreat += ThreatArray[i]; currMaxThreat = std::max(ThreatArray[i], currMaxThreat); } currAvgThreat = currSumThreat / TotalCells; #if (LUA_THREATMAP_DEBUG == 1) std::string luaDataStr; std::stringstream luaDataStream; luaDataStream << "local threatMapArray = GG.AIThreatMap;\n"; #endif for (int i = 0; i < TotalCells; i++) { #if (LUA_THREATMAP_DEBUG == 1) luaDataStream << "threatMapArray[" << i << "]"; luaDataStream << " = "; luaDataStream << ThreatArray[i]; luaDataStream << " / "; luaDataStream << currMaxThreat; luaDataStream << ";\n"; #endif ThreatArray[i] += currAvgThreat; // ? } #if (LUA_THREATMAP_DEBUG == 1) luaDataStr = luaDataStream.str(); // note: the gadget would need to reset its threatmap table to stay // in sync anyway (because the values are re-initialized to 0 here) // if we were to only send the deltas, so just copy the entire map ai->cb->CallLuaRules("[AI::KAIK::ThreatMap::Update]", -1, NULL); ai->cb->CallLuaRules(luaDataStr.c_str(), -1, NULL); #endif }
void CThreatMap::Update() { currMaxThreat = 0.0f; // account for moving units for (std::map<int, EnemyUnit>::iterator it = enemyUnits.begin(); it != enemyUnits.end(); ++it) { EnemyUnit& e = it->second; DelEnemyUnit(e); e.pos = ai->ccb->GetUnitPos(e.id); e.threat = GetEnemyUnitThreat(e); AddEnemyUnit(e, 1.0f); currMaxThreat = std::max(currMaxThreat, e.threat); } // TODO: staggered updates if (threatMapTexID >= 0) { if (currMaxThreat > 0.0f) { for (int i = 0; i < area; i++) { threatCellsVis[i] = (threatCellsRaw[i] - THREATVAL_BASE) / currMaxThreat; } ai->cb->DebugDrawerUpdateOverlayTexture(threatMapTexID, &threatCellsVis[0], 0, 0, width, height); } } #if (LUA_THREATMAP_DEBUG == 1) { std::string luaDataStr; std::stringstream luaDataStream; luaDataStream << "local threatMapArray = GG.AIThreatMap;\n"; // just copy the entire map for (int i = 0; i < area; i++) { luaDataStream << "threatMapArray[" << i << "]"; luaDataStream << " = "; luaDataStream << (threatCellsRaw[i] - THREATVAL_BASE); luaDataStream << " / "; luaDataStream << currMaxThreat; luaDataStream << ";\n"; } luaDataStr = luaDataStream.str(); ai->cb->CallLuaRules("[AI::KAIK::ThreatMap::Update]", -1, NULL); ai->cb->CallLuaRules(luaDataStr.c_str(), -1, NULL); } #endif }
void CThreatMap::Update() { // reset every frame currMaxThreat = 0.0f; // account for moving units for (std::map<int, EnemyUnit>::iterator it = enemyUnits.begin(); it != enemyUnits.end(); ++it) { EnemyUnit& e = it->second; DelEnemyUnit(e); e.pos = ai->ccb->GetUnitPos(e.id); e.threat = GetEnemyUnitThreat(e); AddEnemyUnit(e, 1.0f); currMaxThreat = std::max(currMaxThreat, e.threat); } #if (LUA_THREATMAP_DEBUG == 1) std::string luaDataStr; std::stringstream luaDataStream; luaDataStream << "local threatMapArray = GG.AIThreatMap;\n"; #endif // just copy the entire map for (int i = 0; i < area; i++) { #if (LUA_THREATMAP_DEBUG == 1) luaDataStream << "threatMapArray[" << i << "]"; luaDataStream << " = "; luaDataStream << threatCells[i]; luaDataStream << " / "; luaDataStream << currMaxThreat; luaDataStream << ";\n"; #endif } #if (LUA_THREATMAP_DEBUG == 1) luaDataStr = luaDataStream.str(); ai->cb->CallLuaRules("[AI::KAIK::ThreatMap::Update]", -1, NULL); ai->cb->CallLuaRules(luaDataStr.c_str(), -1, NULL); #endif }
void CThreatMap::DelEnemyUnit(const EnemyUnit& e) { AddEnemyUnit(e, -1.0f); }