Esempio n. 1
0
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();
	}
}