void AAIAttackManager::GetNextDest(AAIAttack *attack) { // prevent command overflow if((ai->Getcb()->GetCurrentFrame() - attack->lastAttack) < 60) return; // get new target sector AAISector *dest = ai->Getbrain()->GetNextAttackDest(attack->dest, attack->land, attack->water); //ai->Log("Getting next dest\n"); if(dest && SufficientAttackPowerVS(dest, &(attack->combat_groups), 2)) attack->AttackSector(dest); else attack->StopAttack(); }
void AAIAttackManager::LaunchAttack() { AAISector *dest; AttackType a_type; bool suitable, land, water; // determine attack sector // todo: improve decision when to attack base or outposts a_type = OUTPOST_ATTACK; if(cfg->AIR_ONLY_MOD) { land = true; water = true; } else { if(map->mapType == LAND_MAP) { land = true; water = false; } else if(map->mapType == LAND_WATER_MAP) { land = true; water = true; } else if(map->mapType == WATER_MAP) { land = false; water = true; } else { land = true; water = false; } } // get target sector dest = ai->brain->GetAttackDest(land, water, a_type); if(dest) { // get all available combat/aa/arty groups for attack set<AAIGroup*> combat_available; set<AAIGroup*> aa_available; if(cfg->AIR_ONLY_MOD) { for(list<UnitCategory>::iterator category = bt->assault_categories.begin(); category != bt->assault_categories.end(); ++category) { for(list<AAIGroup*>::iterator group = ai->group_list[*category].begin(); group != ai->group_list[*category].end(); ++group) { if(!(*group)->attack && (*group)->SufficientAttackPower()) combat_available.insert(*group); } } } else // non air only mods must take movement type into account { // todo: improve by checking how to reach that sector if(dest->water_ratio > 0.65) { land = false; water = true; } else { water = false; land = true; } for(list<UnitCategory>::iterator category = bt->assault_categories.begin(); category != bt->assault_categories.end(); ++category) { for(list<AAIGroup*>::iterator group = ai->group_list[*category].begin(); group != ai->group_list[*category].end(); ++group) { // check movement type first suitable = true; if(land && (*group)->group_movement_type & MOVE_TYPE_SEA) suitable = false; if(water && (*group)->group_movement_type & MOVE_TYPE_GROUND) suitable = false; if(suitable && !(*group)->attack && (*group)->task == GROUP_IDLE ) { if((*group)->group_unit_type == ASSAULT_UNIT && (*group)->SufficientAttackPower()) combat_available.insert(*group); else if((*group)->group_unit_type == ANTI_AIR_UNIT) aa_available.insert(*group); } } } } if((combat_available.size() > 0 && SufficientAttackPowerVS(dest, &combat_available, 2)) || combat_available.size() > 10) { AAIAttack *attack; try { attack = new AAIAttack(ai); } catch(...) { fprintf(ai->file, "Exception thrown when allocating memory for AAIAttack"); return; } attacks.push_back(attack); attack->land = land; attack->water = water; // add combat groups for(set<AAIGroup*>::iterator group = combat_available.begin(); group != combat_available.end(); ++group) attack->AddGroup(*group); // add antiair defence if(!aa_available.empty()) { int aa_added = 0, max_aa; // check how much aa sensible if(brain->max_units_spotted[1] < 0.2) max_aa = 0; else max_aa = 1; for(set<AAIGroup*>::iterator group = aa_available.begin(); group != aa_available.end(); ++group) { attack->AddGroup(*group); ++aa_added; if(aa_added >= max_aa) break; } } // rally attacking groups //this->RallyGroups(attack); // start the attack attack->AttackSector(dest, a_type); } // clean up aa_available.clear(); combat_available.clear(); } }